diff options
| author | Orfeas <38209077+0xfea5@users.noreply.github.com> | 2024-06-08 13:50:47 +0300 |
|---|---|---|
| committer | Orfeas <38209077+0xfea5@users.noreply.github.com> | 2024-06-08 13:50:47 +0300 |
| commit | 7be570c4a6e86fb7060f0bc06910ca57003dfe90 (patch) | |
| tree | a998f976596cb902cd8988d74f756b72660bc29c /day05/solution.nim | |
| parent | Day 21 (part1) (diff) | |
| download | aoc22-7be570c4a6e86fb7060f0bc06910ca57003dfe90.tar.gz aoc22-7be570c4a6e86fb7060f0bc06910ca57003dfe90.zip | |
Diffstat (limited to 'day05/solution.nim')
| -rw-r--r-- | day05/solution.nim | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/day05/solution.nim b/day05/solution.nim new file mode 100644 index 0000000..2bf41aa --- /dev/null +++ b/day05/solution.nim | |||
| @@ -0,0 +1,87 @@ | |||
| 1 | import std/strutils | ||
| 2 | import std/sequtils | ||
| 3 | import std/enumerate | ||
| 4 | import std/algorithm | ||
| 5 | import std/re | ||
| 6 | |||
| 7 | type | ||
| 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 | |||
| 19 | proc 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 | |||
| 57 | proc 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 | |||
| 68 | proc 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 | |||
| 75 | let content = readFile("./input.txt") | ||
| 76 | var input = parseContent(content) | ||
| 77 | |||
| 78 | let moves = input.Moves | ||
| 79 | var stacksPart1 = input.Stacks | ||
| 80 | var stacksPart2 = input.Stacks | ||
| 81 | |||
| 82 | for move in moves: | ||
| 83 | makeMove(stacksPart1, move) | ||
| 84 | makeMove(stacksPart2, move, true) | ||
| 85 | |||
| 86 | echo getAnswer(stacksPart1) | ||
| 87 | echo getAnswer(stacksPart2) | ||
