day07
This commit is contained in:
		
							parent
							
								
									926fc844ae
								
							
						
					
					
						commit
						fa73b26e7b
					
				
					 1 changed files with 79 additions and 0 deletions
				
			
		
							
								
								
									
										79
									
								
								2023/day07.nim
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								2023/day07.nim
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,79 @@
 | 
			
		|||
import std/[algorithm, enumerate, sequtils, sets, strutils, tables]
 | 
			
		||||
 | 
			
		||||
type
 | 
			
		||||
  HandType = enum
 | 
			
		||||
    highCard, onePair, twoPair, threeOfAKind,
 | 
			
		||||
    fullHouse, fourOfAKind, fiveOfAKind
 | 
			
		||||
  Hand = tuple[cards: string, typ: HandType, bid: int]
 | 
			
		||||
 | 
			
		||||
const
 | 
			
		||||
  handValues = {
 | 
			
		||||
    (5, 0): fiveOfAKind,
 | 
			
		||||
    (4, 1): fourOfAKind,
 | 
			
		||||
    (3, 2): fullHouse,
 | 
			
		||||
    (3, 1): threeOfAKind,
 | 
			
		||||
    (2, 2): twoPair,
 | 
			
		||||
    (2, 1): onePair,
 | 
			
		||||
    (1, 1): highCard,
 | 
			
		||||
    (1, 0): highCard
 | 
			
		||||
  }.toTable
 | 
			
		||||
 | 
			
		||||
var cardOrder: string
 | 
			
		||||
 | 
			
		||||
proc cmp(x, y: Hand): int =
 | 
			
		||||
  if x.typ != y.typ:
 | 
			
		||||
    return ord(x.typ) - ord(y.typ)
 | 
			
		||||
  for (xc, yc) in zip(x.cards, y.cards):
 | 
			
		||||
    if xc != yc:
 | 
			
		||||
      return cardOrder.find(xc) - cardOrder.find(yc)
 | 
			
		||||
  return 0
 | 
			
		||||
 | 
			
		||||
func count(cards: string): seq[int] =
 | 
			
		||||
  let cardTypes = cards.toHashSet()
 | 
			
		||||
  result.add(0)
 | 
			
		||||
  for t in cardTypes:
 | 
			
		||||
    result.add(cards.count(t))
 | 
			
		||||
  result.sort(SortOrder.Descending)
 | 
			
		||||
 | 
			
		||||
func handType(cards: string): HandType =
 | 
			
		||||
  let counts = cards.count()
 | 
			
		||||
  result = handValues[(counts[0], counts[1])]
 | 
			
		||||
 | 
			
		||||
func handTypeP2(cards: string): HandType =
 | 
			
		||||
  let 
 | 
			
		||||
    counts = cards.replace("J", "").count()
 | 
			
		||||
    jokers = cards.count('J')
 | 
			
		||||
  if counts.len > 1:
 | 
			
		||||
    result = handValues[(counts[0] + jokers, counts[1])]
 | 
			
		||||
  else:
 | 
			
		||||
    result = handValues[(counts[0] + jokers, 0)]
 | 
			
		||||
 | 
			
		||||
proc hand(line: string, handType: proc(c: string): HandType): Hand =
 | 
			
		||||
  let
 | 
			
		||||
    sp = line.split(' ')  
 | 
			
		||||
    (cards, bid) = (sp[0], sp[1].parseInt)
 | 
			
		||||
    typ = cards.handType()
 | 
			
		||||
  result = (cards, typ, bid)
 | 
			
		||||
 | 
			
		||||
proc winnings(hands: seq[Hand]): int =
 | 
			
		||||
  for (rank, hand) in enumerate(1, hands):
 | 
			
		||||
    result += hand.bid * rank
 | 
			
		||||
 | 
			
		||||
proc parse(input: string): seq[Hand] =
 | 
			
		||||
  input.splitLines().mapIt(hand(it, handType))
 | 
			
		||||
 | 
			
		||||
proc parseP2(input: string): seq[Hand] =
 | 
			
		||||
  input.splitLines().mapIt(hand(it, handTypeP2))
 | 
			
		||||
 | 
			
		||||
proc p1(input: string) =
 | 
			
		||||
  cardOrder = "23456789TJQKA"
 | 
			
		||||
  echo input.parse().sorted(cmp).winnings()
 | 
			
		||||
 | 
			
		||||
proc p2(input: string) =
 | 
			
		||||
  cardOrder = "J123456789TQKA"
 | 
			
		||||
  echo input.parseP2().sorted(cmp).winnings()
 | 
			
		||||
 | 
			
		||||
when isMainModule:
 | 
			
		||||
  let input = stdin.readAll().strip()
 | 
			
		||||
  p1(input)
 | 
			
		||||
  p2(input)
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue