day06.ps (3192B)
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- day06.ps <day06.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 /datafile (%stdin) (r) file def 48 49 /data 50 datafile 4100 string readline 51 not { quit } if 52 def 53 54 % array -> bool 55 /are-all-different { 56 % array 57 dup length 1 sub dup 1 sub 58 % array high-index low-index 59 { 60 % array high-index low-index 61 3 copy pop get 62 % array high-index low-index high-value 63 3 index 2 index get 64 % array high-index low-index high-value low-value 65 eq { pop pop pop false exit } if 66 % array high-index low-index 67 dup 0 eq 68 { % when low-index wraps around 69 pop dup 1 eq 70 { pop pop true exit } if % loop termination 71 1 sub dup % index update 72 } if 73 % array updated-high-index low-index 74 1 sub 75 % array updated-high-index updated-low-index 76 } loop 77 % result 78 } bind def 79 80 % input-array marker-length -> count 81 /find-marker { 82 % input-array marker-length 83 [ exch { 0 } repeat ] 84 1 exch 85 % input-array first-index backlog-array 86 3 2 roll { 87 % index backlog-array cur-char 88 exch aload 89 % index cur-char backlog-n ... backlog-1 backlog-array 90 dup length dup 2 add exch roll 91 % index backlog-(n-1) ... backlog-1 backlog-array cur-char backlog-n 92 pop exch 93 % index backlog-(n-1) ... backlog-1 cur-char backlog-array 94 astore 95 % index updated-backlog-array 96 2 copy length ge { 97 dup are-all-different { pop exit } if 98 } if 99 % index updated-backlog-array 100 exch 1 add exch 101 % updated-index updated-backlog-array 102 } forall 103 % count 104 } bind def 105 106 /Helvetica 20 selectfont 107 108 (First Puzzle: ) 109 72 700 moveto show 110 data 4 find-marker 111 int_to_str show 112 113 (Second Puzzle: ) 114 72 664 moveto show 115 data 14 find-marker 116 int_to_str show 117 118 showpage 119 quit