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)