aoc-all

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

day13.ps (5798B)


      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- day13.ps <day13.txt | display
     19 
     20 /datafile (%stdin) (r) file def
     21 /stderr (%stderr) (w) file def
     22 
     23 % [ item_1 ... item_n ] item_0 -> [ item_0 item_1 ... item_n ]
     24 /apush {
     25   % array new_item
     26   exch aload length 1 add array astore
     27 } bind def
     28 
     29 % [ item_0 ... item_n-1 ] item_n -> [ item_0 item_1 ... item_n ]
     30 /aappend {
     31   exch aload length
     32   % new-item item-0 item-1 ... item-n-1 n
     33   dup dup 2 add exch 1 add roll
     34   % item-0 item-1 ... item-n-1 n new-item
     35   exch
     36   % item-0 item-1 ... item-n-1 new-item n
     37   1 add array astore
     38 } bind def
     39 
     40 % [ item_0 item_1 ... item_n ] -> [ item_1 ... item_n ] item_0
     41 /apop {
     42   aload length 1 sub array astore exch
     43 } bind def
     44 
     45 % (item) -> item
     46 /parse-item {
     47   { % (suffix)
     48     dup length 0 eq { pop exit } if
     49     % (suffix)
     50     { %%% 1-iteration loop to use `exit` as a short circuit
     51       ([) anchorsearch
     52       { % (next-suffix) ([)
     53         pop [ exch
     54         % mark (next-suffix)
     55         exit
     56       } if
     57 
     58       (]) anchorsearch
     59       { % (next-suffix) (])
     60         pop
     61         % mark items (next-suffix)
     62         counttomark 1 add
     63         % mark items (next-suffix) item-count+2
     64         1 roll
     65         % (next-suffix) mark items
     66         ] exch
     67         % array (next-suffix)
     68         exit
     69       } if
     70 
     71       (,) anchorsearch
     72       { % (next-suffix) (,)
     73         pop exit
     74       } if
     75 
     76       0 {
     77         % (suffix) digit-count
     78         2 copy get
     79         % (suffix) digit-count cur-char
     80         dup 48 ge exch 57 le and
     81         % (suffix) digit-count cur-char-is-digit?
     82         { 1 add }
     83         { exit }
     84         ifelse
     85       } loop
     86       % (suffix) digit-count
     87       dup 0 eq { 2.125 pstack quit } if
     88       % (suffix) digit-count
     89       2 copy 0 exch getinterval
     90       % (suffix) digit-count (num)
     91       cvi 3 1 roll
     92       % num (suffix) digit-count
     93       1 index length 1 index sub getinterval
     94       % num (next-suffix)
     95       exit
     96     } loop
     97   } loop
     98 } bind def
     99 
    100 % left right -> num
    101 %   -1 if left < right
    102 %    0 if left = right
    103 %    1 if left > right
    104 /cmp-items {
    105   % left right
    106   1 index type /integertype eq
    107   { % int-left right
    108     dup type /integertype eq
    109     { % int-left int-right
    110       2 copy eq
    111       { pop pop 0 }
    112       { lt { -1 } { 1 } ifelse}
    113       ifelse
    114       % result
    115     }
    116     { % int-left list-right
    117       exch 1 array astore exch
    118       % list-left list-right
    119       cmp-items
    120       % result
    121     }
    122     ifelse
    123   }
    124   { % list-left right
    125     dup type /integertype eq
    126     { % list-left int-right
    127       1 array astore
    128       % list-left list-right
    129       cmp-items
    130       % result
    131     }
    132     { 0 % list-left list-right index
    133       {
    134         2 index length 1 index le
    135         % list-left list-right index list-left-too-short?
    136         2 index length 2 index le
    137         % list-left list-right index list-left-too-short? list-right-too-short?
    138         2 copy or
    139         { 2 copy and
    140           { pop pop pop pop pop 0 }
    141           { 5 1 roll pop pop pop pop { 1 } { -1 } ifelse }
    142           ifelse
    143           % result
    144           exit
    145         }
    146         { pop pop }
    147         ifelse
    148         % list-left list-right index
    149         2 index 1 index get
    150         % list-left list-right index left-item
    151         2 index 2 index get
    152         % list-left list-right index left-item right-item
    153         cmp-items
    154         % list-left list-right index item-cmp
    155         dup 0 eq
    156         { pop }
    157         { 4 1 roll pop pop pop exit }
    158         ifelse
    159         % list-left list-right index
    160         1 add
    161         % list-left list-right next-index
    162       } loop
    163       % result
    164     }
    165     ifelse
    166   }
    167   ifelse
    168 } bind def
    169 
    170 /data [
    171   [
    172   {
    173     datafile 200 string readline
    174     not { pop exit } if
    175     % line
    176     dup length 0 eq
    177     { pop ] [ }
    178     { parse-item }
    179     ifelse
    180   } loop
    181   ]
    182 ] def
    183 
    184 
    185 /Helvetica 20 selectfont
    186 
    187 
    188 (First Puzzle: )
    189 72 700 moveto show
    190 0 0 data {
    191   % sum prev-rank pair
    192   exch 1 add exch
    193   % sum rank pair
    194   dup length 2 eq not
    195   { 1.125 pstack quit } if
    196   % sum rank pair
    197   aload pop
    198   % sum rank left right
    199   cmp-items
    200   % sum rank cmp
    201   stderr (Pair ) writestring
    202   stderr 2 index 15 string cvs writestring
    203   stderr (: ) writestring
    204   stderr 1 index 15 string cvs writestring
    205   stderr 10 write
    206   % sum rank cmp
    207   -1 eq
    208   { exch 1 index add exch } if
    209   % sum rank
    210 } forall
    211 pop
    212 % sum
    213 15 string cvs show
    214 
    215 
    216 (Second Puzzle: )
    217 72 664 moveto show
    218 
    219 1 [[2]] 2 [[6]] 0 data {
    220   % rank-A item-A rank-B item-B prev-index pair
    221   exch 1 add exch
    222   % rank-A item-A rank-B item-B index pair
    223   {
    224     % rank-A item-A rank-B item-B index item
    225     dup 5 index cmp-items -1 le
    226     % rank-A item-A rank-B item-B index item item<item-A?
    227     { 6 5 roll 1 add 6 1 roll } if
    228     % rank-A item-A rank-B item-B index item
    229     2 index cmp-items -1 le
    230     % rank-A item-A rank-B item-B index item<item-B?
    231     { 3 2 roll 1 add 3 1 roll } if
    232     % rank-A item-A rank-B item-B index
    233   } forall
    234   % rank-A item-A rank-B item-B index
    235 } forall
    236 % rank-A item-A rank-B item-B index
    237 pop pop exch pop
    238 % rank-A rank-B
    239 
    240 1 index 15 string cvs show
    241 ( * ) show
    242 dup 15 string cvs show
    243 ( = ) show
    244 mul 15 string cvs show
    245 
    246 showpage
    247 quit