added the code for day 1 and 2 from 2023
Dieser Commit ist enthalten in:
Ursprung
432d3f9317
Commit
e105d73f50
8 geänderte Dateien mit 487 neuen und 20 gelöschten Zeilen
1
Cargo.lock
generiert
1
Cargo.lock
generiert
|
@ -13,6 +13,7 @@ dependencies = [
|
|||
name = "adventofcode-macros"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
|
150
Cargo.toml
150
Cargo.toml
|
@ -5,6 +5,156 @@ edition = "2021"
|
|||
description = "My solutions for Advent of code 2024"
|
||||
|
||||
|
||||
[[bin]]
|
||||
name = "2023-01"
|
||||
test = false
|
||||
bench = false
|
||||
path = "src/bin/2023/01.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "2023-02"
|
||||
test = false
|
||||
bench = false
|
||||
path = "src/bin/2023/02.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "2023-03"
|
||||
test = false
|
||||
bench = false
|
||||
path = "src/bin/2023/03.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "2023-04"
|
||||
test = false
|
||||
bench = false
|
||||
path = "src/bin/2023/04.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "2023-05"
|
||||
test = false
|
||||
bench = false
|
||||
path = "src/bin/2023/05.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "2023-06"
|
||||
test = false
|
||||
bench = false
|
||||
path = "src/bin/2023/06.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "2023-07"
|
||||
test = false
|
||||
bench = false
|
||||
path = "src/bin/2023/07.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "2023-08"
|
||||
test = false
|
||||
bench = false
|
||||
path = "src/bin/2023/08.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "2023-09"
|
||||
test = false
|
||||
bench = false
|
||||
path = "src/bin/2023/09.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "2023-10"
|
||||
test = false
|
||||
bench = false
|
||||
path = "src/bin/2023/10.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "2023-11"
|
||||
test = false
|
||||
bench = false
|
||||
path = "src/bin/2023/11.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "2023-12"
|
||||
test = false
|
||||
bench = false
|
||||
path = "src/bin/2023/12.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "2023-13"
|
||||
test = false
|
||||
bench = false
|
||||
path = "src/bin/2023/13.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "2023-14"
|
||||
test = false
|
||||
bench = false
|
||||
path = "src/bin/2023/14.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "2023-15"
|
||||
test = false
|
||||
bench = false
|
||||
path = "src/bin/2023/15.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "2023-16"
|
||||
test = false
|
||||
bench = false
|
||||
path = "src/bin/2023/16.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "2023-17"
|
||||
test = false
|
||||
bench = false
|
||||
path = "src/bin/2023/17.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "2023-18"
|
||||
test = false
|
||||
bench = false
|
||||
path = "src/bin/2023/18.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "2023-19"
|
||||
test = false
|
||||
bench = false
|
||||
path = "src/bin/2023/19.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "2023-20"
|
||||
test = false
|
||||
bench = false
|
||||
path = "src/bin/2023/20.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "2023-21"
|
||||
test = false
|
||||
bench = false
|
||||
path = "src/bin/2023/21.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "2023-22"
|
||||
test = false
|
||||
bench = false
|
||||
path = "src/bin/2023/22.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "2023-23"
|
||||
test = false
|
||||
bench = false
|
||||
path = "src/bin/2023/23.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "2023-24"
|
||||
test = false
|
||||
bench = false
|
||||
path = "src/bin/2023/24.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "2023-25"
|
||||
test = false
|
||||
bench = false
|
||||
path = "src/bin/2023/25.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "2024-01"
|
||||
test = false
|
||||
|
|
8
build.rs
Normale Datei
8
build.rs
Normale Datei
|
@ -0,0 +1,8 @@
|
|||
fn main() {
|
||||
for year in 2015..2025 {
|
||||
for day in 1..26 {
|
||||
println!("cargo::rerun-if-changed=data/{year:04}/{day:02}.txt");
|
||||
}
|
||||
}
|
||||
println!("cargo::rerun-if-changed=build.rs");
|
||||
}
|
|
@ -9,3 +9,4 @@ proc-macro = true
|
|||
[dependencies]
|
||||
quote = "1.0.*"
|
||||
syn = "2.0.*"
|
||||
proc-macro2 = {version = "*", features = ["span-locations"]}
|
|
@ -13,8 +13,26 @@ struct IncludeData {
|
|||
}
|
||||
|
||||
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))
|
||||
let (lit, c) = match cursor.literal() {
|
||||
Some(literal) => literal,
|
||||
None => return Err(Error::new(cursor.span(), "Failed to get literal")),
|
||||
};
|
||||
let span = lit.span();
|
||||
let text = match span.source_text() {
|
||||
Some(text) => text,
|
||||
None => {
|
||||
let start = span.start();
|
||||
let end = span.end();
|
||||
return Err(Error::new(
|
||||
span,
|
||||
format!(
|
||||
"Failed to get sourcetext for {}:{}-{}:{}",
|
||||
start.line, start.column, end.line, end.column,
|
||||
),
|
||||
));
|
||||
}
|
||||
};
|
||||
Ok((text, c))
|
||||
}
|
||||
|
||||
impl Parse for IncludeData {
|
||||
|
@ -26,19 +44,41 @@ impl Parse for IncludeData {
|
|||
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())));
|
||||
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())));
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
fn get_stream(dir: &str, data: Result<IncludeData>) -> TokenStream {
|
||||
match data {
|
||||
Ok(id) => {
|
||||
let path = format!("../../../{}/{}/{}.txt", dir, id.year, id.day);
|
||||
quote! {
|
||||
static DATA: &str = include_str!(#path);
|
||||
}
|
||||
}
|
||||
Err(_)=> {
|
||||
quote! {
|
||||
static DATA: &str = "";
|
||||
}
|
||||
}
|
||||
}.into()
|
||||
}
|
||||
|
||||
/// includes Data from Advent of code
|
||||
/// ```ignore (cannot-doctest-external-file-dependency)
|
||||
/// include_data!(2015 01)
|
||||
|
@ -47,20 +87,16 @@ impl Parse for IncludeData {
|
|||
/// print!("{DATA}");
|
||||
/// }
|
||||
/// ```
|
||||
/// The Equivalent is
|
||||
/// ```ignore (cannot-doctest-external-file-dependency)
|
||||
/// static DATA: &str = include_str!("../../../data/2015/01.txt");
|
||||
/// ```
|
||||
#[proc_macro]
|
||||
pub fn include_data(data: TokenStream)->TokenStream {
|
||||
let gen = match parse::<IncludeData>(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()
|
||||
pub fn include_data(data: TokenStream) -> TokenStream {
|
||||
get_stream("data", parse::<IncludeData>(data))
|
||||
}
|
||||
|
||||
#[proc_macro]
|
||||
pub fn include_example(data: TokenStream)->TokenStream {
|
||||
get_stream("examples", parse::<IncludeData>(data))
|
||||
}
|
34
src/bin/2023/01.rs
Normale Datei
34
src/bin/2023/01.rs
Normale Datei
|
@ -0,0 +1,34 @@
|
|||
use advent_of_code::strings::{get_numbers, get_string_numbers};
|
||||
#[allow(unused_imports)]
|
||||
use adventofcode_macros::{include_example, include_example};
|
||||
|
||||
include_example!(2023 01);
|
||||
//static DATA: &str;
|
||||
|
||||
fn main() {
|
||||
let mut sum: u32 = 0;
|
||||
let data: String = DATA.into();
|
||||
for coordinates in data.split('\n').map(get_numbers) {
|
||||
if coordinates.len() == 0 {
|
||||
continue;
|
||||
}
|
||||
let first = coordinates.first().unwrap() * 10;
|
||||
let last = *coordinates.last().unwrap();
|
||||
let number = first + last;
|
||||
println!("Number: {}", number);
|
||||
sum += number;
|
||||
}
|
||||
println!("Sum of Numbers {}", sum);
|
||||
sum = 0;
|
||||
for coordinates in data.split('\n').map(get_string_numbers) {
|
||||
if coordinates.len() == 0 {
|
||||
continue;
|
||||
}
|
||||
let first = coordinates.first().unwrap() * 10;
|
||||
let last = *coordinates.last().unwrap();
|
||||
let number = first + last;
|
||||
println!("Number: {}", number);
|
||||
sum += number;
|
||||
}
|
||||
println!("Sum of Numbers with strings {}", sum);
|
||||
}
|
111
src/bin/2023/02.rs
Normale Datei
111
src/bin/2023/02.rs
Normale Datei
|
@ -0,0 +1,111 @@
|
|||
use advent_of_code::strings::parsenumber;
|
||||
#[allow(unused_imports)]
|
||||
use adventofcode_macros::{include_example, include_example};
|
||||
|
||||
include_example!(2023 02);
|
||||
//static DATA: &str;
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
struct Take {
|
||||
red: u32,
|
||||
green: u32,
|
||||
blue: u32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct Round {
|
||||
roundid: u32,
|
||||
takes: Vec<Take>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
struct Sack {
|
||||
reds: u32,
|
||||
greens: u32,
|
||||
blues: u32,
|
||||
}
|
||||
|
||||
impl Round {
|
||||
pub fn possible(&self, sack: Sack) -> bool {
|
||||
let mut ok = true;
|
||||
for take in self.takes.clone() {
|
||||
ok = ok
|
||||
&& if sack.reds.checked_sub(take.red).is_none() {
|
||||
false
|
||||
} else if sack.greens.checked_sub(take.green).is_none() {
|
||||
false
|
||||
} else if sack.blues.checked_sub(take.blue).is_none() {
|
||||
false
|
||||
} else {
|
||||
true
|
||||
};
|
||||
}
|
||||
ok
|
||||
}
|
||||
fn power(&self) -> u64 {
|
||||
let mut sack = Sack{reds:0, greens:0, blues:0};
|
||||
for take in self.takes.clone() {
|
||||
if take.red > sack.reds {
|
||||
sack.reds = take.red
|
||||
}if take.green > sack.greens {
|
||||
sack.greens = take.green
|
||||
}if take.blue > sack.blues {
|
||||
sack.blues = take.blue
|
||||
}
|
||||
}
|
||||
sack.reds as u64 *sack.greens as u64*sack.blues as u64
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for Round {
|
||||
fn from(value: &str) -> Self {
|
||||
let doublecolon = value.find(':').unwrap();
|
||||
let mut round = Round {
|
||||
roundid: parsenumber(value.get(5..doublecolon).unwrap()),
|
||||
takes: Vec::<Take>::new(),
|
||||
};
|
||||
for taking in value.get(doublecolon + 1..).unwrap().split(";") {
|
||||
let mut take = Take {
|
||||
red: 0,
|
||||
green: 0,
|
||||
blue: 0,
|
||||
};
|
||||
for color in taking.split(',').map(str::trim) {
|
||||
let mut i = color.splitn(2, char::is_whitespace);
|
||||
let amount = parsenumber(i.next().unwrap());
|
||||
match i.next() {
|
||||
Some("red") => take.red = amount,
|
||||
Some("green") => take.green = amount,
|
||||
Some("blue") => take.blue = amount,
|
||||
None | Some(_) => panic!(),
|
||||
}
|
||||
}
|
||||
round.takes.push(take);
|
||||
}
|
||||
round
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut gamerounds = Vec::<Round>::with_capacity(100);
|
||||
for game in DATA.split('\n') {
|
||||
gamerounds.push(game.into());
|
||||
}
|
||||
let sack = Sack {
|
||||
reds: 12,
|
||||
greens: 13,
|
||||
blues: 14,
|
||||
};
|
||||
let mut sum = 0;
|
||||
for round in gamerounds.clone() {
|
||||
if round.possible(sack) {
|
||||
sum += round.roundid;
|
||||
}
|
||||
}
|
||||
println!("Sum with putback: {}", sum);
|
||||
let mut sum = 0;
|
||||
for round in gamerounds {
|
||||
sum += round.power();
|
||||
}
|
||||
println!("Combined Power: {}", sum);
|
||||
}
|
126
src/strings.rs
126
src/strings.rs
|
@ -30,3 +30,129 @@ pub fn parsenumber(input: &str) -> u32 {
|
|||
}
|
||||
output
|
||||
}
|
||||
|
||||
pub fn get_numbers(input: &str) -> Vec<u32> {
|
||||
let mut numbers = Vec::new();
|
||||
for char in input.chars() {
|
||||
match char {
|
||||
'1' => numbers.push(1),
|
||||
'2' => numbers.push(2),
|
||||
'3' => numbers.push(3),
|
||||
'4' => numbers.push(4),
|
||||
'5' => numbers.push(5),
|
||||
'6' => numbers.push(6),
|
||||
'7' => numbers.push(7),
|
||||
'8' => numbers.push(8),
|
||||
'9' => numbers.push(9),
|
||||
'0' => numbers.push(0),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
numbers
|
||||
}
|
||||
|
||||
pub fn get_string_numbers(input: &str) -> Vec<u32> {
|
||||
let len = input.len();
|
||||
let mut output = Vec::new();
|
||||
for i in 0..len {
|
||||
match input.get(i..i + 1).unwrap() {
|
||||
"1" => {
|
||||
output.push(1);
|
||||
continue;
|
||||
}
|
||||
"2" => {
|
||||
output.push(2);
|
||||
continue;
|
||||
}
|
||||
"3" => {
|
||||
output.push(3);
|
||||
continue;
|
||||
}
|
||||
"4" => {
|
||||
output.push(4);
|
||||
continue;
|
||||
}
|
||||
"5" => {
|
||||
output.push(5);
|
||||
continue;
|
||||
}
|
||||
"6" => {
|
||||
output.push(6);
|
||||
continue;
|
||||
}
|
||||
"7" => {
|
||||
output.push(7);
|
||||
continue;
|
||||
}
|
||||
"8" => {
|
||||
output.push(8);
|
||||
continue;
|
||||
}
|
||||
"9" => {
|
||||
output.push(9);
|
||||
continue;
|
||||
}
|
||||
"0" => {
|
||||
output.push(0);
|
||||
continue;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
if (i + 3) <= len {
|
||||
match input.get(i..i + 3).unwrap() {
|
||||
"one" => {
|
||||
output.push(1);
|
||||
continue;
|
||||
}
|
||||
"two" => {
|
||||
output.push(2);
|
||||
continue;
|
||||
}
|
||||
"six" => {
|
||||
output.push(6);
|
||||
continue;
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
}
|
||||
if (i + 4) <= len {
|
||||
match input.get(i..i + 4).unwrap() {
|
||||
"four" => {
|
||||
output.push(4);
|
||||
continue;
|
||||
}
|
||||
"five" => {
|
||||
output.push(5);
|
||||
continue;
|
||||
}
|
||||
"nine" => {
|
||||
output.push(9);
|
||||
continue;
|
||||
}
|
||||
"zero" => {
|
||||
output.push(0);
|
||||
continue;
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
}
|
||||
if (i + 5) <= len {
|
||||
match input.get(i..i + 5).unwrap() {
|
||||
"three" => {
|
||||
output.push(3);
|
||||
continue;
|
||||
}
|
||||
"seven" => {
|
||||
output.push(7);
|
||||
continue;
|
||||
}
|
||||
"eight" => {
|
||||
output.push(8);
|
||||
continue;
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
}
|
||||
}
|
||||
output
|
||||
}
|
||||
|
|
Laden …
Tabelle hinzufügen
In neuem Issue referenzieren