aoc-all

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

commit b1fdfddbaa46b51e3e28ead17e0d8f482d98e3ed
parent ba009e5ea9f0a5e3e7b50ab4f27b0dd17a7b2429
Author: Natasha Kerensikova <natgh@instinctive.eu>
Date:   Wed, 18 Dec 2024 06:35:45 +0000

Day 16 references and solutions
Diffstat:
A2024/day16.nim | 114+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A2024/ref/day16a.txt | 15+++++++++++++++
A2024/ref/day16b.txt | 17+++++++++++++++++
3 files changed, 146 insertions(+), 0 deletions(-)

diff --git a/2024/day16.nim b/2024/day16.nim @@ -0,0 +1,114 @@ +# Copyright (c) 2024, Natacha Porté +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +from std/sequtils import addUnique, concat, mapIt, toSeq, zip +from std/tables import `[]`, `[]=`, contains, getOrDefault, initTable, Table + +# Read input file + +let data = stdin.lines().toSeq() + +# Puzzles + +type + Direction = enum + north, east, south, west + Point = tuple + x, y: int + Node = tuple + p: Point + dir: Direction + PathData = tuple + score: int + prev: seq[Node] + +func delta(d: Direction): Point = + case d + of north: (x: 0, y: -1) + of south: (x: 0, y: 1) + of east: (x: 1, y: 0) + of west: (x: -1, y: 0) + +func `+`(a, b: Point): Point = (x: a.x + b.x, y: a.y + b.y) +func `[]`(m: seq[string], p: Point): char = m[p.y][p.x] + +func start(d: seq[string], c: char): Node = + var found = false + for y in 0 ..< len(d): + for x in 0 ..< len(d[y]): + if d[y][x] == c: + assert not found + found = true + result = (p: (x: x, y: y), dir: east) + assert found + +func next(unvisited: seq[Node], path: Table[Node, PathData]): (int, int) = + result = (0, path[unvisited[0]].score) + for i in 1 ..< len(unvisited): + let s = path[unvisited[i]].score + if i == 0 or s < result[1]: + result = (i, s) + +proc update(unvisited: var seq[Node], path: var Table[Node, PathData], d: seq[string], prev, n: Node, s: int): void = + if d[n.p] == '#': + return + if not path.contains(n) or path[n].score > s: + unvisited.addUnique(n) + path[n] = (score: s, prev: @[prev]) + elif path[n].score == s: + path[n].prev.add(prev) + +func search(d: seq[string]): (Table[Node, PathData], int) = + var + unvisited = @[start(d, 'S')] + path = initTable[Node, PathData]() + finish = start(d, 'E').p + found = false + path[unvisited[0]] = (score: 0, prev: @[]) + while len(unvisited) > 0: + let + (i, s) = next(unvisited, path) + n = unvisited[i] + if found: + if s > result[1]: + return + elif n.p == finish: + result = (path, s) + found = true + unvisited = concat(unvisited[0 ..< i], unvisited[i + 1 ..< len(unvisited)]) + update(unvisited, path, d, n, (p: n.p + delta(n.dir), dir: n.dir), s + 1) + for dir in Direction: + update(unvisited, path, d, n, (p: n.p, dir: dir), s + 1000) + assert false + +let (path_data, answer1) = search(data) +echo "Puzzle 1: ", answer1 + +func answer2(path: Table[Node, PathData], p: Point): int = + var + visited = initTable[Point, bool]() + queue: seq[Node] + for d in Direction: + let n = (p: p, dir: d) + if path.contains(n): + queue.add(n) + assert len(queue) > 0 + result = 0 + while len(queue) > 0: + if not visited.contains(queue[0].p): + visited[queue[0].p] = true + result += 1 + queue = concat(queue[1 .. ^1], path[queue[0]].prev) + +echo "Puzzle 2: ", answer2(path_data, start(data, 'E').p) diff --git a/2024/ref/day16a.txt b/2024/ref/day16a.txt @@ -0,0 +1,15 @@ +############### +#.......#....E# +#.#.###.#.###.# +#.....#.#...#.# +#.###.#####.#.# +#.#.#.......#.# +#.#.#####.###.# +#...........#.# +###.#.#####.#.# +#...#.....#.#.# +#.#.#.###.#.#.# +#.....#...#.#.# +#.###.#.#.#.#.# +#S..#.....#...# +############### diff --git a/2024/ref/day16b.txt b/2024/ref/day16b.txt @@ -0,0 +1,17 @@ +################# +#...#...#...#..E# +#.#.#.#.#.#.#.#.# +#.#.#.#...#...#.# +#.#.#.#.###.#.#.# +#...#.#.#.....#.# +#.#.#.#.#.#####.# +#.#...#.#.#.....# +#.#.#####.#.###.# +#.#.#.......#...# +#.#.###.#####.### +#.#.#...#.....#.# +#.#.#.#####.###.# +#.#.#.........#.# +#.#.#.#########.# +#S#.............# +#################