aboutsummaryrefslogtreecommitdiffstats
path: root/day16
diff options
context:
space:
mode:
authorAn0nSaiko <porfeas12@gmail.com>2022-12-17 06:04:19 +0200
committerAn0nSaiko <porfeas12@gmail.com>2022-12-17 06:04:19 +0200
commitc19d3d6d50862b8847e87f018736252dc5e3129f (patch)
treebca50fe98ea7482546a7ceddbedb93531075a1d7 /day16
parentDay 15 (diff)
downloadaoc22-c19d3d6d50862b8847e87f018736252dc5e3129f.tar.gz
aoc22-c19d3d6d50862b8847e87f018736252dc5e3129f.zip
Day 16 (part1)
Diffstat (limited to 'day16')
-rw-r--r--day16/example.txt10
-rw-r--r--day16/input.txt54
-rw-r--r--day16/solution.nim118
3 files changed, 182 insertions, 0 deletions
diff --git a/day16/example.txt b/day16/example.txt
new file mode 100644
index 0000000..9f30acc
--- /dev/null
+++ b/day16/example.txt
@@ -0,0 +1,10 @@
1Valve AA has flow rate=0; tunnels lead to valves DD, II, BB
2Valve BB has flow rate=13; tunnels lead to valves CC, AA
3Valve CC has flow rate=2; tunnels lead to valves DD, BB
4Valve DD has flow rate=20; tunnels lead to valves CC, AA, EE
5Valve EE has flow rate=3; tunnels lead to valves FF, DD
6Valve FF has flow rate=0; tunnels lead to valves EE, GG
7Valve GG has flow rate=0; tunnels lead to valves FF, HH
8Valve HH has flow rate=22; tunnel leads to valve GG
9Valve II has flow rate=0; tunnels lead to valves AA, JJ
10Valve JJ has flow rate=21; tunnel leads to valve II
diff --git a/day16/input.txt b/day16/input.txt
new file mode 100644
index 0000000..6cc1dee
--- /dev/null
+++ b/day16/input.txt
@@ -0,0 +1,54 @@
1Valve OK has flow rate=0; tunnels lead to valves RW, FX
2Valve JY has flow rate=13; tunnel leads to valve TT
3Valve FX has flow rate=16; tunnels lead to valves OK, LF, GO, IV
4Valve TD has flow rate=0; tunnels lead to valves XZ, ED
5Valve VF has flow rate=9; tunnels lead to valves DS, LU, TR, WO
6Valve TT has flow rate=0; tunnels lead to valves XZ, JY
7Valve KR has flow rate=8; tunnels lead to valves VL, CI, GO, JJ, TQ
8Valve HN has flow rate=0; tunnels lead to valves YG, AA
9Valve MC has flow rate=24; tunnels lead to valves MI, EE, TH, YG
10Valve XM has flow rate=0; tunnels lead to valves AF, JL
11Valve XE has flow rate=0; tunnels lead to valves XP, AF
12Valve ZF has flow rate=0; tunnels lead to valves EM, EI
13Valve DS has flow rate=0; tunnels lead to valves VF, LF
14Valve AF has flow rate=7; tunnels lead to valves AW, XE, CI, BJ, XM
15Valve NL has flow rate=0; tunnels lead to valves KF, EM
16Valve LF has flow rate=0; tunnels lead to valves FX, DS
17Valve XZ has flow rate=25; tunnels lead to valves TD, TT
18Valve TQ has flow rate=0; tunnels lead to valves AA, KR
19Valve WO has flow rate=0; tunnels lead to valves VF, NE
20Valve TH has flow rate=0; tunnels lead to valves LU, MC
21Valve AA has flow rate=0; tunnels lead to valves TQ, KF, HN, XP, TY
22Valve KB has flow rate=0; tunnels lead to valves WP, XL
23Valve IV has flow rate=0; tunnels lead to valves PK, FX
24Valve MI has flow rate=0; tunnels lead to valves JF, MC
25Valve EX has flow rate=22; tunnels lead to valves JL, ZZ, SL
26Valve ZZ has flow rate=0; tunnels lead to valves EX, JS
27Valve KF has flow rate=0; tunnels lead to valves NL, AA
28Valve PK has flow rate=11; tunnels lead to valves IV, HP
29Valve TR has flow rate=0; tunnels lead to valves DI, VF
30Valve YG has flow rate=0; tunnels lead to valves HN, MC
31Valve JL has flow rate=0; tunnels lead to valves EX, XM
32Valve VL has flow rate=0; tunnels lead to valves JS, KR
33Valve XP has flow rate=0; tunnels lead to valves AA, XE
34Valve TY has flow rate=0; tunnels lead to valves JS, AA
35Valve EM has flow rate=4; tunnels lead to valves JJ, NL, ZF, WP, AW
36Valve BJ has flow rate=0; tunnels lead to valves WK, AF
37Valve JJ has flow rate=0; tunnels lead to valves EM, KR
38Valve RW has flow rate=14; tunnels lead to valves NE, OK
39Valve EI has flow rate=0; tunnels lead to valves ZF, JS
40Valve SL has flow rate=0; tunnels lead to valves HP, EX
41Valve EE has flow rate=0; tunnels lead to valves MC, XL
42Valve WK has flow rate=0; tunnels lead to valves BJ, JS
43Valve AW has flow rate=0; tunnels lead to valves EM, AF
44Valve XL has flow rate=21; tunnels lead to valves EE, KB
45Valve JF has flow rate=0; tunnels lead to valves MI, ED
46Valve LU has flow rate=0; tunnels lead to valves TH, VF
47Valve CI has flow rate=0; tunnels lead to valves AF, KR
48Valve ED has flow rate=23; tunnels lead to valves JF, TD
49Valve JS has flow rate=3; tunnels lead to valves VL, ZZ, EI, TY, WK
50Valve NE has flow rate=0; tunnels lead to valves RW, WO
51Valve DI has flow rate=12; tunnel leads to valve TR
52Valve WP has flow rate=0; tunnels lead to valves KB, EM
53Valve GO has flow rate=0; tunnels lead to valves FX, KR
54Valve HP has flow rate=0; tunnels lead to valves SL, PK
diff --git a/day16/solution.nim b/day16/solution.nim
new file mode 100644
index 0000000..b6d39e6
--- /dev/null
+++ b/day16/solution.nim
@@ -0,0 +1,118 @@
1import strutils
2import sequtils
3import re
4import tables
5import strformat
6import algorithm
7
8type
9 NodeData = tuple
10 pressure: int
11 neighbors: seq[string]
12
13 Node = tuple
14 id: string
15 data: NodeData
16
17 NodeGraph = Table[string, NodeData]
18
19 ExtendedNodeData = tuple
20 pressure: int
21 neighbors: Table[string, int]
22
23 ExtendedNodeGraph = Table[string, ExtendedNodeData]
24
25proc parseLine(line: string): Node =
26 let tokens = line.replace("Valve ")
27 .replace("has flow rate=")
28 .replace(re"; tunnels? leads? to valves?")
29 .replace(", ", " ")
30 .split(" ")
31 (tokens[0], (tokens[1].parseInt(), @tokens[2..^1]))
32
33proc parseFile(content: string): NodeGraph =
34 let lines = content.strip().splitLines()
35 let nodes = map(lines, parseLine)
36
37 for node in nodes:
38 result[node.id] = node.data
39
40proc bfs(input: NodeGraph, src: string): Table[string, int] =
41 var q = @[(src, 0)]
42 result[src] = 0
43
44 while q.len() > 0:
45 let (curr, pathLen) = q[0]
46 q.delete(0)
47
48 for neighbor in input[curr].neighbors:
49 if result.contains(neighbor):
50 continue
51 result[neighbor] = pathLen+1
52 q.add((neighbor, pathLen+1))
53
54proc setup(input: NodeGraph): ExtendedNodeGraph =
55 for node in input.keys():
56 # Exclude all 0 pressure nodes except the entry node "AA"
57 if (input[node].pressure == 0 and node != "AA"):
58 continue
59 let allConnected = bfs(input, node)
60 var filtConnected: Table[string, int]
61 for conn in allConnected.keys():
62 if input[conn].pressure == 0:
63 continue
64 filtConnected[conn] = allConnected[conn]
65
66 result[node] = (input[node].pressure, filtConnected)
67 # echo fmt"{node} : {result[node]}"
68
69
70var dp: Table[string, int]
71proc normalize(visited: string): string =
72 var s: seq[string]
73 for i in countup(0, visited.len()-1, 2):
74 s.add(visited[i..i+1])
75 result = s.sorted(system.cmp[string]).join()
76
77proc dfs(input: ExtendedNodeGraph, src: string, visited: string, time: int): int =
78 if time <= 1 or visited.len() == input.len():
79 return 0
80
81 # if dp.contains(visited):
82 # return dp[visited]
83
84 let visitedNorm = visited.normalize()
85 let selfScore = (time-1) * input[src].pressure
86 var maxSubscore = 0
87 var maxNeighbor = "undefined"
88 # echo fmt"{src}({selfScore}): "
89 for neighbor in input[src].neighbors.keys():
90 if neighbor in visited:
91 continue
92 let distance = input[src].neighbors[neighbor]
93 let subScore = dfs(input, neighbor, visitedNorm & neighbor, time - 1 - distance)
94 if subScore > maxSubscore:
95 maxSubscore = subScore
96 maxNeighbor = neighbor
97
98 # echo fmt"{src}({selfScore}) => {maxNeighbor}({maxSubscore})"
99 result = selfScore + maxSubscore
100 # dp[visitedNorm & maxNeighbor] = result
101 # echo result
102
103proc solve(input: NodeGraph, time: int): int =
104 let completeGraph = setup(input)
105 # Table of delays to get from starting node "AA" to current
106 let initDelays = completeGraph["AA"].neighbors
107
108 for node in completeGraph.keys():
109 if node == "AA":
110 continue
111 let startTime = time - initDelays[node]
112 result = max(result, dfs(completeGraph, node, node, startTime))
113 echo fmt"{node}({startTime}) : {result}"
114
115let content = readFile("./example.txt")
116
117let input = parseFile(content)
118echo solve(input, 30)