import { Coll, Collection, Collection2D } from "util/collection";
// If blank strings/ints is not enough
export const inputMapper = (inputs: string) => inputs;
function buildStacks(input: Collection<string>): Collection2D<string> {
const stacks: Collection2D<string> = Coll();
for (let i = 0; i < input[0].length / 4; i++) {
stacks.push(Coll());
}
const lines = input.slice(0, input.length - 1).map((line) =>
Coll(...line.split("")).partition(4).map((chars) => chars[1])
);
for (const line of lines) {
for (let i = 0; i < line.length; i++) {
if (line[i] !== " ") {
stacks[i].push(line[i]);
}
}
}
for (const stack of stacks) {
stack.reverse();
}
return stacks;
}
interface Move {
amount: number;
from: number;
to: number;
}
function mapExpressions(input: Collection<string>): Collection<Move> {
return input.map((line) => line.split(" ")).map((strs) => ({
amount: parseInt(strs[1]),
from: parseInt(strs[3]),
to: parseInt(strs[5]),
}));
}
export function solution1(inputs: Collection<string>): string {
const [instructions, setup] = inputs.splitOnValue("");
const stacks = buildStacks(setup);
const expressions = mapExpressions(instructions);
for (const { amount, from, to } of expressions) {
const fromStack = stacks[from - 1];
const toStack = stacks[to - 1];
for (let i = 0; i < amount; i++) {
toStack.push(fromStack.pop() as string);
}
}
return stacks.map((s) => s.last).join("");
}
export function solution2(inputs: Collection<string>): string {
const [instructions, setup] = inputs.splitOnValue("");
const stacks = buildStacks(setup);
const expressions = mapExpressions(instructions);
for (const { amount, from, to } of expressions) {
const fromStack = stacks[from - 1];
const toStack = stacks[to - 1];
toStack.push(...fromStack.splice(fromStack.length - amount, amount));
}
return stacks.map((s) => s.last).join("");
}