Merge branch '2022-06'
This commit is contained in:
commit
c8bfe85ccf
4
.gitignore
vendored
4
.gitignore
vendored
@ -2,3 +2,7 @@ node_modules
|
|||||||
.pls_cache/
|
.pls_cache/
|
||||||
.perl-version
|
.perl-version
|
||||||
pnpm-lock.yaml
|
pnpm-lock.yaml
|
||||||
|
*_BACKUP_*
|
||||||
|
*_BASE_*
|
||||||
|
*_LOCAL_*
|
||||||
|
*_REMOTE_*
|
||||||
|
@ -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
56
2022/05/Part1.pm
Normal 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;
|
@ -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
91
2022/05/part1.js.orig
Normal 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("")
|
||||||
|
);
|
@ -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("")
|
||||||
|
);
|
||||||
|
@ -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");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
7
2022/05/test.t
Normal file
7
2022/05/test.t
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
use 5.36.0;
|
||||||
|
|
||||||
|
use Test2::V0;
|
||||||
|
|
||||||
|
use Part1 qw/ part1 $sample /;
|
||||||
|
|
||||||
|
is part1($sample) => 'CMZ';
|
22
2022/06/part1.js
Normal file
22
2022/06/part1.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import * as R from "remeda";
|
||||||
|
import { readFile } from "../05/part1.js";
|
||||||
|
|
||||||
|
export const puzzleInput = readFile(import.meta.url, "input");
|
||||||
|
|
||||||
|
export default function (code) {
|
||||||
|
const size = 4;
|
||||||
|
let index = size;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
if (
|
||||||
|
R.pipe(
|
||||||
|
code,
|
||||||
|
(c) => c.substr(index - size, size).split(""),
|
||||||
|
R.uniq,
|
||||||
|
(c) => c.length
|
||||||
|
) === size
|
||||||
|
)
|
||||||
|
return index;
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
19
2022/06/part2.js
Normal file
19
2022/06/part2.js
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import * as R from "remeda";
|
||||||
|
|
||||||
|
export default function (code) {
|
||||||
|
const size = 14;
|
||||||
|
let index = size;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
if (
|
||||||
|
R.pipe(
|
||||||
|
code,
|
||||||
|
(c) => c.substr(index - size, size).split(""),
|
||||||
|
R.uniq,
|
||||||
|
(c) => c.length
|
||||||
|
) === size
|
||||||
|
)
|
||||||
|
return index;
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
37
2022/06/test.js
Normal file
37
2022/06/test.js
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import { test, expect, describe } from "vitest";
|
||||||
|
|
||||||
|
import { expectSolution } from "../01/main.js";
|
||||||
|
import part1, { puzzleInput } from "./part1.js";
|
||||||
|
import part2 from "./part2.js";
|
||||||
|
|
||||||
|
describe("part 1", () => {
|
||||||
|
test("samples", () => {
|
||||||
|
expect(part1("mjqjpqmgbljsphdztnvjfqwrcgsmlb")).toEqual(7);
|
||||||
|
|
||||||
|
Object.entries({
|
||||||
|
bvwbjplbgvbhsrlpgdmjqwftvncz: 5,
|
||||||
|
nppdvjthqldpwncqszvftbrmjlhg: 6,
|
||||||
|
nznrnfrfntjfmvfwmzdfjlvtqnbhcprsg: 10,
|
||||||
|
zcfzfwzzqfrljwzlrfnpqdbhtmscgvjw: 11,
|
||||||
|
}).forEach(([code, index]) => expect(part1(code)).toEqual(index));
|
||||||
|
});
|
||||||
|
test("solution", () => {
|
||||||
|
expectSolution(part1(puzzleInput)).toEqual(1640);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("part 2", () => {
|
||||||
|
test("samples", () => {
|
||||||
|
expect(part2("mjqjpqmgbljsphdztnvjfqwrcgsmlb")).toEqual(19);
|
||||||
|
|
||||||
|
Object.entries({
|
||||||
|
bvwbjplbgvbhsrlpgdmjqwftvncz: 23,
|
||||||
|
nppdvjthqldpwncqszvftbrmjlhg: 23,
|
||||||
|
nznrnfrfntjfmvfwmzdfjlvtqnbhcprsg: 29,
|
||||||
|
zcfzfwzzqfrljwzlrfnpqdbhtmscgvjw: 26,
|
||||||
|
}).forEach(([code, index]) => expect(part2(code)).toEqual(index));
|
||||||
|
});
|
||||||
|
test("solution", () => {
|
||||||
|
expectSolution(part2(puzzleInput)).toEqual(3613);
|
||||||
|
});
|
||||||
|
});
|
@ -1,2 +1 @@
|
|||||||
import * as R from "remeda";
|
import * as R from "remeda";
|
||||||
|
|
||||||
|
@ -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");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -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}}"
|
||||||
|
Loading…
Reference in New Issue
Block a user