From ac27b8721d76e6a908608f981136f726db8248aa Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Tue, 14 Dec 2021 20:33:45 -0700 Subject: [PATCH] Add day12 problem + solution --- day12/input.txt | 22 +++++++++++++++ day12/p1.nim | 62 ++++++++++++++++++++++++++++++++++++++++++ day12/p2.nim | 64 ++++++++++++++++++++++++++++++++++++++++++++ day12/prob.md | 0 day12/testinput1.txt | 7 +++++ day12/testinput2.txt | 10 +++++++ day12/testinput3.txt | 18 +++++++++++++ 7 files changed, 183 insertions(+) create mode 100644 day12/input.txt create mode 100644 day12/p1.nim create mode 100644 day12/p2.nim create mode 100644 day12/prob.md create mode 100644 day12/testinput1.txt create mode 100644 day12/testinput2.txt create mode 100644 day12/testinput3.txt diff --git a/day12/input.txt b/day12/input.txt new file mode 100644 index 0000000..731cd4b --- /dev/null +++ b/day12/input.txt @@ -0,0 +1,22 @@ +GC-zi +end-zv +lk-ca +lk-zi +GC-ky +zi-ca +end-FU +iv-FU +lk-iv +lk-FU +GC-end +ca-zv +lk-GC +GC-zv +start-iv +zv-QQ +ca-GC +ca-FU +iv-ca +start-lk +zv-FU +start-zi diff --git a/day12/p1.nim b/day12/p1.nim new file mode 100644 index 0000000..9368b18 --- /dev/null +++ b/day12/p1.nim @@ -0,0 +1,62 @@ +import std/[strutils, sequtils, tables, os, strformat, sets] + +type + CaveKind = enum + ckStart + ckEnd + ckSmall + ckLarge + + CaveNode = ref object + name: string + neighbors: seq[CaveNode] + kind: CaveKind + +proc `$`(cave: CaveNode): string = + fmt"CaveNode(name: {cave.name.repr}, kind: {cave.kind}, neighbors: {cave.neighbors.mapIt(it.name)})" + +template makeCave(caveName: string): CaveNode = + let caveKind = if caveName[0] >= 'A' and caveName[0] <= 'Z': ckLarge else: ckSmall + CaveNode(name: caveName, kind: caveKind) + +proc countPaths(visitCave, targetCave: CaveNode, visited: var HashSet[string]): int = + if visitCave.name == targetCave.name: + return 1 + elif visitCave.kind == ckSmall: + visited.incl visitCave.name + + for cave in visitCave.neighbors: + if cave.name notin visited: + result += countPaths(cave, targetCave, visited) + + visited.excl visitCave.name + +proc main() = + let + fileName = paramStr(1) + startCave = CaveNode(name: "start", kind: ckStart) + endCave = CaveNode(name: "end", kind: ckEnd) + + var caveMap = {"start": startCave, "end": endCave}.newTable + + for line in fileName.lines: + let + split = line.strip().split("-") + left = split[0] + right = split[1] + + if left notin caveMap: + caveMap[left] = makeCave(left) + if right notin caveMap: + caveMap[right] = makeCave(right) + + if right != "start" and left != "end": + caveMap[left].neighbors.add(caveMap[right]) + if right != "end" and left != "start": + caveMap[right].neighbors.add(caveMap[left]) + + var visited = HashSet[string]() + + echo "Paths: ", countPaths(startCave, endCave, visited) + +main() diff --git a/day12/p2.nim b/day12/p2.nim new file mode 100644 index 0000000..d96bc8f --- /dev/null +++ b/day12/p2.nim @@ -0,0 +1,64 @@ +import std/[strutils, sequtils, tables, os, strformat, sets] + +type + CaveKind = enum + ckStart + ckEnd + ckSmall + ckLarge + + CaveNode = ref object + name: string + neighbors: seq[CaveNode] + kind: CaveKind + +proc `$`(cave: CaveNode): string = + fmt"CaveNode(name: {cave.name.repr}, kind: {cave.kind}, neighbors: {cave.neighbors.mapIt(it.name)})" + +template makeCave(caveName: string): CaveNode = + let caveKind = if caveName[0] >= 'A' and caveName[0] <= 'Z': ckLarge else: ckSmall + CaveNode(name: caveName, kind: caveKind) + +proc countPaths(visitCave, targetCave: CaveNode, visited: var HashSet[string], canTwice: bool): int = + if visitCave.name == targetCave.name: + return 1 + elif visitCave.kind == ckSmall: + visited.incl visitCave.name + + for cave in visitCave.neighbors: + if cave.name notin visited: + result += countPaths(cave, targetCave, visited, canTwice) + visited.excl cave.name + elif cave.kind == ckSmall and canTwice: + result += countPaths(cave, targetCave, visited, false) + + +proc main() = + let + fileName = paramStr(1) + startCave = CaveNode(name: "start", kind: ckStart) + endCave = CaveNode(name: "end", kind: ckEnd) + + var caveMap = {"start": startCave, "end": endCave}.newTable + + for line in fileName.lines: + let + split = line.strip().split("-") + left = split[0] + right = split[1] + + if left notin caveMap: + caveMap[left] = makeCave(left) + if right notin caveMap: + caveMap[right] = makeCave(right) + + if right != "start" and left != "end": + caveMap[left].neighbors.add(caveMap[right]) + if right != "end" and left != "start": + caveMap[right].neighbors.add(caveMap[left]) + + var visited = HashSet[string]() + + echo "Paths: ", countPaths(startCave, endCave, visited, true) + +main() diff --git a/day12/prob.md b/day12/prob.md new file mode 100644 index 0000000..e69de29 diff --git a/day12/testinput1.txt b/day12/testinput1.txt new file mode 100644 index 0000000..6fd8c41 --- /dev/null +++ b/day12/testinput1.txt @@ -0,0 +1,7 @@ +start-A +start-b +A-c +A-b +b-d +A-end +b-end diff --git a/day12/testinput2.txt b/day12/testinput2.txt new file mode 100644 index 0000000..62cc714 --- /dev/null +++ b/day12/testinput2.txt @@ -0,0 +1,10 @@ +dc-end +HN-start +start-kj +dc-start +dc-HN +LN-dc +HN-end +kj-sa +kj-HN +kj-dc diff --git a/day12/testinput3.txt b/day12/testinput3.txt new file mode 100644 index 0000000..65f3833 --- /dev/null +++ b/day12/testinput3.txt @@ -0,0 +1,18 @@ +fs-end +he-DX +fs-he +start-DX +pj-DX +end-zg +zg-sl +zg-pj +pj-he +RW-he +fs-DX +pj-RW +zg-RW +start-pj +he-WI +zg-he +pj-fs +start-RW