76 lines
2.1 KiB
Nim
76 lines
2.1 KiB
Nim
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()
|