Untitled
unknown
lisp
2 years ago
3.0 kB
5
Indexable
(defun card-value (char)
(case char
((?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9) (- char 48))
((?T) 10)
((?J) 11)
((?Q) 12)
((?K) 13)
((?A) 14)))
(defstruct hand values count-map max bid strength)
(defun n-of-a-kind-p (hand num)
(some (lambda (n)
(>= n num))
(hash-table-values (hand-count-map hand))))
(defun 5-of-a-kind-p (hand) (n-of-a-kind-p hand 5))
(defun 4-of-a-kind-p (hand) (n-of-a-kind-p hand 4))
(defun 3-of-a-kind-p (hand) (n-of-a-kind-p hand 3))
(defun full-house-p (hand)
(let ((vals (hash-table-values (hand-count-map hand))))
(and (find 3 vals)
(find 2 vals))))
(defun 2-pair-p (hand)
(let ((vals (hash-table-values (hand-count-map hand))))
(>= (count-if (lambda (n) (>= n 2))
vals)
2)))
(defun 1-pair-p (hand)
(let ((vals (hash-table-values (hand-count-map hand))))
(find-if (lambda (n) (>= n 2)) vals)))
(defun less-than-p (card-list card-list2)
(let ((next-l1 (car card-list))
(next-l2 (car card-list2)))
(cond ((null card-list) t)
((> next-l1 next-l2) nil)
((< next-l1 next-l2) t)
(t (less-than-p (cdr card-list)
(cdr card-list2))))))
(defun strength (hand)
(cond ((5-of-a-kind-p hand) 6)
((4-of-a-kind-p hand) 5)
((full-house-p hand) 4)
((3-of-a-kind-p hand) 3)
((2-pair-p hand) 2)
((1-pair-p hand) 1)
(t 0)))
(defun compare (hand hand2)
(let ((rank1 (hand-strength hand))
(rank2 (hand-strength hand2)))
(cond ((= rank1 rank2) (less-than-p (hand-values hand)
(hand-values hand2)))
((< rank1 rank2) t)
((> rank1 rank2) nil))))
(defun line->hand (hand-str bid-str)
(let ((hash (make-hash-table :test #'equal :size 5))
(bid (string-to-number bid-str)))
(multiple-value-bind (values max)
(cl-loop for c across hand-str
do (incf (gethash (card-value c) hash 0) 1)
maximize (card-value c) into m
collect (card-value c) into cards
finally (return (values cards m)))
(let ((hand (make-hand :values values
:count-map hash
:max max
:bid bid)))
(setf (hand-strength hand) (strength hand))
hand))))
(defun read-lines (filePath)
(with-temp-buffer
(insert-file-contents filePath)
(split-string (buffer-string) "\n" t)))
(defun help-elves (filepath)
(let ((hands (cl-loop for (hand-str bid-str)
in (mapcar #'split-string (read-lines filepath))
collect (line->hand hand-str bid-str) into h
finally (return (sort h #'compare)))))
(cl-loop for i from 1 to (+ 1 (length hands))
for h in hands
do (print (cons h i))
sum (* (hand-bid h) i))))Editor is loading...
Leave a Comment