aboutsummaryrefslogtreecommitdiff
path: root/2022/Day02/part-one.cl
blob: e93cae8f85f05ded951a8ca32f398292f7c14e37 (plain) (blame)
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
(defvar *prog-input*)

(let ((ui (read-line)))
  (if (equal ui "")
    (setq *prog-input* *standard-input*)
    (setq *prog-input* (open ui))))

(let
  ((cal (read-line *prog-input* NIL)) (total-score 0)
   (your-rps '(#\0 #\X #\Y #\Z)) (enemy-rps '(#\0 #\A #\B #\C))
   (cy-rps 0) (ce-rps 0))

  (loop until (or (equal cal "end") (not cal)) do
        ;; Rock is 1, paper is 2, scissors is 3
        (setq ce-rps (position (char cal 0) enemy-rps))
        (setq cy-rps (position (char cal 2) your-rps))

        ;; We want, when we lose to add 3 * 0, when we draw to add 3 * 1 and when we win to add 3 * 2
        ;; To get numbers 0, 1, and 2, we'll use `3 mod N`
        ;; Writing down all possible combinations
        ;; (from left to right, columns are "Your choice", "Enemy choice", "Result"):
        ;; 1 1 | 1 = 3 % 1 (Draw)
        ;; 1 2 | 0 = 3 % 3 (Lose)
        ;; 1 3 | 2 = 3 % 2 (Win)
        ;; ----+-----------------
        ;; 2 1 | 2 = 3 % 2 (Win)
        ;; 2 2 | 1 = 3 % 1 (Draw)
        ;; 2 3 | 0 = 3 % 3 (Lose)
        ;; ----+-----------------
        ;; 3 1 | 0 = 3 % 3 (Lose)
        ;; 3 2 | 2 = 3 % 2 (Win)
        ;; 3 3 | 1 = 3 % 1 (Draw)
        ;; We notice, that N (in "3 % N") is a rotation of the numbers 3, 2, 1, where if your choice
        ;; is 3, we don't rotate them, if it's 2 we rotate by one (backwards) and so on.
        ;; We can get 3, 2, 1 from the enemie's 1, 2, 3 by subtracting them from 4. Then we can use
        ;; your choice to do the "rotation" (since we're doing mod, 3 % 3 = 3 % 6).
        (setq total-score (+ total-score (* 3 (mod (+ (- 4 ce-rps) cy-rps) 3)) cy-rps))

        (setq cal (read-line *prog-input* NIL)))

  (print total-score))

(if (not (eq *prog-input* *standard-input*))
  (close *prog-input*))