day07.ps (5285B)
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- day07.ps <day07.txt | display 19 20 /datafile (%stdin) (r) file def 21 /stderr (%stderr) (w) file def 22 23 /new-dir { 100 dict } bind def 24 /root new-dir def 25 26 % read data 27 root 28 { 29 datafile 100 string readline 30 not { pop exit } if 31 % cur-dir line 32 ($ ) anchorsearch 33 { pop 34 % cur-dir cmd-line 35 (cd ) anchorsearch 36 { pop 37 % cur-dir cd-arg 38 dup (..) eq 39 { pop pop } 40 { dup (/) eq not 41 { 1 index exch get } 42 { pop } 43 ifelse 44 } 45 ifelse 46 } 47 { pop } 48 ifelse 49 } 50 { % cur-dir data-line 51 (dir ) anchorsearch 52 { pop 53 % cur-dir new-dir-name 54 1 index exch new-dir put 55 } 56 { ( ) search 57 { exch pop 58 % cur-dir new-file-name new-file-size 59 2 index 3 1 roll put 60 } 61 { quit } 62 ifelse 63 } 64 ifelse 65 } 66 ifelse 67 } loop 68 69 % (string1) (string2) -> (string1string2) 70 /concat { 71 % (string1) (string2) 72 dup length 2 index length add string 73 % (string1) (string2) (blank) 74 dup 0 4 index putinterval 75 % (string1) (string2) (string1blank) 76 3 2 roll length 77 % (string2) (string1blank) string1-length 78 3 2 roll 2 index 4 1 roll putinterval 79 % (string1string2) 80 } bind def 81 82 % dir-dict -> total-size 83 /dir-size { 84 0 exch 85 { 86 % cur-total element-name element-value 87 exch pop 88 % cur-total element-value 89 dup type /dicttype eq 90 { 91 % cur-total dir-value 92 dir-size add 93 } 94 { 95 % cur-total file-value 96 cvi add 97 } 98 ifelse 99 } forall 100 } bind def 101 102 % cur-dir-name dir-dict -> ø 103 /dump-data { 104 { 105 % cur-dir-name element-name element-value 106 dup type /dicttype eq 107 { 108 % cur-dir-name dir-name dir-value 109 exch 100 string cvs 2 index exch concat (/) concat 110 % cur-dir-name dir-value full-dir-name 111 dup stderr exch writestring 112 stderr ( -> ) writestring 113 % cur-dir-name dir-value full-dir-name 114 1 index dir-size 100 string cvs 115 stderr exch writestring 116 stderr 10 write 117 % cur-dir-name dir-value full-dir-name 118 exch dump-data 119 } 120 { 121 % cur-dir-name file-name file-size 122 exch 100 string cvs 2 index exch concat 123 % cur-dir-name file-size full-file-name 124 ( -> ) concat exch concat 125 % cur-dir-name line 126 stderr exch writestring stderr 10 write 127 } 128 ifelse 129 } forall 130 pop 131 } bind def 132 133 % dump data 134 % (/) root dump-data 135 136 % current-sum dir-dict -> updated-sum 137 /first-sum { 138 % prev-sum dir-dict 139 dup dir-size 140 % prev-sum dir-dict dir-size 141 dup 100000 le 142 { 3 2 roll add exch } 143 { pop } 144 ifelse 145 % updated-sum dir-dict 146 { 147 % updated-sum element-name element-value 148 exch pop 149 % updated-sum element-value 150 dup type /dicttype eq 151 { first-sum } 152 { pop } 153 ifelse 154 } forall 155 % updated-sum 156 } bind def 157 158 % size-needed best-name best-size cur-name cur-dict 159 % -> size-needed updated-best-name updated-best-size 160 /second-iter { 161 dup dir-size 162 % size-needed best-name best-size cur-name cur-dict cur-size 163 5 index 1 index le 164 % size-needed best-name best-size cur-name cur-dict cur-size cur-size-enough? 165 4 index 2 index gt and 166 % size-needed best-name best-size cur-name cur-dict cur-size cur-is-best? 167 { 3 copy exch pop 5 2 roll 7 5 roll pop pop } if 168 % size-needed updated-best-name updated-best-size cur-name cur-dict cur-size 169 pop 170 { 171 % size-needed best-name best-size cur-name element-name element-value 172 dup type /dicttype eq 173 { 174 exch 2 index exch 175 % size-needed best-name best-size cur-name element-value cur-name element-name 176 100 string cvs concat (/) concat 177 % size-needed best-name best-size cur-name element-value full-element-name 178 exch 3 2 roll 179 % size-needed best-name best-size full-element-name element-value cur-name 180 6 1 roll 181 % cur-name size-needed best-name best-size full-element-name element-value 182 second-iter 183 % cur-name size-needed updated-best-name updated-best-size 184 4 3 roll 185 % size-needed updated-best-name updated-best-size cur-name 186 } 187 { pop pop } 188 ifelse 189 } forall 190 pop 191 } bind def 192 193 194 /Helvetica 20 selectfont 195 196 (First Puzzle: ) 197 72 700 moveto show 198 0 root first-sum 199 10 string cvs show 200 201 (Second Puzzle: ) 202 72 664 moveto show 203 17 root dir-size 204 % total-size 205 dup 70000000 exch sub 206 % total-size free-size 207 30000000 exch sub 208 % total-size size-needed 209 exch (/) exch (/) root second-iter 210 % size-needed best-name best-size 211 15 string cvs show 212 213 showpage 214 quit