Skip to content

Commit f3512e5

Browse files
author
bt
committed
Day 11
1 parent 5c8da69 commit f3512e5

File tree

5 files changed

+115
-3
lines changed

5 files changed

+115
-3
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ add_compile_options(-Wall -Wextra -Wpedantic -O2)
77
function(add_challenge name)
88
add_executable(${name} ${CMAKE_CURRENT_SOURCE_DIR}/src/${name}.cpp)
99
target_include_directories(${name} PRIVATE ${CMAKE_SOURCE_DIR}/include)
10-
target_include_directories(${name} PRIVATE ${CMAKE_SOURCE_DIR}/include/utils)
1110
endfunction(add_challenge)
1211

1312
add_challenge(day1)
@@ -20,6 +19,7 @@ add_challenge(day7)
2019
add_challenge(day8)
2120
add_challenge(day9)
2221
add_challenge(day10)
22+
add_challenge(day11)
2323

2424
add_custom_command(TARGET day1
2525
COMMAND ${CMAKE_COMMAND} -E create_symlink "${CMAKE_CURRENT_SOURCE_DIR}/data" "./data"

data

Submodule data updated from a93e9a1 to 4e34c1c

include/utils/numeric_algorithm.hpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#pragma once
2+
3+
#include <stdint.h>
4+
#include <cmath>
5+
6+
[[nodiscard]] constexpr size_t numOfDigits(uint64_t num) noexcept {
7+
return static_cast<uint64_t>(std::log10(num) + 1);
8+
}
9+
10+
[[nodiscard]] constexpr std::pair<uint64_t, uint64_t> splitNum(uint64_t num, size_t countOfDigits) noexcept {
11+
// Calculate the power of 10 to split the number
12+
const uint64_t splitPoint = countOfDigits / 2;
13+
const uint64_t divisor = static_cast<uint64_t>(std::pow(10, splitPoint));
14+
15+
// Split the number
16+
const uint64_t firstPart = num / divisor;
17+
const uint64_t secondPart = num % divisor;
18+
19+
return {firstPart, secondPart};
20+
}

src/day11.cpp

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
#include "common_headers.hpp"
2+
#include "utils/numeric_algorithm.hpp"
3+
4+
#include <cmath>
5+
#include <sstream>
6+
7+
8+
using HashTable = std::unordered_map<size_t, std::unordered_map<size_t, uint64_t>>;
9+
size_t calculateStones(size_t maxBlinks, size_t blinks, uint64_t num, HashTable& cache) {
10+
11+
if(cache[num].count(blinks)) {
12+
return cache[num][blinks];
13+
}
14+
if(blinks == maxBlinks) {
15+
return 1;
16+
}
17+
if(num == 0) {
18+
const auto stones = calculateStones(maxBlinks, blinks + 1, 1, cache);
19+
cache[num][blinks] = stones ;
20+
}
21+
else if(auto countOfDigits = numOfDigits(num); countOfDigits % 2 == 0) {
22+
const auto [num1, num2] = splitNum(num, countOfDigits);
23+
24+
const auto stones1 = calculateStones(maxBlinks, blinks + 1, num1, cache);
25+
const auto stones2 = calculateStones(maxBlinks, blinks + 1, num2, cache);
26+
cache[num][blinks] = stones1 + stones2;
27+
}
28+
else {
29+
const auto stones = calculateStones(maxBlinks, blinks + 1, num * 2024, cache);
30+
cache[num][blinks] = stones;
31+
}
32+
33+
return cache[num][blinks];
34+
}
35+
36+
size_t solveFirstPart(const std::vector<uint64_t>& stones, size_t maxBlinks) {
37+
HashTable cache;
38+
size_t stoneCounter{};
39+
for(auto it = stones.rbegin(); it != stones.rend(); ++it) {
40+
stoneCounter += calculateStones(maxBlinks, 0, *it, cache);
41+
}
42+
return stoneCounter;
43+
}
44+
45+
std::vector<uint64_t> lineParser(const std::string& line) {
46+
std::stringstream ss(line);
47+
uint64_t num{};
48+
std::vector<uint64_t> nums;
49+
while ((ss >> num))
50+
{
51+
nums.push_back(num);
52+
}
53+
return nums;
54+
}
55+
56+
void printHelp()
57+
{
58+
std::cerr << "\nUsage:\n"
59+
<< "The program requires 2 args: (part1, part2) and the path to the file."
60+
<< "\nFor example, ./day7 part1 data/day7.txt";
61+
}
62+
63+
int main(int argc, char* argv[])
64+
{
65+
if(argc != 3) {
66+
printHelp();
67+
return 1;
68+
}
69+
70+
std::string_view task{argv[1]};
71+
if(task != "part1" && task != "part2") {
72+
std::cerr << "\nfirst arg can be either `part1` or `part2`\n";
73+
printHelp();
74+
return 1;
75+
}
76+
77+
std::vector<std::vector<uint64_t>> inputVec;
78+
readInput(argv[2], std::back_inserter(inputVec), lineParser);
79+
80+
if(task == "part1") {
81+
const size_t maxBlinks{25};
82+
std::cout << solveFirstPart(inputVec.at(0), maxBlinks);
83+
}
84+
else {
85+
const size_t maxBlinks{75};
86+
std::cout << solveFirstPart(inputVec.at(0), maxBlinks);
87+
}
88+
89+
return 0;
90+
}

src/day7.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
#include "common_headers.hpp"
2+
#include "utils/numeric_algorithm.hpp"
3+
24
#include <sstream>
35
#include <limits>
46
#include <cmath>
@@ -11,7 +13,7 @@ struct Equation final
1113
};
1214

1315
[[nodiscard]] constexpr int64_t cat(int64_t a, int64_t b) noexcept {
14-
const int multiplier = std::pow(10, static_cast<int>(std::log10(b) + 1));
16+
const int multiplier = std::pow(10, numOfDigits(b));
1517
return a * multiplier + b;
1618
};
1719

0 commit comments

Comments
 (0)