2023 day 2 part 1

quickdudley
Aug 16, 2024, 12:31 AM
RDQKKB5GI2SJIHD3QCBBRE5IC6T2LAEPDAAMHOZCGCCKVGLQRSBQC

Dependencies

  • [2] LMKWOZVD Solution for 2023 day 1 part 1

Change contents

  • file addition: day2.lisp (----------)
    [2.16]
    (defconstant cube-limits
    (let ((table (make-hash-table)))
    (setf (gethash 'red table) 12)
    (setf (gethash 'green table) 13)
    (setf (gethash 'blue table) 14)
    table))
    (defun check-limit (draw)
    (block s
    (loop for colour being each hash-key in draw using (hash-value count)
    do (let ((limit (gethash colour cube-limits)))
    (if (> count (or limit 0))
    (return-from s nil))))
    T))
    (defstruct tokenizer
    (source nil :type string)
    (position 0 :type integer))
    (defmacro check-ranges (qe &rest bounds)
    (let ((qry (gensym)) (last-bound nil) (in-range nil) (node-stack nil))
    (dolist (bound bounds)
    (if (and node-stack in-range (eq bound last-bound)
    (not (eq nil last-bound)))
    (progn
    (setf in-range nil)
    (setf (car node-stack) `(if (= ,qry ,bound) t nil)))
    (let ((new-node
    (if in-range
    `(if (<= ,qry ,bound)
    t
    nil)
    `(if (< ,qry ,bound)
    nil
    t))))
    (setf last-bound bound)
    (push new-node node-stack)
    (setf in-range (not in-range)))))
    (let ((node nil))
    (loop for new-node = (pop node-stack)
    while new-node
    do (setf node
    (if node
    (append
    (subseq new-node 0 3)
    (list node)
    (subseq new-node 4))
    new-node)))
    `(let ((,qry ,qe))
    ,node))))
    (defun is-space (the-char)
    (check-ranges (char-code the-char) 9 13 32 32 160 160 5760 5760 8192 8202
    8239 8239 8287 8287 12288 12288))
    (defun skip-whitespace (toks)
    (loop while (and
    (< (tokenizer-position toks) (length (tokenizer-source toks)))
    (is-space
    (aref (tokenizer-source toks) (tokenizer-position toks))))
    do (incf (tokenizer-position toks))))
    (defun next-token (toks)
    (skip-whitespace toks)
    (when (< (tokenizer-position toks) (length (tokenizer-source toks)))
    (let*
    ((ix (tokenizer-position toks))
    (alf (alphanumericp (aref (tokenizer-source toks) ix))))
    (loop
    while (and (< ix (length (tokenizer-source toks)))
    (let ((cc (aref (tokenizer-source toks) ix)))
    (and
    (not (is-space cc))
    (eq alf (alphanumericp cc)))))
    do (incf ix))
    (prog1
    (subseq (tokenizer-source toks) (tokenizer-position toks) ix)
    (setf (tokenizer-position toks) ix)))))
    (defun parse-line (line)
    (let ((toks (make-tokenizer :source line))
    (game-number nil)
    (current-grab (make-hash-table))
    (grabs nil))
    (unless (equalp "Game" (next-token toks))
    (warn "Input line doesn't begin with \"Start\""))
    (setf game-number (parse-integer (next-token toks)))
    (unless (equalp ":" (next-token toks))
    (warn "Missing colon"))
    (loop for count = (let ((tok (next-token toks)))
    (if tok
    (parse-integer tok)))
    for colour = (intern (string-upcase (next-token toks)))
    while (and count colour)
    do (setf (gethash colour current-grab) count)
    (unless (equalp "," (next-token toks))
    (push current-grab grabs)
    (setf current-grab (make-hash-table))))
    (cons game-number (reverse grabs))))
    (defun all (predicate values)
    (dolist (value values)
    (unless (funcall predicate value)
    (return-from all nil)))
    t)
    (defun process-file (instream)
    (format t "~a~%" (loop for line = (read-line instream nil)
    while line
    sum (if (equalp line "")
    0
    (let ((game (parse-line line)))
    (if (all #'check-limit (cdr game))
    (car game)
    0))))))
    (defun main ()
    (loop for arg in (cdr *posix-argv*)
    do (with-open-file (s arg :direction :input)
    (process-file s))))