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