aboutsummaryrefslogtreecommitdiffstats
path: root/day5/solution.nim
diff options
context:
space:
mode:
Diffstat (limited to 'day5/solution.nim')
-rw-r--r--day5/solution.nim87
1 files changed, 87 insertions, 0 deletions
diff --git a/day5/solution.nim b/day5/solution.nim
new file mode 100644
index 0000000..2bf41aa
--- /dev/null
+++ b/day5/solution.nim
@@ -0,0 +1,87 @@
1import std/strutils
2import std/sequtils
3import std/enumerate
4import std/algorithm
5import std/re
6
7type
8 Move = tuple
9 Amount: int
10 From: int
11 To: int
12
13 Stack = seq[char]
14
15 Input = tuple
16 Stacks: seq[Stack]
17 Moves: seq[Move]
18
19proc parseContent(content: string): Input =
20 # Parse stacks
21 let tokens = content.split("\n\n")
22 var strStacks = map(
23 # All lines containing characters of the stacks
24 # Exclude last line since it contain's each stack's id
25 tokens[0].splitLines()[0 .. ^2],
26 proc(line: string): string =
27 var retval = ""
28 # keep only the relevant characters (spaces/letters)
29 for i in countup(1, line.len(), 4):
30 retval.add(line[i])
31 retval
32 )
33
34 var Stacks = newSeq[Stack](10)
35
36 for layer in strStacks:
37 for i, c in enumerate(layer):
38 if c != ' ':
39 Stacks[i+1].add(c)
40
41 var strMoves = map(
42 # All moves described in the input
43 tokens[1].strip().splitLines(),
44 proc(line: string): seq[int] =
45 # Remove words and split on spaces
46 let tokens = line.replace(re"[a-z]+ ").split(" ")
47 # Parse them as integers
48 map(tokens, proc (num: string): int = num.parseInt())
49 )
50
51 var Moves: seq[Move]
52 for move in strMoves:
53 Moves.add((move[0], move[1], move[2]))
54
55 return (Stacks, Moves)
56
57proc makeMove(stacks: var seq[Stack], move: Move, inPlace = false): void =
58 # copy top of the stack
59 var yoink = stacks[move.From][0 ..< move.Amount]
60 # moving in place preserves the order of the moved crates (part2)
61 if not inPlace:
62 yoink.reverse()
63 # remove it from origin
64 stacks[move.From].delete(0 ..< move.Amount)
65 # concat it in front of destination
66 stacks[move.To] = concat(yoink, stacks[move.To])
67
68proc getAnswer(stacks: seq[Stack]): string =
69 var answer = ""
70 for stack in stacks:
71 if stack.len() > 0:
72 answer.add(stack[0])
73 answer
74
75let content = readFile("./input.txt")
76var input = parseContent(content)
77
78let moves = input.Moves
79var stacksPart1 = input.Stacks
80var stacksPart2 = input.Stacks
81
82for move in moves:
83 makeMove(stacksPart1, move)
84 makeMove(stacksPart2, move, true)
85
86echo getAnswer(stacksPart1)
87echo getAnswer(stacksPart2)