ref: 9d3f7ae1148f12e10c0179bdcc4992b44060f43a advent-of-code/2018-12-09.lisp -rw-r--r-- 2.2 KiB View raw
                                                                                
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
81
82
(defpackage "AOC/9" (:use "CL"))
(in-package "AOC/9")

;; store marbles in a record (number . (prev . next))
(defun value (current)
  (car current))

(defun prev (current)
  (cadr current))

(defun (setf prev) (new-value current)
  (setf (cadr current) new-value))

(defun next (current)
  (cddr current))

(defun (setf next) (new-value current)
  (setf (cddr current) new-value))

(defun print-marbles (current)
  (cons (value current)
        (loop for m = (next current) then (next m)
              until (eq m current)
              collect (value m))))

(defun insert (value current)
  (let* ((a (next current))
         (b (next a))
         (new (cons value (cons a b))))
    (setf (next a) new
          (prev b) new)))

(defun start ()
  (let ((node (cons 0 (cons nil nil))))
    (setf (next node) node
          (prev node) node)))

(defun score (value current)
  (let* ((a (prev (prev (prev (prev (prev (prev current)))))))
         (b (prev a))
         (c (prev b)))
    (setf (prev a) c
          (next c) a)
    (values a (+ value (value b)))))

(defun turn (value current)
  (if (zerop (mod value 23))
      (score value current)
      (insert value current)))

;; (defun game (players high-score)
;;   (loop for i from 1
;;         with c = (start)
;;         and scores = (make-list players)
;;         while (< (apply #'max scores) high-score)
;;         do (multiple-value-bind (current score)
;;                (turn i c)
;;              (when score
;;                (incf (nth (mod i players) scores) score))
;;              (setf c current))))

(defun solution-1 ()
  (loop for i from 1 to 71482
        with c = (start)
        and scores = (make-list 424 :initial-element 0)
        do (multiple-value-bind (current score)
               (turn i c)
             (when score
               (incf (nth (mod i 424) scores) score))
             (setf c current))
        finally (return (apply #'max scores))))

(defun solution-2 ()
  (loop for i from 1 to 7148200
        with c = (start)
        and scores = (make-list 424 :initial-element 0)
        do (multiple-value-bind (current score)
               (turn i c)
             (when score
               (incf (nth (mod i 424) scores) score))
             (setf c current))
        finally (return (apply #'max scores))))