Add 2022 solutions
This commit is contained in:
@@ -6,7 +6,6 @@ if [ ! -e cookies.txt ]; then
|
||||
fi
|
||||
|
||||
list=$(find -name "Day*.cpp" | awk -F '/' '{print $3 "/" $4}' | awk -F '.' '{print $1}' | sed 's/Day//g' | sort)
|
||||
echo $list
|
||||
|
||||
for item in $list; do
|
||||
echo $item
|
||||
@@ -23,5 +22,4 @@ for item in $list; do
|
||||
touch "res/$year/day$day/test_input.txt"
|
||||
curl -s --cookie cookies.txt https://adventofcode.com/$year/day/$webitem/input >$dir
|
||||
fi
|
||||
exit
|
||||
done
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
1000
|
||||
2000
|
||||
3000
|
||||
|
||||
4000
|
||||
|
||||
5000
|
||||
6000
|
||||
|
||||
7000
|
||||
8000
|
||||
9000
|
||||
|
||||
10000
|
||||
@@ -0,0 +1,3 @@
|
||||
A Y
|
||||
B X
|
||||
C Z
|
||||
@@ -0,0 +1,6 @@
|
||||
vJrwpWtwJgWrhcsFMMfFFhFp
|
||||
jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL
|
||||
PmmdzqPrVvPwwTWBwg
|
||||
wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn
|
||||
ttgJtRGJQctTZtZT
|
||||
CrZsJsPPZsGzwwsLwLmpwMDw
|
||||
@@ -0,0 +1,6 @@
|
||||
2-4,6-8
|
||||
2-3,4-5
|
||||
5-7,7-9
|
||||
2-8,3-7
|
||||
6-6,4-6
|
||||
2-6,4-8
|
||||
@@ -0,0 +1,9 @@
|
||||
[D]
|
||||
[N] [C]
|
||||
[Z] [M] [P]
|
||||
1 2 3
|
||||
|
||||
move 1 from 2 to 1
|
||||
move 3 from 1 to 3
|
||||
move 2 from 2 to 1
|
||||
move 1 from 1 to 2
|
||||
@@ -0,0 +1 @@
|
||||
mjqjpqmgbljsphdztnvjfqwrcgsmlb
|
||||
@@ -0,0 +1,23 @@
|
||||
$ cd /
|
||||
$ ls
|
||||
dir a
|
||||
14848514 b.txt
|
||||
8504156 c.dat
|
||||
dir d
|
||||
$ cd a
|
||||
$ ls
|
||||
dir e
|
||||
29116 f
|
||||
2557 g
|
||||
62596 h.lst
|
||||
$ cd e
|
||||
$ ls
|
||||
584 i
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd d
|
||||
$ ls
|
||||
4060174 j
|
||||
8033020 d.log
|
||||
5626152 d.ext
|
||||
7214296 k
|
||||
@@ -0,0 +1,5 @@
|
||||
30373
|
||||
25512
|
||||
65332
|
||||
33549
|
||||
35390
|
||||
@@ -0,0 +1,8 @@
|
||||
R 5
|
||||
U 8
|
||||
L 8
|
||||
D 3
|
||||
R 17
|
||||
D 10
|
||||
L 25
|
||||
U 20
|
||||
@@ -0,0 +1,146 @@
|
||||
addx 15
|
||||
addx -11
|
||||
addx 6
|
||||
addx -3
|
||||
addx 5
|
||||
addx -1
|
||||
addx -8
|
||||
addx 13
|
||||
addx 4
|
||||
noop
|
||||
addx -1
|
||||
addx 5
|
||||
addx -1
|
||||
addx 5
|
||||
addx -1
|
||||
addx 5
|
||||
addx -1
|
||||
addx 5
|
||||
addx -1
|
||||
addx -35
|
||||
addx 1
|
||||
addx 24
|
||||
addx -19
|
||||
addx 1
|
||||
addx 16
|
||||
addx -11
|
||||
noop
|
||||
noop
|
||||
addx 21
|
||||
addx -15
|
||||
noop
|
||||
noop
|
||||
addx -3
|
||||
addx 9
|
||||
addx 1
|
||||
addx -3
|
||||
addx 8
|
||||
addx 1
|
||||
addx 5
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx -36
|
||||
noop
|
||||
addx 1
|
||||
addx 7
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx 2
|
||||
addx 6
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx 1
|
||||
noop
|
||||
noop
|
||||
addx 7
|
||||
addx 1
|
||||
noop
|
||||
addx -13
|
||||
addx 13
|
||||
addx 7
|
||||
noop
|
||||
addx 1
|
||||
addx -33
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx 2
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx 8
|
||||
noop
|
||||
addx -1
|
||||
addx 2
|
||||
addx 1
|
||||
noop
|
||||
addx 17
|
||||
addx -9
|
||||
addx 1
|
||||
addx 1
|
||||
addx -3
|
||||
addx 11
|
||||
noop
|
||||
noop
|
||||
addx 1
|
||||
noop
|
||||
addx 1
|
||||
noop
|
||||
noop
|
||||
addx -13
|
||||
addx -19
|
||||
addx 1
|
||||
addx 3
|
||||
addx 26
|
||||
addx -30
|
||||
addx 12
|
||||
addx -1
|
||||
addx 3
|
||||
addx 1
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx -9
|
||||
addx 18
|
||||
addx 1
|
||||
addx 2
|
||||
noop
|
||||
noop
|
||||
addx 9
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx -1
|
||||
addx 2
|
||||
addx -37
|
||||
addx 1
|
||||
addx 3
|
||||
noop
|
||||
addx 15
|
||||
addx -21
|
||||
addx 22
|
||||
addx -6
|
||||
addx 1
|
||||
noop
|
||||
addx 2
|
||||
addx 1
|
||||
noop
|
||||
addx -10
|
||||
noop
|
||||
noop
|
||||
addx 20
|
||||
addx 1
|
||||
addx 2
|
||||
addx 2
|
||||
addx -6
|
||||
addx -11
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
@@ -0,0 +1,27 @@
|
||||
Monkey 0:
|
||||
Starting items: 79, 98
|
||||
Operation: new = old * 19
|
||||
Test: divisible by 23
|
||||
If true: throw to monkey 2
|
||||
If false: throw to monkey 3
|
||||
|
||||
Monkey 1:
|
||||
Starting items: 54, 65, 75, 74
|
||||
Operation: new = old + 6
|
||||
Test: divisible by 19
|
||||
If true: throw to monkey 2
|
||||
If false: throw to monkey 0
|
||||
|
||||
Monkey 2:
|
||||
Starting items: 79, 60, 97
|
||||
Operation: new = old * old
|
||||
Test: divisible by 13
|
||||
If true: throw to monkey 1
|
||||
If false: throw to monkey 3
|
||||
|
||||
Monkey 3:
|
||||
Starting items: 74
|
||||
Operation: new = old + 3
|
||||
Test: divisible by 17
|
||||
If true: throw to monkey 0
|
||||
If false: throw to monkey 1
|
||||
@@ -0,0 +1,5 @@
|
||||
Sabqponm
|
||||
abcryxxl
|
||||
accszExk
|
||||
acctuvwj
|
||||
abdefghi
|
||||
@@ -0,0 +1,24 @@
|
||||
[1,1,3,1,1]
|
||||
[1,1,5,1,1]
|
||||
|
||||
[[1],[2,3,4]]
|
||||
[[1],4]
|
||||
|
||||
[9]
|
||||
[[8,7,6]]
|
||||
|
||||
[[4,4],4,4]
|
||||
[[4,4],4,4,4]
|
||||
|
||||
[7,7,7,7]
|
||||
[7,7,7]
|
||||
|
||||
[]
|
||||
[3]
|
||||
|
||||
[[[]]]
|
||||
[[]]
|
||||
|
||||
|
||||
[1,[2,[3,[4,[5,6,7]]]],8,9]
|
||||
[1,[2,[3,[4,[5,6,0]]]],8,9]
|
||||
@@ -0,0 +1,2 @@
|
||||
498,4 -> 498,6 -> 496,6
|
||||
503,4 -> 502,4 -> 502,9 -> 494,9
|
||||
@@ -0,0 +1,14 @@
|
||||
Sensor at x=2, y=18: closest beacon is at x=-2, y=15
|
||||
Sensor at x=9, y=16: closest beacon is at x=10, y=16
|
||||
Sensor at x=13, y=2: closest beacon is at x=15, y=3
|
||||
Sensor at x=12, y=14: closest beacon is at x=10, y=16
|
||||
Sensor at x=10, y=20: closest beacon is at x=10, y=16
|
||||
Sensor at x=14, y=17: closest beacon is at x=10, y=16
|
||||
Sensor at x=8, y=7: closest beacon is at x=2, y=10
|
||||
Sensor at x=2, y=0: closest beacon is at x=2, y=10
|
||||
Sensor at x=0, y=11: closest beacon is at x=2, y=10
|
||||
Sensor at x=20, y=14: closest beacon is at x=25, y=17
|
||||
Sensor at x=17, y=20: closest beacon is at x=21, y=22
|
||||
Sensor at x=16, y=7: closest beacon is at x=15, y=3
|
||||
Sensor at x=14, y=3: closest beacon is at x=15, y=3
|
||||
Sensor at x=20, y=1: closest beacon is at x=15, y=3
|
||||
@@ -0,0 +1,10 @@
|
||||
Valve AA has flow rate=0; tunnels lead to valves DD, II, BB
|
||||
Valve BB has flow rate=13; tunnels lead to valves CC, AA
|
||||
Valve CC has flow rate=2; tunnels lead to valves DD, BB
|
||||
Valve DD has flow rate=20; tunnels lead to valves CC, AA, EE
|
||||
Valve EE has flow rate=3; tunnels lead to valves FF, DD
|
||||
Valve FF has flow rate=0; tunnels lead to valves EE, GG
|
||||
Valve GG has flow rate=0; tunnels lead to valves FF, HH
|
||||
Valve HH has flow rate=22; tunnel leads to valve GG
|
||||
Valve II has flow rate=0; tunnels lead to valves AA, JJ
|
||||
Valve JJ has flow rate=21; tunnel leads to valve II
|
||||
@@ -0,0 +1 @@
|
||||
>>><<><>><<<>><>>><<<>>><<<><<<>><>><<>>
|
||||
@@ -0,0 +1,13 @@
|
||||
2,2,2
|
||||
1,2,2
|
||||
3,2,2
|
||||
2,1,2
|
||||
2,3,2
|
||||
2,2,1
|
||||
2,2,3
|
||||
2,2,4
|
||||
2,2,6
|
||||
1,2,5
|
||||
3,2,5
|
||||
2,1,5
|
||||
2,3,5
|
||||
@@ -0,0 +1,2 @@
|
||||
Blueprint 1: Each ore robot costs 4 ore. Each clay robot costs 2 ore. Each obsidian robot costs 3 ore and 14 clay. Each geode robot costs 2 ore and 7 obsidian.
|
||||
Blueprint 2: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 8 clay. Each geode robot costs 3 ore and 12 obsidian.
|
||||
@@ -0,0 +1,7 @@
|
||||
1
|
||||
2
|
||||
-3
|
||||
3
|
||||
-2
|
||||
0
|
||||
4
|
||||
@@ -0,0 +1,15 @@
|
||||
root: pppw + sjmn
|
||||
dbpl: 5
|
||||
cczh: sllz + lgvd
|
||||
zczc: 2
|
||||
ptdq: humn - dvpt
|
||||
dvpt: 3
|
||||
lfqf: 4
|
||||
humn: 5
|
||||
ljgn: 2
|
||||
sjmn: drzm * dbpl
|
||||
sllz: 4
|
||||
pppw: cczh / lfqf
|
||||
lgvd: ljgn * ptdq
|
||||
drzm: hmdt - zczc
|
||||
hmdt: 32
|
||||
@@ -0,0 +1,14 @@
|
||||
...#
|
||||
.#..
|
||||
#...
|
||||
....
|
||||
...#.......#
|
||||
........#...
|
||||
..#....#....
|
||||
..........#.
|
||||
...#....
|
||||
.....#..
|
||||
.#......
|
||||
......#.
|
||||
|
||||
10R5L5R10L4R5L5
|
||||
@@ -0,0 +1,7 @@
|
||||
....#..
|
||||
..###.#
|
||||
#...#.#
|
||||
.#...##
|
||||
#.###..
|
||||
##.#.##
|
||||
.#..#..
|
||||
@@ -0,0 +1,6 @@
|
||||
#.######
|
||||
#>>.<^<#
|
||||
#.<..<<#
|
||||
#>v.><>#
|
||||
#<^v^^>#
|
||||
######.#
|
||||
@@ -0,0 +1,13 @@
|
||||
1=-0-2
|
||||
12111
|
||||
2=0=
|
||||
21
|
||||
2=01
|
||||
111
|
||||
20012
|
||||
112
|
||||
1=-1=
|
||||
1-12
|
||||
12
|
||||
1=
|
||||
122
|
||||
@@ -0,0 +1,51 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace y$1::day01
|
||||
{
|
||||
REGISTER_DAY(2022, Day01, std::set<int>, int);
|
||||
|
||||
REGISTER_TEST_EXAMPLE(2022, Day01, ExampleInput, 1, 24000);
|
||||
REGISTER_TEST(2022, Day01, Input, 1, 68292);
|
||||
REGISTER_TEST_EXAMPLE(2022, Day01, ExampleInput, 2, 45000);
|
||||
REGISTER_TEST(2022, Day01, Input, 2, 203203);
|
||||
|
||||
READ_INPUT(input)
|
||||
{
|
||||
std::string str;
|
||||
std::set<int> elfs;
|
||||
int sum = 0;
|
||||
while (std::getline(input, str))
|
||||
{
|
||||
if (str.empty())
|
||||
{
|
||||
elfs.emplace(sum);
|
||||
sum = 0;
|
||||
continue;
|
||||
}
|
||||
sum += std::stoll(str);
|
||||
}
|
||||
if (sum != 0)
|
||||
elfs.emplace(sum);
|
||||
return elfs;
|
||||
}
|
||||
|
||||
OUTPUT1(input)
|
||||
{
|
||||
return Helper::Max(input);
|
||||
}
|
||||
|
||||
OUTPUT2(input)
|
||||
{
|
||||
int sum = 0;
|
||||
int i = 0;
|
||||
for (auto it = input.rbegin(); it != input.rend(); it++)
|
||||
{
|
||||
sum += *it;
|
||||
i++;
|
||||
if (i == 3)
|
||||
break;
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace y$1::day02
|
||||
{
|
||||
REGISTER_DAY(2022, Day02, std::vector<std::string>, int);
|
||||
|
||||
REGISTER_TEST_EXAMPLE(2022, Day02, ExampleInput, 1, 15);
|
||||
REGISTER_TEST(2022, Day02, Input, 1, 13221);
|
||||
REGISTER_TEST_EXAMPLE(2022, Day02, ExampleInput, 2, 12);
|
||||
REGISTER_TEST(2022, Day02, Input, 2, 13131);
|
||||
|
||||
READ_INPUT(input)
|
||||
{
|
||||
std::string str;
|
||||
std::vector<std::string> hands;
|
||||
while (std::getline(input, str))
|
||||
{
|
||||
hands.emplace_back(str);
|
||||
}
|
||||
return hands;
|
||||
}
|
||||
|
||||
OUTPUT1(input)
|
||||
{
|
||||
int sum = 0;
|
||||
for (auto hand : input)
|
||||
{
|
||||
int handPoints = hand[2] - 'X' + 1;
|
||||
int outcomePoints = (((hand[2] - 'X') - (hand[0] - 'A') + 4) % 3) * 3;
|
||||
sum += handPoints + outcomePoints;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
OUTPUT2(input)
|
||||
{
|
||||
int sum = 0;
|
||||
for (auto& hand : input)
|
||||
{
|
||||
int handPoints = ((hand[2] - 'A') + (hand[0] - 'X' - 1) + 3) % 3 + 1;
|
||||
int outcomePoints = (hand[2] - 'X') * 3;
|
||||
sum += handPoints + outcomePoints;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace y$1::day03
|
||||
{
|
||||
REGISTER_DAY(2022, Day03, std::vector<std::string>, int);
|
||||
|
||||
REGISTER_TEST_EXAMPLE(2022, Day03, ExampleInput, 1, 157);
|
||||
REGISTER_TEST(2022, Day03, Input, 1, 7811);
|
||||
REGISTER_TEST_EXAMPLE(2022, Day03, ExampleInput, 2, 70);
|
||||
REGISTER_TEST(2022, Day03, Input, 2, 2639);
|
||||
|
||||
READ_INPUT(input)
|
||||
{
|
||||
std::string str;
|
||||
std::vector<std::string> backpacks;
|
||||
while (std::getline(input, str))
|
||||
{
|
||||
backpacks.emplace_back(str);
|
||||
}
|
||||
return backpacks;
|
||||
}
|
||||
|
||||
OUTPUT1(input)
|
||||
{
|
||||
int sum = 0;
|
||||
for (auto& backpack : input)
|
||||
{
|
||||
std::set<char> s1;
|
||||
std::set<char> s2;
|
||||
for (int i = 0; i < backpack.size(); i++)
|
||||
{
|
||||
if (i < backpack.size() / 2)
|
||||
{
|
||||
s1.emplace(backpack[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
s2.emplace(backpack[i]);
|
||||
}
|
||||
}
|
||||
std::set<char> intersection = Helper::GetIntersection(s1, s2);
|
||||
for (auto c : intersection)
|
||||
{
|
||||
if (c >= 'A' && c <= 'Z')
|
||||
sum += c - 'A' + 27;
|
||||
else
|
||||
sum += c - 'a' + 1;
|
||||
}
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
OUTPUT2(input)
|
||||
{
|
||||
int sum = 0;
|
||||
for (int i = 0; i < input.size() - 2; i += 3)
|
||||
{
|
||||
std::set<char> s1;
|
||||
std::set<char> s2;
|
||||
std::set<char> s3;
|
||||
for (int j = 0; j < input[i].size(); j++)
|
||||
{
|
||||
s1.emplace(input[i][j]);
|
||||
}
|
||||
for (int j = 0; j < input[i + 1].size(); j++)
|
||||
{
|
||||
s2.emplace(input[i + 1][j]);
|
||||
}
|
||||
for (int j = 0; j < input[i + 2].size(); j++)
|
||||
{
|
||||
s3.emplace(input[i + 2][j]);
|
||||
}
|
||||
std::set<char> intersection = Helper::GetIntersection(std::vector<std::set<char>>{s1, s2, s3});
|
||||
for (auto c : intersection)
|
||||
{
|
||||
if (c >= 'A' && c <= 'Z')
|
||||
sum += c - 'A' + 27;
|
||||
else
|
||||
sum += c - 'a' + 1;
|
||||
}
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace y$1::day04
|
||||
{
|
||||
struct Range
|
||||
{
|
||||
int left = 0;
|
||||
int right = 0;
|
||||
};
|
||||
|
||||
struct Pair
|
||||
{
|
||||
Range r1;
|
||||
Range r2;
|
||||
};
|
||||
|
||||
REGISTER_DAY(2022, Day04, std::vector<Pair>, int);
|
||||
|
||||
REGISTER_TEST_EXAMPLE(2022, Day04, ExampleInput, 1, 2);
|
||||
REGISTER_TEST(2022, Day04, Input, 1, 477);
|
||||
REGISTER_TEST_EXAMPLE(2022, Day04, ExampleInput, 2, 4);
|
||||
REGISTER_TEST(2022, Day04, Input, 2, 830);
|
||||
|
||||
READ_INPUT(input)
|
||||
{
|
||||
std::string str;
|
||||
std::vector<Pair> pairs;
|
||||
while (std::getline(input, str))
|
||||
{
|
||||
std::stringstream ss{str};
|
||||
Pair pair;
|
||||
ss >> pair.r1.left >> "-" >> pair.r1.right >> ",";
|
||||
ss >> pair.r2.left >> "-" >> pair.r2.right;
|
||||
pairs.emplace_back(pair);
|
||||
}
|
||||
return pairs;
|
||||
}
|
||||
|
||||
OUTPUT1(input)
|
||||
{
|
||||
int sum = 0;
|
||||
for (auto& pair : input)
|
||||
{
|
||||
if ((pair.r1.left >= pair.r2.left && pair.r1.right <= pair.r2.right) ||
|
||||
(pair.r2.left >= pair.r1.left && pair.r2.right <= pair.r1.right))
|
||||
{
|
||||
sum++;
|
||||
}
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
OUTPUT2(input)
|
||||
{
|
||||
int sum = 0;
|
||||
for (auto& pair : input)
|
||||
{
|
||||
if (pair.r1.left <= pair.r2.right && pair.r1.right >= pair.r2.left)
|
||||
{
|
||||
sum++;
|
||||
}
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace y$1::day05
|
||||
{
|
||||
struct Move
|
||||
{
|
||||
int from;
|
||||
int count;
|
||||
int to;
|
||||
};
|
||||
|
||||
struct Instructions
|
||||
{
|
||||
std::vector<std::deque<char>> stacks;
|
||||
std::vector<Move> moves;
|
||||
};
|
||||
|
||||
REGISTER_DAY(2022, Day05, Instructions, std::string);
|
||||
|
||||
REGISTER_TEST_EXAMPLE(2022, Day05, ExampleInput, 1, "CMZ");
|
||||
REGISTER_TEST(2022, Day05, Input, 1, "JCMHLVGMG");
|
||||
REGISTER_TEST_EXAMPLE(2022, Day05, ExampleInput, 2, "MCD");
|
||||
REGISTER_TEST(2022, Day05, Input, 2, "LVMRWSSPZ");
|
||||
|
||||
READ_INPUT(input)
|
||||
{
|
||||
std::string str;
|
||||
Instructions instructions;
|
||||
while (std::getline(input, str))
|
||||
{
|
||||
if (Helper::StartsWith(str, "move"))
|
||||
{
|
||||
std::stringstream ss{str};
|
||||
Move move;
|
||||
ss >> "move" >> move.count >> "from" >> move.from >> "to" >> move.to;
|
||||
instructions.moves.emplace_back(move);
|
||||
}
|
||||
else if (!str.empty())
|
||||
{
|
||||
for (int i = 1; i < str.size(); i += 4)
|
||||
{
|
||||
int index = (i - 1) / 4;
|
||||
if (instructions.stacks.size() <= index)
|
||||
instructions.stacks.emplace_back(std::deque<char>{});
|
||||
if (str[i] >= 'A' && str[i] <= 'Z')
|
||||
instructions.stacks[index].emplace_front(str[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return instructions;
|
||||
}
|
||||
|
||||
OUTPUT1(input)
|
||||
{
|
||||
Instructions instructions = input;
|
||||
for (auto& move : instructions.moves)
|
||||
{
|
||||
for (int i = 0; i < move.count; i++)
|
||||
{
|
||||
instructions.stacks[move.to - 1].emplace_back(instructions.stacks[move.from - 1].back());
|
||||
instructions.stacks[move.from - 1].pop_back();
|
||||
}
|
||||
}
|
||||
std::stringstream ss;
|
||||
for (auto& stack : instructions.stacks)
|
||||
{
|
||||
ss << stack.back();
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
OUTPUT2(input)
|
||||
{
|
||||
Instructions instructions = input;
|
||||
for (auto& move : instructions.moves)
|
||||
{
|
||||
std::vector<char> chars;
|
||||
for (int i = 0; i < move.count; i++)
|
||||
{
|
||||
chars.emplace_back(instructions.stacks[move.from - 1].back());
|
||||
instructions.stacks[move.from - 1].pop_back();
|
||||
}
|
||||
for (auto it = chars.rbegin(); it != chars.rend(); it++)
|
||||
{
|
||||
instructions.stacks[move.to - 1].emplace_back(*it);
|
||||
}
|
||||
}
|
||||
std::stringstream ss;
|
||||
for (auto& stack : instructions.stacks)
|
||||
{
|
||||
ss << stack.back();
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace y$1::day06
|
||||
{
|
||||
REGISTER_DAY(2022, Day06, std::string, int);
|
||||
|
||||
REGISTER_TEST_EXAMPLE(2022, Day06, ExampleInput, 1, 7);
|
||||
REGISTER_TEST(2022, Day06, Input, 1, 1658);
|
||||
REGISTER_TEST_EXAMPLE(2022, Day06, ExampleInput, 2, 19);
|
||||
REGISTER_TEST(2022, Day06, Input, 2, 2260);
|
||||
|
||||
int GetPosition(const std::string& str, int length)
|
||||
{
|
||||
for (int i = length - 1; i < str.size(); i++)
|
||||
{
|
||||
std::set<char> s;
|
||||
for (int j = i - length + 1; j <= i; j++)
|
||||
{
|
||||
s.emplace(str[j]);
|
||||
}
|
||||
if (s.size() == length)
|
||||
return i + 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
READ_INPUT(input)
|
||||
{
|
||||
std::string str;
|
||||
std::getline(input, str);
|
||||
return str;
|
||||
}
|
||||
|
||||
OUTPUT1(input)
|
||||
{
|
||||
return GetPosition(input, 4);
|
||||
}
|
||||
|
||||
OUTPUT2(input)
|
||||
{
|
||||
return GetPosition(input, 14);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace y$1::day07
|
||||
{
|
||||
struct Directory
|
||||
{
|
||||
Directory* parent;
|
||||
std::string name;
|
||||
int size = 0;
|
||||
std::map<std::string, Directory> directories;
|
||||
std::map<std::string, int> files;
|
||||
|
||||
bool operator<(const Directory& rhs)
|
||||
{
|
||||
return name < rhs.name;
|
||||
}
|
||||
};
|
||||
|
||||
REGISTER_DAY(2022, Day07, Directory, int);
|
||||
|
||||
REGISTER_TEST_EXAMPLE(2022, Day07, ExampleInput, 1, 95437);
|
||||
REGISTER_TEST(2022, Day07, Input, 1, 1084134);
|
||||
REGISTER_TEST_EXAMPLE(2022, Day07, ExampleInput, 2, 24933642);
|
||||
REGISTER_TEST(2022, Day07, Input, 2, 6183184);
|
||||
|
||||
void CalculateSize(Directory& directory)
|
||||
{
|
||||
if (directory.size != 0)
|
||||
return;
|
||||
int size = 0;
|
||||
for (auto& file : directory.files)
|
||||
{
|
||||
size += file.second;
|
||||
}
|
||||
for (auto& directory2 : directory.directories)
|
||||
{
|
||||
CalculateSize(directory2.second);
|
||||
size += directory2.second.size;
|
||||
}
|
||||
directory.size = size;
|
||||
}
|
||||
|
||||
int SumOfDirectories(Directory& directory, int maxSize)
|
||||
{
|
||||
int sum = 0;
|
||||
if (directory.size <= maxSize)
|
||||
sum += directory.size;
|
||||
|
||||
for (auto& directory2 : directory.directories)
|
||||
{
|
||||
sum += SumOfDirectories(directory2.second, maxSize);
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
int FindSmallest(Directory& directory, int minimum)
|
||||
{
|
||||
int smallest = 70000000;
|
||||
if (directory.size >= minimum)
|
||||
smallest = directory.size;
|
||||
|
||||
for (auto& dir : directory.directories)
|
||||
{
|
||||
int min = FindSmallest(dir.second, minimum);
|
||||
if (smallest != 70000000)
|
||||
smallest = std::min(min, smallest);
|
||||
}
|
||||
return smallest;
|
||||
}
|
||||
|
||||
READ_INPUT(input)
|
||||
{
|
||||
std::string str;
|
||||
std::set<int> elfs;
|
||||
int sum = 0;
|
||||
Directory* currentDirectory;
|
||||
|
||||
Directory rootDirectory;
|
||||
rootDirectory.name = "/";
|
||||
currentDirectory = &rootDirectory;
|
||||
std::getline(input, str); // $ cd /
|
||||
while (std::getline(input, str))
|
||||
{
|
||||
if (str[0] == '$')
|
||||
{
|
||||
std::stringstream ss{str};
|
||||
std::string command;
|
||||
ss >> "$" >> command;
|
||||
if (command == "cd")
|
||||
{
|
||||
std::string directory;
|
||||
ss >> directory;
|
||||
if (directory == "..")
|
||||
currentDirectory = currentDirectory->parent;
|
||||
else
|
||||
currentDirectory = ¤tDirectory->directories[directory];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::stringstream ss{str};
|
||||
if (str[0] == 'd')
|
||||
{
|
||||
Directory directory;
|
||||
ss >> "dir" >> directory.name;
|
||||
directory.parent = currentDirectory;
|
||||
currentDirectory->directories.emplace(directory.name, directory);
|
||||
}
|
||||
else
|
||||
{
|
||||
int size;
|
||||
std::string name;
|
||||
ss >> size >> name;
|
||||
currentDirectory->files.emplace(name, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
return rootDirectory;
|
||||
}
|
||||
|
||||
OUTPUT1(input)
|
||||
{
|
||||
Directory directory = input;
|
||||
CalculateSize(directory);
|
||||
|
||||
return SumOfDirectories(directory, 100000);
|
||||
}
|
||||
|
||||
OUTPUT2(input)
|
||||
{
|
||||
Directory directory = input;
|
||||
CalculateSize(directory);
|
||||
int space = 70000000;
|
||||
int neededSpace = 30000000 - (space - directory.size);
|
||||
return FindSmallest(directory, neededSpace);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace y$1::day08
|
||||
{
|
||||
REGISTER_DAY(2022, Day08, Array2D<int>, int);
|
||||
|
||||
REGISTER_TEST_EXAMPLE(2022, Day08, ExampleInput, 1, 21);
|
||||
REGISTER_TEST(2022, Day08, Input, 1, 1820);
|
||||
REGISTER_TEST_EXAMPLE(2022, Day08, ExampleInput, 2, 8);
|
||||
REGISTER_TEST(2022, Day08, Input, 2, 385112);
|
||||
|
||||
READ_INPUT(input)
|
||||
{
|
||||
return Input::ReadDigitsAsArray2D(input);
|
||||
}
|
||||
|
||||
OUTPUT1(input)
|
||||
{
|
||||
// input.Each([&](const Array2D<int>& arr, const Index2D& index) {
|
||||
std::set<Index2D> found;
|
||||
for (auto it = input.begin(); it != input.end(); it++)
|
||||
{
|
||||
if (found.count(it.index) > 0)
|
||||
continue;
|
||||
bool visible = true;
|
||||
for (int x = it.index.x - 1; x >= 0; x--)
|
||||
{
|
||||
if (input.Get(x, it.index.y) >= *it)
|
||||
{
|
||||
visible = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (visible)
|
||||
{
|
||||
found.emplace(it.index);
|
||||
continue;
|
||||
}
|
||||
visible = true;
|
||||
for (int x = it.index.x + 1; x < input.width; x++)
|
||||
{
|
||||
if (input.Get(x, it.index.y) >= *it)
|
||||
{
|
||||
visible = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (visible)
|
||||
{
|
||||
found.emplace(it.index);
|
||||
continue;
|
||||
}
|
||||
visible = true;
|
||||
for (int y = it.index.y - 1; y >= 0; y--)
|
||||
{
|
||||
if (input.Get(it.index.x, y) >= *it)
|
||||
{
|
||||
visible = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (visible)
|
||||
{
|
||||
found.emplace(it.index);
|
||||
continue;
|
||||
}
|
||||
visible = true;
|
||||
for (int y = it.index.y + 1; y < input.height; y++)
|
||||
{
|
||||
if (input.Get(it.index.x, y) >= *it)
|
||||
{
|
||||
visible = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (visible)
|
||||
{
|
||||
found.emplace(it.index);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
return found.size();
|
||||
}
|
||||
|
||||
OUTPUT2(input)
|
||||
{
|
||||
int max = 0;
|
||||
for (auto it = input.begin(); it != input.end(); ++it)
|
||||
{
|
||||
int scenic = 1;
|
||||
bool found = false;
|
||||
for (int x = it.index.x - 1; x >= 0; x--)
|
||||
{
|
||||
if (*it <= input.Get(x, it.index.y))
|
||||
{
|
||||
scenic *= it.index.x - x;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
scenic *= it.index.x;
|
||||
found = false;
|
||||
for (int x = it.index.x + 1; x < input.width; x++)
|
||||
{
|
||||
if (*it <= input.Get(x, it.index.y))
|
||||
{
|
||||
scenic *= x - it.index.x;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
scenic *= input.width - it.index.x - 1;
|
||||
found = false;
|
||||
for (int y = it.index.y - 1; y >= 0; y--)
|
||||
{
|
||||
if (*it <= input.Get(it.index.x, y))
|
||||
{
|
||||
scenic *= it.index.y - y;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
scenic *= it.index.y;
|
||||
found = false;
|
||||
for (int y = it.index.y + 1; y < input.height; y++)
|
||||
{
|
||||
if (*it <= input.Get(it.index.x, y))
|
||||
{
|
||||
scenic *= y - it.index.y;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
scenic *= input.height - it.index.y - 1;
|
||||
max = std::max(max, scenic);
|
||||
};
|
||||
return max;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace y$1::day09
|
||||
{
|
||||
struct Instruction
|
||||
{
|
||||
char dir;
|
||||
int amount;
|
||||
};
|
||||
|
||||
REGISTER_DAY(2022, Day09, std::vector<Instruction>, int);
|
||||
|
||||
REGISTER_TEST_EXAMPLE(2022, Day09, ExampleInput, 1, 88);
|
||||
REGISTER_TEST(2022, Day09, Input, 1, 6011);
|
||||
REGISTER_TEST_EXAMPLE(2022, Day09, ExampleInput, 2, 36);
|
||||
REGISTER_TEST(2022, Day09, Input, 2, 2419);
|
||||
|
||||
READ_INPUT(input)
|
||||
{
|
||||
std::string str;
|
||||
std::vector<Instruction> instructions;
|
||||
while (std::getline(input, str))
|
||||
{
|
||||
std::stringstream ss{str};
|
||||
Instruction ins;
|
||||
ss >> ins.dir >> ins.amount;
|
||||
instructions.emplace_back(ins);
|
||||
}
|
||||
return instructions;
|
||||
}
|
||||
|
||||
OUTPUT1(input)
|
||||
{
|
||||
std::set<Index2D> visited;
|
||||
Index2D headPos{0, 0};
|
||||
Index2D tailPos{0, 0};
|
||||
visited.emplace(tailPos);
|
||||
for (auto& ins : input)
|
||||
{
|
||||
for (int i = 0; i < ins.amount; i++)
|
||||
{
|
||||
switch (ins.dir)
|
||||
{
|
||||
case 'R':
|
||||
headPos.x++;
|
||||
break;
|
||||
case 'U':
|
||||
headPos.y++;
|
||||
break;
|
||||
case 'L':
|
||||
headPos.x--;
|
||||
break;
|
||||
case 'D':
|
||||
headPos.y--;
|
||||
break;
|
||||
}
|
||||
Index2D diff = headPos - tailPos;
|
||||
if (std::abs(diff.x) > 1)
|
||||
{
|
||||
tailPos.x = headPos.x + (diff.x < 0 ? 1 : -1);
|
||||
tailPos.y = headPos.y;
|
||||
visited.emplace(tailPos);
|
||||
}
|
||||
else if (std::abs(diff.y) > 1)
|
||||
{
|
||||
tailPos.x = headPos.x;
|
||||
tailPos.y = headPos.y + (diff.y < 0 ? 1 : -1);
|
||||
visited.emplace(tailPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
return visited.size();
|
||||
}
|
||||
|
||||
OUTPUT2(input)
|
||||
{
|
||||
std::set<Index2D> visited;
|
||||
std::vector<Index2D> bodyPos;
|
||||
bodyPos.resize(10);
|
||||
std::fill(bodyPos.begin(), bodyPos.end(), Index2D{0, 0});
|
||||
visited.emplace(Index2D{0, 0});
|
||||
for (auto& ins : input)
|
||||
{
|
||||
for (int i = 0; i < ins.amount; i++)
|
||||
{
|
||||
switch (ins.dir)
|
||||
{
|
||||
case 'R':
|
||||
bodyPos[0].x++;
|
||||
break;
|
||||
case 'U':
|
||||
bodyPos[0].y++;
|
||||
break;
|
||||
case 'L':
|
||||
bodyPos[0].x--;
|
||||
break;
|
||||
case 'D':
|
||||
bodyPos[0].y--;
|
||||
break;
|
||||
}
|
||||
for (int i = 1; i < bodyPos.size(); i++)
|
||||
{
|
||||
Index2D diff = bodyPos[i - 1] - bodyPos[i];
|
||||
if (std::abs(diff.x) > 1)
|
||||
{
|
||||
bodyPos[i].x += diff.x < 0 ? -1 : 1;
|
||||
if (std::abs(diff.y) >= 1)
|
||||
bodyPos[i].y += diff.y < 0 ? -1 : 1;
|
||||
}
|
||||
else if (std::abs(diff.y) > 1)
|
||||
{
|
||||
if (std::abs(diff.x) >= 1)
|
||||
bodyPos[i].x += diff.x < 0 ? -1 : 1;
|
||||
bodyPos[i].y += diff.y < 0 ? -1 : 1;
|
||||
}
|
||||
}
|
||||
visited.emplace(bodyPos.back());
|
||||
}
|
||||
}
|
||||
return visited.size();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace y$1::day10
|
||||
{
|
||||
enum class Op
|
||||
{
|
||||
Addx,
|
||||
Noop
|
||||
};
|
||||
|
||||
struct Instruction
|
||||
{
|
||||
Op op;
|
||||
int val;
|
||||
};
|
||||
|
||||
REGISTER_DAY(2022, Day10, std::vector<Instruction>, int);
|
||||
|
||||
REGISTER_TEST_EXAMPLE(2022, Day10, ExampleInput, 1, 13140);
|
||||
REGISTER_TEST(2022, Day10, Input, 1, 10760);
|
||||
REGISTER_TEST_EXAMPLE(2022, Day10, ExampleInput, 2, 124);
|
||||
REGISTER_TEST(2022, Day10, Input, 2, 100);
|
||||
|
||||
void Draw(int cycle, int value, Array2D<char>& grid)
|
||||
{
|
||||
int xPos = cycle % 40;
|
||||
int yPos = cycle / 40;
|
||||
if (value - 1 <= xPos && xPos <= value + 1)
|
||||
grid.Set(xPos, yPos, '#');
|
||||
}
|
||||
|
||||
READ_INPUT(input)
|
||||
{
|
||||
std::string str;
|
||||
std::vector<Instruction> instructions;
|
||||
while (std::getline(input, str))
|
||||
{
|
||||
Instruction instruction;
|
||||
if (str == "noop")
|
||||
{
|
||||
instruction.op = Op::Noop;
|
||||
instructions.emplace_back(instruction);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::stringstream ss{str};
|
||||
instruction.op = Op::Addx;
|
||||
ss >> "addx" >> instruction.val;
|
||||
instructions.emplace_back(instruction);
|
||||
}
|
||||
}
|
||||
return instructions;
|
||||
}
|
||||
|
||||
OUTPUT1(input)
|
||||
{
|
||||
int sum = 0;
|
||||
int cycle = 1;
|
||||
int currentCycle = 20;
|
||||
int value = 1;
|
||||
for (auto& instruction : input)
|
||||
{
|
||||
if (instruction.op == Op::Addx)
|
||||
{
|
||||
cycle += 2;
|
||||
if (cycle > currentCycle)
|
||||
{
|
||||
sum += currentCycle * value;
|
||||
|
||||
currentCycle += 40;
|
||||
}
|
||||
value += instruction.val;
|
||||
}
|
||||
else if (instruction.op == Op::Noop)
|
||||
{
|
||||
cycle += 1;
|
||||
if (cycle > currentCycle)
|
||||
{
|
||||
sum += currentCycle * value;
|
||||
|
||||
currentCycle += 40;
|
||||
}
|
||||
}
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
OUTPUT2(input)
|
||||
{
|
||||
Array2D<char> grid{40, 6};
|
||||
grid.Fill('.');
|
||||
|
||||
int cycle = 0;
|
||||
int value = 1;
|
||||
|
||||
for (auto& instruction : input)
|
||||
{
|
||||
Draw(cycle, value, grid);
|
||||
if (instruction.op == Op::Addx)
|
||||
{
|
||||
cycle++;
|
||||
Draw(cycle, value, grid);
|
||||
cycle++;
|
||||
value += instruction.val;
|
||||
}
|
||||
else if (instruction.op == Op::Noop)
|
||||
{
|
||||
cycle++;
|
||||
}
|
||||
}
|
||||
std::cout << grid << std::endl;
|
||||
|
||||
// Output is text in a grid so do some basic verification on the amount of filled in pixels
|
||||
return grid.Count('#');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace y$1::day11
|
||||
{
|
||||
|
||||
enum Op
|
||||
{
|
||||
Add,
|
||||
Mul
|
||||
};
|
||||
|
||||
struct Old
|
||||
{
|
||||
};
|
||||
|
||||
struct Monkey
|
||||
{
|
||||
std::vector<int64_t> items;
|
||||
std::variant<int, Old> bin1;
|
||||
std::variant<int, Old> bin2;
|
||||
int divisible;
|
||||
Op op;
|
||||
int monkeyTrue;
|
||||
int monkeyFalse;
|
||||
};
|
||||
|
||||
REGISTER_DAY(2022, Day11, std::vector<Monkey>, int64_t);
|
||||
|
||||
REGISTER_TEST_EXAMPLE(2022, Day11, ExampleInput, 1, 10605);
|
||||
REGISTER_TEST(2022, Day11, Input, 1, 120756);
|
||||
REGISTER_TEST_EXAMPLE(2022, Day11, ExampleInput, 2, 2713310158);
|
||||
REGISTER_TEST(2022, Day11, Input, 2, 39109444654);
|
||||
|
||||
template <typename Func>
|
||||
void Round(std::vector<Monkey>& monkeys, std::vector<int64_t>& inspections, Func worryManagement)
|
||||
{
|
||||
for (int j = 0; j < monkeys.size(); j++)
|
||||
{
|
||||
for (auto item : monkeys[j].items)
|
||||
{
|
||||
inspections[j]++;
|
||||
int64_t i1 = std::holds_alternative<Old>(monkeys[j].bin1) ? item : std::get<int>(monkeys[j].bin1);
|
||||
int64_t i2 = std::holds_alternative<Old>(monkeys[j].bin2) ? item : std::get<int>(monkeys[j].bin2);
|
||||
int64_t val;
|
||||
|
||||
if (monkeys[j].op == Op::Add)
|
||||
val = i1 + i2;
|
||||
else if (monkeys[j].op == Op::Mul)
|
||||
val = i1 * i2;
|
||||
val = worryManagement(val);
|
||||
if (val % monkeys[j].divisible == 0)
|
||||
monkeys[monkeys[j].monkeyTrue].items.emplace_back(val);
|
||||
else
|
||||
monkeys[monkeys[j].monkeyFalse].items.emplace_back(val);
|
||||
}
|
||||
monkeys[j].items.clear();
|
||||
}
|
||||
}
|
||||
|
||||
READ_INPUT(input)
|
||||
{
|
||||
std::string str;
|
||||
std::vector<Monkey> monkeys;
|
||||
while (std::getline(input, str))
|
||||
{
|
||||
Monkey monkey;
|
||||
{ // items
|
||||
std::getline(input, str);
|
||||
std::stringstream ss{str};
|
||||
ss >> "Starting items: ";
|
||||
while (std::getline(ss, str, ',')) monkey.items.emplace_back(std::stoi(str));
|
||||
}
|
||||
{ // operator
|
||||
std::getline(input, str);
|
||||
std::stringstream ss{str};
|
||||
ss >> "Operation: new = ";
|
||||
ss >> str;
|
||||
if (str == "old")
|
||||
monkey.bin1 = Old{};
|
||||
else
|
||||
monkey.bin1 = std::stoi(str);
|
||||
char c;
|
||||
ss >> c;
|
||||
if (c == '+')
|
||||
monkey.op = Op::Add;
|
||||
else if (c == '*')
|
||||
monkey.op = Op::Mul;
|
||||
ss >> str;
|
||||
if (str == "old")
|
||||
monkey.bin2 = Old{};
|
||||
else
|
||||
monkey.bin2 = std::stoi(str);
|
||||
}
|
||||
{ // Test
|
||||
std::getline(input, str);
|
||||
std::stringstream ss{str};
|
||||
ss >> "Test: divisible by " >> monkey.divisible;
|
||||
}
|
||||
{ // True
|
||||
std::getline(input, str);
|
||||
std::stringstream ss{str};
|
||||
ss >> "If true: throw to monkey " >> monkey.monkeyTrue;
|
||||
}
|
||||
{ // False
|
||||
std::getline(input, str);
|
||||
std::stringstream ss{str};
|
||||
ss >> "If false: throw to monkey " >> monkey.monkeyFalse;
|
||||
}
|
||||
std::getline(input, str);
|
||||
monkeys.emplace_back(monkey);
|
||||
}
|
||||
return monkeys;
|
||||
}
|
||||
|
||||
OUTPUT1(input)
|
||||
{
|
||||
std::vector<int64_t> inspections;
|
||||
inspections.resize(input.size());
|
||||
std::vector<Monkey> monkeys = input;
|
||||
for (int i = 0; i < 20; i++)
|
||||
{
|
||||
Round(monkeys, inspections, [](int64_t val) { return val / 3; });
|
||||
}
|
||||
std::sort(inspections.begin(), inspections.end());
|
||||
return inspections[inspections.size() - 1] * inspections[inspections.size() - 2];
|
||||
}
|
||||
|
||||
OUTPUT2(input)
|
||||
{
|
||||
std::vector<int64_t> inspections;
|
||||
inspections.resize(input.size());
|
||||
std::vector<Monkey> monkeys = input;
|
||||
int mod = 1;
|
||||
for (auto& monkey : monkeys)
|
||||
{
|
||||
mod *= monkey.divisible;
|
||||
}
|
||||
for (int i = 0; i < 10000; i++)
|
||||
{
|
||||
Round(monkeys, inspections, [mod](int64_t val) { return val % mod; });
|
||||
}
|
||||
std::sort(inspections.begin(), inspections.end());
|
||||
return inspections[inspections.size() - 1] * inspections[inspections.size() - 2];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace y$1::day12
|
||||
{
|
||||
REGISTER_DAY(2022, Day12, Array2D<char>, int);
|
||||
|
||||
REGISTER_TEST_EXAMPLE(2022, Day12, ExampleInput, 1, 31);
|
||||
REGISTER_TEST(2022, Day12, Input, 1, 380);
|
||||
REGISTER_TEST_EXAMPLE(2022, Day12, ExampleInput, 2, 29);
|
||||
REGISTER_TEST(2022, Day12, Input, 2, 375);
|
||||
|
||||
int GetElevation(const Array2D<char>& arr, const Index2D& index)
|
||||
{
|
||||
int elevation = 0;
|
||||
char value = arr.Get(index.x, index.y);
|
||||
if (value == 'S')
|
||||
elevation = 'a' - 'a';
|
||||
else if (value == 'E')
|
||||
elevation = 'z' - 'a';
|
||||
else
|
||||
elevation = value - 'a';
|
||||
return elevation;
|
||||
}
|
||||
|
||||
std::vector<std::pair<int, Index2D>> Branch(const Array2D<char>& arr, Index2D index)
|
||||
{
|
||||
std::vector<std::pair<int, Index2D>> branches;
|
||||
int elevation = GetElevation(arr, index);
|
||||
std::vector<Index2D> neighbors = arr.GetNeighbors(index, false);
|
||||
for (auto& neighbor : neighbors)
|
||||
{
|
||||
int neighElevation = GetElevation(arr, neighbor);
|
||||
if ((neighElevation - 1 <= elevation))
|
||||
branches.emplace_back(1, neighbor);
|
||||
}
|
||||
return branches;
|
||||
}
|
||||
|
||||
std::vector<std::pair<int, Index2D>> Branch2(const Array2D<char>& arr, Index2D index)
|
||||
{
|
||||
std::vector<std::pair<int, Index2D>> branches;
|
||||
int elevation = GetElevation(arr, index);
|
||||
std::vector<Index2D> neighbors = arr.GetNeighbors(index, false);
|
||||
for (auto& neighbor : neighbors)
|
||||
{
|
||||
int neighElevation = GetElevation(arr, neighbor);
|
||||
if (elevation - 1 <= neighElevation)
|
||||
branches.emplace_back(1, neighbor);
|
||||
}
|
||||
return branches;
|
||||
}
|
||||
|
||||
bool Goal(const Array2D<char>& arr, Index2D index)
|
||||
{
|
||||
return arr.Get(index.x, index.y) == 'E';
|
||||
}
|
||||
|
||||
bool Goal2(const Array2D<char>& arr, Index2D index)
|
||||
{
|
||||
return arr.Get(index.x, index.y) == 'a';
|
||||
}
|
||||
|
||||
READ_INPUT(input)
|
||||
{
|
||||
return Input::ReadArray2D(input);
|
||||
}
|
||||
|
||||
OUTPUT1(input)
|
||||
{
|
||||
Index2D pos;
|
||||
for (auto it = input.begin(); it != input.end(); it++)
|
||||
{
|
||||
if (*it == 'S')
|
||||
pos = it.index;
|
||||
}
|
||||
|
||||
return Helper::Dijkstras(input, pos, Branch, Goal);
|
||||
}
|
||||
|
||||
OUTPUT2(input)
|
||||
{
|
||||
Index2D pos;
|
||||
for (auto it = input.begin(); it != input.end(); it++)
|
||||
{
|
||||
if (*it == 'E')
|
||||
pos = it.index;
|
||||
}
|
||||
|
||||
return Helper::Dijkstras(input, pos, Branch2, Goal2);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace y$1::day13
|
||||
{
|
||||
struct Node
|
||||
{
|
||||
std::variant<int, std::vector<Node>> nodes;
|
||||
|
||||
bool operator==(const Node& rhs) const
|
||||
{
|
||||
return nodes == rhs.nodes;
|
||||
}
|
||||
|
||||
bool operator<(const Node& rhs) const
|
||||
{
|
||||
if (std::holds_alternative<int>(nodes) && std::holds_alternative<int>(rhs.nodes))
|
||||
{
|
||||
return std::get<int>(nodes) < std::get<int>(rhs.nodes);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (std::holds_alternative<int>(nodes))
|
||||
{
|
||||
Node node;
|
||||
node.nodes = std::vector<Node>{Node{std::get<int>(nodes)}};
|
||||
return node < rhs;
|
||||
}
|
||||
else if (std::holds_alternative<int>(rhs.nodes))
|
||||
{
|
||||
Node node;
|
||||
node.nodes = std::vector<Node>{Node{std::get<int>(rhs.nodes)}};
|
||||
return *this < node;
|
||||
}
|
||||
else
|
||||
{
|
||||
const std::vector<Node>& lhsNodes = std::get<std::vector<Node>>(nodes);
|
||||
const std::vector<Node>& rhsNodes = std::get<std::vector<Node>>(rhs.nodes);
|
||||
for (int i = 0; i < std::min(lhsNodes.size(), rhsNodes.size()); i++)
|
||||
{
|
||||
if (lhsNodes[i] < rhsNodes[i])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (rhsNodes[i] < lhsNodes[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return lhsNodes.size() < rhsNodes.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
REGISTER_DAY(2022, Day13, std::vector<Node>, int);
|
||||
|
||||
REGISTER_TEST_EXAMPLE(2022, Day13, ExampleInput, 1, 13);
|
||||
REGISTER_TEST(2022, Day13, Input, 1, 5843);
|
||||
REGISTER_TEST_EXAMPLE(2022, Day13, ExampleInput, 2, 140);
|
||||
REGISTER_TEST(2022, Day13, Input, 2, 26289);
|
||||
|
||||
void ParseTree(const std::string& str, int& index, Node& parent)
|
||||
{
|
||||
std::vector<Node> nodes{};
|
||||
while (index < str.size())
|
||||
{
|
||||
if (str[index] == '[')
|
||||
{
|
||||
index++;
|
||||
Node node;
|
||||
ParseTree(str, index, node);
|
||||
nodes.emplace_back(node);
|
||||
index++;
|
||||
}
|
||||
else if (str[index] >= '0' && str[index] <= '9')
|
||||
{
|
||||
Node node;
|
||||
node.nodes = std::stoi(str.substr(index));
|
||||
nodes.emplace_back(node);
|
||||
while (str[index] >= '0' && str[index] <= '9') index++;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (str[index] != ',')
|
||||
break;
|
||||
index++;
|
||||
}
|
||||
parent.nodes = nodes;
|
||||
}
|
||||
|
||||
READ_INPUT(input)
|
||||
{
|
||||
std::string str;
|
||||
std::vector<Node> trees;
|
||||
while (std::getline(input, str))
|
||||
{
|
||||
if (str.empty())
|
||||
continue;
|
||||
Node root;
|
||||
int index = 1;
|
||||
ParseTree(str, index, root);
|
||||
trees.emplace_back(root);
|
||||
}
|
||||
return trees;
|
||||
}
|
||||
|
||||
OUTPUT1(input)
|
||||
{
|
||||
int sum = 0;
|
||||
for (int i = 0; i < input.size(); i += 2)
|
||||
{
|
||||
if (input[i] < input[i + 1])
|
||||
sum += i / 2 + 1;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
OUTPUT2(input)
|
||||
{
|
||||
std::vector<Node> nodes = input;
|
||||
Node key1 = Node{std::vector<Node>{Node{2}}};
|
||||
Node key2 = Node{std::vector<Node>{Node{6}}};
|
||||
nodes.emplace_back(key1);
|
||||
nodes.emplace_back(key2);
|
||||
std::sort(nodes.begin(), nodes.end());
|
||||
auto it1 = std::find(nodes.begin(), nodes.end(), key1);
|
||||
auto it2 = std::find(nodes.begin(), nodes.end(), key2);
|
||||
|
||||
return (std::distance(nodes.begin(), it1) + 1) * (std::distance(nodes.begin(), it2) + 1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace y$1::day14
|
||||
{
|
||||
REGISTER_DAY(2022, Day14, std::set<Index2D>, int);
|
||||
|
||||
REGISTER_TEST_EXAMPLE(2022, Day14, ExampleInput, 1, 24);
|
||||
REGISTER_TEST(2022, Day14, Input, 1, 768);
|
||||
REGISTER_TEST_EXAMPLE(2022, Day14, ExampleInput, 2, 93);
|
||||
REGISTER_TEST(2022, Day14, Input, 2, 26686);
|
||||
|
||||
READ_INPUT(input)
|
||||
{
|
||||
std::string str;
|
||||
std::set<Index2D> occupied;
|
||||
int sum = 0;
|
||||
while (std::getline(input, str))
|
||||
{
|
||||
std::stringstream ss{str};
|
||||
Index2D start;
|
||||
ss >> start.x >> "," >> start.y;
|
||||
while ((ss >> "->"))
|
||||
{
|
||||
Index2D next;
|
||||
ss >> next.x >> "," >> next.y;
|
||||
for (int y = std::min(start.y, next.y); y <= std::max(start.y, next.y); y++)
|
||||
{
|
||||
for (int x = std::min(start.x, next.x); x <= std::max(start.x, next.x); x++)
|
||||
{
|
||||
occupied.emplace(Index2D{x, y});
|
||||
}
|
||||
}
|
||||
start = next;
|
||||
}
|
||||
}
|
||||
return occupied;
|
||||
}
|
||||
|
||||
OUTPUT1(input)
|
||||
{
|
||||
int maxY = input.begin()->y;
|
||||
for (auto& index : input)
|
||||
{
|
||||
maxY = std::max(maxY, index.y);
|
||||
}
|
||||
maxY += 2;
|
||||
Array2D<char> grid{maxY * 2 - 1, maxY};
|
||||
grid.Fill('.');
|
||||
for (auto& index : input)
|
||||
{
|
||||
grid.Set(index.x - 500 + maxY - 1, index.y, '#');
|
||||
}
|
||||
while (true)
|
||||
{
|
||||
Index2D sand{maxY - 1, 0};
|
||||
while (true)
|
||||
{
|
||||
if (sand.y >= maxY - 2)
|
||||
return grid.Count('o');
|
||||
else if (grid.Get(sand.x, sand.y + 1) == '.')
|
||||
sand.y++;
|
||||
else if (grid.Get(sand.x - 1, sand.y + 1) == '.')
|
||||
{
|
||||
sand.x--;
|
||||
sand.y++;
|
||||
}
|
||||
else if (grid.Get(sand.x + 1, sand.y + 1) == '.')
|
||||
{
|
||||
sand.x++;
|
||||
sand.y++;
|
||||
}
|
||||
else
|
||||
{
|
||||
grid.Set(sand.x, sand.y, 'o');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
OUTPUT2(input)
|
||||
{
|
||||
int maxY = input.begin()->y;
|
||||
for (auto& index : input)
|
||||
{
|
||||
maxY = std::max(maxY, index.y);
|
||||
}
|
||||
maxY += 2;
|
||||
Array2D<char> grid{maxY * 2 - 1, maxY};
|
||||
grid.Fill('.');
|
||||
for (auto& index : input)
|
||||
{
|
||||
grid.Set(index.x - 500 + maxY - 1, index.y, '#');
|
||||
}
|
||||
while (true)
|
||||
{
|
||||
Index2D sand{maxY - 1, 0};
|
||||
while (true)
|
||||
{
|
||||
if (grid.Get(sand.x, sand.y + 1) == '.')
|
||||
sand.y++;
|
||||
else if (grid.Get(sand.x - 1, sand.y + 1) == '.')
|
||||
{
|
||||
sand.x--;
|
||||
sand.y++;
|
||||
}
|
||||
else if (grid.Get(sand.x + 1, sand.y + 1) == '.')
|
||||
{
|
||||
sand.x++;
|
||||
sand.y++;
|
||||
}
|
||||
else if (sand.y == 0)
|
||||
{
|
||||
grid.Set(sand.x, sand.y, 'o');
|
||||
return grid.Count('o');
|
||||
}
|
||||
else
|
||||
{
|
||||
grid.Set(sand.x, sand.y, 'o');
|
||||
break;
|
||||
}
|
||||
if (sand.y + 1 >= maxY)
|
||||
{
|
||||
grid.Set(sand.x, sand.y, 'o');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,259 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace y$1::day15
|
||||
{
|
||||
struct Scanner
|
||||
{
|
||||
Index2D position;
|
||||
Index2D beacon;
|
||||
};
|
||||
|
||||
REGISTER_DAY(2022, Day15, std::vector<Scanner>, int64_t);
|
||||
|
||||
REGISTER_TEST_EXAMPLE(2022, Day15, ExampleInput, 1, 26);
|
||||
REGISTER_TEST(2022, Day15, Input, 1, 5564017);
|
||||
REGISTER_TEST_EXAMPLE(2022, Day15, ExampleInput, 2, 56000011);
|
||||
REGISTER_TEST(2022, Day15, Input, 2, 11558423398893);
|
||||
|
||||
struct Line
|
||||
{
|
||||
int start;
|
||||
int end;
|
||||
|
||||
bool operator<(const Line& rhs) const
|
||||
{
|
||||
if (start == rhs.start)
|
||||
return end < rhs.end;
|
||||
return start < rhs.start;
|
||||
}
|
||||
};
|
||||
|
||||
bool IsOverlap(const Line& l1, const Line& l2)
|
||||
{
|
||||
return (l1.start >= l2.start && l1.end <= l2.end) || (l2.start >= l1.start && l2.end <= l1.end);
|
||||
}
|
||||
|
||||
READ_INPUT(input)
|
||||
{
|
||||
std::string str;
|
||||
std::vector<Scanner> scanners;
|
||||
while (std::getline(input, str))
|
||||
{
|
||||
std::stringstream ss{str};
|
||||
Scanner scanner;
|
||||
ss >> "Sensor at x=" >> scanner.position.x >> ", y=" >> scanner.position.y >> ": closest beacon is at x=" >>
|
||||
scanner.beacon.x >> ", y=" >> scanner.beacon.y;
|
||||
scanners.emplace_back(scanner);
|
||||
}
|
||||
return scanners;
|
||||
}
|
||||
|
||||
OUTPUT1(input)
|
||||
{
|
||||
int row = 2000000;
|
||||
if (isExample)
|
||||
{
|
||||
row = 10;
|
||||
}
|
||||
std::set<Line> lines;
|
||||
for (auto& scanner : input)
|
||||
{
|
||||
Index2D diff = scanner.position - scanner.beacon;
|
||||
int manhattan = std::abs(diff.x) + std::abs(diff.y);
|
||||
if ((scanner.position.y <= row && scanner.position.y + manhattan >= row) ||
|
||||
(scanner.position.y >= row && scanner.position.y - manhattan <= row))
|
||||
{
|
||||
int distance = std::abs(row - scanner.position.y);
|
||||
int count = manhattan * 2 + 1 - (distance) * 2;
|
||||
Line line;
|
||||
line.start = scanner.position.x - count / 2;
|
||||
line.end = scanner.position.x + count / 2;
|
||||
lines.emplace(line);
|
||||
}
|
||||
}
|
||||
int min = lines.begin()->start;
|
||||
int max = lines.begin()->end;
|
||||
for (auto& line : lines)
|
||||
{
|
||||
min = std::min(min, line.start);
|
||||
max = std::max(max, line.end);
|
||||
}
|
||||
std::set<Index2D> beacons;
|
||||
for (auto& scanner : input)
|
||||
{
|
||||
if (scanner.beacon.y == row && scanner.beacon.x >= min && scanner.beacon.x <= max)
|
||||
beacons.emplace(scanner.beacon);
|
||||
}
|
||||
|
||||
return max - min + 1 - beacons.size();
|
||||
}
|
||||
|
||||
#if 0
|
||||
OUTPUT2(input)
|
||||
{
|
||||
Array2D<char> grid{20, 20};
|
||||
grid.Fill('.');
|
||||
for (int y = 0; y < 20; y++)
|
||||
{
|
||||
for (int x = 0; x < 20; x++)
|
||||
{
|
||||
int i = 0;
|
||||
for (auto& scanner : input)
|
||||
{
|
||||
if (Index2D{x, y} == scanner.position)
|
||||
grid.Set(x, y, 'A' + i);
|
||||
else
|
||||
{
|
||||
Index2D diff = scanner.position - scanner.beacon;
|
||||
int manhattan = std::abs(diff.x) + std::abs(diff.y);
|
||||
int manhattan2 = std::abs(scanner.position.x - x) + std::abs(scanner.position.y - y);
|
||||
if (manhattan2 <= manhattan) {
|
||||
grid.Set(x, y, 'a' + i);
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
std::cout << grid << std::endl;
|
||||
return 0;
|
||||
// return (int64_t)2889604 * (int64_t)4000000 + (int64_t)3398893;
|
||||
int row = 4000000;
|
||||
if (isExample)
|
||||
row = 20;
|
||||
for (int i = 0; i < row; i++)
|
||||
{
|
||||
std::set<Line> lines;
|
||||
for (auto& scanner : input) {
|
||||
Index2D diff = scanner.position - scanner.beacon;
|
||||
int manhattan = std::abs(diff.x) + std::abs(diff.y);
|
||||
if ((scanner.position.y <= i && scanner.position.y + manhattan >= i) || (scanner.position.y >= i && scanner.position.y - manhattan <= i ))
|
||||
{
|
||||
int distance = std::abs(i - scanner.position.y);
|
||||
int count = manhattan * 2 + 1 - (distance) * 2;
|
||||
Line line;
|
||||
line.start = scanner.position.x - count / 2;
|
||||
line.end = scanner.position.x + count / 2;
|
||||
lines.emplace(line);
|
||||
}
|
||||
}
|
||||
std::vector<Line> nonOverlappingLines;
|
||||
if (lines.size() > 0)
|
||||
{
|
||||
Line currentLine = *lines.begin();
|
||||
for (auto& line : lines)
|
||||
{
|
||||
if (currentLine.end + 1 < line.start)
|
||||
{
|
||||
std::cout << "Row: " << i << "Pos: " << currentLine.end << std::endl;
|
||||
return (int64_t)(currentLine.end + 1) * (int64_t)4000000 + (int64_t)i;
|
||||
nonOverlappingLines.emplace_back(currentLine);
|
||||
currentLine = line;
|
||||
}
|
||||
else
|
||||
currentLine.end = std::max(currentLine.end, line.end);
|
||||
}
|
||||
nonOverlappingLines.emplace_back(currentLine);
|
||||
// std::cout << "Size: " << nonOverlappingLines.size() << std::endl;
|
||||
}
|
||||
}
|
||||
return 10;
|
||||
}
|
||||
#else
|
||||
int Manhattan(const Index2D& i1, const Index2D& i2)
|
||||
{
|
||||
return std::abs(i1.x - i2.x) + std::abs(i1.y - i2.y);
|
||||
}
|
||||
|
||||
bool CheckDistances(const Scanner& scanner1, const Scanner& scanner2)
|
||||
{
|
||||
int manhattan1 = Manhattan(scanner1.position, scanner1.beacon);
|
||||
int manhattan2 = Manhattan(scanner2.position, scanner2.beacon);
|
||||
int manhattan3 = Manhattan(scanner1.position, scanner2.position);
|
||||
return manhattan1 + manhattan2 + 2 >= manhattan3;
|
||||
}
|
||||
|
||||
std::vector<Index2D> GetOneAway(const Scanner& scanner1, const Scanner& scanner2, const Scanner& scanner3, int range)
|
||||
{
|
||||
std::vector<Index2D> valid;
|
||||
int distance = Manhattan(scanner1.position, scanner1.beacon) + 1;
|
||||
for (int i = 0; i < distance * 2; i++)
|
||||
{
|
||||
int y = scanner1.position.y + distance - i;
|
||||
if (y >= 0 && y <= range)
|
||||
{
|
||||
if (i >= distance)
|
||||
{
|
||||
if (scanner1.position.x + distance * 2 - i >= 0 && scanner1.position.x + distance * 2 - i <= range)
|
||||
valid.emplace_back(scanner1.position + Index2D{distance * 2 - i, distance - i});
|
||||
if (scanner1.position.x - distance * 2 + i >= 0 && scanner1.position.x - distance * 2 + i <= range)
|
||||
valid.emplace_back(scanner1.position + Index2D{i - distance * 2, distance - i});
|
||||
}
|
||||
else
|
||||
{
|
||||
if (scanner1.position.x + i >= 0 && scanner1.position.x + i <= range)
|
||||
valid.emplace_back(scanner1.position + Index2D{i, distance - i});
|
||||
if (scanner1.position.x - i >= 0 && scanner1.position.x - i <= range)
|
||||
valid.emplace_back(scanner1.position + Index2D{-i, distance - i});
|
||||
}
|
||||
}
|
||||
}
|
||||
std::vector<Index2D> valid2;
|
||||
for (auto& pos : valid)
|
||||
{
|
||||
if (Manhattan(pos, scanner2.position) == Manhattan(scanner2.position, scanner2.beacon) + 1)
|
||||
{
|
||||
valid2.emplace_back(pos);
|
||||
}
|
||||
}
|
||||
std::vector<Index2D> valid3;
|
||||
for (auto& pos : valid2)
|
||||
{
|
||||
if (Manhattan(pos, scanner3.position) == Manhattan(scanner3.position, scanner3.beacon) + 1)
|
||||
{
|
||||
valid3.emplace_back(pos);
|
||||
}
|
||||
}
|
||||
return valid3;
|
||||
}
|
||||
|
||||
OUTPUT2(input)
|
||||
{
|
||||
int range = 4000000;
|
||||
if (isExample)
|
||||
range = 20;
|
||||
for (int i = 0; i < input.size(); i++)
|
||||
{
|
||||
for (int j = i + 1; j < input.size(); j++)
|
||||
{
|
||||
if (CheckDistances(input[i], input[j]))
|
||||
{
|
||||
for (int k = j + 1; k < input.size(); k++)
|
||||
{
|
||||
if (CheckDistances(input[i], input[k]) && CheckDistances(input[j], input[k]))
|
||||
{
|
||||
std::vector<Index2D> valid = GetOneAway(input[i], input[j], input[k], range);
|
||||
for (auto& pos : valid)
|
||||
{
|
||||
bool found = true;
|
||||
for (auto& scanner : input)
|
||||
{
|
||||
if (Manhattan(scanner.position, pos) <= Manhattan(scanner.position, scanner.beacon))
|
||||
{
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
return (int64_t)pos.x * 4000000 + (int64_t)pos.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace y$1::day16
|
||||
{
|
||||
struct Node
|
||||
{
|
||||
std::string name;
|
||||
int flowrate;
|
||||
std::set<std::string> paths;
|
||||
|
||||
bool operator<(const Node& rhs) const
|
||||
{
|
||||
return name < rhs.name;
|
||||
}
|
||||
};
|
||||
|
||||
std::vector<std::pair<int, std::string>> Branch(const std::set<Node>& nodes, const std::string& str)
|
||||
{
|
||||
Node n;
|
||||
n.name = str;
|
||||
const Node& node = *nodes.find(n);
|
||||
std::vector<std::pair<int, std::string>> branches;
|
||||
for (auto& path : node.paths)
|
||||
{
|
||||
branches.emplace_back(1, path);
|
||||
}
|
||||
return branches;
|
||||
}
|
||||
|
||||
int GetDistance(const std::set<Node>& nodes,
|
||||
const std::string& from,
|
||||
const std::string& to,
|
||||
std::map<std::string, int>& distances)
|
||||
{
|
||||
std::string s = from + to;
|
||||
if (to < from)
|
||||
s = to + from;
|
||||
auto it = distances.find(s);
|
||||
int distance = 0;
|
||||
if (it != distances.end())
|
||||
distance = it->second;
|
||||
else
|
||||
{
|
||||
distance = Helper::Dijkstras(
|
||||
nodes, from, Branch, [to](const std::set<Node>& nodes, const std::string& str) { return str == to; });
|
||||
distances.emplace(s, distance);
|
||||
}
|
||||
return distance;
|
||||
}
|
||||
|
||||
int FindMax(const std::set<Node>& nodes,
|
||||
std::map<std::string, int>& distances,
|
||||
const std::string& currentNode,
|
||||
const std::set<std::string>& visit,
|
||||
int timeLeft,
|
||||
int pressure)
|
||||
{
|
||||
if (timeLeft < 0)
|
||||
return 0;
|
||||
if (visit.empty())
|
||||
return pressure;
|
||||
int max = pressure;
|
||||
for (auto& node : visit)
|
||||
{
|
||||
Node newNode;
|
||||
newNode.name = node;
|
||||
std::set<std::string> newVisit = visit;
|
||||
int newTimeLeft = timeLeft - (GetDistance(nodes, currentNode, node, distances) + 1);
|
||||
int newPressure = pressure + newTimeLeft * nodes.find(newNode)->flowrate;
|
||||
newVisit.erase(node);
|
||||
|
||||
max = std::max(max, FindMax(nodes, distances, node, newVisit, newTimeLeft, newPressure));
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
void FindMax(const std::set<Node>& nodes,
|
||||
std::map<std::string, int>& distances,
|
||||
const std::string& currentNode,
|
||||
const std::set<std::string>& visit,
|
||||
int timeLeft,
|
||||
int pressure,
|
||||
int currentBits,
|
||||
std::vector<int>& best,
|
||||
const std::map<std::string, int>& nodeIndex)
|
||||
{
|
||||
if (timeLeft < 0)
|
||||
return;
|
||||
best[currentBits] = std::max(best[currentBits], pressure);
|
||||
for (auto& node : visit)
|
||||
{
|
||||
Node newNode;
|
||||
newNode.name = node;
|
||||
std::set<std::string> newVisit = visit;
|
||||
int newTimeLeft = timeLeft - (GetDistance(nodes, currentNode, node, distances) + 1);
|
||||
int newPressure = pressure + newTimeLeft * nodes.find(newNode)->flowrate;
|
||||
newVisit.erase(node);
|
||||
|
||||
int bits = currentBits | (1 << (nodeIndex.find(node)->second));
|
||||
|
||||
FindMax(nodes, distances, node, newVisit, newTimeLeft, newPressure, bits, best, nodeIndex);
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<std::set<std::string>, std::set<std::string>> Split(const std::vector<std::string>& nodes, int bits)
|
||||
{
|
||||
std::pair<std::set<std::string>, std::set<std::string>> pairs;
|
||||
for (int i = 0; i < nodes.size(); i++)
|
||||
{
|
||||
if (bits & 1)
|
||||
pairs.first.emplace(nodes[i]);
|
||||
else
|
||||
pairs.second.emplace(nodes[i]);
|
||||
bits >>= 1;
|
||||
}
|
||||
return pairs;
|
||||
}
|
||||
|
||||
REGISTER_DAY(2022, Day16, std::set<Node>, int);
|
||||
|
||||
REGISTER_TEST_EXAMPLE(2022, Day16, ExampleInput, 1, 1651);
|
||||
REGISTER_TEST(2022, Day16, Input, 1, 1775);
|
||||
REGISTER_TEST_EXAMPLE(2022, Day16, ExampleInput, 2, 1707);
|
||||
REGISTER_TEST(2022, Day16, Input, 2, 2351);
|
||||
|
||||
READ_INPUT(input)
|
||||
{
|
||||
std::string str;
|
||||
std::set<Node> nodes;
|
||||
while (std::getline(input, str))
|
||||
{
|
||||
std::stringstream ss{str};
|
||||
Node node;
|
||||
ss >> "Valve" >> node.name >> "has flow rate=" >> node.flowrate >> "; tunnel";
|
||||
if (ss.peek() == 's')
|
||||
ss >> "s lead to valves";
|
||||
else
|
||||
ss >> "leads to valve";
|
||||
while (std::getline(ss, str, ','))
|
||||
{
|
||||
if (str.front() == ' ')
|
||||
str = str.substr(1);
|
||||
node.paths.emplace(str);
|
||||
}
|
||||
nodes.emplace(node);
|
||||
}
|
||||
return nodes;
|
||||
}
|
||||
|
||||
OUTPUT1(input)
|
||||
{
|
||||
std::map<std::string, int> distances;
|
||||
std::set<std::string> nodes;
|
||||
for (auto& node : input)
|
||||
{
|
||||
if (node.flowrate != 0)
|
||||
nodes.emplace(node.name);
|
||||
}
|
||||
|
||||
return FindMax(input, distances, "AA", nodes, 30, 0);
|
||||
}
|
||||
|
||||
OUTPUT2(input)
|
||||
{
|
||||
if (true)
|
||||
{
|
||||
std::map<std::string, int> distances;
|
||||
std::map<std::string, int> nodeIndices;
|
||||
std::set<std::string> nodes;
|
||||
int i = 0;
|
||||
for (auto& node : input)
|
||||
{
|
||||
if (node.flowrate != 0)
|
||||
{
|
||||
nodes.emplace(node.name);
|
||||
nodeIndices.emplace(node.name, i++);
|
||||
}
|
||||
}
|
||||
std::vector<int> best;
|
||||
best.resize(1 << nodes.size());
|
||||
|
||||
FindMax(input, distances, "AA", nodes, 26, 0, 0, best, nodeIndices);
|
||||
int mask = (1 << nodes.size()) - 1;
|
||||
int max = 0;
|
||||
for (int i = 0; i < best.size(); i++)
|
||||
{
|
||||
int max2 = 0;
|
||||
for (int j = 0; j < best.size(); j++)
|
||||
{
|
||||
if ((j | ((~i) & mask)) == ((~i) & mask))
|
||||
{
|
||||
max2 = std::max(max2, best[j]);
|
||||
}
|
||||
}
|
||||
max = std::max(max, best[i] + max2);
|
||||
}
|
||||
return max;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace y$1::day17
|
||||
{
|
||||
Array2D<char> block1{4, 1, {'#', '#', '#', '#'}};
|
||||
Array2D<char> block2{3, 3, {'.', '#', '.', '#', '#', '#', '.', '#', '.'}};
|
||||
Array2D<char> block3{3, 3, {'#', '#', '#', '.', '.', '#', '.', '.', '#'}};
|
||||
Array2D<char> block4{1, 4, {'#', '#', '#', '#'}};
|
||||
Array2D<char> block5{2, 2, {'#', '#', '#', '#'}};
|
||||
std::vector<Array2D<char>> blocks{block1, block2, block3, block4, block5};
|
||||
|
||||
bool Overlap(const Array2D<char>& grid, const Array2D<char>& block, int xOffset, int yOffset)
|
||||
{
|
||||
for (int y = 0; y < block.height; y++)
|
||||
{
|
||||
for (int x = 0; x < block.width; x++)
|
||||
{
|
||||
if (block.Get(x, y) == '#' && grid.Get(x + xOffset, y + yOffset) == '#')
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Set(Array2D<char>& grid, const Array2D<char>& block, int xOffset, int yOffset)
|
||||
{
|
||||
for (int y = 0; y < block.height; y++)
|
||||
{
|
||||
for (int x = 0; x < block.width; x++)
|
||||
{
|
||||
if (block.Get(x, y) == '#')
|
||||
{
|
||||
grid.Set(x + xOffset, y + yOffset, '#');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Print(const Array2D<char>& grid, int height)
|
||||
{
|
||||
for (int y = height; y >= 0; y--)
|
||||
{
|
||||
for (int x = 0; x < grid.width; x++)
|
||||
{
|
||||
std::cout << grid.Get(x, y);
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
REGISTER_DAY(2022, Day17, std::string, int64_t);
|
||||
|
||||
REGISTER_TEST_EXAMPLE(2022, Day17, ExampleInput, 1, 3068);
|
||||
REGISTER_TEST(2022, Day17, Input, 1, 3065);
|
||||
// REGISTER_TEST_EXAMPLE(2022, Day17, ExampleInput, 2, 0);
|
||||
REGISTER_TEST(2022, Day17, Input, 2, 1562536022966);
|
||||
|
||||
READ_INPUT(input)
|
||||
{
|
||||
std::string str;
|
||||
std::getline(input, str);
|
||||
return str;
|
||||
}
|
||||
|
||||
OUTPUT1(input)
|
||||
{
|
||||
int j = 0;
|
||||
int index = 0;
|
||||
Array2D<char> grid{7, 4044};
|
||||
grid.Fill('.');
|
||||
int top = 0;
|
||||
int piece = 0;
|
||||
for (int i = 0; i < 2022; i++)
|
||||
{
|
||||
Array2D<char> block = blocks[piece];
|
||||
piece++;
|
||||
piece %= blocks.size();
|
||||
|
||||
int x = 2;
|
||||
int y = top + 3;
|
||||
while (true)
|
||||
{
|
||||
if (input[index++] == '>')
|
||||
{
|
||||
x++;
|
||||
if (x + block.width > 7)
|
||||
x--;
|
||||
else if (Overlap(grid, block, x, y))
|
||||
x--;
|
||||
}
|
||||
else
|
||||
{
|
||||
x--;
|
||||
if (x < 0)
|
||||
x++;
|
||||
else if (Overlap(grid, block, x, y))
|
||||
x++;
|
||||
}
|
||||
index %= input.size();
|
||||
y--;
|
||||
if (y < 0 || Overlap(grid, block, x, y))
|
||||
{
|
||||
y++;
|
||||
Set(grid, block, x, y);
|
||||
top = std::max(top, y + block.height);
|
||||
break;
|
||||
}
|
||||
}
|
||||
j++;
|
||||
}
|
||||
return top;
|
||||
}
|
||||
|
||||
OUTPUT2(input)
|
||||
{
|
||||
int blockIndex = 0;
|
||||
int index = 0;
|
||||
Array2D<char> grid{7, 10000};
|
||||
grid.Fill('.');
|
||||
int top = 0;
|
||||
int piece = 0;
|
||||
std::map<std::pair<int, int>, std::pair<int, int>> state;
|
||||
int loopStart = 0;
|
||||
int loopStartHeight = 0;
|
||||
int loopSize = 0;
|
||||
int loopTopDiff = 0;
|
||||
std::pair<int, int> loop;
|
||||
|
||||
int64_t total = 1000000000000;
|
||||
for (int64_t i = 0; i < total; i++)
|
||||
{
|
||||
Array2D<char> block = blocks[piece];
|
||||
piece++;
|
||||
piece %= blocks.size();
|
||||
|
||||
int x = 2;
|
||||
int y = top + 3;
|
||||
while (true)
|
||||
{
|
||||
if (input[index++] == '>')
|
||||
{
|
||||
x++;
|
||||
if (x + block.width > 7)
|
||||
x--;
|
||||
else if (Overlap(grid, block, x, y))
|
||||
x--;
|
||||
}
|
||||
else
|
||||
{
|
||||
x--;
|
||||
if (x < 0)
|
||||
x++;
|
||||
else if (Overlap(grid, block, x, y))
|
||||
x++;
|
||||
}
|
||||
index %= input.size();
|
||||
y--;
|
||||
if (y < 0 || Overlap(grid, block, x, y))
|
||||
{
|
||||
y++;
|
||||
Set(grid, block, x, y);
|
||||
top = std::max(top, y + block.height);
|
||||
if (loopStart == 0)
|
||||
{
|
||||
bool found = true;
|
||||
for (int x = 0; x < grid.width; x++)
|
||||
{
|
||||
if (grid.Get(x, top - 1) != '#')
|
||||
{
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
{
|
||||
auto it = state.find({piece, index});
|
||||
if (it != state.end())
|
||||
{
|
||||
loopStart = it->second.first;
|
||||
loopStartHeight = it->second.second;
|
||||
loopSize = blockIndex - it->second.first;
|
||||
loopTopDiff = top - it->second.second;
|
||||
int64_t fastForward = (total - loopStart) / loopSize;
|
||||
fastForward = fastForward * loopSize + loopStart;
|
||||
i = fastForward;
|
||||
}
|
||||
state.emplace(std::pair<int, int>{piece, index}, std::pair<int, int>{blockIndex, top});
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
blockIndex++;
|
||||
}
|
||||
return top - loopTopDiff + (total - loopStart) / loopSize * loopTopDiff;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace y$1::day18
|
||||
{
|
||||
REGISTER_DAY(2022, Day18, Array3D<char>, int);
|
||||
|
||||
REGISTER_TEST_EXAMPLE(2022, Day18, ExampleInput, 1, 64);
|
||||
REGISTER_TEST(2022, Day18, Input, 1, 4504);
|
||||
REGISTER_TEST_EXAMPLE(2022, Day18, ExampleInput, 2, 58);
|
||||
REGISTER_TEST(2022, Day18, Input, 2, 2556);
|
||||
|
||||
READ_INPUT(input)
|
||||
{
|
||||
std::string str;
|
||||
std::vector<Index3D> indices;
|
||||
Index3D min;
|
||||
Index3D max;
|
||||
while (std::getline(input, str))
|
||||
{
|
||||
std::stringstream ss{str};
|
||||
Index3D index;
|
||||
ss >> index.x >> "," >> index.y >> "," >> index.z;
|
||||
if (!min.IsValid())
|
||||
min = index;
|
||||
if (!max.IsValid())
|
||||
max = index;
|
||||
min.x = std::min(min.x, index.x);
|
||||
min.y = std::min(min.y, index.y);
|
||||
min.z = std::min(min.z, index.z);
|
||||
max.x = std::max(max.x, index.x);
|
||||
max.y = std::max(max.y, index.y);
|
||||
max.z = std::max(max.z, index.z);
|
||||
indices.emplace_back(index);
|
||||
}
|
||||
Array3D<char> grid{max.x - min.x + 3, max.y - min.y + 3, max.z - min.z + 3};
|
||||
grid.Fill('.');
|
||||
for (auto& index : indices)
|
||||
{
|
||||
grid.Set(index.x - min.x + 1, index.y - min.y + 1, index.z - min.z + 1, '#');
|
||||
}
|
||||
|
||||
return grid;
|
||||
}
|
||||
|
||||
OUTPUT1(input)
|
||||
{
|
||||
int sum = 0;
|
||||
std::vector<Index3D> neighbors{
|
||||
Index3D{-1, 0, 0}, Index3D{1, 0, 0}, Index3D{0, -1, 0}, Index3D{0, 1, 0}, Index3D{0, 0, -1}, Index3D{0, 0, 1}};
|
||||
for (auto it = input.begin(); it != input.end(); ++it)
|
||||
{
|
||||
if (*it != '#')
|
||||
continue;
|
||||
sum += neighbors.size();
|
||||
|
||||
for (auto& neighbor : neighbors)
|
||||
{
|
||||
Index3D i = it.index + neighbor;
|
||||
if (input.IsInside(i) && input.Get(i) == '#')
|
||||
sum--;
|
||||
}
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
OUTPUT2(input)
|
||||
{
|
||||
int sum = 0;
|
||||
std::set<Index3D> visited;
|
||||
std::stack<Index3D> stack;
|
||||
stack.emplace(Index3D{0, 0, 0});
|
||||
std::vector<Index3D> neighbors{
|
||||
Index3D{-1, 0, 0}, Index3D{1, 0, 0}, Index3D{0, -1, 0}, Index3D{0, 1, 0}, Index3D{0, 0, -1}, Index3D{0, 0, 1}};
|
||||
while (!stack.empty())
|
||||
{
|
||||
Index3D index = stack.top();
|
||||
stack.pop();
|
||||
|
||||
for (auto& neighbor : neighbors)
|
||||
{
|
||||
Index3D i = index + neighbor;
|
||||
if (input.IsInside(i))
|
||||
{
|
||||
if (visited.count(i) == 0 && input.Get(i) == '.')
|
||||
{
|
||||
visited.emplace(i);
|
||||
stack.emplace(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (auto& index : visited)
|
||||
{
|
||||
for (auto& neighbor : neighbors)
|
||||
{
|
||||
Index3D i = index + neighbor;
|
||||
if (input.IsInside(i) && input.Get(i) == '#')
|
||||
{
|
||||
sum++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace y$1::day19
|
||||
{
|
||||
struct Blueprint
|
||||
{
|
||||
int oreOreCost;
|
||||
int clayOreCost;
|
||||
int obsidianOreCost;
|
||||
int obsidianClayCost;
|
||||
int geodeOreCost;
|
||||
int geodeObsidianCost;
|
||||
};
|
||||
|
||||
struct Robots
|
||||
{
|
||||
int ore = 1;
|
||||
int clay = 0;
|
||||
int obsidian = 0;
|
||||
int geode = 0;
|
||||
};
|
||||
|
||||
struct Materials
|
||||
{
|
||||
int ore = 0;
|
||||
int clay = 0;
|
||||
int obsidian = 0;
|
||||
int geode = 0;
|
||||
};
|
||||
|
||||
REGISTER_DAY(2022, Day19, std::vector<Blueprint>, int);
|
||||
|
||||
REGISTER_TEST_EXAMPLE(2022, Day19, ExampleInput, 1, 33);
|
||||
REGISTER_TEST(2022, Day19, Input, 1, 600);
|
||||
REGISTER_TEST_EXAMPLE(2022, Day19, ExampleInput, 2, 3472);
|
||||
REGISTER_TEST(2022, Day19, Input, 2, 6000);
|
||||
|
||||
READ_INPUT(input)
|
||||
{
|
||||
std::string str;
|
||||
std::vector<Blueprint> blueprints;
|
||||
while (std::getline(input, str))
|
||||
{
|
||||
std::stringstream ss{str};
|
||||
Blueprint blueprint;
|
||||
int i = 0;
|
||||
// Blueprint 1: Each ore robot costs 4 ore. Each clay robot costs 2 ore. Each obsidian robot costs 3 ore and 14
|
||||
// clay. Each geode robot costs 2 ore and 7 obsidian.
|
||||
ss >> "Blueprint" >> i >> ": Each ore robot costs" >> blueprint.oreOreCost >> "ore. Each clay robot costs" >>
|
||||
blueprint.clayOreCost >> "ore. Each obsidian robot costs" >> blueprint.obsidianOreCost >> "ore and" >>
|
||||
blueprint.obsidianClayCost >> "clay. Each geode robot costs" >> blueprint.geodeOreCost >> "ore and" >>
|
||||
blueprint.geodeObsidianCost;
|
||||
blueprints.emplace_back(blueprint);
|
||||
}
|
||||
return blueprints;
|
||||
}
|
||||
|
||||
void Mine(const Robots& robots, Materials& materials)
|
||||
{
|
||||
materials.ore += robots.ore;
|
||||
materials.clay += robots.clay;
|
||||
materials.obsidian += robots.obsidian;
|
||||
materials.geode += robots.geode;
|
||||
}
|
||||
|
||||
int Max(const Blueprint& blueprint, Robots robots, Materials materials, int timeLeft)
|
||||
{
|
||||
if (timeLeft == 0)
|
||||
return materials.geode;
|
||||
timeLeft--;
|
||||
|
||||
int max = 0;
|
||||
|
||||
int maxOresNeeded =
|
||||
std::max({blueprint.oreOreCost, blueprint.clayOreCost, blueprint.obsidianOreCost, blueprint.geodeOreCost});
|
||||
|
||||
if (materials.ore - robots.ore < blueprint.oreOreCost && materials.ore >= blueprint.oreOreCost &&
|
||||
robots.ore < maxOresNeeded)
|
||||
{
|
||||
Robots newRobots = robots;
|
||||
Materials newMaterials = materials;
|
||||
Mine(newRobots, newMaterials);
|
||||
newRobots.ore++;
|
||||
newMaterials.ore -= blueprint.oreOreCost;
|
||||
max = std::max(max, Max(blueprint, newRobots, newMaterials, timeLeft));
|
||||
}
|
||||
if (materials.ore - robots.ore < blueprint.clayOreCost && materials.ore >= blueprint.clayOreCost &&
|
||||
robots.clay < blueprint.obsidianClayCost)
|
||||
{
|
||||
Robots newRobots = robots;
|
||||
Materials newMaterials = materials;
|
||||
Mine(newRobots, newMaterials);
|
||||
newRobots.clay++;
|
||||
newMaterials.ore -= blueprint.clayOreCost;
|
||||
max = std::max(max, Max(blueprint, newRobots, newMaterials, timeLeft));
|
||||
}
|
||||
if ((materials.ore - robots.ore < blueprint.obsidianOreCost ||
|
||||
materials.clay - robots.clay < blueprint.obsidianClayCost) &&
|
||||
materials.ore >= blueprint.obsidianOreCost && materials.clay >= blueprint.obsidianClayCost &&
|
||||
robots.obsidian < blueprint.geodeObsidianCost)
|
||||
{
|
||||
Robots newRobots = robots;
|
||||
Materials newMaterials = materials;
|
||||
Mine(newRobots, newMaterials);
|
||||
newRobots.obsidian++;
|
||||
newMaterials.ore -= blueprint.obsidianOreCost;
|
||||
newMaterials.clay -= blueprint.obsidianClayCost;
|
||||
max = std::max(max, Max(blueprint, newRobots, newMaterials, timeLeft));
|
||||
}
|
||||
if ((materials.ore - robots.ore < blueprint.geodeOreCost ||
|
||||
materials.obsidian - robots.obsidian < blueprint.geodeObsidianCost) &&
|
||||
materials.ore >= blueprint.geodeOreCost && materials.obsidian >= blueprint.geodeObsidianCost)
|
||||
{
|
||||
Robots newRobots = robots;
|
||||
Materials newMaterials = materials;
|
||||
Mine(newRobots, newMaterials);
|
||||
newRobots.geode++;
|
||||
newMaterials.ore -= blueprint.geodeOreCost;
|
||||
newMaterials.obsidian -= blueprint.geodeObsidianCost;
|
||||
max = std::max(max, Max(blueprint, newRobots, newMaterials, timeLeft));
|
||||
}
|
||||
Mine(robots, materials);
|
||||
return std::max(max, Max(blueprint, robots, materials, timeLeft));
|
||||
}
|
||||
|
||||
OUTPUT1(input)
|
||||
{
|
||||
int sum = 0;
|
||||
for (int i = 0; i < input.size(); i++)
|
||||
{
|
||||
sum += (i + 1) * Max(input[i], Robots{}, Materials{}, 24);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
OUTPUT2(input)
|
||||
{
|
||||
int sum = 1;
|
||||
for (int i = 0; i < input.size() && i < 3; i++)
|
||||
{
|
||||
sum *= Max(input[i], Robots{}, Materials{}, 32);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace y$1::day20
|
||||
{
|
||||
REGISTER_DAY(2022, Day20, std::vector<int>, int64_t);
|
||||
|
||||
REGISTER_TEST_EXAMPLE(2022, Day20, ExampleInput, 1, 3);
|
||||
REGISTER_TEST(2022, Day20, Input, 1, 988);
|
||||
REGISTER_TEST_EXAMPLE(2022, Day20, ExampleInput, 2, 1623178306);
|
||||
REGISTER_TEST(2022, Day20, Input, 2, 7768531372516);
|
||||
|
||||
READ_INPUT(input)
|
||||
{
|
||||
return Input::ReadInts(input);
|
||||
}
|
||||
|
||||
OUTPUT1(input)
|
||||
{
|
||||
int sum = 0;
|
||||
std::vector<std::pair<int, int>> newList;
|
||||
for (int i = 0; i < input.size(); i++)
|
||||
{
|
||||
newList.emplace_back(input[i], i);
|
||||
}
|
||||
for (int i = 0; i < input.size(); i++)
|
||||
{
|
||||
auto it = std::find_if(newList.begin(), newList.end(), [i](auto& p) { return p.second == i; });
|
||||
int distance = std::distance(newList.begin(), it);
|
||||
if (input[i] == 0)
|
||||
continue;
|
||||
int newPos = (distance + input[i]) % ((int)input.size() - 1);
|
||||
if (newPos < 0)
|
||||
newPos += (int)newList.size() - 1;
|
||||
std::pair<int, int> p = *it;
|
||||
newList.erase(it);
|
||||
newList.insert(newList.begin() + newPos, p);
|
||||
}
|
||||
// std::sort(newList.begin(), newList.end(), [](auto& p1, auto& p2) { return p1.second < p2.second; });
|
||||
auto it = std::find_if(newList.begin(), newList.end(), [](const std::pair<int, int>& p1) { return p1.first == 0; });
|
||||
int pos = std::distance(newList.begin(), it);
|
||||
return newList[(pos + 1000) % input.size()].first + newList[(pos + 2000) % input.size()].first +
|
||||
newList[(pos + 3000) % input.size()].first;
|
||||
}
|
||||
|
||||
OUTPUT2(input)
|
||||
{
|
||||
int sum = 0;
|
||||
std::vector<std::pair<int64_t, int>> newList;
|
||||
for (int i = 0; i < input.size(); i++)
|
||||
{
|
||||
newList.emplace_back((int64_t)input[i] * (int64_t)811589153, i);
|
||||
}
|
||||
for (int j = 0; j < 10; j++)
|
||||
{
|
||||
for (int i = 0; i < input.size(); i++)
|
||||
{
|
||||
auto it = std::find_if(newList.begin(), newList.end(), [i](auto& p) { return p.second == i; });
|
||||
int oldPos = std::distance(newList.begin(), it);
|
||||
if (it->first == 0)
|
||||
continue;
|
||||
int newPos = (oldPos + it->first) % ((int64_t)input.size() - 1);
|
||||
if (newPos < 0)
|
||||
newPos += (int64_t)newList.size() - 1;
|
||||
std::pair<int64_t, int> p = *it;
|
||||
newList.erase(it);
|
||||
newList.insert(newList.begin() + newPos, p);
|
||||
}
|
||||
}
|
||||
// std::sort(newList.begin(), newList.end(), [](auto& p1, auto& p2) { return p1.second < p2.second; });
|
||||
auto it =
|
||||
std::find_if(newList.begin(), newList.end(), [](const std::pair<int64_t, int>& p1) { return p1.first == 0; });
|
||||
int pos = std::distance(newList.begin(), it);
|
||||
return newList[(pos + 1000) % input.size()].first + newList[(pos + 2000) % input.size()].first +
|
||||
newList[(pos + 3000) % input.size()].first;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace y$1::day21
|
||||
{
|
||||
enum class Operator
|
||||
{
|
||||
Add,
|
||||
Mul,
|
||||
Sub,
|
||||
Div
|
||||
|
||||
};
|
||||
|
||||
struct Operation
|
||||
{
|
||||
std::string lhs;
|
||||
std::string rhs;
|
||||
Operator op;
|
||||
};
|
||||
|
||||
struct Monkey
|
||||
{
|
||||
std::string name;
|
||||
std::variant<int64_t, Operation> yell;
|
||||
|
||||
bool operator<(const Monkey& rhs) const
|
||||
{
|
||||
return name < rhs.name;
|
||||
}
|
||||
};
|
||||
|
||||
REGISTER_DAY(2022, Day21, std::set<Monkey>, int64_t);
|
||||
|
||||
REGISTER_TEST_EXAMPLE(2022, Day21, ExampleInput, 1, 152);
|
||||
REGISTER_TEST(2022, Day21, Input, 1, 160274622817992);
|
||||
REGISTER_TEST_EXAMPLE(2022, Day21, ExampleInput, 2, 301);
|
||||
REGISTER_TEST(2022, Day21, Input, 2, 3087390115721);
|
||||
|
||||
READ_INPUT(input)
|
||||
{
|
||||
std::string str;
|
||||
std::set<Monkey> monkeys;
|
||||
while (std::getline(input, str))
|
||||
{
|
||||
std::stringstream ss{str};
|
||||
Monkey monkey;
|
||||
ss >> monkey.name;
|
||||
monkey.name.pop_back(); // remove :
|
||||
|
||||
if (str[6] >= '0' && str[6] <= '9')
|
||||
{
|
||||
int64_t i;
|
||||
ss >> i;
|
||||
monkey.yell = i;
|
||||
}
|
||||
else
|
||||
{
|
||||
Operation operation;
|
||||
char c;
|
||||
ss >> operation.lhs;
|
||||
ss >> c;
|
||||
ss >> operation.rhs;
|
||||
if (c == '+')
|
||||
operation.op = Operator::Add;
|
||||
if (c == '-')
|
||||
operation.op = Operator::Sub;
|
||||
if (c == '*')
|
||||
operation.op = Operator::Mul;
|
||||
if (c == '/')
|
||||
operation.op = Operator::Div;
|
||||
monkey.yell = operation;
|
||||
}
|
||||
monkeys.emplace(monkey);
|
||||
}
|
||||
return monkeys;
|
||||
}
|
||||
|
||||
int64_t Resolve(const std::set<Monkey>& monkeys, const std::string& name)
|
||||
{
|
||||
Monkey findMonkey;
|
||||
findMonkey.name = name;
|
||||
const Monkey& monkey = *monkeys.find(findMonkey);
|
||||
if (std::holds_alternative<int64_t>(monkey.yell))
|
||||
return std::get<int64_t>(monkey.yell);
|
||||
|
||||
const Operation& operation = std::get<Operation>(monkey.yell);
|
||||
switch (operation.op)
|
||||
{
|
||||
case Operator::Add:
|
||||
return Resolve(monkeys, operation.lhs) + Resolve(monkeys, operation.rhs);
|
||||
case Operator::Sub:
|
||||
return Resolve(monkeys, operation.lhs) - Resolve(monkeys, operation.rhs);
|
||||
case Operator::Mul:
|
||||
return Resolve(monkeys, operation.lhs) * Resolve(monkeys, operation.rhs);
|
||||
case Operator::Div:
|
||||
return Resolve(monkeys, operation.lhs) / Resolve(monkeys, operation.rhs);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool HasHuman(const std::set<Monkey>& monkeys, const std::string& name)
|
||||
{
|
||||
if (name == "humn")
|
||||
return true;
|
||||
|
||||
Monkey findMonkey;
|
||||
findMonkey.name = name;
|
||||
const Monkey& monkey = *monkeys.find(findMonkey);
|
||||
if (std::holds_alternative<Operation>(monkey.yell))
|
||||
{
|
||||
return HasHuman(monkeys, std::get<Operation>(monkey.yell).lhs) ||
|
||||
HasHuman(monkeys, std::get<Operation>(monkey.yell).rhs);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int64_t Resolve(const std::set<Monkey>& monkeys, const std::string& name, int64_t result)
|
||||
{
|
||||
if (name == "humn")
|
||||
return result;
|
||||
|
||||
Monkey findMonkey;
|
||||
findMonkey.name = name;
|
||||
const Monkey& monkey = *monkeys.find(findMonkey);
|
||||
if (std::holds_alternative<int64_t>(monkey.yell))
|
||||
return std::get<int64_t>(monkey.yell);
|
||||
|
||||
const Operation& operation = std::get<Operation>(monkey.yell);
|
||||
if (name == "root")
|
||||
{
|
||||
if (HasHuman(monkeys, operation.lhs))
|
||||
{
|
||||
return Resolve(monkeys, operation.lhs, Resolve(monkeys, operation.rhs));
|
||||
}
|
||||
else
|
||||
{
|
||||
return Resolve(monkeys, operation.rhs, Resolve(monkeys, operation.lhs));
|
||||
}
|
||||
}
|
||||
|
||||
if (HasHuman(monkeys, operation.lhs))
|
||||
{
|
||||
int64_t rhs = Resolve(monkeys, operation.rhs);
|
||||
switch (operation.op)
|
||||
{
|
||||
case Operator::Add:
|
||||
return Resolve(monkeys, operation.lhs, result - rhs); // lhs + rhs = result => lhs = result - rhs
|
||||
case Operator::Sub:
|
||||
return Resolve(monkeys, operation.lhs, result + rhs); // lhs - rhs = result => lhs = result + rhs
|
||||
case Operator::Mul:
|
||||
return Resolve(monkeys, operation.lhs, result / rhs); // lhs * rhs = result => lhs = result / rhs
|
||||
case Operator::Div:
|
||||
return Resolve(monkeys, operation.lhs, result * rhs); // lhs / rhs = result => lhs = result * rhs
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int64_t lhs = Resolve(monkeys, operation.lhs);
|
||||
switch (operation.op)
|
||||
{
|
||||
case Operator::Add:
|
||||
return Resolve(monkeys, operation.rhs, result - lhs); // lhs + rhs = result => rhs = result - lhs
|
||||
case Operator::Sub:
|
||||
return Resolve(monkeys, operation.rhs, lhs - result); // lhs - rhs = result => rhs = lhs - result
|
||||
case Operator::Mul:
|
||||
return Resolve(monkeys, operation.rhs, result / lhs); // lhs * rhs = result => result / lhs
|
||||
case Operator::Div:
|
||||
return Resolve(monkeys, operation.rhs, lhs * result); // lhs / rhs = result => lhs / result
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
OUTPUT1(input)
|
||||
{
|
||||
return Resolve(input, "root");
|
||||
}
|
||||
|
||||
OUTPUT2(input)
|
||||
{
|
||||
return Resolve(input, "root", 0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,284 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace y$1::day22
|
||||
{
|
||||
|
||||
struct Input
|
||||
{
|
||||
Array2D<char> grid;
|
||||
std::string directions;
|
||||
};
|
||||
|
||||
bool Between(int x, int bound1, int bound2)
|
||||
{
|
||||
if (bound1 < bound2)
|
||||
return x >= bound1 && x <= bound2;
|
||||
else
|
||||
return x <= bound1 && x >= bound2;
|
||||
}
|
||||
|
||||
REGISTER_DAY(2022, Day22, Input, int);
|
||||
|
||||
REGISTER_TEST_EXAMPLE(2022, Day22, ExampleInput, 1, 6032);
|
||||
REGISTER_TEST(2022, Day22, Input, 1, 89224);
|
||||
REGISTER_TEST(2022, Day22, Input, 2, 136182);
|
||||
|
||||
struct State
|
||||
{
|
||||
Index2D pos;
|
||||
Index2D facing;
|
||||
};
|
||||
|
||||
struct Edge
|
||||
{
|
||||
Index2D from1;
|
||||
Index2D to1;
|
||||
Index2D facing1;
|
||||
Index2D from2;
|
||||
Index2D to2;
|
||||
Index2D facing2;
|
||||
|
||||
Edge(Index2D from1, Index2D to1, Index2D facing1, Index2D from2, Index2D to2, Index2D facing2)
|
||||
: from1{from1},
|
||||
to1{to1},
|
||||
facing1{facing1},
|
||||
from2{from2},
|
||||
to2{to2},
|
||||
facing2{facing2}
|
||||
{
|
||||
}
|
||||
|
||||
void CalcTransition(Index2D& pos, Index2D& facing)
|
||||
{
|
||||
if (facing == facing1 && Between(pos.x, from1.x, to1.x) && Between(pos.y, from1.y, to1.y))
|
||||
{
|
||||
facing.x = -facing2.x;
|
||||
facing.y = -facing2.y;
|
||||
Index2D diff1 = pos - from1;
|
||||
int offset = std::max(std::abs(diff1.x), std::abs(diff1.y));
|
||||
Index2D diff2 = to2 - from2;
|
||||
diff2.x = Helper::Sign(diff2.x);
|
||||
diff2.y = Helper::Sign(diff2.y);
|
||||
pos.x = from2.x + offset * diff2.x;
|
||||
pos.y = from2.y + offset * diff2.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
facing.x = -facing1.x;
|
||||
facing.y = -facing1.y;
|
||||
Index2D diff2 = pos - from2;
|
||||
int offset = std::max(std::abs(diff2.x), std::abs(diff2.y));
|
||||
Index2D diff1 = to1 - from1;
|
||||
diff1.x = Helper::Sign(diff1.x);
|
||||
diff1.y = Helper::Sign(diff1.y);
|
||||
pos.x = from1.x + offset * diff1.x;
|
||||
pos.y = from1.y + offset * diff1.y;
|
||||
}
|
||||
}
|
||||
|
||||
bool operator==(const State& state) const
|
||||
{
|
||||
return (state.facing == facing1 && Between(state.pos.x, from1.x, to1.x) &&
|
||||
Between(state.pos.y, from1.y, to1.y)) ||
|
||||
(state.facing == facing2 && Between(state.pos.x, from2.x, to2.x) && Between(state.pos.y, from2.y, to2.y));
|
||||
}
|
||||
};
|
||||
|
||||
READ_INPUT(input)
|
||||
{
|
||||
Input in;
|
||||
std::string str;
|
||||
int max = 0;
|
||||
std::vector<std::string> vector;
|
||||
while (std::getline(input, str))
|
||||
{
|
||||
if (str.empty())
|
||||
break;
|
||||
vector.emplace_back(str);
|
||||
max = std::max(max, (int)str.size());
|
||||
}
|
||||
|
||||
in.grid = Array2D<char>{max, (int)vector.size()};
|
||||
in.grid.Fill(' ');
|
||||
for (int i = 0; i < vector.size(); i++)
|
||||
{
|
||||
for (int j = 0; j < vector[i].size(); j++)
|
||||
{
|
||||
in.grid.Set(j, i, vector[i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
std::getline(input, in.directions);
|
||||
return in;
|
||||
}
|
||||
|
||||
OUTPUT1(input)
|
||||
{
|
||||
State state;
|
||||
state.facing = Index2D{1, 0};
|
||||
|
||||
for (int i = 0; i < input.grid.width; i++)
|
||||
{
|
||||
if (input.grid.Get(i, 0) != ' ')
|
||||
{
|
||||
state.pos = {i, 0};
|
||||
break;
|
||||
}
|
||||
}
|
||||
int i = 0;
|
||||
while (i < input.directions.size())
|
||||
{
|
||||
if (input.directions[i] >= '0' && input.directions[i] <= '9')
|
||||
{
|
||||
int amount = std::stoi(&input.directions[i]);
|
||||
while (input.directions[i] >= '0' && input.directions[i] <= '9') i++;
|
||||
|
||||
for (int j = 0; j < amount; j++)
|
||||
{
|
||||
Index2D oldPos = state.pos;
|
||||
state.pos = state.pos + state.facing;
|
||||
if (input.grid.GetMod(state.pos.x, state.pos.y) == '#')
|
||||
{
|
||||
state.pos = oldPos;
|
||||
break;
|
||||
}
|
||||
else if (input.grid.GetMod(state.pos.x, state.pos.y) == ' ')
|
||||
{
|
||||
while (input.grid.GetMod(state.pos.x, state.pos.y) == ' ')
|
||||
{
|
||||
state.pos = state.pos + state.facing;
|
||||
}
|
||||
if (input.grid.GetMod(state.pos.x, state.pos.y) == '#')
|
||||
{
|
||||
state.pos = oldPos;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
state.pos.x = ((state.pos.x % input.grid.width) + input.grid.width) % input.grid.width;
|
||||
state.pos.y = ((state.pos.y % input.grid.height) + input.grid.height) % input.grid.height;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (input.directions[i] == 'R')
|
||||
{
|
||||
int tmp = state.facing.x;
|
||||
state.facing.x = -state.facing.y;
|
||||
state.facing.y = tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
int tmp = state.facing.x;
|
||||
state.facing.x = state.facing.y;
|
||||
state.facing.y = -tmp;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
int face = 0;
|
||||
if (state.facing == Index2D{0, 1})
|
||||
face = 1;
|
||||
if (state.facing == Index2D{-1, 0})
|
||||
face = 2;
|
||||
if (state.facing == Index2D{0, -1})
|
||||
face = 3;
|
||||
return (state.pos.y + 1) * 1000 + 4 * (state.pos.x + 1) + face;
|
||||
}
|
||||
|
||||
OUTPUT2(input)
|
||||
{
|
||||
State state;
|
||||
state.facing = Index2D{1, 0};
|
||||
std::vector<Edge> edges;
|
||||
edges.emplace_back(
|
||||
Index2D{50, 50}, Index2D{50, 99}, Index2D{-1, 0}, Index2D{0, 100}, Index2D{49, 100}, Index2D{0, -1});
|
||||
edges.emplace_back(
|
||||
Index2D{50, 0}, Index2D{50, 49}, Index2D{-1, 0}, Index2D{0, 149}, Index2D{0, 100}, Index2D{-1, 0});
|
||||
edges.emplace_back(
|
||||
Index2D{100, 49}, Index2D{149, 49}, Index2D{0, 1}, Index2D{99, 50}, Index2D{99, 99}, Index2D{1, 0});
|
||||
edges.emplace_back(
|
||||
Index2D{50, 149}, Index2D{99, 149}, Index2D{0, 1}, Index2D{49, 150}, Index2D{49, 199}, Index2D{1, 0});
|
||||
edges.emplace_back(
|
||||
Index2D{50, 0}, Index2D{99, 0}, Index2D{0, -1}, Index2D{0, 150}, Index2D{0, 199}, Index2D{-1, 0});
|
||||
edges.emplace_back(
|
||||
Index2D{99, 100}, Index2D{99, 149}, Index2D{1, 0}, Index2D{149, 49}, Index2D{149, 0}, Index2D{1, 0});
|
||||
edges.emplace_back(
|
||||
Index2D{100, 0}, Index2D{149, 0}, Index2D{0, -1}, Index2D{0, 199}, Index2D{49, 199}, Index2D{0, 1});
|
||||
|
||||
for (int i = 0; i < input.grid.width; i++)
|
||||
{
|
||||
if (input.grid.Get(i, 0) != ' ')
|
||||
{
|
||||
state.pos = {i, 0};
|
||||
break;
|
||||
}
|
||||
}
|
||||
int i = 0;
|
||||
while (i < input.directions.size())
|
||||
{
|
||||
if (input.directions[i] >= '0' && input.directions[i] <= '9')
|
||||
{
|
||||
int amount = std::stoi(&input.directions[i]);
|
||||
while (input.directions[i] >= '0' && input.directions[i] <= '9') i++;
|
||||
|
||||
for (int j = 0; j < amount; j++)
|
||||
{
|
||||
Index2D oldPos = state.pos;
|
||||
Index2D oldFacing = state.facing;
|
||||
state.pos = state.pos + state.facing;
|
||||
state.pos.x = ((state.pos.x % input.grid.width) + input.grid.width) % input.grid.width;
|
||||
state.pos.y = ((state.pos.y % input.grid.height) + input.grid.height) % input.grid.height;
|
||||
if (input.grid.Get(state.pos.x, state.pos.y) == '#')
|
||||
{
|
||||
state.pos = oldPos;
|
||||
break;
|
||||
}
|
||||
else if (input.grid.Get(state.pos.x, state.pos.y) == ' ')
|
||||
{
|
||||
state.pos = oldPos;
|
||||
auto it = std::find(edges.begin(), edges.end(), state);
|
||||
if (it != edges.end())
|
||||
{
|
||||
it->CalcTransition(state.pos, state.facing);
|
||||
if (input.grid.Get(state.pos.x, state.pos.y) == '#')
|
||||
{
|
||||
state.pos = oldPos;
|
||||
state.facing = oldFacing;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Not found: state.pos: " << state.pos << " state.facing: " << state.facing << std::endl;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (input.directions[i] == 'R')
|
||||
{
|
||||
int tmp = state.facing.x;
|
||||
state.facing.x = -state.facing.y;
|
||||
state.facing.y = tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
int tmp = state.facing.x;
|
||||
state.facing.x = state.facing.y;
|
||||
state.facing.y = -tmp;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
int face = 0;
|
||||
if (state.facing == Index2D{0, 1})
|
||||
face = 1;
|
||||
if (state.facing == Index2D{-1, 0})
|
||||
face = 2;
|
||||
if (state.facing == Index2D{0, -1})
|
||||
face = 3;
|
||||
return (state.pos.y + 1) * 1000 + 4 * (state.pos.x + 1) + face;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,263 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace y$1::day23
|
||||
{
|
||||
REGISTER_DAY(2022, Day23, Array2D<char>, int);
|
||||
|
||||
REGISTER_TEST_EXAMPLE(2022, Day23, ExampleInput, 1, 110);
|
||||
REGISTER_TEST(2022, Day23, Input, 1, 4254);
|
||||
REGISTER_TEST_EXAMPLE(2022, Day23, ExampleInput, 2, 20);
|
||||
REGISTER_TEST(2022, Day23, Input, 2, 992);
|
||||
|
||||
READ_INPUT(input)
|
||||
{
|
||||
return Input::ReadArray2D(input);
|
||||
}
|
||||
|
||||
void Reset(Array2D<char>& grid, const Index2D& pos)
|
||||
{
|
||||
char c = grid.Get(pos);
|
||||
if (c == '1')
|
||||
grid.Set(pos.x, pos.y + 1, '0');
|
||||
if (c == '2')
|
||||
grid.Set(pos.x, pos.y - 1, '0');
|
||||
if (c == '3')
|
||||
grid.Set(pos.x + 1, pos.y, '0');
|
||||
if (c == '4')
|
||||
grid.Set(pos.x - 1, pos.y, '0');
|
||||
grid.Set(pos.x, pos.y, '.');
|
||||
}
|
||||
|
||||
OUTPUT1(input)
|
||||
{
|
||||
Array2D<char> grid{input.width * 3, input.height * 3};
|
||||
Array2D<char> moves{input.width * 3, input.height * 3};
|
||||
grid.Fill('.');
|
||||
moves.Fill('.');
|
||||
for (auto it = input.begin(); it != input.end(); ++it)
|
||||
{
|
||||
grid.Set(input.width + it.index.x, input.height + it.index.y, *it);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
for (auto it = grid.begin(); it != grid.end(); ++it)
|
||||
{
|
||||
if (*it != '#')
|
||||
continue;
|
||||
|
||||
if (grid.GetNeighbors('#', it.index.x, it.index.y) == 0)
|
||||
{
|
||||
moves.Set(it.index.x, it.index.y, '0');
|
||||
}
|
||||
else
|
||||
{
|
||||
int up = 0;
|
||||
if (grid.Get(it.index.x, it.index.y - 1) == '#')
|
||||
up++;
|
||||
if (grid.Get(it.index.x - 1, it.index.y - 1) == '#')
|
||||
up++;
|
||||
if (grid.Get(it.index.x + 1, it.index.y - 1) == '#')
|
||||
up++;
|
||||
int down = 0;
|
||||
if (grid.Get(it.index.x, it.index.y + 1) == '#')
|
||||
down++;
|
||||
if (grid.Get(it.index.x - 1, it.index.y + 1) == '#')
|
||||
down++;
|
||||
if (grid.Get(it.index.x + 1, it.index.y + 1) == '#')
|
||||
down++;
|
||||
int left = 0;
|
||||
if (grid.Get(it.index.x - 1, it.index.y) == '#')
|
||||
left++;
|
||||
if (grid.Get(it.index.x - 1, it.index.y - 1) == '#')
|
||||
left++;
|
||||
if (grid.Get(it.index.x - 1, it.index.y + 1) == '#')
|
||||
left++;
|
||||
int right = 0;
|
||||
if (grid.Get(it.index.x + 1, it.index.y) == '#')
|
||||
right++;
|
||||
if (grid.Get(it.index.x + 1, it.index.y - 1) == '#')
|
||||
right++;
|
||||
if (grid.Get(it.index.x + 1, it.index.y + 1) == '#')
|
||||
right++;
|
||||
|
||||
std::vector<int> neighs{up, down, left, right};
|
||||
std::vector<Index2D> dirs{Index2D{it.index.x, it.index.y - 1},
|
||||
Index2D{it.index.x, it.index.y + 1},
|
||||
Index2D{it.index.x - 1, it.index.y},
|
||||
Index2D{it.index.x + 1, it.index.y}};
|
||||
std::vector<char> val{'1', '2', '3', '4'};
|
||||
|
||||
bool set = false;
|
||||
for (int j = 0; j < 4; j++)
|
||||
{
|
||||
if (neighs[(i + j) % 4] == 0)
|
||||
{
|
||||
Index2D index = dirs[(i + j) % 4];
|
||||
char c = moves.Get(index);
|
||||
if (c != '.')
|
||||
{
|
||||
moves.Set(it.index.x, it.index.y, '0');
|
||||
Reset(moves, index);
|
||||
}
|
||||
else
|
||||
{
|
||||
moves.Set(index.x, index.y, val[(i + j) % 4]);
|
||||
}
|
||||
set = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!set)
|
||||
{
|
||||
moves.Set(it.index.x, it.index.y, '0');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
grid.Fill('.');
|
||||
for (auto it = moves.begin(); it != moves.end(); ++it)
|
||||
{
|
||||
if (*it != '.')
|
||||
{
|
||||
grid.Set(it.index.x, it.index.y, '#');
|
||||
}
|
||||
}
|
||||
moves.Fill('.');
|
||||
}
|
||||
|
||||
Index2D min{grid.width, grid.height};
|
||||
Index2D max{0, 0};
|
||||
for (auto it = grid.begin(); it != grid.end(); ++it)
|
||||
{
|
||||
if (*it == '#')
|
||||
{
|
||||
min.x = std::min(min.x, it.index.x);
|
||||
min.y = std::min(min.y, it.index.y);
|
||||
max.x = std::max(max.x, it.index.x);
|
||||
max.y = std::max(max.y, it.index.y);
|
||||
}
|
||||
}
|
||||
|
||||
return (max.x - min.x + 1) * (max.y - min.y + 1) - grid.Count('#');
|
||||
}
|
||||
|
||||
OUTPUT2(input)
|
||||
{
|
||||
Array2D<char> grid{input.width * 3, input.height * 3};
|
||||
Array2D<char> moves{input.width * 3, input.height * 3};
|
||||
grid.Fill('.');
|
||||
moves.Fill('.');
|
||||
for (auto it = input.begin(); it != input.end(); ++it)
|
||||
{
|
||||
grid.Set(input.width + it.index.x, input.height + it.index.y, *it);
|
||||
}
|
||||
|
||||
bool moved = true;
|
||||
int i = 0;
|
||||
while (moved)
|
||||
{
|
||||
for (auto it = grid.begin(); it != grid.end(); ++it)
|
||||
{
|
||||
if (*it != '#')
|
||||
continue;
|
||||
|
||||
if (grid.GetNeighbors('#', it.index.x, it.index.y) == 0)
|
||||
{
|
||||
moves.Set(it.index.x, it.index.y, '0');
|
||||
}
|
||||
else
|
||||
{
|
||||
int up = 0;
|
||||
if (grid.Get(it.index.x, it.index.y - 1) == '#')
|
||||
up++;
|
||||
if (grid.Get(it.index.x - 1, it.index.y - 1) == '#')
|
||||
up++;
|
||||
if (grid.Get(it.index.x + 1, it.index.y - 1) == '#')
|
||||
up++;
|
||||
int down = 0;
|
||||
if (grid.Get(it.index.x, it.index.y + 1) == '#')
|
||||
down++;
|
||||
if (grid.Get(it.index.x - 1, it.index.y + 1) == '#')
|
||||
down++;
|
||||
if (grid.Get(it.index.x + 1, it.index.y + 1) == '#')
|
||||
down++;
|
||||
int left = 0;
|
||||
if (grid.Get(it.index.x - 1, it.index.y) == '#')
|
||||
left++;
|
||||
if (grid.Get(it.index.x - 1, it.index.y - 1) == '#')
|
||||
left++;
|
||||
if (grid.Get(it.index.x - 1, it.index.y + 1) == '#')
|
||||
left++;
|
||||
int right = 0;
|
||||
if (grid.Get(it.index.x + 1, it.index.y) == '#')
|
||||
right++;
|
||||
if (grid.Get(it.index.x + 1, it.index.y - 1) == '#')
|
||||
right++;
|
||||
if (grid.Get(it.index.x + 1, it.index.y + 1) == '#')
|
||||
right++;
|
||||
|
||||
std::vector<int> neighs{up, down, left, right};
|
||||
std::vector<Index2D> dirs{Index2D{it.index.x, it.index.y - 1},
|
||||
Index2D{it.index.x, it.index.y + 1},
|
||||
Index2D{it.index.x - 1, it.index.y},
|
||||
Index2D{it.index.x + 1, it.index.y}};
|
||||
std::vector<char> val{'1', '2', '3', '4'};
|
||||
|
||||
bool set = false;
|
||||
for (int j = 0; j < 4; j++)
|
||||
{
|
||||
if (neighs[(i + j) % 4] == 0)
|
||||
{
|
||||
Index2D index = dirs[(i + j) % 4];
|
||||
char c = moves.Get(index);
|
||||
if (c != '.')
|
||||
{
|
||||
moves.Set(it.index.x, it.index.y, '0');
|
||||
Reset(moves, index);
|
||||
}
|
||||
else
|
||||
{
|
||||
moves.Set(index.x, index.y, val[(i + j) % 4]);
|
||||
}
|
||||
set = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!set)
|
||||
{
|
||||
moves.Set(it.index.x, it.index.y, '0');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
grid.Fill('.');
|
||||
moved = false;
|
||||
for (auto it = moves.begin(); it != moves.end(); ++it)
|
||||
{
|
||||
if (*it != '.')
|
||||
{
|
||||
grid.Set(it.index.x, it.index.y, '#');
|
||||
if (*it != '0')
|
||||
moved = true;
|
||||
}
|
||||
}
|
||||
moves.Fill('.');
|
||||
i++;
|
||||
}
|
||||
|
||||
Index2D min{grid.width, grid.height};
|
||||
Index2D max{0, 0};
|
||||
for (auto it = grid.begin(); it != grid.end(); ++it)
|
||||
{
|
||||
if (*it == '#')
|
||||
{
|
||||
min.x = std::min(min.x, it.index.x);
|
||||
min.y = std::min(min.y, it.index.y);
|
||||
max.x = std::max(max.x, it.index.x);
|
||||
max.y = std::max(max.y, it.index.y);
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace y$1::day24
|
||||
{
|
||||
struct World
|
||||
{
|
||||
const Array2D<char> world;
|
||||
Array2D<char> up;
|
||||
Array2D<char> down;
|
||||
Array2D<char> left;
|
||||
Array2D<char> right;
|
||||
|
||||
World(const Array2D<char>& world)
|
||||
: world{world}
|
||||
{
|
||||
up = Array2D<char>{world.width, world.height};
|
||||
down = Array2D<char>{world.width, world.height};
|
||||
left = Array2D<char>{world.width, world.height};
|
||||
right = Array2D<char>{world.width, world.height};
|
||||
up.Fill('.');
|
||||
down.Fill('.');
|
||||
right.Fill('.');
|
||||
left.Fill('.');
|
||||
for (auto it = world.begin(); it != world.end(); ++it)
|
||||
{
|
||||
if (*it == '^')
|
||||
up.Set(it.index.x, it.index.y, '^');
|
||||
if (*it == 'v')
|
||||
down.Set(it.index.x, it.index.y, 'v');
|
||||
if (*it == '>')
|
||||
right.Set(it.index.x, it.index.y, '>');
|
||||
if (*it == '<')
|
||||
left.Set(it.index.x, it.index.y, '<');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct State
|
||||
{
|
||||
Index2D pos;
|
||||
int depth;
|
||||
int vert;
|
||||
int hor;
|
||||
|
||||
bool operator<(const State& rhs) const
|
||||
{
|
||||
if (pos != rhs.pos)
|
||||
return pos < rhs.pos;
|
||||
if (vert != rhs.vert)
|
||||
return vert < rhs.vert;
|
||||
return hor < rhs.hor;
|
||||
}
|
||||
};
|
||||
|
||||
REGISTER_DAY(2022, Day24, World, int);
|
||||
|
||||
REGISTER_TEST_EXAMPLE(2022, Day24, ExampleInput, 1, 18);
|
||||
REGISTER_TEST(2022, Day24, Input, 1, 299);
|
||||
REGISTER_TEST_EXAMPLE(2022, Day24, ExampleInput, 2, 54);
|
||||
REGISTER_TEST(2022, Day24, Input, 2, 899);
|
||||
|
||||
READ_INPUT(input)
|
||||
{
|
||||
return World{Input::ReadArray2D(input)};
|
||||
}
|
||||
|
||||
void Step(World& world)
|
||||
{
|
||||
Array2D<char> upCpy = world.up;
|
||||
world.up.Fill('.');
|
||||
for (auto it = upCpy.begin(); it != upCpy.end(); ++it)
|
||||
{
|
||||
if (*it == '^')
|
||||
{
|
||||
int y = it.index.y - 1;
|
||||
if (y == 0)
|
||||
world.up.Set(it.index.x, world.up.height - 2, '^');
|
||||
else
|
||||
world.up.Set(it.index.x, it.index.y - 1, '^');
|
||||
}
|
||||
}
|
||||
|
||||
Array2D<char> downCpy = world.down;
|
||||
world.down.Fill('.');
|
||||
for (auto it = downCpy.begin(); it != downCpy.end(); ++it)
|
||||
{
|
||||
if (*it == 'v')
|
||||
{
|
||||
int y = it.index.y + 1;
|
||||
if (y == world.down.height - 1)
|
||||
world.down.Set(it.index.x, 1, 'v');
|
||||
else
|
||||
world.down.Set(it.index.x, it.index.y + 1, 'v');
|
||||
}
|
||||
}
|
||||
|
||||
Array2D<char> rightCpy = world.right;
|
||||
world.right.Fill('.');
|
||||
for (auto it = rightCpy.begin(); it != rightCpy.end(); ++it)
|
||||
{
|
||||
if (*it == '>')
|
||||
{
|
||||
int x = it.index.x + 1;
|
||||
if (x == world.right.width - 1)
|
||||
world.right.Set(1, it.index.y, '>');
|
||||
else
|
||||
world.right.Set(it.index.x + 1, it.index.y, '>');
|
||||
}
|
||||
}
|
||||
|
||||
Array2D<char> leftCpy = world.left;
|
||||
world.left.Fill('.');
|
||||
for (auto it = leftCpy.begin(); it != leftCpy.end(); ++it)
|
||||
{
|
||||
if (*it == '<')
|
||||
{
|
||||
int x = it.index.x - 1;
|
||||
if (x == 0)
|
||||
world.left.Set(world.left.width - 2, it.index.y, '<');
|
||||
else
|
||||
world.left.Set(it.index.x - 1, it.index.y, '<');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int PathFind(World& world, const Index2D& from, const Index2D& to)
|
||||
{
|
||||
std::set<State> visited;
|
||||
int lastDepth = -1;
|
||||
std::queue<State> queue;
|
||||
State initialState;
|
||||
initialState.pos = from;
|
||||
initialState.depth = 0;
|
||||
initialState.vert = 0;
|
||||
initialState.hor = 0;
|
||||
queue.emplace(initialState);
|
||||
visited.emplace(initialState);
|
||||
while (!queue.empty())
|
||||
{
|
||||
State state = queue.front();
|
||||
queue.pop();
|
||||
if (state.pos == to)
|
||||
{
|
||||
return state.depth;
|
||||
}
|
||||
if (lastDepth != state.depth)
|
||||
{
|
||||
Step(world);
|
||||
lastDepth = state.depth;
|
||||
}
|
||||
|
||||
std::vector<Index2D> moves{Index2D{0, 0}, Index2D{1, 0}, Index2D{-1, 0}, Index2D{0, 1}, Index2D{0, -1}};
|
||||
for (auto& move : moves)
|
||||
{
|
||||
Index2D newPos = state.pos + move;
|
||||
if (!world.world.IsInside(newPos))
|
||||
continue;
|
||||
if (world.world.Get(newPos) == '#')
|
||||
continue;
|
||||
if (world.up.Get(newPos) == '^')
|
||||
continue;
|
||||
if (world.down.Get(newPos) == 'v')
|
||||
continue;
|
||||
if (world.left.Get(newPos) == '<')
|
||||
continue;
|
||||
if (world.right.Get(newPos) == '>')
|
||||
continue;
|
||||
State newState;
|
||||
newState.pos = newPos;
|
||||
newState.depth = state.depth + 1;
|
||||
newState.vert = state.vert + 1;
|
||||
newState.hor = state.hor + 1;
|
||||
if (newState.vert == world.world.height - 2)
|
||||
newState.vert = 0;
|
||||
if (newState.hor == world.world.width - 2)
|
||||
newState.hor = 0;
|
||||
if (visited.count(newState) > 0)
|
||||
continue;
|
||||
visited.emplace(newState);
|
||||
queue.emplace(newState);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
OUTPUT1(input)
|
||||
{
|
||||
World world = input;
|
||||
return PathFind(world, Index2D{1, 0}, Index2D{world.world.width - 2, world.world.height - 1});
|
||||
}
|
||||
|
||||
OUTPUT2(input)
|
||||
{
|
||||
World world = input;
|
||||
int path1 = PathFind(world, Index2D{1, 0}, Index2D{world.world.width - 2, world.world.height - 1});
|
||||
int path2 = PathFind(world, Index2D{world.world.width - 2, world.world.height - 1}, Index2D{1, 0});
|
||||
int path3 = PathFind(world, Index2D{1, 0}, Index2D{world.world.width - 2, world.world.height - 1});
|
||||
|
||||
return path1 + path2 + path3 + 2;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace y$1::day25
|
||||
{
|
||||
int64_t Pow(int64_t number, int64_t pow)
|
||||
{
|
||||
int64_t result = number;
|
||||
for (int i = 0; i < pow; i++)
|
||||
{
|
||||
result *= number;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int64_t ConvertToBase10(const std::string& string)
|
||||
{
|
||||
int64_t total = 0;
|
||||
for (int i = 0; i < string.size(); i++)
|
||||
{
|
||||
total *= 5;
|
||||
if (string[i] == '1')
|
||||
total += 1;
|
||||
else if (string[i] == '2')
|
||||
total += 2;
|
||||
else if (string[i] == '-')
|
||||
total += -1;
|
||||
else if (string[i] == '=')
|
||||
total += -2;
|
||||
else if (string[i] == '0')
|
||||
total += 0;
|
||||
else
|
||||
std::cout << "Invalid character in " << string << std::endl;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
std::string ConvertToBase5(int64_t base10)
|
||||
{
|
||||
// Convert to base 5
|
||||
std::string base5 = "";
|
||||
int64_t numbers = log(base10) / log(5) + 1;
|
||||
for (int i = 0; i < numbers + 1; i++) base5.push_back('0');
|
||||
int64_t base5Max = Pow(5, numbers - 2);
|
||||
|
||||
for (int i = 1; i < base5.size(); i++)
|
||||
{
|
||||
int64_t val = base10 / base5Max;
|
||||
base5[i] = val + '0';
|
||||
base10 -= val * base5Max;
|
||||
base5Max /= 5;
|
||||
}
|
||||
return base5;
|
||||
}
|
||||
|
||||
std::string ConvertToSNAFU(const std::string& base5)
|
||||
{
|
||||
std::string snafu = base5;
|
||||
for (int i = snafu.size() - 1; i > 0; i--)
|
||||
{
|
||||
if (snafu[i] == '3')
|
||||
{
|
||||
snafu[i] = '=';
|
||||
snafu[i - 1] += 1;
|
||||
}
|
||||
else if (snafu[i] == '4')
|
||||
{
|
||||
snafu[i] = '-';
|
||||
snafu[i - 1] += 1;
|
||||
}
|
||||
else if (snafu[i] == '5')
|
||||
{
|
||||
snafu[i] = '0';
|
||||
snafu[i - 1] += 1;
|
||||
}
|
||||
}
|
||||
if (snafu[0] == '0')
|
||||
return snafu.substr(1);
|
||||
return snafu;
|
||||
}
|
||||
|
||||
REGISTER_DAY(2022, Day25, std::vector<std::string>, std::string);
|
||||
|
||||
REGISTER_TEST_EXAMPLE(2022, Day25, ExampleInput, 1, "2=-1=0");
|
||||
REGISTER_TEST(2022, Day25, Input, 1, "2=12-100--1012-0=012");
|
||||
REGISTER_TEST(2022, Day25, Input, 2, "");
|
||||
|
||||
READ_INPUT(input)
|
||||
{
|
||||
return Input::ReadLines(input);
|
||||
}
|
||||
|
||||
OUTPUT1(input)
|
||||
{
|
||||
int64_t base10 = 0;
|
||||
for (auto& line : input)
|
||||
{
|
||||
base10 += ConvertToBase10(line);
|
||||
}
|
||||
|
||||
std::string base5 = ConvertToBase5(base10);
|
||||
return ConvertToSNAFU(base5);
|
||||
}
|
||||
|
||||
OUTPUT2(input)
|
||||
{
|
||||
std::cout << " ___ ___" << std::endl;
|
||||
std::cout << " (o o) (o o)" << std::endl;
|
||||
std::cout << "( V ) MERRY CHRISTMAS! ( V )" << std::endl;
|
||||
std::cout << "--m-m----------------------m-m--" << std::endl;
|
||||
return "";
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace day01
|
||||
namespace y2024::day01
|
||||
{
|
||||
using InputType = std::pair<std::vector<int>, std::vector<int>>;
|
||||
REGISTER_DAY(2024, Day01, InputType, int);
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace day02
|
||||
namespace y2024::day02
|
||||
{
|
||||
REGISTER_DAY(2024, Day02, std::vector<std::vector<int>>, int);
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace day03
|
||||
namespace y2024::day03
|
||||
{
|
||||
REGISTER_DAY(2024, Day03, std::string, int32_t);
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace day04
|
||||
namespace y2024::day04
|
||||
{
|
||||
REGISTER_DAY(2024, Day04, Array2D<char>, int32_t);
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace day05
|
||||
namespace y2024::day05
|
||||
{
|
||||
struct Manual
|
||||
{
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace day06
|
||||
namespace y2024::day06
|
||||
{
|
||||
REGISTER_DAY(2024, Day06, Array2D<char>, int32_t);
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace day07
|
||||
namespace y2024::day07
|
||||
{
|
||||
struct Data
|
||||
{
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace day08
|
||||
namespace y2024::day08
|
||||
{
|
||||
struct Data
|
||||
{
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace day09
|
||||
namespace y2024::day09
|
||||
{
|
||||
REGISTER_DAY(2024, Day09, std::vector<int>, int64_t);
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace day10
|
||||
namespace y2024::day10
|
||||
{
|
||||
REGISTER_DAY(2024, Day10, Array2D<int>, int32_t);
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace day11
|
||||
namespace y2024::day11
|
||||
{
|
||||
using Stones = std::map<int64_t, int64_t>;
|
||||
REGISTER_DAY(2024, Day11, Stones, int64_t);
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace day12
|
||||
namespace y2024::day12
|
||||
{
|
||||
REGISTER_DAY(2024, Day12, Array2D<char>, int);
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace day13
|
||||
namespace y2024::day13
|
||||
{
|
||||
struct ClawMachine
|
||||
{
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace day14
|
||||
namespace y2024::day14
|
||||
{
|
||||
struct Robot
|
||||
{
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace day15
|
||||
namespace y2024::day15
|
||||
{
|
||||
struct Map
|
||||
{
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace day16
|
||||
namespace y2024::day16
|
||||
{
|
||||
REGISTER_DAY(2024, Day16, Array2D<char>, int32_t);
|
||||
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace day17
|
||||
namespace y2024::day17
|
||||
{
|
||||
struct Program
|
||||
{
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace day18
|
||||
namespace y2024::day18
|
||||
{
|
||||
using Memory = std::map<Index2D, int>;
|
||||
REGISTER_DAY(2024, Day18, Memory, int32_t);
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace day19
|
||||
namespace y2024::day19
|
||||
{
|
||||
struct Towels
|
||||
{
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace day20
|
||||
namespace y2024::day20
|
||||
{
|
||||
REGISTER_DAY(2024, Day20, Array2D<char>, int32_t);
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace day21
|
||||
namespace y2024::day21
|
||||
{
|
||||
REGISTER_DAY(2024, Day21, std::vector<std::string>, int64_t);
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace day22
|
||||
namespace y2024::day22
|
||||
{
|
||||
REGISTER_DAY(2024, Day22, std::vector<int>, int64_t);
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace day23
|
||||
namespace y2024::day23
|
||||
{
|
||||
struct Network
|
||||
{
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace day24
|
||||
namespace y2024::day24
|
||||
{
|
||||
struct Gate
|
||||
{
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#include "common/aoc.h"
|
||||
|
||||
namespace day25
|
||||
namespace y2024::day25
|
||||
{
|
||||
struct KeysLocks
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user