blob: 3a1fe8a92350541a0f159afd48f7e897e4215ea1 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
(ql:quickload '(fiveam arrows trivia str))
(defpackage #:day07
(:use #:cl)
(:local-nicknames (#:f #:fiveam)))
(in-package :day07)
(defparameter eg-input "32T3K 765
T55J5 684
KK677 28
KTJJT 220
QQQJA 483")
(defun occurences (str)
(let ((bag (make-hash-table)))
(loop
for le across str
do (incf (gethash le bag 0)))
(sort (alexandria:hash-table-values bag) #'>)))
(defun hand-type (str)
(trivia:match (occurences str)
((list 5) 5)
((list 4 1) 4)
((list 3 2) 3)
((list 3 1 1) 2)
((list 2 2 1) 1)
((list 2 1 1 1) 0)
((list 1 1 1 1 1) -1)))
(defun card-strength (card)
(position card "23456789TJQKA"))
(defun card-< (a b)
(< (card-strength a) (card-strength b)))
(defun hand-< (a b)
(let ((a-t (hand-type a))
(b-t (hand-type b)))
(cond
((< a-t b-t))
((= a-t b-t)
(loop for l across a
for s across b
unless (eq l s)
return (card-< l s))))))
(f:test partial
(f:is
(equal '(3 1 1)
(occurences "QJQAQ")))
(f:is (hand-< "2AAAA" "33332"))
(f:is (hand-< "77788" "77888"))
(f:is (hand-< "77788" "77778")))
(defun parse-input (str)
(let ((data (arrows:->>
(ppcre:split "\\s" str)
(remove-if #'str:empty?))))
(loop for (hand bid) on data by #'cddr
collect (cons hand (parse-integer bid)))))
(defun total-win (sorted-hands)
(loop for (hand . bid) in sorted-hands
for c from 1
sum (* c bid)))
(defun solver1 (lines)
(arrows:->
(parse-input lines)
(sort #'hand-< :key #'car)
(total-win)))
(f:test solutions
(f:is
(= 6440
(solver1 eg-input)))
(f:is
(= 253205868
(solver1
(uiop:read-file-string "input")))))
|