3895878bfe72
2021/16
author | Steve Losh <steve@stevelosh.com> |
---|---|
date | Thu, 16 Dec 2021 01:23:51 -0500 |
parents | e41337e3b59b |
children | 6545da7f5f73 |
branches/tags | (none) |
files | data/2021/16.txt src/2021/days/day-16.lisp |
Changes
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/data/2021/16.txt Thu Dec 16 01:23:51 2021 -0500 @@ -0,0 +1,1 @@ +0052E4A00905271049796FB8872A0D25B9FB746893847236200B4F0BCE5194401C9B9E3F9C63992C8931A65A1CCC0D222100511A00BCBA647D98BE29A397005E55064A9DFEEC86600BD002AF2343A91A1CCE773C26600D126B69D15A6793BFCE2775D9E4A9002AB86339B5F9AB411A15CCAF10055B3EFFC00BCCE730112FA6620076268CE5CDA1FCEB69005A3800D24F4DB66E53F074F811802729733E0040E5C5E5C5C8015F9613937B83F23B278724068018014A00588014005519801EC04B220116CC0402000EAEC03519801A402B30801A802138801400170A0046A800C10001AB37FD8EB805D1C266963E95A4D1A5FF9719FEF7FDB4FB2DB29008CD2BAFA3D005CD31EB4EF2EBE4F4235DF78C66009E80293AE9310D3FCBFBCA440144580273BAEE17E55B66508803C2E0087E630F72BCD5E71B32CCFBBE2800017A2C2803D272BCBCD12BD599BC874B939004B5400964AE84A6C1E7538004CD300623AC6C882600E4328F710CC01C82D1B228980292ECD600B48E0526E506F700760CCC468012E68402324F9668028200C41E8A30E00010D8B11E62F98029801AB88039116344340004323EC48873233E72A36402504CB75006EA00084C7B895198001098D91AE2190065933AA6EB41AD0042626A93135681A400804CB54C0318032200E47B8F71C0001098810D61D8002111B228468000E5269324AD1ECF7C519B86309F35A46200A1660A280150968A4CB45365A03F3DDBAE980233407E00A80021719A1B4181006E1547D87C6008E0043337EC434C32BDE487A4AE08800D34BC3DEA974F35C20100BE723F1197F59E662FDB45824AA1D2DDCDFA2D29EBB69005072E5F2EDF3C0B244F30E0600AE00203229D229B342CC007EC95F5D6E200202615D000FB92CE7A7A402354EE0DAC0141007E20C5E87A200F4318EB0C
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/2021/days/day-16.lisp Thu Dec 16 01:23:51 2021 -0500 @@ -0,0 +1,59 @@ +(advent:defpackage* :advent/2021/16) +(in-package :advent/2021/16) + +(defun parse (stream) + (let ((line (read-line stream))) + (values (parse-integer line :radix 16) + (* 4 (length line))))) + +(defun-inline rldb (size pos byte) + (ldb (byte size (- pos (1- size))) byte)) + +(defun gt (a b) (if (> a b) 1 0)) +(defun lt (a b) (if (< a b) 1 0)) +(defun == (a b) (if (= a b) 1 0)) + +(defun packets (data length &aux (i (1- length))) + (labels ((pop-bits (size) + (prog1 (rldb size i data) (decf i size))) + (parse-literal () + (iterate (for marker = (pop-bits 1)) + (for chunk = (pop-bits 4)) + (collect chunk :into result) + (until (zerop marker)) + (finally (return (digits->number result :radix 16))))) + (parse-operator () + (ecase (pop-bits 1) + (0 (loop :with subpacket-length = (pop-bits 15) + :with end = (- i subpacket-length) + :while (> i end) + :collect (parse-packet))) + (1 (loop :with number-of-subpackets = (pop-bits 11) + :repeat number-of-subpackets + :collect (parse-packet))))) + (op (type-id) + (aref #(+ * min max quote gt lt ==) type-id)) + (parse-packet () + (let ((version (pop-bits 3)) + (type-id (pop-bits 3))) + (list* :version version :op (op type-id) + (case type-id + (4 (list :value (parse-literal))) + (t (list :contents (parse-operator)))))))) + (parse-packet))) + +(defun version-sum (packet) + (reduce #'+ (getf packet :contents) + :key #'version-sum :initial-value (getf packet :version))) + +(defun packet-sum (packet &aux (op (getf packet :op))) + (case op + (quote (getf packet :value)) + (t (reduce (getf packet :op) (getf packet :contents) :key #'packet-sum)))) + +(define-problem (2021 16) (stream) (986 18234816469452) + (multiple-value-bind (data length) (parse stream) + (let ((packets (packets data length))) + (values (version-sum packets) (packet-sum packets))))) + +#; Scratch --------------------------------------------------------------------