aoc-2022

My solutions in postscript to Advent of Code 2022
Log | Files | Refs | README | LICENSE

commit 99a2d0233f0e6fc1ee6407e5684bb93fbfaf0136
parent e4ef5290fbb41cf2df77b8564e02456dc579ca6d
Author: Natasha Kerensikova <natacha@instinctive.eu>
Date:   Mon, 19 Dec 2022 16:42:49 +0100

Add day 19 reference input and solutions

Diffstat:
Aday19.ps | 617+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aday19.txt | 2++
2 files changed, 619 insertions(+), 0 deletions(-)

diff --git a/day19.ps b/day19.ps @@ -0,0 +1,617 @@ +%!PS +% +% Copyright (c) 2022, Natacha Porté +% +% Permission to use, copy, modify, and distribute this software for any +% purpose with or without fee is hereby granted, provided that the above +% copyright notice and this permission notice appear in all copies. +% +% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +% +% Usage: +% gs -q- -sDEVICE=png16m -o- day19.ps <day19.txt | display + +% [ item_1 ... item_n ] item_0 -> [ item_0 item_1 ... item_n ] +/apush { + % array new_item + exch aload length 1 add array astore +} bind def + +% [ item_0 ... item_n-1 ] item_n -> [ item_0 item_1 ... item_n ] +/aappend { + % [ item_0 ... item_n-1 ] item_n + 1 index length + % [ item_0 ... item_n-1 ] item_n n + dup 1 add array + % [ item_0 ... item_n-1 ] item_n n new-array + dup 5 4 roll + % item_n n new-array new-array [ item_0 ... item_n-1 ] + 0 exch putinterval + % item_n n [ item_0 ... item_n-1 null ] + dup 4 2 roll + % [ item_0 ... item_n-1 null ] [ item_0 ... item_n-1 null ] item_n n + exch put + % [ item_0 ... item_n-1 item_n ] +} bind def + +% [ item_0 item_1 ... item_n ] -> [ item_1 ... item_n ] item_0 +/apop { + % [ item_0 item_1 ... item_n ] + dup 0 get exch + % item_0 [ item_0 item_1 ... item_n ] + 1 1 index length 1 sub + % item_0 [ item_0 item_1 ... item_n ] 1 n + getinterval + % item_0 [ item_1 ... item_n ] + exch + % [ item_1 ... item_n ] item_0 +} bind def + +% [item1a item2a ... itemma] [item1b item2b ... itemmnb] +% -> [[item1a item1b] [item2a item2b] ... [item(min(m,n))a item(min(m,n))b]] +/azip { + % [item1a item2a ... itemma] [item1b item2b ... itemnb] + 0 1 3 index length 3 index length + % [item1a item2a ... itemma] [item1b item2b ... itemnb] 0 1 n m + 2 copy gt { exch } if pop + % [item1a item2a ... itemma] [item1b item2b ... itemnb] 0 1 min(m,n) + [ 6 1 roll + % mark [item1a item2a ... itemma] [item1b item2b ... itemnb] 0 1 min(m,n) + 1 sub { + % mark prev-items array1 array2 index + 2 index 1 index get + % mark prev-items array1 array2 index val1 + exch 2 index exch get + % mark prev-items array1 array2 val1 val2 + 2 array astore + % mark prev-items array1 array2 cur-item + 3 1 roll + % mark prev-items cur-item array1 array2 + } for + % mark items [item1a item2a ... itemma] [item1b item2b ... itemnb] + pop pop + ] +} bind def + +% [item1a item2a ... itemma] [item1b item2b ... itemmnb] +% -> [item1a+item1b item2a+item2b ... item(min(m,n))a+item(min(m,n))b] +/vec-add { + [ 3 1 roll azip { aload pop add } forall ] +} bind def + +% [item1a item2a ... itemma] [item1b item2b ... itemmnb] +% -> [item1a-item1b item2a-item2b ... item(min(m,n))a-item(min(m,n))b] +/vec-sub { + [ 3 1 roll azip { aload pop sub } forall ] +} bind def + +% [item1a item2a ... itemma] [item1b item2b ... itemmnb] +% -> item1a>=item1b & item2a>=item2b & ... & item(min(m,n))a>=item(min(m,n))b +/vec-all-ge { + true 3 1 roll + azip { aload pop ge and } forall +} bind def + +/datafile (%stdin) (r) file def +/stderr (%stderr) (w) file def + +/data [ + { + datafile 300 string readline + not { pop exit } if + % line + counttomark exch + % expected-rank line + (Blueprint ) anchorsearch + not { 1.125 pstack quit } if + pop + % expected-rank suffix + (: Each ore robot costs ) search + not { 2.125 pstack quit } if + exch pop cvi exch + % expected-rank rank suffix + ( ore. Each clay robot costs ) search + not { 3.125 pstack quit } if + exch pop cvi exch + % expected-rank rank cost0 suffix + ( ore. Each obsidian robot costs ) search + not { 4.125 pstack quit } if + exch pop cvi exch + % expected-rank rank cost0 cost1 suffix + ( ore and ) search + not { 5.125 pstack quit } if + exch pop cvi exch + % expected-rank rank cost0 cost1 cost2a suffix + ( clay. Each geode robot costs ) search + not { 6.125 pstack quit } if + exch pop cvi exch + % expected-rank rank cost0 cost1 cost2a cost2b suffix + ( ore and ) search + not { 7.125 pstack quit } if + exch pop cvi exch + % expected-rank rank cost0 cost1 cost2a cost2b cost3a suffix + ( obsidian.) search + not { 8.125 pstack quit } if + exch pop cvi exch + % expected-rank rank cost0 cost1 cost2a cost2b cost3a cost3b suffix + dup length 0 eq not { 9.125 pstack quit } if pop + % expected-rank rank cost0 cost1 cost2a cost2b cost3a cost3b + 8 6 roll 2 copy eq not { 10.125 pstack quit } if pop pop + % cost0 cost1 cost2a cost2b cost3a cost3b + 0 exch 0 4 array astore + % cost0 cost1 cost2a cost2b cost3-array + 5 1 roll 0 0 4 array astore + % cost3-array cost0 cost1 cost2-array + 4 1 roll 0 0 0 4 array astore + % cost2-array cost3-array cost0 cost1-array + 4 1 roll 0 0 0 4 array astore + % cost1-array cost2-array cost3-array cost0-array + 4 1 roll 4 array astore + % cost-array + } loop +] def + +/max-cost [ + 0 0 0 0 data { + { + % prev-max-cost0 prev-max-cost1 prev-max-cost2 prev-max-cost3 cur-cost + dup 0 get + % prev-max-cost0 prev-max-cost1 prev-max-cost2 prev-max-cost3 cur-cost cost0 + 6 5 roll + % prev-max-cost1 prev-max-cost2 prev-max-cost3 cur-cost cost0 prev-max-cost0 + 2 copy lt { exch } if pop + % prev-max-cost0 prev-max-cost1 prev-max-cost2 cur-cost max-cost0 + 1 index 1 get + % prev-max-cost1 prev-max-cost2 prev-max-cost3 cur-cost max-cost0 cost1 + 6 5 roll 2 copy lt { exch } if pop + % prev-max-cost2 prev-max-cost3 cur-cost max-cost0 max-cost1 + 2 index 2 get + % prev-max-cost2 prev-max-cost3 cur-cost max-cost0 max-cost1 cost2 + 6 5 roll 2 copy lt { exch } if pop + % prev-max-cost3 cur-cost max-cost0 max-cost1 max-cost2 + 3 index 3 get + % prev-max-cost3 cur-cost max-cost0 max-cost1 max-cost2 cost3 + 6 5 roll 2 copy lt { exch } if pop + % cur-cost max-cost0 max-cost1 max-cost2 max-cost3 + 5 4 roll pop + % max-cost0 max-cost1 max-cost2 max-cost3 + } forall + } forall +] def + +max-cost == + +% blueprint resources flows build -> blueprint next-resources next-flows +/simulate-minute { + % blueprint resources flows build + dup 0 ge + % blueprint resources flows build has-build? + { % blueprint resources flows build + 3 index 1 index get + % blueprint resources flows build costs + 4 3 roll exch vec-sub + % blueprint flows build updated-resources + } + { 3 2 roll } + ifelse + % blueprint flows build resources + 2 index vec-add + % blueprint flows build next-resources + 3 1 roll + % blueprint next-resources flows build + dup 0 ge + % blueprint next-resources flows build has-build? + { % blueprint next-resources flows build + 2 copy get 1 add + % blueprint next-resources flows build next-flow + 2 index 3 1 roll put + % blueprint next-resources next-flows + } + { pop } + ifelse + % blueprint next-resources next-flows +} bind def + +% blueprint build-list max-time -> score true +% -> false +/simulate-build-list { + % blueprint build-list max-time + 0 [0 0 0 0] [1 0 0 0] 4 3 roll + % blueprint build-list build-index resources flows max-time + 6 5 roll 4 1 roll + % build-list build-index blueprint resources flows max-time + { % build-list build-index blueprint resources flows + 4 index length 4 index gt + % build-list build-index blueprint resources flows has-build? + { % build-list build-index blueprint resources flows + 4 index 4 index get + % build-list build-index blueprint resources flows build + 3 index 1 index get + % build-list build-index blueprint resources flows build costs + 3 index exch vec-all-ge + % build-list build-index blueprint resources flows build can-build? + { 5 4 roll 1 add 5 1 roll } + { pop -1 } + ifelse + % build-list build-index blueprint resources flows build + } + { -1 } + ifelse + % build-list build-index blueprint resources flows build + simulate-minute + % build-list build-index blueprint resources flows + } repeat + % build-list build-index blueprint resources flows + 4 index length 4 index le + % build-list build-index blueprint resources flows build-list-finished? + { pop 3 get 4 1 roll pop pop pop true } + { pop pop pop pop pop false } + ifelse +} bind def + +% build-list -> next-build-list +/next-build-list { + % build-list + dup length 2 sub + % build-list index + { + % build-list index + dup 0 lt { pop 0 apush exit } if + % build-list index + 2 copy get + % build-list index item + 1 add 4 mod + % build-list index next-item + 3 copy put + % next-build-list index next-item + 0 eq + { 1 sub } + { pop exit } + ifelse + } loop + % next-build-list +} bind def + +% build-list -> build-list +/next-valid-build-list { + { + % prev-build-list + next-build-list + % build-list + [ 0 0 0 0 ] 1 index { + % build-list count-list cur-item + 2 copy get + % build-list count-list cur-item prev-count + 1 add + % build-list count-list cur-item count + 2 index 3 1 roll put + % build-list updated-count-list + } forall + % build-list count-list + dup 3 0 put + % build-list fixed-count-list + max-cost exch vec-all-ge + % build-list is-valid? + { exit } if + % build-list + } loop + % valid-build-list +} bind def + +% array -> copied-array +/copy-array { + aload length array astore +} bind def + +% blueprint prev-state build -> next-state +/update-state { + % blueprint prev-state build + exch aload pop + % blueprint build prev-resources prev-flows prev-build-list + 3 index 0 ge + { 3 index aappend } if + % blueprint build prev-resources prev-flows build-list + 5 1 roll + % build-list blueprint build prev-resources prev-flows + exch copy-array exch copy-array + % build-list blueprint build prev-resources-copy prev-flows-copy + 3 2 roll + % build-list blueprint prev-resources-copy prev-flows-copy build + simulate-minute + % build-list blueprint resources flows + 3 2 roll pop + % build-list resources flows + 3 2 roll + % resources flows build-list + 3 array astore + % next-state +} bind def + +% int-list -> key +/list-to-key { + % int-list + dup length string + % int-list empty-key + 0 1 2 index length 1 sub { + % int-list key index + 2 index 1 index get + % int-list key index value + 2 index 3 1 roll put + % int-list updated-key + } for + % int-list final-key + exch pop + % final-key +} bind def + +% active-dict blueprint prev-state build +% -> active-dict blueprint prev-state build is-valid? +/update-valid? { + % active-dict blueprint prev-state build + dup 0 ge + { % active-dict blueprint prev-state build + 1 index 2 get + % active-dict blueprint prev-state build prev-build-list + 1 index aappend + % active-dict blueprint prev-state build next-build-list + list-to-key + % active-dict blueprint prev-state build next-key + 4 index 1 index known + % active-dict blueprint prev-state build next-key already-active? + { pop false } + { % active-dict blueprint prev-state build next-key + 2 index 0 get + % active-dict blueprint prev-state build next-key resources + 4 index 3 index get + % active-dict blueprint prev-state build next-key resources cost + vec-all-ge + % active-dict blueprint prev-state build next-key is-possible? + 3 index 1 get + % active-dict blueprint prev-state build next-key is-possible? rates + 3 index get + % active-dict blueprint prev-state build next-key is-possible? rate + max-cost 4 index get lt + % active-dict blueprint prev-state build next-key is-possible? rate-ok? + 3 index 3 eq or and + % active-dict blueprint prev-state build next-key is-valid? + { % active-dict blueprint prev-state build next-key + 4 index exch 1 put + % active-dict blueprint prev-state build + true + } + { pop false } + ifelse + % active-dict blueprint prev-state build is-valid? + } + ifelse + } + { true } + ifelse +} bind def + +% blueprint max-time -> score +/eval-blueprint { + % blueprint max-time + 0 1000 dict [[[0 0 0 0] [1 0 0 0] []]] 4 3 roll + % blueprint init-time init-active-dict init-state-list max-time + { + % blueprint prev-time active-dict state-list + 3 2 roll 1 add 3 1 roll + % blueprint time active-dict state-list + [ exch + % blueprint time active-dict mark state-list + 2 index 5 index 3 2 roll + % blueprint time active-dict mark active-dict blueprint state-list + { +%%% Exchaustive search of build-list-space +%%% % ... active-dict blueprint prev-state +%%% -1 1 3 { +%%% % ... active-dict blueprint prev-state build +%%% update-valid? +%%% { % ... active-dict blueprint prev-state build +%%% 3 copy update-state +%%% % ... active-dict blueprint prev-state build next-state +%%% 5 1 roll pop +%%% % ... next-state active-dict blueprint prev-state +%%% } +%%% { pop } +%%% ifelse +%%% } for +%%% % ... active-dict blueprint prev-state +%%% pop +%%% % ... active-dict blueprint +%%% Greedy search of build-list-space, prioritizing geode over obsidian over +%%% everything else. This is a bit of a hack, it doesn't work with the +%%% reference input (first blueprint needs to build an obsidian bot when +%%% both obsidian and geode are possible), but it works on my input, +%%% so let's say it's good enough. + % ... active-dict blueprint prev-state + 3 update-valid? + { %%% drop everything to build a geode bot + % ... active-dict blueprint prev-state build + 2 index 3 1 roll + % ... active-dict blueprint blueprint prev-state build + update-state + % ... active-dict blueprint next-state + 3 1 roll + % ... next-state active-dict blueprint + } + { pop 2 update-valid? + { %%% drop everything to build an obsidian bot + % ... active-dict blueprint prev-state build + 2 index 3 1 roll + % ... active-dict blueprint blueprint prev-state build + update-state + % ... active-dict blueprint next-state + 3 1 roll + % ... next-state active-dict blueprint + } + { pop + % ... active-dict blueprint prev-state + -1 1 1 { + % ... active-dict blueprint prev-state build + update-valid? + { % ... active-dict blueprint prev-state build + 3 copy update-state + % ... active-dict blueprint prev-state build next-state + 5 1 roll pop + % ... next-state active-dict blueprint prev-state + } + { pop } + ifelse + } for + % ... active-dict blueprint prev-state + pop + % ... active-dict blueprint + } + ifelse + } + ifelse + % ... active-dict blueprint + } forall + % blueprint time mark new-states active-dict blueprint + pop pop + ] + % blueprint time active-dict new-state-list + } repeat + % blueprint time active-dict final-state-list + exch pop + % blueprint time final-state-list + stderr (Final list with ) writestring + stderr 1 index length 15 string cvs writestring + stderr ( states\012) writestring + % blueprint time final-state-list + exch pop 0 exch { + % blueprint best-so-far state + 0 get + % blueprint best-so-far resources + 3 get + % blueprint best-so-far score + 2 copy lt { exch } if pop + % blueprint new-best-so-far + } forall + % blueprint best-score + exch pop + % best-score + stderr (Score ) writestring + stderr 1 index 15 string cvs writestring + stderr 10 write +} bind def + +/Helvetica 20 selectfont + + +(First Puzzle: ) +72 700 moveto show + +0 0 data { + % accumulator prev-rank cur-blueprint + exch 1 add exch + % accumulator rank cur-blueprint + stderr (Running blueprint ) writestring + stderr 2 index 15 string cvs writestring + stderr ( / ) writestring + stderr data length 15 string cvs writestring + stderr 10 write + stderr flushfile + % accumulator rank cur-blueprint + 24 eval-blueprint + % accumulator rank score + 1 index mul + % accumulator rank contribution + 3 2 roll add exch + % updated-accumulator rank +} forall +% final-accumulator last-rank +pop 15 string cvs show + +%%% [ data length { 0 } repeat ] [3] +%%% { +%%% % best-score-array prev-build-list +%%% next-valid-build-list false +%%% % best-score-array build-list updated? +%%% 0 1 data length 1 sub { +%%% % best-score-array build-list updated? index +%%% data 1 index get +%%% % best-score-array build-list updated? index blueprint +%%% 3 index +%%% % best-score-array build-list updated? index blueprint build-list +%%% 24 simulate-build-list +%%% { % best-score-array build-list updated? index score +%%% dup 5 index 3 index get gt +%%% % best-score-array build-list updated? index score score>prev-max? +%%% { 4 index 2 index 2 index put +%%% % updated-best-score-array build-list updated? index score +%%% pop pop pop true +%%% % updated-best-score-array build-list updated? +%%% } +%%% { pop pop } +%%% ifelse +%%% % updated-best-score-array build-list updated? +%%% } +%%% { pop } +%%% ifelse +%%% % best-score-array build-list updated? +%%% } for +%%% % best-score-array build-list updated? +%%% { +%%% % best-score-array build-list +%%% stderr (\015Score ) writestring +%%% 0 0 3 index { +%%% % ... accumulator prev-rank score +%%% exch 1 add exch +%%% % ... accumulator rank score +%%% 1 index mul +%%% % ... accumulator rank contribution +%%% 3 2 roll add exch +%%% % ... accumulator rank +%%% } forall +%%% % best-score-array build-list accumulator rank +%%% 1 index 33 eq { quit } if +%%% % best-score-array build-list accumulator rank +%%% pop 15 string cvs +%%% stderr exch writestring +%%% stderr ( at length ) writestring +%%% stderr 1 index length 15 string cvs writestring +%%% stderr flushfile +%%% % best-score-array build-list +%%% } if +%%% % best-score-array build-list +%%% } loop + +(Second Puzzle: ) +72 664 moveto show + +1 0 data { + % accumulator prev-rank cur-blueprint + exch 1 add exch + % accumulator rank cur-blueprint + 1 index 4 ge { pop exit } if + % accumulator rank cur-blueprint + stderr (Running blueprint ) writestring + stderr 2 index 15 string cvs writestring + stderr ( / ) writestring + stderr data length 15 string cvs writestring + stderr 10 write + stderr flushfile + % accumulator rank cur-blueprint + 32 eval-blueprint + % accumulator rank score + 3 2 roll mul exch + % updated-accumulator rank +} forall +% final-accumulator last-rank +stderr (Result 2: ) writestring +stderr 2 index 15 string cvs writestring +stderr 10 write +pop 15 string cvs show + + +showpage +quit diff --git a/day19.txt b/day19.txt @@ -0,0 +1,2 @@ +Blueprint 1: Each ore robot costs 4 ore. Each clay robot costs 2 ore. Each obsidian robot costs 3 ore and 14 clay. Each geode robot costs 2 ore and 7 obsidian. +Blueprint 2: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 8 clay. Each geode robot costs 3 ore and 12 obsidian.