import std/[strutils, sequtils, strformat, sugar] let input = readFile("day_05/input.txt") type Stacks = seq[seq[char]] proc readStacks(data: string): Stacks = let lines = data.splitLines() let count = lines[lines.len - 1].split(" ").len var stacks = newSeqWith[char](count, newSeq[char]()) for line in 0..lines.len-2: for stack in 0..count-1: let crate = lines[line][stack*4..stack*4+2] if not crate.isEmptyOrWhitespace: stacks[stack].insert(lines[line][stack*4+1..stack*4+1]) return stacks #region debug-only proc echoStacks(stacks: Stacks) = var height = stacks.mapIt(it.len).max() while height > 0: height -= 1 var line = "" for i in 0..stacks.len-1: if height < stacks[i].len: # let item = stacks[i][height] line.add fmt"[{stacks[i][height]}] " else: line.add fmt" " echo line var line = "" for i in 0..stacks.len-1: line.add fmt" {i+1} " echo line #endregion debug-only proc moveCrate(stacks: var Stacks, operation: string, preserveOrder: bool = false) = let tokens = operation.split(" ") assert tokens[0] == "move" let amount = tokens[1].parseInt assert tokens[2] == "from" let fromStack = tokens[3].parseInt - 1 assert tokens[4] == "to" let toStack = tokens[5].parseInt - 1 if preserveOrder: var moving = (0..amount-1).toSeq.mapIt(stacks[fromStack].pop) for crate in 0..amount-1: stacks[toStack].add(moving.pop) return for i in 0..amount-1: stacks[toStack].add(stacks[fromStack].pop) proc solvePart1() = let inputData = input.split("\n\n") var stacks = readStacks(inputData[0]) for operation in inputData[1].splitLines: stacks.moveCrate(operation) stacks.echoStacks echo stacks.mapIt(it[it.len - 1]).foldl(a & b, "") proc solvePart2() = let inputData = input.split("\n\n") var stacks = readStacks(inputData[0]) for operation in inputData[1].splitLines: stacks.moveCrate(operation, true) stacks.echoStacks echo stacks.mapIt(it[it.len - 1]).foldl(a & b, "") if isMainModule: solvePart1() solvePart2()