Add day12 problem + solution
This commit is contained in:
parent
e60c687e42
commit
ac27b8721d
7 changed files with 183 additions and 0 deletions
22
day12/input.txt
Normal file
22
day12/input.txt
Normal 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
62
day12/p1.nim
Normal 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
64
day12/p2.nim
Normal 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
0
day12/prob.md
Normal file
7
day12/testinput1.txt
Normal file
7
day12/testinput1.txt
Normal 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
10
day12/testinput2.txt
Normal 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
18
day12/testinput3.txt
Normal 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
|
||||
Loading…
Add table
Add a link
Reference in a new issue