Add day12 problem + solution

This commit is contained in:
Joey Yakimowich-Payne 2021-12-14 20:33:45 -07:00
commit ac27b8721d
7 changed files with 183 additions and 0 deletions

22
day12/input.txt Normal file
View file

@ -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

62
day12/p1.nim Normal file
View file

@ -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()

64
day12/p2.nim Normal file
View file

@ -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()

0
day12/prob.md Normal file
View file

7
day12/testinput1.txt Normal file
View file

@ -0,0 +1,7 @@
start-A
start-b
A-c
A-b
b-d
A-end
b-end

10
day12/testinput2.txt Normal file
View file

@ -0,0 +1,10 @@
dc-end
HN-start
start-kj
dc-start
dc-HN
LN-dc
HN-end
kj-sa
kj-HN
kj-dc

18
day12/testinput3.txt Normal file
View file

@ -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