From ba07ab68f32572439debeb1ee665af1eb8b0e0e8 Mon Sep 17 00:00:00 2001 From: Alessio Molinari Date: Wed, 3 Dec 2025 23:29:17 +0100 Subject: [PATCH] first three days --- .gitignore | 5 ++ day1/CMakeLists.txt | 29 ++++++++++++ day1/Makefile | 9 ++++ day1/flake.lock | 27 +++++++++++ day1/flake.nix | 58 +++++++++++++++++++++++ day1/input_test.txt | 10 ++++ day1/src/main.cpp | 71 ++++++++++++++++++++++++++++ day2/CMakeLists.txt | 29 ++++++++++++ day2/Makefile | 13 ++++++ day2/flake.lock | 27 +++++++++++ day2/flake.nix | 58 +++++++++++++++++++++++ day2/input_test.txt | 1 + day2/src/main.cpp | 111 ++++++++++++++++++++++++++++++++++++++++++++ day3/CMakeLists.txt | 29 ++++++++++++ day3/Makefile | 13 ++++++ day3/flake.lock | 27 +++++++++++ day3/flake.nix | 58 +++++++++++++++++++++++ day3/input_test.txt | 4 ++ day3/src/main.cpp | 90 +++++++++++++++++++++++++++++++++++ 19 files changed, 669 insertions(+) create mode 100644 .gitignore create mode 100644 day1/CMakeLists.txt create mode 100644 day1/Makefile create mode 100644 day1/flake.lock create mode 100644 day1/flake.nix create mode 100644 day1/input_test.txt create mode 100644 day1/src/main.cpp create mode 100644 day2/CMakeLists.txt create mode 100644 day2/Makefile create mode 100644 day2/flake.lock create mode 100644 day2/flake.nix create mode 100644 day2/input_test.txt create mode 100644 day2/src/main.cpp create mode 100644 day3/CMakeLists.txt create mode 100644 day3/Makefile create mode 100644 day3/flake.lock create mode 100644 day3/flake.nix create mode 100644 day3/input_test.txt create mode 100644 day3/src/main.cpp diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..76c5847 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +*/build +*/compile_commands.json +*/input.txt +*/.* +.direnv diff --git a/day1/CMakeLists.txt b/day1/CMakeLists.txt new file mode 100644 index 0000000..09f14d6 --- /dev/null +++ b/day1/CMakeLists.txt @@ -0,0 +1,29 @@ +cmake_minimum_required(VERSION 3.10) + +# Project name and version +project(Day1 VERSION 1.0) + +# Set default build type +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Debug) +endif() + +# 1. This is the critical line for Clangd. +# It generates the file clangd reads to know where headers are. +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +# Debug and Release flags +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -O0 -Wall -Wextra") +set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3") + +# Specify C standard +set(CMAKE_CXX_STANDARD 23) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +# Add include directory +include_directories(${PROJECT_SOURCE_DIR}/include) + +# Add executable +add_executable(${PROJECT_NAME} + src/main.cpp +) diff --git a/day1/Makefile b/day1/Makefile new file mode 100644 index 0000000..8045d0e --- /dev/null +++ b/day1/Makefile @@ -0,0 +1,9 @@ + + +clear: + rm -rf build/* + +run: + cp input.txt build + cp input_test.txt build + cd build && cmake .. && make && ./Day1 diff --git a/day1/flake.lock b/day1/flake.lock new file mode 100644 index 0000000..2b1bdda --- /dev/null +++ b/day1/flake.lock @@ -0,0 +1,27 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1756787288, + "narHash": "sha256-rw/PHa1cqiePdBxhF66V7R+WAP8WekQ0mCDG4CFqT8Y=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "d0fc30899600b9b3466ddb260fd83deb486c32f1", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/day1/flake.nix b/day1/flake.nix new file mode 100644 index 0000000..20aa75f --- /dev/null +++ b/day1/flake.nix @@ -0,0 +1,58 @@ +{ + description = "A Nix-flake-based C/C++ development environment"; + + inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + + outputs = + { self, nixpkgs }: + let + supportedSystems = [ + "x86_64-linux" + "aarch64-linux" + "x86_64-darwin" + "aarch64-darwin" + ]; + forEachSupportedSystem = + f: + nixpkgs.lib.genAttrs supportedSystems ( + system: + f { + pkgs = import nixpkgs { inherit system; }; + } + ); + in + { + devShells = forEachSupportedSystem ( + { pkgs }: + { + default = + pkgs.mkShell.override + { + # Override stdenv in order to change compiler: + # stdenv = pkgs.clangStdenv; + } + + { + nativeBuildInputs = with pkgs; [ + pkg-config + ]; + packages = + with pkgs; + [ + clang-tools + cmake + codespell + cppcheck + doxygen + gtest + lcov + nodejs + vscode-extensions.vadimcn.vscode-lldb + ] + ++ (if system == "aarch64-darwin" then [ ] else [ gdb ]); + CODELLDB_PATH = "${pkgs.vscode-extensions.vadimcn.vscode-lldb}/share/vscode/extensions/vadimcn.vscode-lldb/adapter/codelldb"; + }; + } + ); + }; +} diff --git a/day1/input_test.txt b/day1/input_test.txt new file mode 100644 index 0000000..53287c7 --- /dev/null +++ b/day1/input_test.txt @@ -0,0 +1,10 @@ +L68 +L30 +R48 +L5 +R60 +L55 +L1 +L99 +R14 +L82 diff --git a/day1/src/main.cpp b/day1/src/main.cpp new file mode 100644 index 0000000..b6720e3 --- /dev/null +++ b/day1/src/main.cpp @@ -0,0 +1,71 @@ +#include +#include +#include + +struct Instruction { + const char direction; + const int value; +}; + +std::vector parse_input_file(const std::string &path) { + std::ifstream file; + std::vector vec; + std::string line; + + file.open(path); + if (file.is_open()) { + while (std::getline(file, line)) { + auto instr = line.at(0); + int value = std::stoi(line.substr(1)); + vec.emplace_back(Instruction{instr, value}); + } + file.close(); + } else { + std::cout << "Failed to open file: " << path << std::endl; + } + + return vec; +} + +std::tuple doit(const std::vector &instructions) { + int dial_val = 50; + int zero_counter_part1 = 0; + int zero_counter_part2 = 0; + for (const auto &instr : instructions) { + for (int i = 0; i < instr.value; i++) { + if (instr.direction == 'L') { + dial_val--; + } else { + dial_val++; + } + + if (dial_val > 99) + dial_val = 0; + else if (dial_val < 0) + dial_val = 99; + if (dial_val == 0) + zero_counter_part2 += 1; + } + if (dial_val == 0) + zero_counter_part1 += 1; + + std::cout << "dial_val: " << dial_val << std::endl; + } + return std::make_tuple(zero_counter_part1, zero_counter_part2); +} + +int main(int argc, char *argv[]) { + if (argc < 2) { + std::cout << "One argument required: input txt" << std::endl; + } + + auto instructions = parse_input_file(argv[1]); + + auto num_zeros = doit(instructions); + + std::cout << "Number of times dial hits zero (part 1): " + << std::get<0>(num_zeros) << std::endl; + std::cout << "Number of times dial hits zero (part 2): " + << std::get<1>(num_zeros) << std::endl; + return 0; +} diff --git a/day2/CMakeLists.txt b/day2/CMakeLists.txt new file mode 100644 index 0000000..c728db5 --- /dev/null +++ b/day2/CMakeLists.txt @@ -0,0 +1,29 @@ +cmake_minimum_required(VERSION 3.10) + +# Project name and version +project(Day2 VERSION 1.0) + +# Set default build type +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Debug) +endif() + +# 1. This is the critical line for Clangd. +# It generates the file clangd reads to know where headers are. +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +# Debug and Release flags +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -O0 -Wall -Wextra") +set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3") + +# Specify C standard +set(CMAKE_CXX_STANDARD 23) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +# Add include directory +include_directories(${PROJECT_SOURCE_DIR}/include) + +# Add executable +add_executable(${PROJECT_NAME} + src/main.cpp +) diff --git a/day2/Makefile b/day2/Makefile new file mode 100644 index 0000000..dea646c --- /dev/null +++ b/day2/Makefile @@ -0,0 +1,13 @@ + + +clear: + rm -rf build/* + +run: + cp input.txt build + cp input_test.txt build + cd build && cmake .. && make && ./Day2 input_test.txt + +release: + cp input.txt build + cd build && cmake .. -DCMAKE_BUILD_TYPE=Release && make && ./Day2 input.txt diff --git a/day2/flake.lock b/day2/flake.lock new file mode 100644 index 0000000..2b1bdda --- /dev/null +++ b/day2/flake.lock @@ -0,0 +1,27 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1756787288, + "narHash": "sha256-rw/PHa1cqiePdBxhF66V7R+WAP8WekQ0mCDG4CFqT8Y=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "d0fc30899600b9b3466ddb260fd83deb486c32f1", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/day2/flake.nix b/day2/flake.nix new file mode 100644 index 0000000..20aa75f --- /dev/null +++ b/day2/flake.nix @@ -0,0 +1,58 @@ +{ + description = "A Nix-flake-based C/C++ development environment"; + + inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + + outputs = + { self, nixpkgs }: + let + supportedSystems = [ + "x86_64-linux" + "aarch64-linux" + "x86_64-darwin" + "aarch64-darwin" + ]; + forEachSupportedSystem = + f: + nixpkgs.lib.genAttrs supportedSystems ( + system: + f { + pkgs = import nixpkgs { inherit system; }; + } + ); + in + { + devShells = forEachSupportedSystem ( + { pkgs }: + { + default = + pkgs.mkShell.override + { + # Override stdenv in order to change compiler: + # stdenv = pkgs.clangStdenv; + } + + { + nativeBuildInputs = with pkgs; [ + pkg-config + ]; + packages = + with pkgs; + [ + clang-tools + cmake + codespell + cppcheck + doxygen + gtest + lcov + nodejs + vscode-extensions.vadimcn.vscode-lldb + ] + ++ (if system == "aarch64-darwin" then [ ] else [ gdb ]); + CODELLDB_PATH = "${pkgs.vscode-extensions.vadimcn.vscode-lldb}/share/vscode/extensions/vadimcn.vscode-lldb/adapter/codelldb"; + }; + } + ); + }; +} diff --git a/day2/input_test.txt b/day2/input_test.txt new file mode 100644 index 0000000..a3f22ef --- /dev/null +++ b/day2/input_test.txt @@ -0,0 +1 @@ +11-22,95-115,998-1012,1188511880-1188511890,222220-222224,1698522-1698528,446443-446449,38593856-38593862,565653-565659,824824821-824824827,2121212118-2121212124 diff --git a/day2/src/main.cpp b/day2/src/main.cpp new file mode 100644 index 0000000..057b672 --- /dev/null +++ b/day2/src/main.cpp @@ -0,0 +1,111 @@ +#include +#include +#include +#include + +long check_num_part2(const std::string &num_str) { + if (num_str.length() == 2) { + if (num_str[0] == num_str[1]) { + return std::stol(num_str); + } + return 0; + } + + size_t half = std::ceil(num_str.length() / 2); + for (size_t j = 0; j <= half; j++) { + auto sub = num_str.substr(0, j); + auto rest = num_str.substr(j); + if (sub.empty() || rest.empty()) { + continue; + } + int matched = 0; + bool all_matched = true; + for (size_t k = 0; k < rest.length(); k += sub.length()) { + auto rest_sub = rest.substr(k, sub.length()); + if (sub != rest_sub) { + all_matched = false; + break; + } else { + matched += 1; + } + } + if (all_matched && matched >= 1) { + return std::stol(num_str); + } + } + return 0; +} + +long check_range(const std::string &range, bool part_2) { + auto pos = range.find('-'); + long count = 0; + std::cout << "Checking range " << range << std::endl; + if (pos != std::string::npos) { + auto range_start = range.substr(0, pos); + auto range_end = range.substr(pos + 1); + long rstart = std::stol(range_start); + long rend = std::stol(range_end); + for (long i = rstart; i < rend + 1; i++) { + auto istr = std::to_string(i); + if (!part_2) { + if (istr.length() % 2 == 0) { + auto first_half = istr.substr(0, istr.length() / 2); + auto second_half = istr.substr(istr.length() / 2); + count += (first_half == second_half) ? i : 0; + } + } else { + count += check_num_part2(istr); + } + } + } else { + std::cout << "Invalid range format: " << range << std::endl; + std::exit(1); + } + + std::cout << "count: " << count << std::endl; + return count; +} + +std::tuple parse_input_file(const std::string &path, + bool do_part_2_only) { + std::ifstream file; + std::string line; + + file.open(path); + long part_1 = 0; + long part_2 = 0; + if (file.is_open()) { + std::getline(file, line); + auto pos = line.find_first_of(','); + while (pos != std::string::npos) { + auto range = line.substr(0, pos); + if (!do_part_2_only) + part_1 += check_range(range, false); + part_2 += check_range(range, true); + line = line.substr(pos + 1); + pos = line.find_first_of(','); + } + if (line.find_first_of('-') != std::string::npos) { + if (!do_part_2_only) + part_1 += check_range(line, false); + part_2 += check_range(line, true); + } + file.close(); + } else { + std::cout << "Failed to open file: " << path << std::endl; + } + + return {part_1, part_2}; +} + +int main(int argc, char *argv[]) { + if (argc < 2) { + std::cout << "One argument required: input txt" << std::endl; + } + + auto results = parse_input_file(argv[1], true); + std::cout << "Part 1: " << std::get<0>(results) << std::endl; + std::cout << "Part 2: " << std::get<1>(results) << std::endl; + + return 0; +} diff --git a/day3/CMakeLists.txt b/day3/CMakeLists.txt new file mode 100644 index 0000000..3fc017b --- /dev/null +++ b/day3/CMakeLists.txt @@ -0,0 +1,29 @@ +cmake_minimum_required(VERSION 3.10) + +# Project name and version +project(Day3 VERSION 1.0) + +# Set default build type +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Debug) +endif() + +# 1. This is the critical line for Clangd. +# It generates the file clangd reads to know where headers are. +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +# Debug and Release flags +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -O0 -Wall -Wextra") +set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3") + +# Specify C standard +set(CMAKE_CXX_STANDARD 23) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +# Add include directory +include_directories(${PROJECT_SOURCE_DIR}/include) + +# Add executable +add_executable(${PROJECT_NAME} + src/main.cpp +) diff --git a/day3/Makefile b/day3/Makefile new file mode 100644 index 0000000..382c0da --- /dev/null +++ b/day3/Makefile @@ -0,0 +1,13 @@ + + +clear: + rm -rf build/* + +run: + cp input.txt build + cp input_test.txt build + cd build && cmake .. && make && ./Day3 input_test.txt + +release: + cp input.txt build + cd build && cmake .. -DCMAKE_BUILD_TYPE=Release && make && ./Day3 input.txt diff --git a/day3/flake.lock b/day3/flake.lock new file mode 100644 index 0000000..2b1bdda --- /dev/null +++ b/day3/flake.lock @@ -0,0 +1,27 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1756787288, + "narHash": "sha256-rw/PHa1cqiePdBxhF66V7R+WAP8WekQ0mCDG4CFqT8Y=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "d0fc30899600b9b3466ddb260fd83deb486c32f1", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/day3/flake.nix b/day3/flake.nix new file mode 100644 index 0000000..20aa75f --- /dev/null +++ b/day3/flake.nix @@ -0,0 +1,58 @@ +{ + description = "A Nix-flake-based C/C++ development environment"; + + inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + + outputs = + { self, nixpkgs }: + let + supportedSystems = [ + "x86_64-linux" + "aarch64-linux" + "x86_64-darwin" + "aarch64-darwin" + ]; + forEachSupportedSystem = + f: + nixpkgs.lib.genAttrs supportedSystems ( + system: + f { + pkgs = import nixpkgs { inherit system; }; + } + ); + in + { + devShells = forEachSupportedSystem ( + { pkgs }: + { + default = + pkgs.mkShell.override + { + # Override stdenv in order to change compiler: + # stdenv = pkgs.clangStdenv; + } + + { + nativeBuildInputs = with pkgs; [ + pkg-config + ]; + packages = + with pkgs; + [ + clang-tools + cmake + codespell + cppcheck + doxygen + gtest + lcov + nodejs + vscode-extensions.vadimcn.vscode-lldb + ] + ++ (if system == "aarch64-darwin" then [ ] else [ gdb ]); + CODELLDB_PATH = "${pkgs.vscode-extensions.vadimcn.vscode-lldb}/share/vscode/extensions/vadimcn.vscode-lldb/adapter/codelldb"; + }; + } + ); + }; +} diff --git a/day3/input_test.txt b/day3/input_test.txt new file mode 100644 index 0000000..7255fca --- /dev/null +++ b/day3/input_test.txt @@ -0,0 +1,4 @@ +987654321111111 +811111111111119 +234234234234278 +818181911112111 diff --git a/day3/src/main.cpp b/day3/src/main.cpp new file mode 100644 index 0000000..05e5ae3 --- /dev/null +++ b/day3/src/main.cpp @@ -0,0 +1,90 @@ +#include +#include +#include +#include +#include +#include + +int do_part_1(const std::string &line) { + int greatest = -1; + int second_greatest = -1; + for (size_t i = 0; i < line.length(); i++) { + char c = line[i]; + int j = static_cast(c - '0'); + if (j > greatest && i < (line.length() - 1)) { + second_greatest = -1; + greatest = j; + } else if (j > second_greatest) { + second_greatest = j; + } + } + + auto joint = std::to_string(greatest) + std::to_string(second_greatest); + + return std::stoi(joint); +} + +int find_highest_leading(std::string &line, int len) { + int highest_leading = -1; + int highest_pos = -1; + for (size_t i = 0; i < (line.length() - len + 1); i++) { + int j = static_cast(line[i] - '0'); + if (j > highest_leading) { + highest_leading = j; + highest_pos = i; + } + } + line = line.substr(highest_pos + 1); + return highest_leading; +} + +long do_part_2(std::string line) { + std::string highest_seq = ""; + for (int i = 12; i > 0; i--) { + std::cout << "line " << line << std::endl; + int highest_leading = find_highest_leading(line, i); + highest_seq += std::to_string(highest_leading); + } + return std::stol(highest_seq); +} + +std::tuple parse_input_file(const std::string &path) { + std::ifstream file; + std::string line; + + file.open(path); + long part_1 = 0; + long part_2 = 0; + std::vector part1_ints; + std::vector part2_longs; + if (file.is_open()) { + std::getline(file, line); + while (!line.empty()) { + part_1 = do_part_1(line); + part1_ints.emplace_back(part_1); + part_2 = do_part_2(line); + part2_longs.emplace_back(part_2); + std::getline(file, line); + } + } else { + std::cerr << "Error opening file: " << path << std::endl; + return {0, 0}; + } + + part_1 = std::accumulate(part1_ints.begin(), part1_ints.end(), 0L); + part_2 = std::accumulate(part2_longs.begin(), part2_longs.end(), 0L); + + return {part_1, part_2}; +} + +int main(int argc, char *argv[]) { + if (argc < 2) { + std::cout << "One argument required: input txt" << std::endl; + } + + auto results = parse_input_file(argv[1]); + std::cout << "Part 1: " << std::get<0>(results) << std::endl; + std::cout << "Part 2: " << std::get<1>(results) << std::endl; + + return 0; +}