This commit is contained in:
Yanick Champoux 2022-12-07 18:42:05 -05:00
parent 999e63ec22
commit 09f79cb253
10 changed files with 213 additions and 21 deletions

View File

@ -1,14 +1,17 @@
import * as R from "remeda"; import * as R from "remeda";
import { test, expect } from "vitest"; import { test, expect } from "vitest";
import fs from "fs-extra"; import fs from "fs-extra";
import path from 'path'; import path from "path";
import { expectSolution } from './main.js'; import { expectSolution } from "./main.js";
const split = (splitter) => (text) => text.split(splitter); const split = (splitter) => (text) => text.split(splitter);
const sum = R.sumBy(R.identity); const sum = R.sumBy(R.identity);
const input = R.pipe( const input = R.pipe(
fs.readFileSync( path.join( path.dirname(import.meta.url), "input").replace('file:',''), "utf8"), fs.readFileSync(
path.join(path.dirname(import.meta.url), "input").replace("file:", ""),
"utf8"
),
split("\n\n"), split("\n\n"),
R.map((x) => R.map((x) =>
split("\n")(x) split("\n")(x)
@ -18,7 +21,6 @@ const input = R.pipe(
R.map(sum) R.map(sum)
); );
test("part 1", () => { test("part 1", () => {
const maxCalories = R.pipe(input, (calories) => Math.max(...calories)); const maxCalories = R.pipe(input, (calories) => Math.max(...calories));

56
2022/05/Part1.pm Normal file
View File

@ -0,0 +1,56 @@
package Part1;
use 5.36.0;
our @ISA = 'Exporter';
our @EXPORT_OK = qw/ part1 $sample /;
use Path::Tiny;
our $sample = path('./sample')->slurp;
sub parse_heaps($heaps) {
my( $header, @crates ) = reverse split "\n", $heaps;
my @stacks;
while( $header !~ /^\s*$/ ) {
$header =~ s/^(\s+)\d//;
my $n = length $1;
@crates = map { no warnings; substr $_, $n } @crates;
my @stack = grep { /\w/ } map { no warnings; s/(.)//; $1 } @crates;
push @stacks, \@stack;
}
return @stacks;
}
sub parse_commands($text) {
return map { [/\d+/g] } split "\n", $text
}
sub move_stacks($stacks, $commands) {
for my $command ( @$commands ) {
for( 1..$command->[0] ) {
push $stacks->[$command->[2] - 1]->@*,
pop $stacks->[$command->[1]- 1]->@*;
}
}
return @$stacks;
}
sub part1($text) {
my( $heaps, $commands ) = split "\n\n", $text;
my @heaps = parse_heaps($heaps);
my @commands = parse_commands($commands);
my @stacks = move_stacks( \@heaps, \@commands );
return join '', map { pop @$_ } @stacks;
}
1;

View File

@ -1,9 +1,14 @@
import * as R from "remeda"; import * as R from "remeda";
import { readFile } from "../03/part1.js"; import fs from "fs-extra";
import path from "path";
import { fileURLToPath } from "url";
export const sample = readFile("2022", "05", "sample"); export const readFile = (url, file) =>
export const puzzleInput = readFile("2022", "05", "input"); fs.readFileSync(path.join(fileURLToPath(new URL(".", url)), file), "utf8");
export const sample = readFile(import.meta.url, "sample");
export const puzzleInput = readFile(import.meta.url, "input");
function parseHeaps(text) { function parseHeaps(text) {
const lines = text.split("\n").filter(R.identity); const lines = text.split("\n").filter(R.identity);
@ -54,16 +59,20 @@ function moveStacks([stacks, commands]) {
return stacks; return stacks;
} }
const spy = (x) => { export const spy = (x) => {
console.log(x); console.log(x);
return x; return x;
}; };
export const parseLines = ([heaps, commands]) => [
parseHeaps(heaps),
parseCommands(commands),
];
export const solutionPart1 = R.createPipe( export const solutionPart1 = R.createPipe(
(text) => text.split("\n\n"), (text) => text.split("\n\n"),
([heaps, commands]) => [parseHeaps(heaps), parseCommands(commands)], parseLines,
moveStacks, moveStacks,
spy,
R.map((x) => x.pop()), R.map((x) => x.pop()),
(x) => x.join("") (x) => x.join("")
); );

91
2022/05/part1.js.orig Normal file
View File

@ -0,0 +1,91 @@
import * as R from "remeda";
import fs from "fs-extra";
import path from "path";
import { fileURLToPath } from "url";
export const readFile = (url, file) =>
fs.readFileSync(path.join(fileURLToPath(new URL(".", url)), file), "utf8");
export const sample = readFile(import.meta.url, "sample");
export const puzzleInput = readFile(import.meta.url, "input");
function parseHeaps(text) {
const lines = text.split("\n").filter(R.identity);
lines.reverse();
let [header, ...crates] = lines;
const stacks = [];
while (header.trimEnd()) {
header = header.replace(/^(\s+)\d/, (...args) => {
crates = crates.map((c) => c.slice(args[1].length));
const stack = [];
crates = crates.map((l) =>
l.replace(/./, (c) => {
if (c !== " ") stack.push(c);
return "";
})
);
stacks.push(stack);
return "";
});
}
return stacks;
}
function parseCommands(text) {
return text
.split("\n")
.filter(R.identity)
.map((line) => line.match(/\d+/g).map((x) => parseInt(x)));
}
function moveStacks([stacks, commands]) {
for (let [move, from, to] of commands) {
console.log({ move, from, to });
while (move-- > 0) {
stacks[to - 1].push(stacks[from - 1].pop());
}
}
return stacks;
}
<<<<<<< HEAD
const spy = (x) => {
console.log(x);
return x;
};
export const solutionPart1 = R.createPipe(
(text) => text.split("\n\n"),
([heaps, commands]) => [parseHeaps(heaps), parseCommands(commands)],
moveStacks,
spy,
=======
export const spy = (x) => {
console.log(x);
return x;
};
export const parseLines = ([heaps, commands]) => [
parseHeaps(heaps),
parseCommands(commands),
];
export const solutionPart1 = R.createPipe(
(text) => text.split("\n\n"),
parseLines,
moveStacks,
>>>>>>> 2a1e7da (part 1)
R.map((x) => x.pop()),
(x) => x.join("")
);

View File

@ -1 +1,24 @@
import * as R from "remeda"; import * as R from "remeda";
import { parseLines, spy } from "./part1.js";
function moveStacks([stacks, commands]) {
for (let [move, from, to] of commands) {
console.log({ move, from, to });
stacks[to - 1].push(
...stacks[from - 1].splice(stacks[from - 1].length - move)
);
}
return stacks;
}
export default R.createPipe(
(text) => text.split("\n\n"),
parseLines,
moveStacks,
spy,
R.map((x) => x.pop()),
(x) => x.join("")
);

View File

@ -2,19 +2,19 @@ import { test, expect, describe } from "vitest";
import { expectSolution } from "../01/main.js"; import { expectSolution } from "../01/main.js";
import { solutionPart1, puzzleInput, sample } from "./part1.js"; import { solutionPart1, puzzleInput, sample } from "./part1.js";
import { solutionPart2 } from "./part2.js"; import part2 from "./part2.js";
describe("part 1", () => { describe("part 1", () => {
test("sample", () => { test("sample", () => {
expect(solutionPart1(sample)).toEqual("CMZ"); expect(solutionPart1(sample)).toEqual("CMZ");
}); });
test.only("solution", () => { test("solution", () => {
expectSolution(solutionPart1(puzzleInput)).toEqual("VPCDMSLWJ"); expectSolution(solutionPart1(puzzleInput)).toEqual("VPCDMSLWJ");
}); });
}); });
describe("part 2", () => { describe("part 2", () => {
test.todo("solution", () => { test("solution", () => {
expectSolution(solutionPart2(puzzleInput)).toEqual("TODO"); expectSolution(part2(puzzleInput)).toEqual("TPWCGNCCG");
}); });
}); });

8
2022/05/test.t Normal file
View File

@ -0,0 +1,8 @@
use 5.36.0;
use Test2::V0;
use Part1 qw/ part1 $sample /;
is part1($sample) => 'CMZ';

View File

@ -1,2 +1 @@
import * as R from "remeda"; import * as R from "remeda";

View File

@ -1,20 +1,17 @@
import { test, expect, describe } from "vitest"; import { test, expect, describe } from "vitest";
import { expectSolution } from "../01/main.js"; import { expectSolution } from "../01/main.js";
import { import { solutionPart1, puzzleInput } from "./part1.js";
solutionPart1,
puzzleInput,
} from "./part1.js";
import { solutionPart2 } from "./part2.js"; import { solutionPart2 } from "./part2.js";
describe("part 1", () => { describe("part 1", () => {
test.todo("solution", () => { test.todo("solution", () => {
expectSolution(solutionPart1(puzzleInput)).toEqual('TODO'); expectSolution(solutionPart1(puzzleInput)).toEqual("TODO");
}); });
}); });
describe("part 2", () => { describe("part 2", () => {
test.todo("solution", () => { test.todo("solution", () => {
expectSolution(solutionPart2(puzzleInput)).toEqual('TODO'); expectSolution(solutionPart2(puzzleInput)).toEqual("TODO");
}); });
}); });

View File

@ -3,6 +3,9 @@
version: "3" version: "3"
vars: vars:
YEAR: 2022
DAY:
sh: date '+%d' | perl -pe's/^0//'
GREETING: Hello, World! GREETING: Hello, World!
tasks: tasks:
@ -18,6 +21,10 @@ tasks:
cmds: cmds:
- npx prettier --write {{.CLI_ARGS | default "." }} - npx prettier --write {{.CLI_ARGS | default "." }}
page:
cmds:
- firefox https://adventofcode.com/{{.YEAR}}/day/{{.DAY}}
default: default:
cmds: cmds:
- echo "{{.GREETING}}" - echo "{{.GREETING}}"