Summary Files Commits Branches @commit @diff @stats
path: root / AoC-2022-Exercise11-Incomplete.cl
blob: cceb2b1b757d2e1b8dcbafb8ef406318159948dd (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
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
(require :senzill)
(use-package :senzill.math)
(use-package :senzill.collections)
(use-package :senzill.io)

(defmacro { (&rest body)
  (loop for com in body
        unless (and (symbolp com) (string= com '}))
        if (string= (car com) 'var)
          collect (cdr com) into localvars
        else
          if (string= (car com) 'fun)
            collect (cdr com) into localfuncs
          else
            collect com into newbody
        finally
          (return `(let ,localvars (flet ,localfuncs ,@newbody)))))

(defun split-seq (seq &key (delim #\ ) (delim-len 1) (start 0))
  (loop for itms = (subseq seq start) then (subseq itms (+ delim-len sppos))
        for sppos = (position delim itms) then (position delim itms)
        collect (subseq itms 0 sppos)
        while sppos))

;;;;;;;;;

(defparameter +rounds+ 20)

({
  (fun monkey-ctor (starting-items operation divisible throw-t throw-f) ({
       (var opfun (if (symbolp (second operation))
                    (lambda (old) (funcall (first operation) old old))
                    (lambda (old) (funcall (first operation) old (second operation)))))
       (var testfun (lambda (worry-level) (zerop (% worry-level divisible))))
       (list :i starting-items :op opfun :test testfun :t throw-t :f throw-f
             :insp 0)
       }))

  (fun inspect-throw (m mt mf) ({
       (setf (first (getf m :i))
             (floor (/ (funcall (getf m :op) (first (getf m :i))) 3)))
       (++1 (getf m :insp))
       (if (funcall (getf m :test) (first (getf m :i)))
         (push-back (pop (getf m :i)) (getf mt :i))
         (push-back (pop (getf m :i)) (getf mf :i)))
       }))

  (var monkeys '())
  (var cmonkey '(() (+ 0) 1 -1 -1))
  (ask-for-stream (prog-input)
    (doread-lines (inpt :read-line-options (prog-input NIL))
                  (cond ((zerop (length inpt)))
                        ((char= (char inpt 0) #\M) ; Monkey #:
                         (push-back (apply #'monkey-ctor cmonkey) monkeys)
                         (setf cmonkey '()))
                        ((char= (char inpt 2) #\S) ;   Starting items:
                         (push-back (map 'list #'parse-integer (split-seq inpt :delim #\, :delim-len 2 :start 18)) cmonkey))
                        ((char= (char inpt 2) #\O) ;   Operation:
                         (push-back (map 'list #'read-from-string (split-seq inpt :start 23)) cmonkey))
                        ((char= (char inpt 2) #\T) ;   Test:
                         (push-back (parse-integer inpt :start 21) cmonkey))
                        ((char= (char inpt 7) #\t) ;     If true:
                         (push-back (parse-integer inpt :start 29) cmonkey))
                        ((char= (char inpt 7) #\f) ;     If false:
                         (push-back (parse-integer inpt :start 30) cmonkey)))))
  (pop monkeys)
  (push-back (apply #'monkey-ctor cmonkey) monkeys)

  (dotimes (r +rounds+)
    (loop for m in monkeys
          do (loop for item in (getf m :i)
                   do (inspect-throw m
                                     (nth (getf m :t) monkeys)
                                     (nth (getf m :f) monkeys))
                      (print r))))
  (print monkeys)

  })