day 2: rock-paper-scissors scoring
This commit is contained in:
parent
455cee8c79
commit
540a1a52c5
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,174 @@
|
||||||
|
;;;; https://adventofcode.com/2022/day/2
|
||||||
|
|
||||||
|
;; input is lines [A B C] [X Y Z]
|
||||||
|
;; meaning a-b-c what opponent will play
|
||||||
|
;; and x y z what i should play in rock-paper-scissors
|
||||||
|
;;
|
||||||
|
;; score is calculated as:
|
||||||
|
;; 1 for Rock X
|
||||||
|
;; 2 for Paper Y
|
||||||
|
;; 3 for Scissors Z
|
||||||
|
;;
|
||||||
|
;; 0 if Lost
|
||||||
|
;; 3 if Tie
|
||||||
|
;; 6 if Win
|
||||||
|
;;
|
||||||
|
;; Win if
|
||||||
|
;; (A Y) (B Z) (C X)
|
||||||
|
(setq MY-WIN-COMBINATIONS '((A Y) (B Z) (C X)))
|
||||||
|
;;
|
||||||
|
;; Loss if
|
||||||
|
;; (X B) (Y C) (Z A)
|
||||||
|
(setq MY-LOSS-COMBINATIONS '((B X) (C Y) (A Z)))
|
||||||
|
;;
|
||||||
|
;; otherwise it's a tie
|
||||||
|
(setq TIE-COMBINATIONS '((A X) (B Y) (C Z)))
|
||||||
|
|
||||||
|
;; now i'd also like to get symbol from the string...
|
||||||
|
(equal (intern "a") (intern "A")) ; not exactly what i means, but yeah this is it
|
||||||
|
|
||||||
|
;; now i'd like to get list of two symbols from string of two symbols
|
||||||
|
(setq my-test-line "A Z")
|
||||||
|
|
||||||
|
;; https://stackoverflow.com/questions/59516459/split-string-by-delimiter-and-include-delimiter-common-lisp
|
||||||
|
(require 'cl-ppcre)
|
||||||
|
(cl-ppcre:split "(\\.)" "a.bc.def.com" :with-registers-p t)
|
||||||
|
(cl-ppcre:split "(\\.)" "a.bc.def.com" :with-registers-p nil)
|
||||||
|
|
||||||
|
(setq my-test-line-list (mapcar #'intern (cl-ppcre:split "(\\ )" my-test-line :with-registers-p nil)))
|
||||||
|
;; yay
|
||||||
|
|
||||||
|
;;; now write scoring function over the lists of chars, for tie-win-loose match and for "my-selection-match"
|
||||||
|
;; sum the scores of the two parts of scoring
|
||||||
|
;; and iterate over input
|
||||||
|
;; would be cool to use pattern matching...
|
||||||
|
;; that's something like CASE in my
|
||||||
|
|
||||||
|
(case 1
|
||||||
|
((:in :in2) :lala)
|
||||||
|
((2 3) :numBig)
|
||||||
|
((1 -1) :numOne))
|
||||||
|
|
||||||
|
(case (list 1 2)
|
||||||
|
((:in :in2) :just-sym)
|
||||||
|
((list 1 2) :a-list))
|
||||||
|
;; this doesn't work with lists.
|
||||||
|
|
||||||
|
;; COND is similar to CASE, except it is more general. It accepts arbitrary
|
||||||
|
(find my-test-line-list my-win-combinations :TEST #'equal)
|
||||||
|
(find my-test-line-list my-loss-combinations :TEST #'equal)
|
||||||
|
|
||||||
|
(cond
|
||||||
|
((find my-test-line-list my-win-combinations :TEST #'equal) :WIN)
|
||||||
|
((find my-test-line-list my-loss-combinations :TEST #'equal) :LOSS)
|
||||||
|
(t :TIE))
|
||||||
|
|
||||||
|
(defun score-result (hands)
|
||||||
|
(cond
|
||||||
|
((find hands my-win-combinations :TEST #'equal)
|
||||||
|
6)
|
||||||
|
((find hands my-loss-combinations :TEST #'equal)
|
||||||
|
0)
|
||||||
|
(t 3)))
|
||||||
|
|
||||||
|
(score-result '(A Z))
|
||||||
|
(score-result '(A Y))
|
||||||
|
|
||||||
|
;;; now let's get score of the hands, by only my hand
|
||||||
|
(defun score-my-hand (hands)
|
||||||
|
(let ((my-hand (second hands)))
|
||||||
|
(case my-hand
|
||||||
|
(X 1)
|
||||||
|
(Y 2)
|
||||||
|
(z 3))))
|
||||||
|
|
||||||
|
(score-my-hand '(A Z))
|
||||||
|
(score-my-hand '(A Y))
|
||||||
|
(score-my-hand '(A X))
|
||||||
|
|
||||||
|
(defun full-score-hands (hands)
|
||||||
|
(+ (score-my-hand hands) (score-result hands)))
|
||||||
|
|
||||||
|
(full-score-hands '(A Y))
|
||||||
|
(full-score-hands '(B X))
|
||||||
|
(full-score-hands '(C Z))
|
||||||
|
|
||||||
|
;;; and now, iterate over file, converting strings into symbols and accumulating the score...
|
||||||
|
(require 'cl-ppcre)
|
||||||
|
(setq running-sum 0)
|
||||||
|
(let ((running-sum 0))
|
||||||
|
(with-open-file (in "~/Documents/personal/advent-of-code/2022/day2-input.txt")
|
||||||
|
(loop
|
||||||
|
for line = (read-line in nil nil)
|
||||||
|
while line
|
||||||
|
;; do (format t "line ~A~%" line)
|
||||||
|
do (let* ((line-word-list (cl-ppcre:split "(\\ )" line :with-registers-p nil))
|
||||||
|
(hands (mapcar #'intern line-word-list)))
|
||||||
|
(incf running-sum (full-score-hands hands)))
|
||||||
|
finally (return running-sum)
|
||||||
|
)))
|
||||||
|
|
||||||
|
;; (setq my-test-line-list (mapcar #'intern (cl-ppcre:split "(\\ )" my-test-line :with-registers-p nil)))
|
||||||
|
;; 12156 is the right answer!
|
||||||
|
;; let's wrap this into a function
|
||||||
|
(defun count-plays-score (filename)
|
||||||
|
(require 'cl-ppcre)
|
||||||
|
(let ((running-sum 0))
|
||||||
|
(with-open-file (in filename)
|
||||||
|
(loop
|
||||||
|
for line = (read-line in nil nil)
|
||||||
|
while line
|
||||||
|
do (let* ((line-word-list (cl-ppcre:split "(\\ )" line :with-registers-p nil))
|
||||||
|
(hands (mapcar #'intern line-word-list)))
|
||||||
|
(incf running-sum (full-score-hands hands)))
|
||||||
|
finally (return running-sum)
|
||||||
|
))))
|
||||||
|
(count-plays-score "~/Documents/personal/advent-of-code/2022/day2-input.txt")
|
||||||
|
|
||||||
|
;;; now for the Second part of the game
|
||||||
|
;; second part means something else!
|
||||||
|
;; X - need to loose
|
||||||
|
;; Y - need to draw
|
||||||
|
;; Z - need to win
|
||||||
|
;;
|
||||||
|
;; so, scoring is the same, but I need to calculate what is my hand
|
||||||
|
;; C Z means they play (SCISSORS) and i need to WIN, so I need to get ROCK
|
||||||
|
;; that goes into the calculation of the score
|
||||||
|
;; i would be able to reuse the scoring function,
|
||||||
|
;; but! i need a funtion that returns my hand
|
||||||
|
;; let's put it off for a bit?
|
||||||
|
;; or no. so. this would be best with what? ugh.
|
||||||
|
;; so Z - find hand from loose-hands that starts with required hand
|
||||||
|
;; Y - find from draw, Z - find from win
|
||||||
|
;; could use #'FIND with cusom :TEST - to compare only first item
|
||||||
|
|
||||||
|
(defun get-hand-set-by-result (hands)
|
||||||
|
(case (second hands)
|
||||||
|
(X my-loss-combinations)
|
||||||
|
(Y tie-combinations)
|
||||||
|
(Z my-win-combinations)))
|
||||||
|
|
||||||
|
(get-hand-set-by-result '(A Y))
|
||||||
|
(get-hand-set-by-result '(B X))
|
||||||
|
(get-hand-set-by-result '(C Z))
|
||||||
|
|
||||||
|
;; ok, somewhat like that
|
||||||
|
(find (first '(A Y))
|
||||||
|
(get-hand-set-by-result '(A Y)) :KEY (lambda (hands) (first hands)) )
|
||||||
|
|
||||||
|
(defun count-plays-score-2 (filename)
|
||||||
|
(require 'cl-ppcre)
|
||||||
|
(let ((running-sum 0))
|
||||||
|
(with-open-file (in filename)
|
||||||
|
(loop
|
||||||
|
for line = (read-line in nil nil)
|
||||||
|
while line
|
||||||
|
do (let* ((line-word-list (cl-ppcre:split "(\\ )" line :with-registers-p nil))
|
||||||
|
(hand-and-result (mapcar #'intern line-word-list))
|
||||||
|
(handset (get-hand-set-by-result hand-and-result))
|
||||||
|
(hands (find (first hand-and-result) handset :KEY (lambda (hands) (first hands)) )))
|
||||||
|
(incf running-sum (full-score-hands hands)))
|
||||||
|
finally (return running-sum)
|
||||||
|
))))
|
||||||
|
(count-plays-score-2 "~/Documents/personal/advent-of-code/2022/day2-input.txt")
|
||||||
|
;; 10835 is the right answer!
|
Loading…
Reference in New Issue