commit 432d3f9317406183f9bc12034b19f98ee967c4e4 Author: Sebastian Tobie Date: Sun Dec 1 16:30:48 2024 +0100 Day 01 of 2024 diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 0000000..0314b35 --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,4 @@ +[build] +rustflags = [ + "-A", "dead_code", +] \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..9eb3ea8 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,53 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "adventofcode" +version = "0.1.0" +dependencies = [ + "adventofcode-macros", +] + +[[package]] +name = "adventofcode-macros" +version = "0.1.0" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "proc-macro2" +version = "1.0.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "syn" +version = "2.0.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..9708ac4 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,168 @@ +[package] +name = "adventofcode" +version = "0.1.0" +edition = "2021" +description = "My solutions for Advent of code 2024" + + +[[bin]] +name = "2024-01" +test = false +bench = false +path = "src/bin/2024/01.rs" + +[[bin]] +name = "2024-02" +test = false +bench = false +path = "src/bin/2024/02.rs" + +[[bin]] +name = "2024-03" +test = false +bench = false +path = "src/bin/2024/03.rs" + +[[bin]] +name = "2024-04" +test = false +bench = false +path = "src/bin/2024/04.rs" + +[[bin]] +name = "2024-05" +test = false +bench = false +path = "src/bin/2024/05.rs" + +[[bin]] +name = "2024-06" +test = false +bench = false +path = "src/bin/2024/06.rs" + +[[bin]] +name = "2024-07" +test = false +bench = false +path = "src/bin/2024/07.rs" + +[[bin]] +name = "2024-08" +test = false +bench = false +path = "src/bin/2024/08.rs" + +[[bin]] +name = "2024-09" +test = false +bench = false +path = "src/bin/2024/09.rs" + +[[bin]] +name = "2024-10" +test = false +bench = false +path = "src/bin/2024/10.rs" + +[[bin]] +name = "2024-11" +test = false +bench = false +path = "src/bin/2024/11.rs" + +[[bin]] +name = "2024-12" +test = false +bench = false +path = "src/bin/2024/12.rs" + +[[bin]] +name = "2024-13" +test = false +bench = false +path = "src/bin/2024/13.rs" + +[[bin]] +name = "2024-14" +test = false +bench = false +path = "src/bin/2024/14.rs" + +[[bin]] +name = "2024-15" +test = false +bench = false +path = "src/bin/2024/15.rs" + +[[bin]] +name = "2024-16" +test = false +bench = false +path = "src/bin/2024/16.rs" + +[[bin]] +name = "2024-17" +test = false +bench = false +path = "src/bin/2024/17.rs" + +[[bin]] +name = "2024-18" +test = false +bench = false +path = "src/bin/2024/18.rs" + +[[bin]] +name = "2024-19" +test = false +bench = false +path = "src/bin/2024/19.rs" + +[[bin]] +name = "2024-20" +test = false +bench = false +path = "src/bin/2024/20.rs" + +[[bin]] +name = "2024-21" +test = false +bench = false +path = "src/bin/2024/21.rs" + +[[bin]] +name = "2024-22" +test = false +bench = false +path = "src/bin/2024/22.rs" + +[[bin]] +name = "2024-23" +test = false +bench = false +path = "src/bin/2024/23.rs" + +[[bin]] +name = "2024-24" +test = false +bench = false +path = "src/bin/2024/24.rs" + +[[bin]] +name = "2024-25" +test = false +bench = false +path = "src/bin/2024/25.rs" + +[lib] +name = "advent_of_code" + +[dependencies] + +[dependencies.adventofcode-macros] +path = "macros" + +[workspace] + +[workspace.dependencies] diff --git a/macros/Cargo.toml b/macros/Cargo.toml new file mode 100644 index 0000000..74680c1 --- /dev/null +++ b/macros/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "adventofcode-macros" +version = "0.1.0" +edition = "2021" + +[lib] +proc-macro = true + +[dependencies] +quote = "1.0.*" +syn = "2.0.*" diff --git a/macros/src/lib.rs b/macros/src/lib.rs new file mode 100644 index 0000000..12b6fbe --- /dev/null +++ b/macros/src/lib.rs @@ -0,0 +1,66 @@ +use proc_macro::TokenStream; +use quote::quote; +use syn::{ + buffer::Cursor, + parse::{Parse, ParseStream, StepCursor}, + Error, +}; +use syn::{parse, LitInt, Result}; + +struct IncludeData { + year: String, + day: String, +} + +fn get_string<'a, 'b>(cursor: StepCursor<'a, 'b>) -> Result<(String, Cursor<'a>)> { + let (lit, c) = cursor.literal().unwrap(); + Ok((lit.span().source_text().unwrap(), c)) +} + +impl Parse for IncludeData { + fn parse(input: ParseStream) -> Result { + let mut data = IncludeData { + year: "".into(), + day: "".into(), + }; + let mut look = input.lookahead1(); + if !look.peek(LitInt) { + let s = input.span(); + return Err(Error::new(s, format!("{} is not an valid Year", s.source_text().unwrap()))); + } + data.year = input.step(get_string).expect("Wanted an string"); + look = input.lookahead1(); + if !look.peek(LitInt) { + let s = input.span(); + return Err(Error::new(s, format!("{} is not an valid Day", s.source_text().unwrap()))); + } + data.day = input.step(get_string).expect("Wanted an string"); + Ok(data) + } +} + +/// includes Data from Advent of code +/// ```ignore (cannot-doctest-external-file-dependency) +/// include_data!(2015 01) +/// +/// fn main() { +/// print!("{DATA}"); +/// } +/// ``` +#[proc_macro] +pub fn include_data(data: TokenStream)->TokenStream { + let gen = match parse::(data) { + Ok(data) => { + let path = format!("../../../data/{}/{}.txt", data.year, data.day); + quote! { + static DATA: &str = include_str!(#path); + } + }, + Err(_) => { + quote! { + static DATA: &str = ""; + } + }, + }; + gen.into() +} diff --git a/src/bin/2024/01.rs b/src/bin/2024/01.rs new file mode 100644 index 0000000..8f8ab3b --- /dev/null +++ b/src/bin/2024/01.rs @@ -0,0 +1,52 @@ +use advent_of_code::strings::{parsenumber, splitspace}; +use adventofcode_macros::include_data; + +include_data!(2024 01); + +fn distance(leftlist: &Vec, rightlist: &Vec) -> u32 { + let mut distance = 0; + for i in 0..leftlist.len() { + let left = leftlist[i]; + let right = rightlist[i]; + distance += match right > left { + true => right - left, + false => left - right, + }; + } + distance +} + +fn similarity(leftlist: &Vec, rightlist: &Vec) -> u32 { + let mut similarity = 0; + let mut count: u32; + for i in leftlist { + if rightlist.contains(i) { + count = 0; + for j in rightlist { + if *i == *j { + count += 1; + } + } + similarity += i * count; + } + } + similarity +} + +fn main() { + let mut leftlist = Vec::::with_capacity(1000); + let mut rightlist = Vec::::with_capacity(1000); + for (left, right) in DATA.split("\n").map(splitspace) { + leftlist.push(parsenumber(left)); + rightlist.push(parsenumber(right)); + } + leftlist.sort(); + rightlist.sort(); + let length = leftlist.len(); + if length != rightlist.len() { + println!("Not matching lists"); + return; + } + println!("Maximum Distance: {}", distance(&leftlist, &rightlist)); + println!("Similarity: {}", similarity(&leftlist, &rightlist)) +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..e8dfd78 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1 @@ +pub mod strings; diff --git a/src/strings.rs b/src/strings.rs new file mode 100644 index 0000000..09338f2 --- /dev/null +++ b/src/strings.rs @@ -0,0 +1,32 @@ +const MAXMUL: u32 = 100000; + +pub fn splitspace(input: &str) -> (&str, &str) { + let mut output = input.split_ascii_whitespace(); + (output.next().unwrap(), output.next().unwrap()) +} + +pub fn parsenumber(input: &str) -> u32 { + let mut output = 0; + let mut mul = 1; + for c in input.chars().rev() { + let i: u32 = match c { + '1' => 1, + '2' => 2, + '3' => 3, + '4' => 4, + '5' => 5, + '6' => 6, + '7' => 7, + '8' => 8, + '9' => 9, + '0' => 0, + _ => 0, + }; + if mul > MAXMUL { + return output; + } + output += i * mul; + mul *= 10; + } + output +}