From 661ae7a8b4e0601aae8bfbf1708b894b4ade2b4d Mon Sep 17 00:00:00 2001 From: Orfeas Chatzipanagiotis Date: Fri, 9 Dec 2022 04:40:44 +0200 Subject: Day 5 --- day5/solution.nim | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 day5/solution.nim (limited to 'day5/solution.nim') 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 @@ +import std/strutils +import std/sequtils +import std/enumerate +import std/algorithm +import std/re + +type + Move = tuple + Amount: int + From: int + To: int + + Stack = seq[char] + + Input = tuple + Stacks: seq[Stack] + Moves: seq[Move] + +proc parseContent(content: string): Input = + # Parse stacks + let tokens = content.split("\n\n") + var strStacks = map( + # All lines containing characters of the stacks + # Exclude last line since it contain's each stack's id + tokens[0].splitLines()[0 .. ^2], + proc(line: string): string = + var retval = "" + # keep only the relevant characters (spaces/letters) + for i in countup(1, line.len(), 4): + retval.add(line[i]) + retval + ) + + var Stacks = newSeq[Stack](10) + + for layer in strStacks: + for i, c in enumerate(layer): + if c != ' ': + Stacks[i+1].add(c) + + var strMoves = map( + # All moves described in the input + tokens[1].strip().splitLines(), + proc(line: string): seq[int] = + # Remove words and split on spaces + let tokens = line.replace(re"[a-z]+ ").split(" ") + # Parse them as integers + map(tokens, proc (num: string): int = num.parseInt()) + ) + + var Moves: seq[Move] + for move in strMoves: + Moves.add((move[0], move[1], move[2])) + + return (Stacks, Moves) + +proc makeMove(stacks: var seq[Stack], move: Move, inPlace = false): void = + # copy top of the stack + var yoink = stacks[move.From][0 ..< move.Amount] + # moving in place preserves the order of the moved crates (part2) + if not inPlace: + yoink.reverse() + # remove it from origin + stacks[move.From].delete(0 ..< move.Amount) + # concat it in front of destination + stacks[move.To] = concat(yoink, stacks[move.To]) + +proc getAnswer(stacks: seq[Stack]): string = + var answer = "" + for stack in stacks: + if stack.len() > 0: + answer.add(stack[0]) + answer + +let content = readFile("./input.txt") +var input = parseContent(content) + +let moves = input.Moves +var stacksPart1 = input.Stacks +var stacksPart2 = input.Stacks + +for move in moves: + makeMove(stacksPart1, move) + makeMove(stacksPart2, move, true) + +echo getAnswer(stacksPart1) +echo getAnswer(stacksPart2) -- cgit v1.2.3