Implement safe cracking logic and setup development environment
- Added a new `main.cpp` file with logic to parse dial rotations from a file and execute safe cracking based on the parsed data. - Introduced a `DialRotation` struct to represent the direction and distance of dial rotations. - Implemented `parseRotations` function to read and parse input from a specified file, returning a vector of `DialRotation` or an error message. - Created `executeSafeCrack` function to process the dial rotations and print the current state of the dial. - Added `.clang-format` and `.clang-tidy` configuration files for code formatting and linting. - Set up a Dockerfile for a development container with necessary tools and dependencies. - Configured VS Code settings and tasks for building, formatting, and running clang-tidy. - Added a script to run clang-tidy on the source files, ensuring code quality.
This commit is contained in:
parent
c093e8a4bf
commit
38eca3b747
11 changed files with 4654 additions and 3 deletions
3
.clang-format
Normal file
3
.clang-format
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
BasedOnStyle: Google
|
||||||
|
IndentWidth: 4
|
||||||
|
ColumnLimit: 120
|
||||||
4
.clang-tidy
Normal file
4
.clang-tidy
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
Checks: '-*,modernize-*,readability-*,bugprone-*,performance-*'
|
||||||
|
WarningsAsErrors: ''
|
||||||
|
HeaderFilterRegex: '.*'
|
||||||
|
FormatStyle: file
|
||||||
23
.devcontainer/Dockerfile
Normal file
23
.devcontainer/Dockerfile
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
FROM xianpengshen/clang-tools:21
|
||||||
|
|
||||||
|
# Install development tools (cmake, ninja, build essentials)
|
||||||
|
USER root
|
||||||
|
RUN apt-get update \
|
||||||
|
&& apt-get install -y --no-install-recommends \
|
||||||
|
cmake \
|
||||||
|
ninja-build \
|
||||||
|
build-essential \
|
||||||
|
git \
|
||||||
|
python3 \
|
||||||
|
python3-pip \
|
||||||
|
ca-certificates \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Create workspace folder (VS Code devcontainer convention)
|
||||||
|
ARG WORKSPACE_FOLDER=/workspaces/aoc25
|
||||||
|
RUN mkdir -p ${WORKSPACE_FOLDER} && chown -R root:root ${WORKSPACE_FOLDER}
|
||||||
|
WORKDIR ${WORKSPACE_FOLDER}
|
||||||
|
|
||||||
|
ENV SHELL=/bin/bash
|
||||||
|
|
||||||
|
CMD ["bash"]
|
||||||
20
.devcontainer/devcontainer.json
Normal file
20
.devcontainer/devcontainer.json
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"name": "aoc25-clang21",
|
||||||
|
"build": {
|
||||||
|
"dockerfile": "Dockerfile"
|
||||||
|
},
|
||||||
|
"workspaceFolder": "/workspaces/aoc25",
|
||||||
|
"workspaceMount": "source=${localWorkspaceFolder},target=/workspaces/aoc25,type=bind,consistency=cached",
|
||||||
|
"settings": {
|
||||||
|
"C_Cpp.default.compilerPath": "/usr/bin/clang++-21",
|
||||||
|
"C_Cpp.default.intelliSenseMode": "linux-clang-x64",
|
||||||
|
"clang-format.executable": "/usr/bin/clang-format-21"
|
||||||
|
},
|
||||||
|
"extensions": [
|
||||||
|
"ms-vscode.cpptools",
|
||||||
|
"ms-vscode.cmake-tools",
|
||||||
|
"llvm-vs-code-extensions.vscode-clangd",
|
||||||
|
"xaver.clang-format"
|
||||||
|
],
|
||||||
|
"postCreateCommand": "cmake -S . -B build || true"
|
||||||
|
}
|
||||||
9
.vscode/settings.json
vendored
Normal file
9
.vscode/settings.json
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"editor.formatOnSave": true,
|
||||||
|
"C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools",
|
||||||
|
"cmake.configureOnOpen": false,
|
||||||
|
"cmake.generator": "Ninja",
|
||||||
|
"clangd.arguments": [
|
||||||
|
"--compile-commands-dir=build"
|
||||||
|
]
|
||||||
|
}
|
||||||
33
.vscode/tasks.json
vendored
Normal file
33
.vscode/tasks.json
vendored
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
{
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"label": "CMake: Configure",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "cmake -S . -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON",
|
||||||
|
"problemMatcher": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "CMake: Build",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "cmake --build build -- -j",
|
||||||
|
"problemMatcher": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Clang-Format: Format Workspace",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "bash -lc \"find . -name \"*.cpp\" -o -name \"*.hpp\" -o -name \"*.h\" | xargs -r clang-format -i\"",
|
||||||
|
"problemMatcher": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Clang-Tidy: Run",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "./scripts/run-clang-tidy.sh",
|
||||||
|
"presentation": {
|
||||||
|
"reveal": "always",
|
||||||
|
"panel": "shared"
|
||||||
|
},
|
||||||
|
"problemMatcher": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,9 @@
|
||||||
cmake_minimum_required(VERSION 3.10.0)
|
cmake_minimum_required(VERSION 3.10.0)
|
||||||
|
|
||||||
|
# Set compilers before project() to ensure they're used
|
||||||
|
set(CMAKE_C_COMPILER /usr/bin/clang-21)
|
||||||
|
set(CMAKE_CXX_COMPILER /usr/bin/clang++-21)
|
||||||
|
|
||||||
project(aoc25 VERSION 0.1.0 LANGUAGES C CXX)
|
project(aoc25 VERSION 0.1.0 LANGUAGES C CXX)
|
||||||
|
|
||||||
# Per-day subprojects (example: day1)
|
# Per-day subprojects (example: day1)
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,11 @@
|
||||||
add_executable(day1 main.cpp)
|
add_executable(day1 main.cpp)
|
||||||
set_target_properties(day1 PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED ON)
|
set_target_properties(day1 PROPERTIES CXX_STANDARD 23 CXX_STANDARD_REQUIRED ON)
|
||||||
|
# Use GCC 15's libstdc++ with Clang 21
|
||||||
|
target_compile_options(day1 PRIVATE --gcc-toolchain=/usr)
|
||||||
|
|
||||||
|
add_custom_command(TARGET day1 POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/day1_input
|
||||||
|
$<TARGET_FILE_DIR:day1>/day1_input
|
||||||
|
COMMENT "Copying day1_input to build directory"
|
||||||
|
)
|
||||||
|
|
|
||||||
4446
day1/day1_input
4446
day1/day1_input
File diff suppressed because it is too large
Load diff
|
|
@ -1,5 +1,76 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <vector>
|
||||||
|
#include <expected>
|
||||||
|
#include <print>
|
||||||
|
|
||||||
int main(int, char**){
|
struct DialRotation {
|
||||||
std::cout << "Hello, from aoc25 day1!\n";
|
char direction;
|
||||||
|
int distance;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto parseRotations(const std::string& filename) -> std::expected<std::vector<DialRotation>, std::string> {
|
||||||
|
std::ifstream inputF {filename};
|
||||||
|
|
||||||
|
if (!inputF){
|
||||||
|
|
||||||
|
return std::unexpected{"Some file open error.\n"};
|
||||||
|
}
|
||||||
|
std::vector<DialRotation> dialRotations{};
|
||||||
|
DialRotation curDial{};
|
||||||
|
while ( inputF >> curDial.direction >> curDial.distance)
|
||||||
|
{
|
||||||
|
//std::println("{} : {}", curDial.direction, curDial.distance);
|
||||||
|
dialRotations.push_back(curDial);
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::move(dialRotations);
|
||||||
|
}
|
||||||
|
constexpr int dialStart = 50;
|
||||||
|
constexpr int maxDial = 100 ;
|
||||||
|
|
||||||
|
auto executeSafeCrack(const std::vector<DialRotation>& dialRotations){
|
||||||
|
int dial {dialStart};
|
||||||
|
int countZero {};
|
||||||
|
for (const auto& curDial : dialRotations){
|
||||||
|
if(curDial.direction == 'L'){
|
||||||
|
dial -= curDial.distance % maxDial;
|
||||||
|
if (dial < 0){
|
||||||
|
dial += maxDial;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
dial += curDial.distance % maxDial;
|
||||||
|
if (dial > maxDial - 1){
|
||||||
|
dial -= maxDial;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::println("{} : {:3}, Dial now at: {:5}", curDial.direction, curDial.distance, dial);
|
||||||
|
if (dial == 0){
|
||||||
|
countZero++;
|
||||||
|
}
|
||||||
|
if (dial < 0){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (dial > maxDial){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::print("Zeros: {}", countZero);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto main(int, char**) -> int {
|
||||||
|
std::cout << "Hello, from aoc25 day1!!\n";
|
||||||
|
auto retval = parseRotations("day1_input");
|
||||||
|
|
||||||
|
if(retval)
|
||||||
|
{
|
||||||
|
executeSafeCrack(*retval);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
std::print("{}\n", retval.error());
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
28
scripts/run-clang-tidy.sh
Normal file
28
scripts/run-clang-tidy.sh
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
BUILD_DIR=build
|
||||||
|
if [ ! -f "${BUILD_DIR}/compile_commands.json" ]; then
|
||||||
|
echo "compile_commands.json not found; running cmake configure..."
|
||||||
|
cmake -S . -B "${BUILD_DIR}" -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
|
||||||
|
fi
|
||||||
|
if ! command -v clang-tidy >/dev/null 2>&1; then
|
||||||
|
echo "clang-tidy not found in PATH"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Prefer files tracked by git; fallback to find
|
||||||
|
if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
||||||
|
FILES=$(git ls-files '*.cpp' '*.cxx' '*.cc' '*.h' '*.hpp' || true)
|
||||||
|
else
|
||||||
|
FILES=$(find . -iname "*.cpp" -o -iname "*.cc" -o -iname "*.cxx" -o -iname "*.h" -o -iname "*.hpp")
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${FILES}" ]; then
|
||||||
|
echo "No source files found for clang-tidy"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
for f in ${FILES}; do
|
||||||
|
echo "Running clang-tidy on ${f}"
|
||||||
|
clang-tidy "${f}" -p "${BUILD_DIR}" || true
|
||||||
|
done
|
||||||
Loading…
Add table
Add a link
Reference in a new issue