day04.ps (3530B)
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- day04.ps <day04.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 % (X-Y) -> X Y 59 /parse-pair { 60 (-) search 61 not { stop } if 62 % (Y) (-) (X) 63 exch pop 64 % (Y) (X) 65 str_to_int 66 exch 67 str_to_int 68 % X Y 69 } bind def 70 71 % (I-J,K-L) -> I J K L 72 /parse-line { 73 (,) search 74 not { stop } if 75 % (K-L) (,) (I-J) 76 exch pop 77 % (K-L) (I-J) 78 parse-pair 79 3 2 roll 80 % I J (K-L) 81 parse-pair 82 % I J K L 83 } bind def 84 85 /data [ 86 { 87 datafile 100 string readline 88 not {pop exit} if 89 % line 90 parse-line 91 % I J K L 92 4 array astore 93 % [I J K L] 94 } loop 95 ] def 96 97 /stderr (%stderr) (w) file def 98 99 /Helvetica 20 selectfont 100 101 (First Puzzle: ) 102 72 700 moveto show 103 0 data { 104 % accumulator cur-array 105 aload pop 106 % accumulator first1 last1 first2 last2 107 % 3 index int_to_str stderr exch writestring stderr 32 write 108 % 2 index int_to_str stderr exch writestring stderr 32 write 109 % 1 index int_to_str stderr exch writestring stderr 32 write 110 % dup int_to_str stderr exch writestring stderr 32 write 111 % force first1 <= first2 112 3 index 2 index gt { 113 4 2 roll 114 } if 115 % accumulator first1 last1 first2 last2 116 2 index 1 index ge 117 % accumulator first1 last1 first2 last2 last1>=last2? 118 4 index 3 index eq or 119 % accumulator first1 last1 first2 last2 last1>=last2||first1==first2? 120 5 1 roll pop pop pop pop 121 % accumulator last1>=last2||first1==first2? 122 { 1 add } if 123 % updated-accumulator 124 % dup int_to_str stderr exch writestring stderr 10 write 125 } forall 126 int_to_str show 127 128 129 (Second Puzzle: ) 130 72 664 moveto show 131 0 data { 132 % accumulator cur-array 133 aload pop 134 % accumulator first1 last1 first2 last2 135 % force first1 <= first2 136 3 index 2 index gt { 137 4 2 roll 138 } if 139 % accumulator first1 last1 first2 last2 140 3 copy pop ge 141 % accumulator first1 last1 first2 last2 last1>=first2? 142 5 1 roll pop pop pop pop 143 % accumulator last1>=first2? 144 { 1 add } if 145 % updated-accumulator 146 } forall 147 int_to_str show 148 149 showpage 150 quit 151