Add 2022 solutions

This commit is contained in:
Thraix
2025-11-26 23:02:30 +01:00
parent 908b362ee5
commit ff9bd6ce01
76 changed files with 3840 additions and 27 deletions
-2
View File
@@ -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
+14
View File
@@ -0,0 +1,14 @@
1000
2000
3000
4000
5000
6000
7000
8000
9000
10000
+3
View File
@@ -0,0 +1,3 @@
A Y
B X
C Z
+6
View File
@@ -0,0 +1,6 @@
vJrwpWtwJgWrhcsFMMfFFhFp
jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL
PmmdzqPrVvPwwTWBwg
wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn
ttgJtRGJQctTZtZT
CrZsJsPPZsGzwwsLwLmpwMDw
+6
View File
@@ -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
+9
View File
@@ -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
+1
View File
@@ -0,0 +1 @@
mjqjpqmgbljsphdztnvjfqwrcgsmlb
+23
View File
@@ -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
+5
View File
@@ -0,0 +1,5 @@
30373
25512
65332
33549
35390
+8
View File
@@ -0,0 +1,8 @@
R 5
U 8
L 8
D 3
R 17
D 10
L 25
U 20
+146
View File
@@ -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
+27
View File
@@ -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
+5
View File
@@ -0,0 +1,5 @@
Sabqponm
abcryxxl
accszExk
acctuvwj
abdefghi
+24
View File
@@ -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]
+2
View File
@@ -0,0 +1,2 @@
498,4 -> 498,6 -> 496,6
503,4 -> 502,4 -> 502,9 -> 494,9
+14
View File
@@ -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
+10
View File
@@ -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
+1
View File
@@ -0,0 +1 @@
>>><<><>><<<>><>>><<<>>><<<><<<>><>><<>>
+13
View File
@@ -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
+2
View File
@@ -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.
+7
View File
@@ -0,0 +1,7 @@
1
2
-3
3
-2
0
4
+15
View File
@@ -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
+14
View File
@@ -0,0 +1,14 @@
...#
.#..
#...
....
...#.......#
........#...
..#....#....
..........#.
...#....
.....#..
.#......
......#.
10R5L5R10L4R5L5
+7
View File
@@ -0,0 +1,7 @@
....#..
..###.#
#...#.#
.#...##
#.###..
##.#.##
.#..#..
+6
View File
@@ -0,0 +1,6 @@
#.######
#>>.<^<#
#.<..<<#
#>v.><>#
#<^v^^>#
######.#
+13
View File
@@ -0,0 +1,13 @@
1=-0-2
12111
2=0=
21
2=01
111
20012
112
1=-1=
1-12
12
1=
122
+51
View File
@@ -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;
}
}
+46
View File
@@ -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;
}
}
+84
View File
@@ -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;
}
}
+65
View File
@@ -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;
}
}
+95
View File
@@ -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();
}
}
+43
View File
@@ -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);
}
}
+138
View File
@@ -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 = &currentDirectory->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);
}
}
+143
View File
@@ -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;
}
}
+122
View File
@@ -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();
}
}
+116
View File
@@ -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('#');
}
}
+145
View File
@@ -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];
}
}
+91
View File
@@ -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);
}
}
+133
View File
@@ -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);
}
}
+133
View File
@@ -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;
}
}
+259
View File
@@ -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
}
+200
View File
@@ -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;
}
}
}
+200
View File
@@ -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;
}
}
+105
View File
@@ -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;
}
}
+145
View File
@@ -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;
}
}
+76
View File
@@ -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;
}
}
+184
View File
@@ -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);
}
}
+284
View File
@@ -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;
}
}
+263
View File
@@ -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;
}
}
+201
View File
@@ -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;
}
}
+112
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -1,6 +1,6 @@
#include "common/aoc.h"
namespace day03
namespace y2024::day03
{
REGISTER_DAY(2024, Day03, std::string, int32_t);
+1 -1
View File
@@ -1,6 +1,6 @@
#include "common/aoc.h"
namespace day04
namespace y2024::day04
{
REGISTER_DAY(2024, Day04, Array2D<char>, int32_t);
+1 -1
View File
@@ -1,6 +1,6 @@
#include "common/aoc.h"
namespace day05
namespace y2024::day05
{
struct Manual
{
+1 -1
View File
@@ -1,6 +1,6 @@
#include "common/aoc.h"
namespace day06
namespace y2024::day06
{
REGISTER_DAY(2024, Day06, Array2D<char>, int32_t);
+1 -1
View File
@@ -1,6 +1,6 @@
#include "common/aoc.h"
namespace day07
namespace y2024::day07
{
struct Data
{
+1 -1
View File
@@ -1,6 +1,6 @@
#include "common/aoc.h"
namespace day08
namespace y2024::day08
{
struct Data
{
+1 -1
View File
@@ -1,6 +1,6 @@
#include "common/aoc.h"
namespace day09
namespace y2024::day09
{
REGISTER_DAY(2024, Day09, std::vector<int>, int64_t);
+1 -1
View File
@@ -1,6 +1,6 @@
#include "common/aoc.h"
namespace day10
namespace y2024::day10
{
REGISTER_DAY(2024, Day10, Array2D<int>, int32_t);
+1 -1
View File
@@ -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
View File
@@ -1,6 +1,6 @@
#include "common/aoc.h"
namespace day12
namespace y2024::day12
{
REGISTER_DAY(2024, Day12, Array2D<char>, int);
+1 -1
View File
@@ -1,6 +1,6 @@
#include "common/aoc.h"
namespace day13
namespace y2024::day13
{
struct ClawMachine
{
+1 -1
View File
@@ -1,6 +1,6 @@
#include "common/aoc.h"
namespace day14
namespace y2024::day14
{
struct Robot
{
+1 -1
View File
@@ -1,6 +1,6 @@
#include "common/aoc.h"
namespace day15
namespace y2024::day15
{
struct Map
{
+1 -1
View File
@@ -1,6 +1,6 @@
#include "common/aoc.h"
namespace day16
namespace y2024::day16
{
REGISTER_DAY(2024, Day16, Array2D<char>, int32_t);
+1 -1
View File
@@ -2,7 +2,7 @@
#include "common/aoc.h"
namespace day17
namespace y2024::day17
{
struct Program
{
+1 -1
View File
@@ -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
View File
@@ -1,6 +1,6 @@
#include "common/aoc.h"
namespace day19
namespace y2024::day19
{
struct Towels
{
+1 -1
View File
@@ -1,6 +1,6 @@
#include "common/aoc.h"
namespace day20
namespace y2024::day20
{
REGISTER_DAY(2024, Day20, Array2D<char>, int32_t);
+1 -1
View File
@@ -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
View File
@@ -1,6 +1,6 @@
#include "common/aoc.h"
namespace day22
namespace y2024::day22
{
REGISTER_DAY(2024, Day22, std::vector<int>, int64_t);
+1 -1
View File
@@ -1,6 +1,6 @@
#include "common/aoc.h"
namespace day23
namespace y2024::day23
{
struct Network
{
+1 -1
View File
@@ -1,6 +1,6 @@
#include "common/aoc.h"
namespace day24
namespace y2024::day24
{
struct Gate
{
+1 -1
View File
@@ -1,6 +1,6 @@
#include "common/aoc.h"
namespace day25
namespace y2024::day25
{
struct KeysLocks
{