day01.ps (2781B)
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- -r300 -dDownScaleFactor=3 day01.ps <day01.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 { 61 datafile 100 string readline 62 not {pop exit} if 63 dup length 0 eq 64 { pop [] } 65 { str_to_int apush } 66 ifelse 67 } loop 68 ] def 69 70 /sums [ 71 data 72 { 0 exch 73 { add } forall 74 } forall 75 ] def 76 77 /Helvetica 20 selectfont 78 79 (First Puzzle: ) 80 72 700 moveto show 81 % compute max (sums) 82 0 sums { 83 % max-so-far new-value 84 2 copy lt { exch } if 85 % max(max-so-far, new-value) min(max-so-far, new-value) 86 pop 87 } forall 88 int_to_str show 89 90 (Second Puzzle: ) 91 72 664 moveto show 92 % compute three largest 93 0 0 0 sums { 94 % save3 save2 save1 new 95 2 copy gt { exch } if 96 % save3 save2 rank2(save1,new) rank1(save1,new) 97 4 1 roll 98 % rank1(save1,new) save3 save2 rank2(save1,new) 99 2 copy gt { exch } if 100 % rank1(save1,new) save3 rank3(save2,save1,new) rank2(save2,save1,new) 101 4 1 roll 102 % rank2(save2,save1,new) rank1(save1,new) save3 rank3(save2,save1,new) 103 2 copy gt { exch } if 104 % rank2(save2,save1,new) rank1(save1,new) rank4(all) rank3(all) 105 4 1 roll 106 % rank3(all) rank2(save2,save1,new) rank1(save1,new) rank4(all) 107 pop 108 } forall 109 add add 110 int_to_str show 111 112 showpage 113 quit