aoc-all

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

day10.nim (2502B)


      1 # Copyright (c) 2024, Natacha Porté
      2 #
      3 # Permission to use, copy, modify, and distribute this software for any
      4 # purpose with or without fee is hereby granted, provided that the above
      5 # copyright notice and this permission notice appear in all copies.
      6 #
      7 # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      8 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
      9 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     10 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     11 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     12 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     13 # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     14 
     15 from std/sequtils import addUnique, foldl, mapIt, toSeq
     16 
     17 # Read input file
     18 
     19 let data = stdin.lines().toSeq().mapIt(it.mapIt(ord(it) - ord('0')))
     20 
     21 # Puzzle 1
     22 
     23 type Point = tuple
     24   x, y: int
     25 
     26 func start_points(d: seq[seq[int]]): seq[Point] =
     27   for y in 0 ..< len(d):
     28     for x in 0 ..< len(d[y]):
     29       if d[y][x] == 0:
     30         result.add((x: x, y: y))
     31 
     32 func update_points(d: seq[seq[int]], points: seq[Point]): seq[Point] =
     33   for p in points:
     34     let v = d[p.y][p.x] + 1
     35     if p.x > 0 and d[p.y][p.x-1] == v:
     36       result.addUnique((x: p.x-1, y: p.y))
     37     if p.y > 0 and d[p.y-1][p.x] == v:
     38       result.addUnique((x: p.x, y: p.y-1))
     39     if p.x < len(d[p.y])-1 and d[p.y][p.x+1] == v:
     40       result.addUnique((x: p.x+1, y: p.y))
     41     if p.y < len(d)-1 and d[p.y+1][p.x] == v:
     42       result.addUnique((x: p.x, y: p.y+1))
     43 
     44 proc head_score(d: seq[seq[int]], pt: Point): int =
     45   var pts = @[pt]
     46   for v in d[pt.y][pt.x]+1 .. 9:
     47     pts = update_points(d, pts)
     48   result = len(pts)
     49 
     50 echo "Puzzle 1: ", start_points(data).mapIt(head_score(data, it)).foldl(a + b)
     51 
     52 # Puzzle 2
     53 
     54 func update_points2(d: seq[seq[int]], points: seq[Point]): seq[Point] =
     55   for p in points:
     56     let v = d[p.y][p.x] + 1
     57     if p.x > 0 and d[p.y][p.x-1] == v:
     58       result.add((x: p.x-1, y: p.y))
     59     if p.y > 0 and d[p.y-1][p.x] == v:
     60       result.add((x: p.x, y: p.y-1))
     61     if p.x < len(d[p.y])-1 and d[p.y][p.x+1] == v:
     62       result.add((x: p.x+1, y: p.y))
     63     if p.y < len(d)-1 and d[p.y+1][p.x] == v:
     64       result.add((x: p.x, y: p.y+1))
     65 
     66 proc head_score2(d: seq[seq[int]], pt: Point): int =
     67   var pts = @[pt]
     68   for v in d[pt.y][pt.x]+1 .. 9:
     69     pts = update_points2(d, pts)
     70   result = len(pts)
     71 
     72 echo "Puzzle 2: ", start_points(data).mapIt(head_score2(data, it)).foldl(a + b)