day21.ps (4944B)
1 %!PS 2 % 3 % Copyright (c) 2022, Natacha Porté 4 % 5 % Permission to use, copy, modify, and distribute this software for any 6 % purpose with or without fee is hereby granted, provided that the above 7 % copyright notice and this permission notice appear in all copies. 8 % 9 % THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 % WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 % MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 % ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 % WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 % ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 % OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 % 17 % Usage: 18 % gs -q- -sDEVICE=png16m -o- day21.ps <day21.txt | display 19 20 /datafile (%stdin) (r) file def 21 /stderr (%stderr) (w) file def 22 23 /data << 24 { 25 datafile 200 string readline 26 not { pop exit } if 27 % (monkey: job) 28 (: ) search 29 not { 1.125 pstack quit } if 30 exch pop exch 31 % (monkey) (job) 32 { %%% 1-iteration loop to use `exit` as a short circuit 33 % (monkey) (job) 34 ( + ) search 35 { exch pop exch 36 % (monkey) (left) (right) 37 /add load 3 array astore 38 % (monkey) job 39 exit 40 } if 41 ( - ) search 42 { exch pop exch 43 % (monkey) (left) (right) 44 /sub load 3 array astore 45 % (monkey) job 46 exit 47 } if 48 ( * ) search 49 { exch pop exch 50 % (monkey) (left) (right) 51 /mul load 3 array astore 52 % (monkey) job 53 exit 54 } if 55 ( / ) search 56 { exch pop exch 57 % (monkey) (left) (right) 58 /idiv load 3 array astore 59 % (monkey) job 60 exit 61 } if 62 cvi 63 exit 64 } loop 65 % (monkey) job 66 } loop 67 >> def 68 69 % name -> value 70 /eval-monkey { 71 % name 72 data exch get 73 % job 74 dup type /arraytype eq 75 { aload pop 76 % (left) (right) op 77 3 1 roll eval-monkey 78 % (right) op left-value 79 3 1 roll eval-monkey 80 % op left-value right-value 81 3 1 roll exec 82 % result 83 } if 84 % result 85 } bind def 86 87 % target-name node-name -> bool 88 /has-target { 89 % target-name node-name 90 2 copy eq 91 { pop pop true } 92 { % target-name node-name 93 data exch get 94 % target-name job 95 dup type /arraytype eq 96 { aload pop pop 97 % target-name left-name right-name 98 2 index exch has-target 99 % target-name left-name right-has-target 100 3 1 roll has-target or 101 % result 102 } 103 { pop pop false} 104 ifelse 105 % result 106 } 107 ifelse 108 % result 109 } bind def 110 111 % dictionary of procedures: result left -> right 112 /build-right << 113 /add load /sub load 114 /sub load { exch sub } 115 /idiv load { exch idiv } 116 /mul load /idiv load 117 >> def 118 119 % dictionary of procedures: result right -> left 120 /build-left << 121 /add load /sub load 122 /sub load /add load 123 /idiv load /mul load 124 /mul load /idiv load 125 >> def 126 127 % target-name node-name result -> target-value 128 /back-propagate { 129 % target-name node-name result 130 exch data exch get 131 % target-name result job 132 dup type /arraytype eq 133 { aload pop 134 % target-name result left-name right-name op 135 4 index 3 index has-target 136 % target-name result left-name right-name op left-has-target 137 5 index 3 index has-target 138 % target-name result left-name right-name op left-has-target right-has-target 139 1 index eq { 2.125 pstack quit } if 140 % target-name result left-name right-name op left-has-target 141 { % target-name result left-name right-name op 142 exch eval-monkey 143 % target-name result left-name op right-value 144 4 3 roll 3 1 roll exch 145 % target-name left-name result right-value op 146 build-left exch get exec 147 % target-name left-name left-value 148 back-propagate 149 % target-value 150 } 151 { % target-name result left-name right-name op 152 3 2 roll eval-monkey 153 % target-name result right-name op left-value 154 4 3 roll 3 1 roll exch 155 % target-name right-name result left-value op 156 build-right exch get exec 157 % target-name right-name right-value 158 back-propagate 159 % target-value 160 } 161 ifelse 162 % target-value 163 } 164 { % target-name result job 165 pop exch pop 166 } 167 ifelse 168 % target-value 169 } bind def 170 171 172 173 /Helvetica 20 selectfont 174 175 176 (First Puzzle: ) 177 72 700 moveto show 178 (root) eval-monkey 15 string cvs show 179 180 181 (Second Puzzle: ) 182 72 664 moveto show 183 184 (humn) data (root) get aload pop pop 185 % target-name left-name right-name 186 2 index 2 index has-target 187 % target-name left-name right-name left-has-target 188 3 index 2 index has-target 189 % target-name left-name right-name left-has-target right-has-target 190 1 index eq { 3.125 pstack quit } if 191 % target-name left-name right-name left-has-target 192 { exch } if 193 % target-name ref-side-name target-side-name 194 exch eval-monkey 195 % target-name node-name node-value 196 back-propagate 197 % target-value 198 15 string cvs show 199 200 showpage 201 quit