diff --git a/day7/CMakeLists.txt b/day7/CMakeLists.txt new file mode 100644 index 0000000..f6872a6 --- /dev/null +++ b/day7/CMakeLists.txt @@ -0,0 +1,29 @@ +cmake_minimum_required(VERSION 3.10) + +# Project name and version +project(Day7 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/day7/Makefile b/day7/Makefile new file mode 100644 index 0000000..48caf0c --- /dev/null +++ b/day7/Makefile @@ -0,0 +1,13 @@ + + +clear: + rm -rf build/* + +run: + cp input.txt build + cp input_test.txt build + cd build && cmake .. && make && ./Day7 input_test.txt + +release: + cp input.txt build + cd build && cmake .. -DCMAKE_BUILD_TYPE=Release && make && ./Day7 input.txt diff --git a/day7/flake.lock b/day7/flake.lock new file mode 100644 index 0000000..2b1bdda --- /dev/null +++ b/day7/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/day7/flake.nix b/day7/flake.nix new file mode 100644 index 0000000..20aa75f --- /dev/null +++ b/day7/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/day7/input_test.txt b/day7/input_test.txt new file mode 100644 index 0000000..57a2466 --- /dev/null +++ b/day7/input_test.txt @@ -0,0 +1,16 @@ +.......S....... +............... +.......^....... +............... +......^.^...... +............... +.....^.^.^..... +............... +....^.^...^.... +............... +...^.^...^.^... +............... +..^...^.....^.. +............... +.^.^.^.^.^...^. +............... diff --git a/day7/src/main.cpp b/day7/src/main.cpp new file mode 100644 index 0000000..6afb5a7 --- /dev/null +++ b/day7/src/main.cpp @@ -0,0 +1,141 @@ +#include +#include +#include +#include +#include +#include +#include + +typedef long melem; +typedef std::vector> Matrix; + +void print_matrix(const Matrix &matrix) { + for (const auto &row : matrix) { + for (const auto &cell : row) { + std::cout << std::setw(4) << static_cast(cell) << ' '; + } + std::cout << std::endl; + } +} + +long compute_splits_part2(Matrix &matrix, int row_pos, int col_pos) { + for (int i = row_pos + 1; i < matrix.size(); i++) { + if (matrix[i][col_pos] == 1) { + if (col_pos > 0) { + matrix[i][col_pos] = compute_splits_part2(matrix, i, col_pos - 1); + } + if (col_pos < matrix[i].size() - 1) { + matrix[i][col_pos] += compute_splits_part2(matrix, i, col_pos + 1); + } + return matrix[i][col_pos]; + } + if (matrix[i][col_pos] > 1) + return matrix[i][col_pos]; + } + return 1; +} + +long compute_num_splits(Matrix &matrix, int row_pos, int col_pos) { + if (matrix[row_pos][col_pos] == -1) { + return 0; + } + for (int i = row_pos + 1; i < matrix.size(); i++) { + if (matrix[i][col_pos] == -1) + return 0; + if (matrix[i][col_pos] == 1) { + if (col_pos > 0) { + matrix[i][col_pos] += compute_num_splits(matrix, i, col_pos - 1); + } + if (col_pos < matrix[i].size() - 1) { + matrix[i][col_pos] += compute_num_splits(matrix, i, col_pos + 1); + } + return matrix[i][col_pos]; + } + matrix[i][col_pos] = -1; + } + return matrix[row_pos][col_pos]; +} + +long compute_score(Matrix &matrix, bool do_part2) { + int row_pos = -1, col_pos = -1; + for (size_t i = 0; i < matrix.size(); i++) { + for (size_t j = 0; j < matrix[i].size(); j++) { + if (matrix[i][j] == 1) { + // found the first splitter + row_pos = i; + col_pos = j; + break; + } + } + if (row_pos != -1 || col_pos != -1) + break; + } + + if (row_pos == -1 || col_pos == -1) { + std::cerr << "No splitter found in the matrix." << std::endl; + return -1; + } + if (!do_part2) { + matrix[row_pos][col_pos] += + compute_num_splits(matrix, row_pos, col_pos - 1); + matrix[row_pos][col_pos] += + compute_num_splits(matrix, row_pos, col_pos + 1); + } else { + matrix[row_pos][col_pos] = + compute_splits_part2(matrix, row_pos, col_pos - 1); + matrix[row_pos][col_pos] += + compute_splits_part2(matrix, row_pos, col_pos + 1); + } + return matrix[row_pos][col_pos]; +} + +Matrix parse_file(const std::string &path) { + std::ifstream file; + std::string line; + Matrix matrix; + + file.open(path); + if (!file.is_open()) { + std::cerr << "Error opening file: " << path << std::endl; + return matrix; + } + while (std::getline(file, line)) { + std::vector row(line.length(), 0); + for (int i = 0; i < line.length(); i++) { + char c = line[i]; + if (c == '.') { + row[i] = 0; + } else if (c == '^') { + row[i] = 1; + } else if (c == 'S') { + row[i] = -1; + } + } + matrix.emplace_back(row); + } + + file.close(); + return matrix; +} + +int main(int argc, char *argv[]) { + if (argc < 2) { + std::cout << "One argument required: input txt" << std::endl; + } + auto matrix = parse_file(argv[1]); + auto matrix_copy(matrix); + + std::cout << "Matrix before computing" << std::endl; + print_matrix(matrix); + melem score = compute_score(matrix, false); + + std::cout << "Matrix after computing" << std::endl; + print_matrix(matrix); + std::cout << "part 1 " << score << std::endl; + + score = compute_score(matrix_copy, true); + print_matrix(matrix_copy); + std::cout << "part 2 " << score << std::endl; + + return 0; +}