aoc-2022

My solutions in postscript to Advent of Code 2022
git clone https://git.instinctive.eu/aoc-2022.git
Log | Files | Refs | README | LICENSE

day24.ps (5636B)


      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- day24.ps <day24.txt | display
     19 
     20 /datafile (%stdin) (r) file def
     21 /stderr (%stderr) (w) file def
     22 
     23 /data [
     24   {
     25     datafile 200 string readline
     26     not { exit } if
     27   } loop
     28   pop
     29 ] def
     30 
     31 /width data 0 get length def
     32 /starty 0 def
     33 /endy data length 1 sub def
     34 
     35 /init-wind-list [
     36   -1 data {
     37     % ... prev-y line
     38     exch 1 add exch -1 exch
     39     % ... y -1 line
     40     {
     41       % ... y prev-x char
     42       exch 1 add exch
     43       % ... y x char
     44       dup 94 eq { % `^`
     45         [ 2 index 4 index 0 -1 ] 4 1 roll
     46       } if
     47       dup 118 eq { % `v`
     48         [ 2 index 4 index 0 1 ] 4 1 roll
     49       } if
     50       dup 62 eq { % `>`
     51         [ 2 index 4 index 1 0 ] 4 1 roll
     52       } if
     53       dup 60 eq { % `<`
     54         [ 2 index 4 index -1 0 ] 4 1 roll
     55       } if
     56       dup 46 eq { % `.`
     57         2 index 0 eq {
     58           /startx 2 index def
     59         } if
     60         2 index endy eq {
     61           /endx 2 index def
     62         } if
     63       } if
     64       % ... y x char
     65       pop
     66     } forall
     67     % ... y x
     68     pop
     69   } forall
     70   % ... y
     71   pop
     72 ] def
     73 
     74 % prev-x prev-y dx dy -> x y dx dy
     75 /next-wind {
     76   % prev-x prev-x dx dy
     77   4 2 roll
     78   % dx dy prev-x prev-y
     79   exch 3 index add exch 2 index add
     80   % dx dy tentative-x tentative-y
     81   dup 0 eq { pop endy 1 sub } if
     82   dup endy eq { pop 1 } if
     83   % dx dy tentative-x y
     84   exch
     85   dup 0 eq { pop width 2 sub } if
     86   dup width 1 sub eq { pop 1 } if
     87   exch
     88   % dx dy x y
     89   4 2 roll
     90 } bind def
     91 
     92 % prev-wind-list -> wind-list
     93 /next-wind-list {
     94   % prev-wind-list
     95   [ exch
     96     % mark prev-wind-list
     97     {
     98       % ... prev-wind-array
     99       aload pop
    100       next-wind
    101       4 array astore
    102       % ... new-wind-array
    103     } forall
    104   ]
    105 } bind def
    106 
    107 % wind-list -> wind-dict
    108 /wind-dict {
    109   << exch
    110      {
    111        % ... wind-array
    112        aload pop pop pop
    113        % ... x y
    114        width mul add
    115        % ... key
    116        1
    117      } forall
    118   >>
    119 } bind def
    120 
    121 
    122 % prev-time prev-wind-list prev-pos-dict -> time wind-list pos-dict
    123 /cycle {
    124   % prev-time prev-wind-list pos-dict
    125   3 2 roll 1 add 3 1 roll
    126   % time prev-wind-list pos-dict
    127   exch next-wind-list exch
    128   % time wind-list pos-dict
    129   1 index wind-dict exch
    130   % time wind-list wind-dict pos-dict
    131   endy width mul dict exch
    132   % time wind-list wind-dict next-pos-dict pos-dict
    133   { pop
    134     % time wind-list wind-dict next-pos-dict key
    135     dup width mod exch width idiv
    136     % time wind-list wind-dict next-pos-dict x y
    137     movelist { aload pop
    138       % time wind-list wind-dict next-pos-dict x y dx dy
    139       exch 3 index add exch 2 index add
    140       % time wind-list wind-dict next-pos-dict x y next-x next-y
    141       true
    142       2 index 0 gt and
    143 % dup { (  true\012) } { (  false\012) } ifelse stderr exch writestring
    144       2 index width 1 sub lt and
    145       1 index 0 ge and
    146       1 index endy le and
    147       1 index starty gt 3 index startx eq or and
    148       1 index endy lt 3 index endx eq or and
    149       % time wind-list wind-dict next-pos-dict x y next-x next-y is-valid?
    150       {
    151         width mul add
    152         % time wind-list wind-dict next-pos-dict x y next-key
    153         4 index 1 index known
    154         4 index 1 index known or
    155         % time wind-list wind-dict next-pos-dict x y next-key is-known?
    156         not {
    157           % time wind-list wind-dict next-pos-dict x y next-key
    158           3 index 1 index 1 put
    159         } if
    160         % time wind-list wind-dict next-pos-dict x y next-key
    161         pop
    162       }
    163       { pop pop }
    164       ifelse
    165       % time wind-list wind-dict next-pos-dict x y
    166     } forall
    167     % time wind-list wind-dict next-pos-dict x y
    168     pop pop
    169   } forall
    170   % time wind-list wind-dict next-pos-dict
    171   exch pop
    172   % time wind-list next-pos-dict
    173 } bind def
    174 
    175 
    176 /Helvetica 20 selectfont
    177 
    178 
    179 (First Puzzle: )
    180 72 700 moveto show
    181 
    182 /endkey endy width mul endx add def
    183 /movelist [[0 0] [0 1] [0 -1] [1 0] [-1 0]] def
    184 0 init-wind-list << startx 1 >>
    185 { % prev-time prev-wind-list pos-dict
    186   cycle
    187   % time next-wind-list next-pos-dict
    188 % dup { pop
    189 %   dup width mod exch width idiv
    190 %   % time next-wind-list next-pos-dict x y
    191 %   stderr 5 index 15 string cvs writestring
    192 %   stderr (: ) writestring
    193 %   stderr 2 index 15 string cvs writestring
    194 %   stderr (, ) writestring
    195 %   stderr 1 index 15 string cvs writestring
    196 %   stderr 10 write
    197 %   pop pop
    198 % } forall
    199 % stderr (Cycle ) writestring
    200 % stderr 3 index 15 string cvs writestring
    201 % stderr (, ) writestring
    202 % stderr 1 index length 15 string cvs writestring
    203 % stderr ( states\012) writestring
    204 % stderr flushfile
    205   % time next-wind-list next-pos-dict
    206   dup endkey known { exit } if
    207   dup length 0 eq { 1.125 pstack quit } if
    208 } loop
    209 % time next-wind-list next-pos-dict
    210 2 index 15 string cvs show
    211 % time next-wind-list next-pos-dict
    212 
    213 (Second Puzzle: )
    214 72 664 moveto show
    215 
    216 % time next-wind-list next-pos-dict
    217 pop << endkey 1 >>
    218 { cycle dup startx known { exit } if } loop
    219 pop << startx 1 >>
    220 { cycle dup endkey known { exit } if } loop
    221 2 index 15 string cvs show
    222 
    223 showpage
    224 quit