day03.ps (4719B)
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- day03.ps <day03.txt | display 19 20 /str_to_int { 21 0 exch { exch 10 mul add 48 sub } forall 22 } bind def 23 24 /int_to_str { 25 % number 26 1 10 27 { % number length upper-bound 28 2 index 1 index lt { exit } if 29 exch 1 add exch 10 mul } loop 30 pop dup string exch 1 sub 31 { % number string index 32 2 copy 1 sub 5 1 roll exch 33 % next_index number string string index 34 3 index 10 mod 48 add 35 % next_index number string string index digit 36 put 37 % next_index number next_string 38 3 1 roll 10 idiv 39 % next_string next_index next_number 40 dup 0 eq { pop pop exit } if 41 % next_string next_index next_number 42 3 1 roll 43 % next_nubmer next_string next_index 44 } loop 45 } bind def 46 47 /apush { 48 % array new_item 49 exch aload length 1 add array astore 50 } bind def 51 52 /apop { 53 aload length 1 sub array astore exch 54 } bind def 55 56 /datafile (%stdin) (r) file def 57 58 /data [ 59 { 60 datafile 100 string readline 61 not {pop exit} if 62 % line 63 dup length dup dict exch 2 idiv 0 4 3 roll 64 % data-dict half-length 0 line 65 { 66 % data-dict half-length index string-element 67 dup 90 le { 64 sub 26 add } if 68 dup 97 ge { 96 sub } if 69 % data-dict half-length index element-priority 70 3 copy pop gt { 1 } { 1000 } ifelse 71 % data-dict half-length index element-priority element-index 72 4 index 2 index known 73 { 4 index 2 index get } 74 { 0 } 75 ifelse 76 add 77 % data-dict half-length index element-priority new-value 78 4 index 3 1 roll put 79 % new-data-dict half-length index 80 1 add 81 % new-data-dict half-length new-index 82 } forall 83 pop pop 84 } loop 85 ] def 86 87 /Helvetica 20 selectfont 88 89 (First Puzzle: ) 90 72 700 moveto show 91 0 data { 92 % accumulator cur-dict 93 0 exch 94 { 95 % result cur-key cur-value 96 dup 1000 idiv exch 1000 mod 97 % result cur-key first-count second-count 98 mul 0 gt 99 { exch 100 mul add } 100 { pop } 101 ifelse 102 % new-result 103 } forall 104 % accumulator cur-result 105 add 106 } forall 107 int_to_str show 108 109 (Second Puzzle: ) 110 72 664 moveto show 111 0 0 [ 52 { 0 } repeat ] data { 112 % accumulator index global-track-array cur-dict 113 [ 52 { 0 } repeat ] exch 114 { 115 % local-track-array cur-key cur-value 116 pop 1 sub 117 % local-track-array cur-index 118 1 index exch 119 1 put 120 % updated-local-track-array 121 } forall 122 % accumulator index global-track-array local-track-array 123 0 1 51 { 124 % global-track-array local-track-array cur-index 125 2 index 1 index get 126 % global-track-array local-track-array cur-index prev-global-value 127 2 index 2 index get add 128 % global-track-array local-track-array cur-index updated-global-value 129 3 index 3 1 roll put 130 % updated-global-track-array local-track-array 131 } for 132 % accumulator index updated-global-track-array local-track-array 133 pop 134 % accumulator index updated-global-track-array 135 exch 1 add exch 136 % accumulator updated-index updated-global-track-array 137 1 index 3 mod 0 eq 138 { 139 % accumulator updated-index updated-global-track-array 140 0 1 51 { 141 % accumulator updated-index updated-global-track-array cur-index 142 2 copy get 143 % accumulator updated-index updated-global-track-array cur-index cur-value 144 3 eq { 145 % accumulator updated-index updated-global-track-array cur-index 146 dup 1 add 147 % accumulator updated-index updated-global-track-array cur-index cur-pri 148 5 4 roll add 149 % updated-index updated-global-track-array cur-index updated-acc 150 4 1 roll 151 % updated-acc updated-index updated-global-track-array cur-index 152 } if 153 % updated-accumulator updated-index updated-global-track-array cur-index 154 pop 155 } for 156 % updated-accumulator updated-index updated-global-track-array 157 pop [ 52 { 0 } repeat ] 158 % updated-accumulator updated-index cleared-global-track-array 159 } if 160 } forall 161 % accumulator last-index last-global-track-array 162 pop pop 163 int_to_str show 164 165 showpage 166 quit 167