mirror of
https://github.com/OMGeeky/advent-of-code-2023.git
synced 2025-12-26 16:07:38 +01:00
initial setup & day 1
This commit is contained in:
47
.devcontainer/devcontainer.json
Normal file
47
.devcontainer/devcontainer.json
Normal file
@@ -0,0 +1,47 @@
|
||||
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
|
||||
// README at: https://github.com/devcontainers/templates/tree/main/src/rust
|
||||
{
|
||||
"name": "Rust",
|
||||
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
|
||||
"image": "mcr.microsoft.com/devcontainers/rust:1-1-bullseye",
|
||||
"features": {
|
||||
"ghcr.io/devcontainers-contrib/features/zsh-plugins:0": {}
|
||||
},
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": [
|
||||
"rust-lang.rust-analyzer",
|
||||
"GitHub.copilot-chat",
|
||||
"tamasfe.even-better-toml",
|
||||
"GitHub.copilot-labs",
|
||||
"GitHub.copilot",
|
||||
"yzhang.markdown-all-in-one",
|
||||
"alexcvzz.vscode-sqlite"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
// Use 'mounts' to make the cargo cache persistent in a Docker Volume.
|
||||
// "mounts": [
|
||||
// {
|
||||
// "source": "devcontainer-cargo-cache-${devcontainerId}",
|
||||
// "target": "/usr/local/cargo",
|
||||
// "type": "volume"
|
||||
// }
|
||||
// ]
|
||||
|
||||
// Features to add to the dev container. More info: https://containers.dev/features.
|
||||
// "features": {},
|
||||
|
||||
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||
// "forwardPorts": [],
|
||||
|
||||
// Use 'postCreateCommand' to run commands after the container is created.
|
||||
// "postCreateCommand": "rustc --version",
|
||||
|
||||
// Configure tool-specific properties.
|
||||
// "customizations": {},
|
||||
|
||||
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
|
||||
// "remoteUser": "root"
|
||||
}
|
||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -12,3 +12,8 @@ Cargo.lock
|
||||
|
||||
# MSVC Windows builds of rustc generate these, which store debugging information
|
||||
*.pdb
|
||||
|
||||
|
||||
# Added by cargo
|
||||
|
||||
/target
|
||||
|
||||
64
.vscode/launch.json
vendored
Normal file
64
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"name": "Debug unit tests in library 'advent-of-code-2023'",
|
||||
"cargo": {
|
||||
"args": [
|
||||
"test",
|
||||
"--no-run",
|
||||
"--lib",
|
||||
"--package=advent-of-code-2023"
|
||||
],
|
||||
"filter": {
|
||||
"name": "advent-of-code-2023",
|
||||
"kind": "lib"
|
||||
}
|
||||
},
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}"
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"name": "Debug executable 'advent-of-code-2023'",
|
||||
"cargo": {
|
||||
"args": [
|
||||
"build",
|
||||
"--bin=advent-of-code-2023",
|
||||
"--package=advent-of-code-2023"
|
||||
],
|
||||
"filter": {
|
||||
"name": "advent-of-code-2023",
|
||||
"kind": "bin"
|
||||
}
|
||||
},
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}"
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"name": "Debug unit tests in executable 'advent-of-code-2023'",
|
||||
"cargo": {
|
||||
"args": [
|
||||
"test",
|
||||
"--no-run",
|
||||
"--bin=advent-of-code-2023",
|
||||
"--package=advent-of-code-2023"
|
||||
],
|
||||
"filter": {
|
||||
"name": "advent-of-code-2023",
|
||||
"kind": "bin"
|
||||
}
|
||||
},
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}"
|
||||
}
|
||||
]
|
||||
}
|
||||
13
Cargo.toml
Normal file
13
Cargo.toml
Normal file
@@ -0,0 +1,13 @@
|
||||
[package]
|
||||
name = "advent-of-code-2023"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
tokio = { version = "1.16.1", features = ["full"] }
|
||||
serde = { version = "1.0.130", features = ["derive"] }
|
||||
serde_json = "1.0.68"
|
||||
|
||||
paste ={ version = "1.0" }
|
||||
1000
input/day01.txt
Normal file
1000
input/day01.txt
Normal file
File diff suppressed because it is too large
Load Diff
114
src/day01.rs
Normal file
114
src/day01.rs
Normal file
@@ -0,0 +1,114 @@
|
||||
use crate::{Day, DayPart2};
|
||||
|
||||
pub struct Day01;
|
||||
impl Day for Day01 {
|
||||
const DAY_NUM: u8 = 01;
|
||||
|
||||
type Input = String;
|
||||
|
||||
type Output = usize;
|
||||
|
||||
fn get_test_data() -> Vec<Self::Input> {
|
||||
vec![
|
||||
"1abc2".to_string(),
|
||||
"pqr3stu8vwx".to_string(),
|
||||
"a1b2c3d4e5f".to_string(),
|
||||
"treb7uchet".to_string(),
|
||||
]
|
||||
}
|
||||
|
||||
fn get_test_result() -> Self::Output {
|
||||
142
|
||||
}
|
||||
|
||||
fn run(data: Vec<Self::Input>) -> Self::Output {
|
||||
let mut sum = 0;
|
||||
for line in data {
|
||||
let mut digits = line.chars().filter(|c| c.is_digit(10));
|
||||
let first = digits.next().unwrap_or(' ');
|
||||
let last = digits.last().unwrap_or(first);
|
||||
let num = format!("{}{}", first, last)
|
||||
.trim()
|
||||
.parse::<usize>()
|
||||
.unwrap();
|
||||
println!(
|
||||
"{} + {} = {}; total: {} => {}",
|
||||
first,
|
||||
last,
|
||||
num,
|
||||
sum,
|
||||
sum + num
|
||||
);
|
||||
sum += num;
|
||||
}
|
||||
sum
|
||||
}
|
||||
}
|
||||
impl DayPart2 for Day01 {
|
||||
fn get_test_data_part2() -> Vec<String> {
|
||||
vec![
|
||||
"two1nine".to_string(),
|
||||
"eightwothree".to_string(),
|
||||
"abcone2threexyz".to_string(),
|
||||
"xtwone3four".to_string(),
|
||||
"4nineeightseven2".to_string(),
|
||||
"zoneight234".to_string(),
|
||||
"7pqrstsixteen".to_string(),
|
||||
]
|
||||
}
|
||||
fn get_test_result_part2() -> usize {
|
||||
281
|
||||
}
|
||||
|
||||
fn run_part2(data: Vec<String>) -> usize {
|
||||
let mut sum = 0;
|
||||
for line in data {
|
||||
let mut l = String::new();
|
||||
for i in 0..line.len() {
|
||||
let part = &line[i..];
|
||||
// println!("{}", part);
|
||||
let c = part.chars().next().unwrap();
|
||||
if c.is_digit(10) {
|
||||
l.push(c);
|
||||
}
|
||||
if part.starts_with("one") {
|
||||
l.push('1')
|
||||
} else if part.starts_with("two") {
|
||||
l.push('2')
|
||||
} else if part.starts_with("three") {
|
||||
l.push('3')
|
||||
} else if part.starts_with("four") {
|
||||
l.push('4')
|
||||
} else if part.starts_with("five") {
|
||||
l.push('5')
|
||||
} else if part.starts_with("six") {
|
||||
l.push('6')
|
||||
} else if part.starts_with("seven") {
|
||||
l.push('7')
|
||||
} else if part.starts_with("eight") {
|
||||
l.push('8')
|
||||
} else if part.starts_with("nine") {
|
||||
l.push('9')
|
||||
}
|
||||
}
|
||||
let mut digits = l.chars().filter(|c| c.is_digit(10));
|
||||
let first = digits.next().unwrap_or(' ');
|
||||
let last = digits.last().unwrap_or(first);
|
||||
// println!("'{}' '{}'", first, last);
|
||||
let num = format!("{}{}", first, last)
|
||||
.trim()
|
||||
.parse::<usize>()
|
||||
.unwrap();
|
||||
println!(
|
||||
"{} + {} = {}; total: {} => {}",
|
||||
first,
|
||||
last,
|
||||
num,
|
||||
sum,
|
||||
sum + num
|
||||
);
|
||||
sum += num;
|
||||
}
|
||||
sum
|
||||
}
|
||||
}
|
||||
20
src/day02.rs
Normal file
20
src/day02.rs
Normal file
@@ -0,0 +1,20 @@
|
||||
use crate::*;
|
||||
|
||||
pub struct Day02;
|
||||
impl Day for Day02 {
|
||||
const DAY_NUM: u8 = 02;
|
||||
type Input = String;
|
||||
type Output = usize;
|
||||
|
||||
fn get_test_data() -> Vec<Self::Input> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_test_result() -> Self::Output {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn run(data: Vec<Self::Input>) -> Self::Output {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
20
src/day_templatce.rs
Normal file
20
src/day_templatce.rs
Normal file
@@ -0,0 +1,20 @@
|
||||
use crate::*;
|
||||
|
||||
pub struct Dayxx;
|
||||
impl Day for Dayxx {
|
||||
const DAY_NUM: u8 = xx;
|
||||
type Input = String;
|
||||
type Output = usize;
|
||||
|
||||
fn get_test_data() -> Vec<Self::Input> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_test_result() -> Self::Output {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn run(data: Vec<Self::Input>) -> Self::Output {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
128
src/lib.rs
Normal file
128
src/lib.rs
Normal file
@@ -0,0 +1,128 @@
|
||||
use std::str::FromStr;
|
||||
|
||||
pub fn read_input<T>(day: u8) -> Vec<T>
|
||||
where
|
||||
T: From<String>,
|
||||
{
|
||||
let filename = format!("input/day{:02}.txt", day);
|
||||
println!("Reading input from {}", filename);
|
||||
let input = std::fs::read_to_string(filename).unwrap();
|
||||
utils::day!();
|
||||
input.lines().map(|s| s.to_string().into()).collect()
|
||||
}
|
||||
mod day01;
|
||||
pub use day01::Day01;
|
||||
mod day02;
|
||||
pub use day02::Day02;
|
||||
|
||||
pub mod utils {
|
||||
#[macro_export]
|
||||
macro_rules! day {
|
||||
($num: expr) => {
|
||||
paste::item! {
|
||||
fn [< run_test_day $num >] () {
|
||||
use [< day $num>];
|
||||
type D = [< Day $num>];
|
||||
let test_res = D::run(D::get_test_data());
|
||||
println!("Day {}: {:?}", $num, test_res);
|
||||
assert_eq!(D::get_test_result(), test_res);
|
||||
}
|
||||
fn [< run_day $num >] () {
|
||||
let test_res = [< day $num>]::run(read_input($num));
|
||||
println!("Day {} result: \n{:?}", $num, test_res);
|
||||
}
|
||||
fn [< run_test_day $num _part2>] () {
|
||||
let test_res = [< day $num>]::run_part2([< day $num>]::get_test_data_part2());
|
||||
println!("Day {} part2 test: {:?}", $num, test_res);
|
||||
assert_eq!([< day $num>]::get_test_result_part2(), test_res);
|
||||
}
|
||||
fn [< run_day $num _part2>] () {
|
||||
let test_res = [< day $num>]::run_part2(read_input($num));
|
||||
println!("Day {} part 2 result: \n{:?}", $num, test_res);
|
||||
}
|
||||
}
|
||||
};
|
||||
() => {
|
||||
//hi
|
||||
};
|
||||
}
|
||||
pub use day;
|
||||
#[macro_export]
|
||||
macro_rules! run {
|
||||
// ($num: expr) => {
|
||||
// paste::item! {
|
||||
// [< run_test_day $num >] ();
|
||||
// [< run_day $num >] ();
|
||||
// [< run_test_day $num _part2 >] ();
|
||||
// [< run_day $num _part2>] ();
|
||||
// }
|
||||
// };
|
||||
() => {
|
||||
// run!(01);
|
||||
// run!(02);
|
||||
// run!(03);
|
||||
// run!(04);
|
||||
// run!(05);
|
||||
// run!(06);
|
||||
// run!(07);
|
||||
// run!(08);
|
||||
// run!(09);
|
||||
};
|
||||
}
|
||||
pub use run;
|
||||
}
|
||||
pub trait Day
|
||||
where
|
||||
<Self as Day>::Input: std::fmt::Debug + From<String>,
|
||||
<Self as Day>::Output: std::fmt::Debug + PartialEq,
|
||||
{
|
||||
const DAY_NUM: u8;
|
||||
type Input;
|
||||
type Output;
|
||||
|
||||
fn get_test_data() -> Vec<Self::Input>;
|
||||
fn get_test_result() -> Self::Output;
|
||||
fn run(data: Vec<Self::Input>) -> Self::Output;
|
||||
}
|
||||
pub trait DayPart2: Day {
|
||||
fn run_part2(data: Vec<Self::Input>) -> Self::Output;
|
||||
fn get_test_result_part2() -> Self::Output;
|
||||
fn get_test_data_part2() -> Vec<Self::Input>;
|
||||
}
|
||||
pub trait DayConvenience: Day {
|
||||
fn run_day_test() {
|
||||
let test_res = Self::run(Self::get_test_data());
|
||||
println!("Day {}: {:?}", Self::DAY_NUM, test_res);
|
||||
assert_eq!(Self::get_test_result(), test_res);
|
||||
}
|
||||
fn run_day() {
|
||||
let test_res = Self::run(read_input(Self::DAY_NUM));
|
||||
println!("Day {} result: \n{:?}", Self::DAY_NUM, test_res);
|
||||
}
|
||||
fn part1() {
|
||||
Self::run_day_test();
|
||||
Self::run_day();
|
||||
}
|
||||
}
|
||||
impl<T> DayConvenience for T where T: Day {}
|
||||
|
||||
pub trait DayPart2Convenience: DayPart2 + DayConvenience {
|
||||
fn run_day_part2_test() {
|
||||
let test_res = Self::run_part2(Self::get_test_data_part2());
|
||||
println!("Day {} part 2: {:?}", Self::DAY_NUM, test_res);
|
||||
assert_eq!(Self::get_test_result_part2(), test_res);
|
||||
}
|
||||
fn run_day_part2() {
|
||||
let test_res = Self::run_part2(read_input(Self::DAY_NUM));
|
||||
println!("Day {} part 2 result: \n{:?}", Self::DAY_NUM, test_res);
|
||||
}
|
||||
fn part2(){
|
||||
Self::run_day_part2_test();
|
||||
Self::run_day_part2();
|
||||
}
|
||||
fn run_all() {
|
||||
Self::part1();
|
||||
Self::part2();
|
||||
}
|
||||
}
|
||||
impl<T> DayPart2Convenience for T where T: DayPart2 {}
|
||||
10
src/main.rs
Normal file
10
src/main.rs
Normal file
@@ -0,0 +1,10 @@
|
||||
use advent_of_code_2023::*;
|
||||
fn main() {
|
||||
// run_test_day01_part2();
|
||||
Day01::run_all();
|
||||
Day02::part1();
|
||||
// utils::run!(01);
|
||||
// utils::run!(02);
|
||||
}
|
||||
// utils::day!(01);
|
||||
// utils::day!(02);
|
||||
Reference in New Issue
Block a user