From 77c9806c3de6ee09130f2c5c2344b4ef054c1433 Mon Sep 17 00:00:00 2001 From: An0nSaiko Date: Sun, 18 Dec 2022 23:30:13 +0200 Subject: Day 18 --- day16/solution.nim | 297 +++---- day18/example.txt | 13 + day18/input.txt | 2165 ++++++++++++++++++++++++++++++++++++++++++++++++++++ day18/solution.nim | 83 ++ 4 files changed, 2416 insertions(+), 142 deletions(-) create mode 100644 day18/example.txt create mode 100644 day18/input.txt create mode 100644 day18/solution.nim diff --git a/day16/solution.nim b/day16/solution.nim index ae93568..66015d3 100644 --- a/day16/solution.nim +++ b/day16/solution.nim @@ -5,25 +5,26 @@ import tables import strformat import algorithm import sets +import sugar type NodeData = tuple pressure: int - neighbors: seq[string] + neighbors: seq[int64] Node = tuple - id: string + id: int64 data: NodeData - NodeGraph = Table[string, NodeData] + NodeGraph = Table[int64, NodeData] ExtendedNodeData = tuple pressure: int - neighbors: Table[string, int] + neighbors: Table[int64, int] - ExtendedNodeGraph = Table[string, ExtendedNodeData] + ExtendedNodeGraph = Table[int64, ExtendedNodeData] -proc parseLine(line: string): Node = +proc parseLine(line: string): auto = let tokens = line.replace("Valve ") .replace("has flow rate=") .replace(re"; tunnels? leads? to valves?") @@ -35,145 +36,157 @@ proc parseFile(content: string): NodeGraph = let lines = content.strip().splitLines() let nodes = map(lines, parseLine) - for node in nodes: - result[node.id] = node.data - -proc bfs(input: NodeGraph, src: string): Table[string, int] = - var q = @[(src, 0)] - result[src] = 0 - - while q.len() > 0: - let (curr, pathLen) = q[0] - q.delete(0) - - for neighbor in input[curr].neighbors: - if result.contains(neighbor): - continue - result[neighbor] = pathLen+1 - q.add((neighbor, pathLen+1)) - -proc setup(input: NodeGraph): ExtendedNodeGraph = - for node in input.keys(): - # Exclude all 0 pressure nodes except the entry node "AA" - if (input[node].pressure == 0 and node != "AA"): - continue - let allConnected = bfs(input, node) - var filtConnected: Table[string, int] - for conn in allConnected.keys(): - if input[conn].pressure == 0: - continue - filtConnected[conn] = allConnected[conn] - - result[node] = (input[node].pressure, filtConnected) - # echo fmt"{node} : {result[node]}" - -type Agent = tuple - valv: string - time: int - -# Nodes with their neighbors -var Graph: ExtendedNodeGraph -# Node names -var nodes = newSeq[string]() - -proc playing(agent: Agent, time: int): bool = - agent.time == time - -proc agentScores(agent: Agent, time: int): int = - Graph[agent.valv].pressure * (time-1) - + # Create stringID to intID mapping + var nodeIDs: Table[string, int64] + for i, node in nodes: + nodeIDs[node[0]] = 1 shl i + + echo nodeIDs + # for i, node in nodes: + # result[nodeIDs[nodes[0]]] = (node[1][0], map(node[1][1], (stringID) => nodeIDs[stringID])) + +# proc bfs(input: NodeGraph, src: string): Table[string, int] = +# var q = @[(src, 0)] +# result[src] = 0 +# +# while q.len() > 0: +# let (curr, pathLen) = q[0] +# q.delete(0) +# +# for neighbor in input[curr].neighbors: +# if result.contains(neighbor): +# continue +# result[neighbor] = pathLen+1 +# q.add((neighbor, pathLen+1)) +# +# proc setup(input: NodeGraph): ExtendedNodeGraph = +# for node in input.keys(): +# # Exclude all 0 pressure nodes except the entry node "AA" +# if (input[node].pressure == 0 and node != "AA"): +# continue +# let allConnected = bfs(input, node) +# var filtConnected: Table[string, int] +# for conn in allConnected.keys(): +# if input[conn].pressure == 0: +# continue +# filtConnected[conn] = allConnected[conn] +# +# result[node] = (input[node].pressure, filtConnected) +# # echo fmt"{node} : {result[node]}" +# +# type Agent = tuple +# valv: string +# time: int +# +# # Nodes with their neighbors +# var Graph: ExtendedNodeGraph +# # Node names +# var nodes = newSeq[string]() +# +# proc playing(agent: Agent, time: int): bool = +# agent.time == time +# +# proc agentScores(agent: Agent, time: int): int = +# Graph[agent.valv].pressure * (time-1) +# # type ValveSet = uint64 +# # proc incl(set: var ValveSet, valve: uint64): void = # set = set or valve - -var part2 = false -proc dfs(visited: HashSet[string], time: int, human, elephant: Agent): int = - # echo fmt"time: {time}, human: {human}, elephant: {elephant}" - let remainingValves = nodes.len() - visited.len() - if time <= 1 or remainingValves == 0 or (part2 and human.valv == elephant.valv and remainingValves > 1): - return 0 - - let - neighborsHuman = Graph[human.valv].neighbors - neighborsElephant = Graph[elephant.valv].neighbors - var - # check for race - humanScore = if human.valv notin visited: human.agentScores(time) else: 0 - elephantScore = if elephant.valv notin visited: elephant.agentScores(time) else: 0 - - var bestNextScore = 0 - if human.playing(time) and elephant.playing(time): - for nextHuman in nodes: - for nextElephant in nodes: - if nextHuman in visited or nextElephant in visited: - continue - let - nextTimeHuman = time - 1 - neighborsHuman[nextHuman] - nextTimeElephant = time - 1 - neighborsElephant[nextElephant] - nextTime = max(nextTimeHuman, nextTimeElephant) - nextScore = dfs(union(visited, toHashSet(@[elephant.valv, human.valv])), nextTime, (nextHuman, nextTimeHuman), (nextElephant, nextTimeElephant)) - bestNextScore = max(bestNextScore, nextScore) - - # elephant keeps his score only if he isn't in the same valve as human - elephantScore = (if human != elephant: elephantScore else: 0) - return bestNextScore + humanScore + elephantScore - - if human.playing(time): - for nextHuman in nodes: - if nextHuman in visited: - continue - let - nextTimeHuman = time - 1 - neighborsHuman[nextHuman] - nextTime = max(nextTimeHuman, elephant.time) - nextScore = dfs(union(visited, toHashSet(@[human.valv])), nextTime, (nextHuman, nextTimeHuman), elephant) - bestNextScore = max(bestNextScore, nextScore) - - # Check for race - return bestNextScore + humanScore - - if elephant.playing(time): - for nextElephant in nodes: - if nextElephant in visited: - continue - let - nextTimeElephant = time - 1 - neighborsElephant[nextElephant] - nextTime = max(human.time, nextTimeElephant) - nextScore = dfs(union(visited, toHashSet(@[elephant.valv])), nextTime, human, (nextElephant, nextTimeElephant)) - bestNextScore = max(bestNextScore, nextScore) - - # Check for race - return bestNextScore + elephantScore - - assert(false) - -proc solve(initDelays: Table[string, int], time: int): int = - - if not part2: - for human in nodes: - let - humanStartTime = time - initDelays[human] - startTime = humanStartTime - result = max(result, dfs(initHashSet[string](), startTime, (human, humanStartTime), (human, -1))) - else: - for i, human in nodes[0 ..< ^1]: - for elephant in nodes[i+1 .. ^1]: - let - elephantStartTime = time - initDelays[elephant] - humanStartTime = time - initDelays[human] - startTime = max(elephantStartTime, humanStartTime) - result = max(result, dfs(initHashSet[string](), startTime, (human, humanStartTime), (elephant, elephantStartTime))) +# +# proc contains(set: ValveSet, valve: uint64): bool = +# return (set and valve) > 0 +# +# var part2 = false +# proc dfs(visited: ValveSet, time: int, human, elephant: Agent): int = +# # echo fmt"time: {time}, human: {human}, elephant: {elephant}" +# let remainingValves = nodes.len() - visited.len() +# if time <= 1 or remainingValves == 0 or (part2 and human.valv == elephant.valv and remainingValves > 1): +# return 0 +# +# let +# neighborsHuman = Graph[human.valv].neighbors +# neighborsElephant = Graph[elephant.valv].neighbors +# var +# # check for race +# humanScore = if human.valv notin visited: human.agentScores(time) else: 0 +# elephantScore = if elephant.valv notin visited: elephant.agentScores(time) else: 0 +# +# var bestNextScore = 0 +# if human.playing(time) and elephant.playing(time): +# for nextHuman in nodes: +# for nextElephant in nodes: +# if nextHuman in visited or nextElephant in visited: +# continue +# let +# nextTimeHuman = time - 1 - neighborsHuman[nextHuman] +# nextTimeElephant = time - 1 - neighborsElephant[nextElephant] +# nextTime = max(nextTimeHuman, nextTimeElephant) +# nextScore = dfs(union(visited, toHashSet(@[elephant.valv, human.valv])), nextTime, (nextHuman, nextTimeHuman), (nextElephant, nextTimeElephant)) +# bestNextScore = max(bestNextScore, nextScore) +# +# # elephant keeps his score only if he isn't in the same valve as human +# elephantScore = (if human != elephant: elephantScore else: 0) +# return bestNextScore + humanScore + elephantScore +# +# if human.playing(time): +# for nextHuman in nodes: +# if nextHuman in visited: +# continue +# let +# nextTimeHuman = time - 1 - neighborsHuman[nextHuman] +# nextTime = max(nextTimeHuman, elephant.time) +# nextScore = dfs(union(visited, toHashSet(@[human.valv])), nextTime, (nextHuman, nextTimeHuman), elephant) +# bestNextScore = max(bestNextScore, nextScore) +# +# # Check for race +# return bestNextScore + humanScore +# +# if elephant.playing(time): +# for nextElephant in nodes: +# if nextElephant in visited: +# continue +# let +# nextTimeElephant = time - 1 - neighborsElephant[nextElephant] +# nextTime = max(human.time, nextTimeElephant) +# nextScore = dfs(union(visited, toHashSet(@[elephant.valv])), nextTime, human, (nextElephant, nextTimeElephant)) +# bestNextScore = max(bestNextScore, nextScore) +# +# # Check for race +# return bestNextScore + elephantScore +# +# assert(false) +# +# proc solve(initDelays: Table[string, int], time: int): int = +# +# if not part2: +# for human in nodes: +# let +# humanStartTime = time - initDelays[human] +# startTime = humanStartTime +# result = max(result, dfs(initHashSet[string](), startTime, (human, humanStartTime), (human, -1))) +# else: +# for i, human in nodes[0 ..< ^1]: +# for elephant in nodes[i+1 .. ^1]: +# let +# elephantStartTime = time - initDelays[elephant] +# humanStartTime = time - initDelays[human] +# startTime = max(elephantStartTime, humanStartTime) +# result = max(result, dfs(initHashSet[string](), startTime, (human, humanStartTime), (elephant, elephantStartTime))) +# +# let content = readFile("./example.txt") - let input = parseFile(content) -Graph = setup(input) -# Table of delays to get from starting node "AA" to current -let initDelays = Graph["AA"].neighbors -Graph.del("AA") - -for node in Graph.keys(): - nodes.add(node) - -echo solve(initDelays, 30) -part2 = true -echo solve(initDelays, 26) +echo input + +# # Table of delays to get from starting node "AA" to current +# let initDelays = Graph["AA"].neighbors +# Graph.del("AA") +# +# for node in Graph.keys(): +# nodes.add(node) +# +# echo solve(initDelays, 30) +# part2 = true +# echo solve(initDelays, 26) diff --git a/day18/example.txt b/day18/example.txt new file mode 100644 index 0000000..73a7202 --- /dev/null +++ b/day18/example.txt @@ -0,0 +1,13 @@ +2,2,2 +1,2,2 +3,2,2 +2,1,2 +2,3,2 +2,2,1 +2,2,3 +2,2,4 +2,2,6 +1,2,5 +3,2,5 +2,1,5 +2,3,5 diff --git a/day18/input.txt b/day18/input.txt new file mode 100644 index 0000000..5ea9dff --- /dev/null +++ b/day18/input.txt @@ -0,0 +1,2165 @@ +7,2,7 +12,2,8 +11,18,11 +7,6,3 +7,7,17 +9,15,2 +12,17,8 +12,8,3 +11,6,17 +8,18,10 +11,14,3 +16,14,8 +12,5,4 +7,4,14 +10,3,15 +4,16,7 +14,13,15 +13,17,8 +8,17,13 +3,14,12 +7,17,11 +3,15,12 +5,12,15 +17,8,10 +8,17,9 +3,12,11 +16,12,7 +12,4,8 +12,10,1 +7,12,17 +15,12,11 +9,5,15 +9,17,8 +8,13,3 +8,15,5 +5,7,14 +9,2,13 +3,9,8 +11,4,12 +5,10,14 +7,8,2 +9,3,4 +10,12,2 +9,5,16 +7,14,16 +14,18,11 +6,14,16 +4,13,10 +6,10,17 +9,9,18 +12,4,6 +2,8,13 +4,6,12 +17,13,7 +16,7,7 +8,6,16 +15,6,12 +11,16,12 +9,1,8 +13,16,9 +16,13,10 +15,7,4 +9,15,16 +9,17,6 +3,12,6 +12,14,15 +12,1,8 +5,8,4 +10,18,11 +12,4,3 +13,12,3 +3,5,7 +15,6,6 +16,11,16 +4,13,6 +3,4,10 +13,12,2 +16,8,6 +12,17,9 +9,11,16 +9,17,12 +16,10,14 +16,9,6 +14,3,11 +9,8,19 +16,6,6 +4,3,11 +17,10,5 +17,13,11 +14,15,13 +13,5,4 +16,12,4 +13,15,15 +4,4,6 +16,7,14 +6,17,8 +9,17,9 +13,15,11 +14,16,10 +9,2,7 +17,10,8 +12,9,2 +9,11,18 +9,11,17 +16,6,9 +3,14,8 +4,4,7 +7,15,7 +8,7,17 +10,7,3 +14,10,14 +15,11,16 +7,3,13 +14,10,3 +13,10,2 +12,12,4 +4,8,4 +1,8,9 +11,13,2 +12,6,16 +11,10,17 +1,9,11 +5,16,10 +9,15,5 +3,9,7 +8,11,17 +10,2,10 +16,7,4 +10,18,9 +12,3,11 +10,11,1 +10,2,8 +13,7,15 +11,11,16 +2,13,5 +3,8,9 +14,3,6 +12,10,17 +7,1,10 +8,5,15 +11,15,4 +4,15,11 +12,2,12 +8,9,17 +15,14,6 +7,14,13 +8,4,5 +9,3,12 +4,16,12 +6,3,7 +9,3,13 +16,5,13 +10,1,10 +6,12,15 +11,7,16 +8,10,18 +10,17,7 +3,14,6 +3,8,5 +2,11,8 +13,4,4 +6,4,6 +8,16,13 +12,9,17 +7,12,2 +15,6,5 +15,5,11 +10,8,16 +4,13,7 +15,6,15 +5,12,3 +2,9,13 +2,8,10 +12,3,6 +7,3,14 +12,16,7 +10,17,13 +14,4,5 +5,15,15 +15,9,3 +11,2,12 +5,3,13 +6,15,15 +6,2,8 +9,5,2 +4,6,14 +15,14,8 +8,9,18 +7,5,12 +11,7,1 +10,15,16 +5,16,12 +4,12,14 +9,1,12 +9,1,13 +17,7,6 +4,7,13 +13,15,12 +5,14,13 +16,5,5 +14,7,7 +6,11,3 +8,11,1 +4,8,13 +5,2,8 +8,4,4 +12,3,7 +11,9,17 +4,10,5 +4,11,16 +15,8,14 +8,4,13 +14,8,3 +6,6,5 +8,3,8 +14,16,8 +7,10,1 +14,10,17 +15,11,15 +11,13,5 +5,9,3 +12,7,17 +16,8,16 +17,13,8 +11,9,3 +7,3,8 +17,14,9 +17,11,7 +6,16,11 +3,5,8 +12,5,3 +17,5,6 +14,9,16 +9,16,6 +9,7,2 +14,14,14 +14,15,10 +16,13,12 +8,3,4 +11,6,15 +1,10,11 +14,11,13 +9,17,13 +4,10,4 +9,2,6 +10,5,15 +10,4,16 +8,5,16 +6,14,15 +10,10,15 +13,2,8 +4,5,10 +3,13,7 +17,7,10 +16,12,6 +15,4,13 +7,14,3 +8,6,3 +5,13,13 +14,11,2 +6,4,11 +8,17,8 +5,16,9 +13,7,3 +16,9,14 +15,6,11 +9,14,6 +4,6,15 +3,8,14 +14,17,10 +3,13,11 +18,10,9 +10,16,13 +12,1,7 +14,12,10 +12,14,5 +16,7,13 +4,7,11 +9,9,1 +11,4,3 +6,4,8 +5,16,8 +15,11,6 +6,11,17 +9,15,15 +5,14,14 +8,10,17 +4,16,11 +3,13,4 +3,10,14 +9,5,4 +5,15,14 +6,8,2 +5,3,9 +4,9,5 +15,12,13 +11,16,6 +5,4,5 +11,15,9 +14,6,14 +17,8,7 +18,11,7 +10,4,4 +8,3,9 +4,13,13 +3,3,11 +16,9,5 +3,6,5 +6,13,3 +2,10,11 +11,15,3 +14,2,9 +10,12,18 +11,4,9 +5,13,14 +6,15,5 +7,15,14 +5,4,13 +1,7,9 +3,9,14 +11,11,17 +10,16,9 +7,17,9 +9,2,11 +8,8,2 +16,9,4 +3,6,7 +9,6,3 +5,12,16 +14,9,3 +12,13,2 +15,6,7 +7,5,3 +15,3,10 +7,2,9 +11,15,5 +15,16,10 +15,11,13 +10,4,5 +11,5,15 +1,13,7 +17,11,6 +7,13,15 +10,3,4 +8,1,9 +5,5,11 +17,8,6 +9,1,7 +9,2,12 +16,7,12 +9,12,18 +17,6,10 +14,7,8 +6,15,12 +13,9,17 +14,17,11 +13,7,4 +15,3,11 +11,5,16 +14,10,15 +11,0,10 +8,14,4 +12,14,7 +14,17,12 +13,13,13 +6,4,9 +5,16,15 +10,1,12 +10,9,18 +11,3,7 +17,10,14 +3,11,13 +15,4,6 +9,3,11 +5,10,4 +12,14,16 +3,10,13 +9,12,3 +6,16,13 +6,8,3 +5,4,8 +5,3,5 +15,13,9 +14,14,15 +13,13,3 +8,16,11 +5,11,5 +5,17,7 +5,5,7 +13,16,8 +18,12,11 +10,4,15 +6,14,6 +4,15,7 +7,5,4 +14,4,7 +16,12,9 +13,11,17 +2,9,8 +9,1,10 +11,5,3 +14,3,7 +11,14,13 +14,11,3 +2,11,11 +2,8,8 +14,8,16 +15,13,5 +5,7,2 +10,8,17 +11,6,2 +6,12,17 +14,6,5 +6,13,4 +10,18,7 +12,3,14 +2,10,12 +4,4,8 +5,8,14 +9,14,4 +4,5,8 +9,13,18 +3,11,6 +10,10,1 +13,5,15 +10,7,1 +14,9,4 +16,10,5 +15,4,12 +12,9,16 +2,10,10 +11,17,7 +15,9,4 +16,13,14 +15,8,5 +4,14,15 +6,3,10 +6,17,6 +5,11,3 +6,10,2 +10,7,17 +11,10,18 +12,7,16 +13,4,5 +13,15,9 +14,10,4 +16,4,8 +4,9,4 +14,8,15 +10,13,2 +8,11,3 +6,2,10 +8,8,16 +7,17,6 +1,8,11 +13,6,4 +10,3,14 +17,9,13 +16,5,9 +14,11,16 +3,5,14 +17,11,13 +2,9,12 +1,10,10 +16,7,11 +7,5,5 +9,13,5 +11,4,6 +2,7,13 +12,17,7 +7,3,7 +16,5,11 +9,12,1 +3,12,5 +16,5,6 +13,3,12 +7,14,4 +8,2,13 +12,16,14 +15,4,7 +15,15,11 +9,6,4 +3,9,15 +8,2,10 +15,4,10 +9,17,7 +4,4,9 +7,12,4 +11,16,13 +2,12,7 +11,10,2 +8,4,6 +11,2,11 +6,4,14 +9,16,4 +11,1,9 +11,9,1 +15,14,11 +4,6,4 +15,5,8 +16,14,7 +15,12,14 +15,4,11 +15,10,3 +13,12,17 +8,15,4 +6,5,14 +8,4,15 +1,8,8 +13,8,2 +10,16,15 +14,12,16 +15,16,9 +11,15,12 +16,8,7 +14,14,12 +5,8,2 +10,7,16 +5,17,10 +2,6,10 +8,14,17 +13,11,14 +6,10,16 +17,8,8 +6,9,3 +12,13,16 +13,3,10 +8,3,6 +6,7,17 +3,7,6 +12,2,9 +14,5,14 +13,6,16 +7,3,11 +2,12,9 +6,8,17 +14,15,12 +16,10,4 +17,5,12 +11,8,16 +3,13,9 +7,1,6 +9,7,18 +4,7,15 +5,15,4 +16,5,8 +12,16,5 +3,3,8 +13,17,9 +7,17,13 +16,8,5 +4,14,12 +14,4,6 +9,15,13 +10,3,13 +5,15,10 +16,14,9 +7,11,2 +7,12,6 +5,17,12 +3,15,9 +5,2,7 +3,8,13 +8,8,1 +3,14,7 +8,16,5 +3,7,9 +7,5,16 +12,14,3 +14,12,4 +4,2,9 +7,4,13 +17,6,7 +8,8,17 +13,16,6 +12,12,17 +5,8,15 +10,1,8 +9,10,2 +5,15,8 +12,2,7 +14,16,11 +4,6,13 +18,10,11 +15,12,5 +13,14,14 +5,3,8 +4,7,12 +13,18,10 +3,8,11 +7,12,16 +4,13,4 +5,3,7 +12,5,14 +10,2,12 +12,9,3 +10,13,3 +15,8,15 +4,8,15 +13,2,9 +14,17,7 +18,10,12 +12,5,5 +15,3,7 +8,3,14 +10,15,4 +11,7,4 +1,10,13 +6,6,4 +5,10,3 +18,11,11 +4,6,3 +7,5,15 +8,3,13 +8,10,3 +7,4,5 +8,17,10 +11,5,12 +4,5,16 +6,9,4 +15,7,3 +18,11,10 +9,6,17 +16,11,14 +7,8,17 +14,6,15 +13,12,16 +6,5,5 +6,9,15 +13,13,16 +16,13,7 +14,2,6 +16,5,7 +11,10,1 +18,8,11 +2,8,11 +17,14,11 +3,10,12 +13,7,17 +10,7,18 +5,10,17 +17,9,14 +5,7,16 +12,4,14 +9,13,16 +17,9,11 +1,9,13 +2,6,7 +13,15,16 +15,5,14 +12,16,8 +15,10,16 +7,7,16 +11,15,16 +16,10,12 +6,3,13 +2,12,11 +12,16,6 +11,5,4 +10,12,17 +17,6,15 +2,6,12 +12,7,5 +8,3,10 +12,5,16 +6,17,13 +14,4,4 +9,18,8 +5,16,13 +2,11,6 +6,16,7 +8,4,14 +11,12,2 +6,4,5 +14,8,4 +6,1,10 +12,4,16 +9,4,3 +18,8,10 +16,15,10 +5,9,16 +17,10,9 +17,7,9 +7,7,4 +3,10,5 +6,13,15 +11,16,10 +6,6,15 +9,14,17 +4,8,6 +4,4,12 +9,3,3 +7,16,12 +10,14,16 +4,15,6 +16,4,7 +8,6,2 +8,6,17 +16,13,13 +15,15,7 +18,8,8 +12,13,4 +14,13,4 +5,12,4 +15,12,15 +4,4,15 +5,8,17 +17,11,14 +13,16,13 +5,7,7 +8,13,16 +8,5,14 +16,15,8 +6,1,9 +11,18,7 +11,5,2 +9,4,4 +9,13,2 +7,17,7 +6,7,2 +17,10,6 +14,8,2 +7,16,6 +17,9,10 +16,14,6 +7,16,10 +7,3,10 +16,11,13 +6,13,16 +3,8,4 +12,15,5 +17,6,12 +18,9,11 +14,13,5 +15,8,16 +13,14,15 +17,8,13 +5,14,3 +8,13,17 +14,15,9 +8,14,16 +11,12,18 +15,5,10 +10,14,15 +14,7,15 +13,6,3 +3,14,9 +15,17,11 +1,12,9 +11,15,14 +6,16,6 +12,9,14 +11,18,10 +10,13,4 +13,17,11 +5,13,6 +10,1,7 +15,12,6 +12,12,15 +4,6,6 +3,5,13 +11,17,10 +5,14,8 +5,3,10 +13,13,17 +5,13,5 +15,5,12 +5,6,4 +12,15,14 +16,12,12 +12,17,10 +10,13,17 +8,13,1 +15,10,9 +17,13,9 +10,11,16 +8,12,17 +1,13,8 +13,8,3 +5,10,5 +14,5,15 +7,16,8 +7,9,15 +11,17,14 +12,17,11 +7,17,8 +13,10,17 +4,11,15 +3,11,8 +5,5,15 +11,9,18 +3,13,5 +11,14,4 +10,16,12 +7,3,4 +4,7,16 +8,15,16 +2,6,9 +2,13,7 +13,14,3 +6,9,18 +9,7,16 +13,15,13 +7,2,13 +5,11,4 +6,15,14 +18,11,8 +5,6,16 +12,17,5 +9,8,18 +7,4,11 +13,3,7 +7,11,18 +12,3,5 +15,12,4 +6,7,4 +14,13,12 +15,5,15 +9,17,10 +3,15,10 +17,10,11 +9,3,10 +9,13,15 +5,9,4 +16,9,7 +4,11,4 +5,15,16 +17,7,12 +12,6,3 +15,11,4 +13,6,5 +9,3,7 +8,8,18 +13,7,16 +13,16,12 +15,14,7 +6,6,2 +15,9,16 +5,4,6 +2,8,7 +13,17,12 +5,13,4 +11,15,15 +11,2,7 +16,11,9 +6,7,5 +9,9,17 +8,10,1 +9,14,3 +11,5,5 +14,9,5 +5,6,3 +10,2,11 +7,11,15 +16,14,10 +8,1,11 +16,6,13 +12,3,10 +12,4,10 +4,3,10 +9,11,2 +3,13,6 +5,16,7 +11,11,15 +7,17,10 +16,14,11 +16,14,12 +2,5,8 +3,6,10 +10,8,18 +7,4,6 +6,12,3 +15,15,6 +7,3,12 +9,1,9 +5,11,2 +15,5,6 +11,1,12 +17,9,8 +10,18,10 +2,7,11 +6,9,17 +6,12,4 +16,8,11 +15,5,13 +3,10,8 +16,11,12 +8,3,7 +7,2,10 +4,11,5 +16,13,6 +2,11,12 +4,15,9 +7,16,5 +3,11,12 +14,16,9 +2,10,13 +5,12,5 +16,6,11 +5,7,3 +13,11,3 +5,3,11 +14,14,7 +6,5,16 +5,11,17 +11,3,3 +9,10,18 +14,11,15 +12,5,15 +7,4,15 +16,10,10 +8,2,9 +14,6,17 +10,3,3 +5,14,11 +11,12,16 +14,5,9 +10,9,1 +10,3,10 +2,9,10 +7,3,6 +12,6,15 +9,18,9 +3,8,15 +3,4,11 +13,17,13 +5,5,14 +6,11,16 +5,4,9 +7,13,17 +14,6,3 +1,11,6 +5,11,14 +14,15,7 +3,11,14 +7,11,1 +16,8,12 +2,9,14 +13,5,2 +8,2,12 +4,4,11 +13,12,6 +8,6,15 +13,8,1 +17,12,6 +13,5,12 +16,9,8 +6,12,16 +13,7,1 +7,17,12 +5,13,7 +14,7,5 +10,2,7 +11,14,5 +11,16,11 +2,11,7 +9,18,7 +13,15,14 +8,2,14 +15,12,16 +10,7,2 +5,15,6 +7,13,3 +4,5,5 +18,11,9 +7,9,3 +0,10,10 +10,10,17 +16,10,11 +7,9,2 +3,7,8 +9,16,13 +11,13,3 +13,10,3 +9,5,17 +14,8,17 +11,1,8 +16,9,9 +15,6,13 +11,11,2 +10,16,11 +1,11,9 +0,11,9 +15,6,10 +1,5,10 +8,18,11 +7,15,15 +5,17,9 +5,5,4 +10,14,17 +9,6,14 +2,14,9 +6,16,10 +17,14,10 +10,2,5 +6,8,4 +9,18,12 +4,13,12 +4,5,6 +16,6,14 +3,9,11 +16,4,10 +13,5,14 +9,16,8 +14,4,14 +13,14,5 +5,5,6 +7,19,10 +7,6,16 +6,16,9 +8,13,2 +4,12,3 +17,7,8 +4,9,13 +3,5,6 +10,14,3 +4,14,9 +5,4,11 +5,2,9 +10,17,5 +5,10,15 +2,7,8 +3,5,5 +6,17,12 +9,16,11 +16,8,15 +3,5,11 +2,10,9 +9,9,2 +6,6,16 +13,14,12 +10,8,3 +11,6,16 +5,8,3 +3,6,8 +16,8,14 +11,3,4 +11,1,10 +6,12,2 +8,1,6 +5,6,15 +6,14,5 +17,15,10 +7,16,13 +11,2,5 +11,17,5 +15,13,7 +15,15,10 +5,11,16 +12,3,12 +2,12,8 +9,1,6 +11,5,14 +17,8,5 +7,14,15 +17,13,12 +9,15,14 +16,11,6 +8,11,2 +4,16,10 +14,17,9 +4,14,8 +9,18,11 +9,16,14 +10,15,12 +15,13,13 +17,9,7 +13,14,13 +1,12,11 +13,13,15 +13,15,8 +9,16,5 +11,12,17 +16,2,10 +17,12,12 +14,16,12 +10,17,12 +2,14,7 +7,10,2 +4,4,10 +6,16,4 +12,3,8 +6,7,3 +14,3,12 +13,2,10 +13,8,18 +4,5,7 +12,17,14 +14,11,14 +13,18,9 +9,11,1 +6,14,8 +11,8,2 +4,10,16 +16,13,11 +13,8,4 +10,6,17 +14,5,8 +6,8,16 +14,3,5 +14,16,7 +16,11,7 +13,4,11 +2,6,11 +2,10,7 +14,10,6 +10,11,2 +4,12,4 +16,13,8 +15,7,15 +4,9,3 +1,9,9 +16,5,10 +15,11,14 +14,13,14 +7,18,11 +7,3,15 +12,6,4 +16,7,15 +18,13,11 +9,4,15 +2,5,11 +9,2,9 +10,16,14 +11,2,8 +15,8,13 +3,10,6 +17,9,12 +3,10,9 +16,11,15 +11,5,17 +17,8,9 +5,4,10 +16,12,15 +12,2,11 +8,14,13 +14,4,12 +13,4,14 +15,8,6 +7,10,17 +17,12,8 +12,15,6 +3,7,7 +15,9,14 +3,5,10 +6,5,4 +10,8,2 +10,15,15 +7,1,7 +2,7,9 +18,7,9 +12,6,17 +6,16,12 +9,17,11 +6,6,3 +8,1,10 +6,16,5 +4,2,10 +3,10,4 +1,11,11 +5,11,10 +14,13,3 +8,7,2 +2,5,12 +3,11,10 +4,12,13 +4,6,11 +5,3,12 +12,16,11 +2,9,6 +7,2,12 +8,15,3 +3,12,12 +4,15,12 +6,7,16 +4,2,8 +15,7,16 +3,8,8 +13,17,6 +17,9,9 +3,12,14 +9,5,3 +8,8,3 +3,6,9 +11,7,17 +13,11,2 +7,12,3 +13,5,5 +15,10,5 +13,9,2 +9,6,15 +15,14,10 +8,18,6 +5,6,14 +9,14,14 +3,11,11 +9,11,3 +7,7,2 +16,9,10 +12,13,17 +11,3,10 +12,10,3 +16,5,14 +7,9,17 +4,10,13 +8,6,1 +12,15,15 +4,12,12 +3,12,7 +11,10,15 +8,5,18 +7,4,3 +16,12,10 +16,7,8 +12,1,9 +1,11,10 +16,8,9 +6,10,15 +16,12,5 +8,12,16 +14,13,7 +9,4,6 +17,9,6 +14,15,11 +13,11,16 +6,15,7 +2,7,12 +16,15,11 +11,2,13 +12,17,13 +4,13,11 +7,11,3 +9,4,5 +15,16,8 +2,14,11 +4,14,5 +14,6,4 +11,17,9 +5,6,12 +3,11,15 +4,3,9 +12,4,5 +4,12,16 +5,5,5 +8,13,15 +13,3,5 +6,10,3 +18,7,12 +15,8,4 +4,5,13 +5,8,16 +13,14,6 +17,5,9 +5,10,16 +12,18,8 +8,2,11 +13,2,7 +6,2,9 +11,4,15 +4,12,6 +13,5,3 +6,2,12 +11,4,4 +15,10,15 +3,7,5 +15,4,9 +3,11,7 +5,15,7 +5,14,5 +12,17,6 +16,6,10 +12,4,12 +14,11,5 +9,10,17 +13,16,11 +8,7,16 +10,17,4 +2,11,9 +18,9,7 +7,16,15 +2,10,14 +18,8,7 +17,11,9 +5,14,6 +8,3,11 +4,7,14 +2,9,11 +13,15,4 +8,17,6 +7,10,3 +9,9,15 +6,14,17 +2,5,10 +12,13,3 +3,15,7 +16,8,8 +8,3,5 +4,4,13 +12,15,13 +18,12,10 +9,3,14 +4,15,13 +13,15,5 +14,12,6 +16,11,11 +15,6,9 +7,6,17 +17,11,12 +6,18,8 +13,3,13 +13,2,6 +15,14,12 +12,15,3 +2,12,5 +3,4,9 +5,13,15 +14,15,5 +9,7,1 +2,9,7 +10,17,8 +4,7,4 +14,14,4 +11,15,6 +6,9,2 +12,12,3 +14,7,4 +10,6,1 +15,13,14 +11,3,13 +5,4,12 +15,6,4 +9,1,11 +15,17,8 +5,14,10 +11,14,16 +16,8,13 +16,10,13 +9,3,5 +14,12,14 +12,8,2 +3,7,13 +15,4,8 +2,14,5 +10,7,15 +6,12,13 +7,8,3 +10,15,5 +5,15,12 +8,14,5 +1,8,10 +8,16,7 +9,2,4 +15,5,7 +5,15,11 +14,4,13 +10,18,13 +13,12,5 +5,12,12 +4,5,14 +17,8,14 +12,11,2 +14,3,10 +13,7,5 +6,14,13 +3,10,15 +16,7,5 +10,15,14 +6,3,6 +12,17,12 +13,2,11 +15,4,5 +2,7,7 +12,16,12 +9,8,17 +17,11,10 +4,10,14 +12,12,2 +4,6,7 +14,5,12 +3,6,13 +14,8,14 +2,7,10 +16,9,11 +11,1,11 +9,4,16 +8,16,8 +10,2,6 +11,13,17 +6,14,14 +15,14,9 +4,12,10 +8,7,15 +3,6,6 +4,3,8 +13,5,10 +7,7,3 +4,16,9 +5,7,6 +5,12,14 +14,16,6 +16,11,5 +9,4,9 +1,7,13 +9,3,16 +11,3,11 +15,14,14 +4,14,11 +3,13,13 +18,9,9 +9,0,9 +2,6,8 +12,12,1 +17,12,14 +16,14,15 +3,12,4 +12,4,11 +14,15,6 +7,6,2 +10,14,4 +8,12,2 +12,8,17 +5,12,6 +9,3,8 +16,7,6 +6,11,15 +13,9,16 +11,4,16 +16,11,8 +12,15,8 +1,7,11 +5,9,5 +11,2,6 +8,18,9 +8,3,15 +10,17,11 +18,11,12 +14,4,8 +13,14,11 +13,5,7 +11,14,14 +4,15,8 +12,13,6 +12,12,18 +15,6,14 +5,5,13 +15,16,11 +9,7,17 +4,10,15 +14,15,14 +6,15,6 +9,15,3 +12,7,2 +11,16,14 +5,7,15 +17,8,12 +4,5,11 +13,6,7 +5,2,10 +14,3,8 +4,6,5 +17,11,11 +3,14,10 +6,3,9 +14,7,3 +10,5,2 +13,5,16 +15,16,13 +17,6,11 +8,17,15 +13,6,14 +18,7,10 +4,14,14 +13,14,4 +8,17,14 +17,12,9 +10,15,6 +16,9,15 +16,13,5 +11,17,11 +15,5,16 +4,15,10 +9,3,15 +4,8,14 +5,14,9 +11,8,18 +15,10,14 +12,14,14 +4,8,10 +11,7,2 +5,4,7 +15,15,12 +7,8,15 +10,6,16 +7,16,9 +14,4,9 +6,16,8 +8,12,3 +13,3,14 +4,7,3 +13,11,18 +17,10,7 +2,14,10 +5,9,15 +11,4,13 +2,9,9 +10,8,1 +12,15,12 +4,13,14 +8,9,0 +11,18,8 +11,17,12 +3,6,11 +4,13,15 +17,12,10 +11,2,9 +15,3,8 +7,5,14 +2,12,10 +11,7,18 +12,13,15 +12,7,1 +3,13,15 +16,9,13 +3,3,9 +10,7,0 +4,12,5 +17,10,10 +13,13,14 +10,11,18 +7,3,9 +15,15,13 +3,11,4 +15,7,13 +9,4,14 +1,9,7 +15,9,17 +8,11,16 +2,10,6 +4,11,3 +13,15,7 +10,1,11 +10,17,6 +5,13,3 +1,11,7 +11,13,16 +16,10,15 +8,2,6 +10,10,3 +11,2,4 +5,14,12 +7,15,13 +9,3,6 +7,15,4 +7,8,4 +10,13,16 +13,3,8 +1,10,9 +15,10,4 +13,6,2 +14,6,11 +7,13,16 +2,11,13 +3,6,12 +17,10,12 +3,9,13 +5,4,14 +10,4,3 +10,3,5 +9,16,7 +2,12,6 +17,6,9 +9,14,16 +11,13,4 +9,10,16 +7,2,11 +8,2,8 +3,14,5 +14,9,14 +1,6,10 +15,10,2 +14,12,5 +6,14,4 +3,7,11 +5,7,4 +8,17,5 +10,5,5 +14,14,11 +14,5,4 +6,4,7 +14,15,8 +12,5,6 +19,8,11 +11,14,2 +9,2,5 +7,1,9 +15,7,12 +8,9,1 +14,4,11 +8,14,15 +18,12,8 +11,16,5 +13,12,15 +16,12,13 +6,15,10 +15,4,14 +7,6,4 +7,2,14 +5,15,9 +8,19,10 +10,6,2 +16,15,9 +8,5,1 +5,4,15 +16,3,8 +4,4,5 +9,13,17 +5,14,7 +14,10,2 +5,15,5 +11,2,10 +3,12,9 +7,9,1 +12,16,3 +8,15,14 +6,5,15 +15,10,8 +17,7,11 +9,16,9 +15,13,15 +8,9,2 +5,12,8 +14,13,16 +6,15,4 +15,7,5 +11,12,3 +16,4,11 +11,9,2 +3,9,9 +1,11,12 +7,11,17 +11,3,12 +8,5,17 +14,5,7 +5,2,14 +13,10,16 +7,2,8 +17,8,11 +12,12,16 +12,1,13 +8,5,2 +16,5,12 +11,9,16 +2,13,8 +13,12,1 +8,16,4 +17,6,6 +15,7,6 +8,16,15 +18,7,8 +13,6,15 +7,2,6 +5,14,15 +8,14,3 +14,12,3 +11,9,19 +4,17,11 +16,14,5 +13,12,4 +18,10,7 +9,10,1 +10,1,9 +3,9,16 +9,12,17 +6,5,3 +11,17,8 +14,7,16 +10,15,3 +3,12,8 +14,12,17 +7,16,14 +3,15,11 +12,16,13 +9,11,0 +5,7,13 +1,8,13 +11,15,13 +16,12,14 +16,12,11 +9,18,10 +16,13,9 +12,6,2 +8,16,12 +15,11,3 +7,9,18 +6,8,5 +13,16,5 +9,8,2 +2,8,4 +4,14,10 +17,12,7 +17,7,7 +17,13,10 +6,13,10 +14,10,5 +16,3,12 +6,7,15 +10,4,13 +17,6,8 +9,11,19 +16,7,10 +9,6,2 +7,14,14 +11,18,9 +15,7,14 +3,16,9 +12,16,10 +6,16,14 +14,6,10 +14,3,9 +4,5,4 +13,5,13 +12,7,15 +12,3,4 +15,8,3 +7,8,18 +14,2,12 +14,14,8 +4,14,7 +8,7,1 +2,4,10 +8,4,7 +15,7,17 +11,16,8 +14,9,17 +18,12,9 +8,15,15 +10,2,14 +11,4,14 +11,16,15 +4,12,7 +12,4,15 +9,7,3 +10,4,14 +14,5,16 +14,7,17 +5,16,11 +15,3,13 +10,5,17 +8,3,12 +5,11,15 +2,7,5 +3,8,6 +8,17,7 +13,3,9 +8,4,16 +9,2,8 +7,10,16 +11,6,4 +6,15,13 +14,8,7 +6,2,11 +15,14,15 +14,14,6 +7,8,1 +2,8,9 +13,4,6 +14,9,12 +14,6,16 +13,3,6 +4,13,5 +14,2,8 +15,15,9 +8,11,18 +7,15,5 +10,11,3 +17,14,8 +8,18,7 +7,13,2 +13,10,1 +2,14,8 +10,11,0 +6,3,12 +3,11,9 +2,6,6 +16,9,16 +11,18,14 +7,15,16 +10,16,4 +8,17,11 +13,13,5 +10,10,18 +10,16,5 +10,14,5 +12,3,3 +1,9,8 +3,5,9 +7,4,4 +13,3,11 +9,2,10 +8,4,11 +13,9,4 +6,4,4 +1,10,6 +12,10,2 +7,16,11 +7,17,5 +2,11,4 +4,11,6 +8,2,5 +13,3,15 +6,2,7 +6,17,11 +10,5,3 +6,15,9 +11,3,9 +13,14,16 +13,4,9 +17,10,13 +12,2,10 +6,17,10 +7,1,8 +4,7,6 +10,3,6 +14,10,16 +2,12,12 +4,8,5 +8,2,7 +9,4,10 +14,11,17 +6,4,12 +15,10,7 +16,6,7 +2,11,10 +11,6,3 +4,11,8 +11,17,6 +11,16,9 +4,5,12 +2,7,4 +3,14,13 +3,13,10 +13,4,13 +6,9,16 +11,7,3 +13,2,13 +9,13,4 +16,10,3 +12,8,16 +8,16,6 +16,6,12 +1,10,7 +16,10,7 +6,9,1 +11,13,15 +6,13,2 +15,9,15 +5,4,3 +16,15,12 +6,15,11 +10,2,13 +5,6,5 +17,13,6 +8,5,3 +2,7,6 +12,2,13 +12,9,18 +5,17,8 +7,9,16 +13,1,8 +5,3,6 +6,3,11 +11,1,7 +12,4,4 +14,7,2 +17,7,14 +8,1,13 +18,7,7 +10,18,8 +17,12,11 +4,10,8 +18,8,12 +1,9,10 +9,8,3 +12,11,17 +4,11,13 +7,18,8 +3,12,13 +15,13,11 +2,12,15 +3,4,6 +1,10,8 +16,6,5 +15,13,16 +14,5,6 +15,13,4 +9,19,8 +6,18,13 +4,9,15 +7,16,7 +12,8,18 +10,16,6 +12,5,13 +14,5,5 +8,5,4 +9,4,2 +17,12,13 +9,12,4 +12,7,4 +11,17,13 +13,4,15 +3,4,8 +14,7,11 +4,10,2 +13,12,13 +15,3,12 +13,10,14 +4,7,5 +5,9,2 +13,9,6 +6,2,6 +9,6,1 +3,3,10 +18,9,8 +4,15,14 +13,11,4 +14,16,14 +8,1,5 +14,13,13 +4,9,2 +9,16,10 +14,12,15 +9,14,15 +6,4,15 +12,5,7 +3,9,6 +15,14,5 +7,1,11 +15,11,5 +11,3,8 +10,9,17 +9,12,2 +5,8,5 +6,17,7 +12,7,3 +10,12,16 +2,11,14 +1,7,10 +4,8,9 +16,16,12 +2,9,5 +13,8,17 +2,8,12 +4,3,13 +16,8,4 +5,16,6 +15,5,9 +7,14,17 +13,13,4 +5,14,4 +12,3,9 +12,11,1 +11,3,14 +6,12,6 +16,9,12 +11,8,6 +9,9,3 +18,6,12 +10,5,4 +9,14,10 +13,4,8 +13,8,16 +4,13,8 +7,17,14 +10,6,18 +16,3,9 +4,11,10 +6,5,2 +14,15,15 +4,3,12 +3,16,10 +8,7,3 +3,13,12 +6,13,5 +9,17,5 +9,16,16 +11,8,17 +2,8,5 +9,6,18 +9,5,5 +16,12,8 +12,15,16 +4,14,13 +7,11,16 +15,14,13 +14,8,5 +12,11,3 +8,8,4 +14,13,8 +13,8,13 +14,14,5 +10,15,13 +14,5,13 +12,10,4 +10,12,3 +8,13,14 +0,8,9 +2,13,11 +1,12,6 +15,13,8 +9,16,15 +3,7,4 +12,10,18 +4,11,14 +10,9,2 +4,12,15 +15,12,10 +14,7,14 +3,10,7 +17,14,5 +2,11,5 +15,3,9 +4,15,5 +12,11,18 +5,1,10 +6,12,14 +4,16,8 +11,15,2 +1,9,12 +3,10,16 +10,10,16 +8,16,14 +17,7,13 +11,14,17 +5,5,3 +16,7,9 +3,14,14 +15,13,12 +13,4,12 +10,9,3 +4,9,16 +15,13,6 +7,3,5 +15,11,7 +7,4,16 +8,4,8 +4,5,3 +12,16,15 +2,12,13 +18,9,12 +11,11,3 +14,2,10 +8,14,2 +9,9,19 +16,10,6 +2,8,14 +5,6,13 +7,5,6 +14,5,10 +13,10,15 +7,7,18 +17,11,8 +12,15,9 +8,10,2 +8,18,8 +15,8,12 +7,15,11 +12,11,4 +7,13,5 +17,11,4 +2,5,9 +9,8,1 +6,15,16 +5,7,5 +12,6,5 +9,17,14 +11,11,18 +9,15,4 +10,17,9 +8,16,10 +17,11,5 +13,8,15 +18,11,13 +3,13,14 +11,11,1 +13,16,7 +15,16,12 +5,5,9 +3,12,15 +3,14,11 +2,7,14 +11,4,5 +6,6,7 +12,1,10 +3,9,4 +13,17,10 +4,17,12 +5,6,2 +13,4,10 +7,15,3 +15,11,12 +4,13,16 +9,12,15 +6,2,14 +3,7,12 +15,9,5 +13,5,6 +10,17,14 +6,15,8 +10,1,13 +17,12,4 +6,3,8 +6,5,7 +14,14,13 +17,15,11 +12,10,16 +18,8,6 +12,10,15 +17,13,14 +11,5,13 +10,3,7 +15,15,8 +12,9,1 +6,11,2 +4,14,6 +10,15,17 +7,18,6 +12,8,5 +6,11,11 +13,16,10 +6,10,18 +16,6,4 +11,6,1 +16,15,7 +6,5,13 +7,5,17 +6,17,9 +8,15,13 +12,1,11 +12,14,17 +9,2,14 +1,6,8 +9,8,16 +13,7,14 +4,14,4 +12,11,15 +1,12,7 +3,9,12 +14,7,6 +10,2,9 +10,16,8 +6,11,4 +18,9,13 +4,8,16 +4,9,17 +14,11,4 +15,16,7 +18,10,10 +18,10,13 +17,5,11 +10,13,18 +4,9,14 +5,4,4 +9,4,17 +1,10,12 +3,15,13 diff --git a/day18/solution.nim b/day18/solution.nim new file mode 100644 index 0000000..0ef81fb --- /dev/null +++ b/day18/solution.nim @@ -0,0 +1,83 @@ +import strutils +import sequtils +import sugar +import sets + +type Cube = tuple + x, y, z: int + +proc parseLine(line: string): Cube = + let tokens = map(line.split(","), (e) => e.parseInt()) + (tokens[0], tokens[1], tokens[2]) + +proc parseFile(content: string): seq[Cube] = + let lines = content.strip().splitLines() + result = map(lines, parseLine) + +proc nextTo(A, B: Cube): bool = + let + dx = abs(A.x - B.x) + dy = abs(A.y - B.y) + dz = abs(A.z - B.z) + + dx + dy + dz <= 1 and dx <= 1 and dy <= 1 and dz <= 1 + +proc part1(cubes: seq[Cube]): int = + result = 6 * cubes.len() + for i, cube in cubes[0 .. ^2]: + for other in cubes[i+1 .. ^1]: + if cube.nextTo(other): + result -= 2 + +var + solid: HashSet[Cube] + visited: HashSet[Cube] + maxn = 0 + minn = -1 + +proc blocksAround(cube: Cube): int = + for x in [cube.x-1, cube.x+1]: + if (x, cube.y, cube.z) in solid: + result += 1 + + for y in [cube.y-1, cube.y+1]: + if (cube.x, y, cube.z) in solid: + result += 1 + + for z in [cube.z-1, cube.z+1]: + if (cube.x, cube.y, z) in solid: + result += 1 + +proc dfs(curr: Cube): int = + let maxp = max([curr.x, curr.y, curr.z]) + let minp = min([curr.x, curr.y, curr.z]) + if minp < minn or maxp >= maxn or visited.containsOrIncl(curr): + return 0 + + # if is air block + if curr notin solid: + result = blocksAround(curr) + + dfs((curr.x+1, curr.y, curr.z)) + + dfs((curr.x-1, curr.y, curr.z)) + + dfs((curr.x, curr.y+1, curr.z)) + + dfs((curr.x, curr.y-1, curr.z)) + + dfs((curr.x, curr.y, curr.z+1)) + + dfs((curr.x, curr.y, curr.z-1)) + + +proc part2(cubes: seq[Cube]): int = + # echo cubes + for cube in cubes: + maxn = max([cube.x, cube.y, cube.z]) + maxn += 6 + + for cube in cubes: + solid.incl(cube) + + result = dfs((0,0,0)) + +let content = readFile("./input.txt") +let input = parseFile(content) + +echo part1(input) +echo part2(input) -- cgit v1.2.3