From 8d8fe535740217ad700a7d1b895147b521e5b546 Mon Sep 17 00:00:00 2001 From: Spectre Date: Tue, 3 Dec 2024 01:28:15 +0100 Subject: [PATCH 1/4] main.rs --- src/fetch_input.rs | 30 +++++++++++++++++++++++++++++ src/main.rs | 47 ++++++++++++++-------------------------------- 2 files changed, 44 insertions(+), 33 deletions(-) create mode 100644 src/fetch_input.rs diff --git a/src/fetch_input.rs b/src/fetch_input.rs new file mode 100644 index 0000000..cfa89fb --- /dev/null +++ b/src/fetch_input.rs @@ -0,0 +1,30 @@ +use reqwest::{blocking::Client, Url}; + +use std::fs::File; +use std::io::prelude::*; +use std::path::Path; +use std::sync::Arc; +use std::env; + +pub fn fetch_input(year: usize, day: usize) -> Result<(), Box> { + let url = format!("https://adventofcode.com/{year}/day/{day}/input"); + let session_cookie = env::var("ADVENT_TOKEN")?; + + let jar = reqwest::cookie::Jar::default(); + jar.add_cookie_str(&format!("session={session_cookie}; Domain=.adventofcode.com"), &"https://adventofcode.com".parse::().unwrap()); + + let client = Client::builder().cookie_provider(Arc::new(jar)).build().unwrap(); + let response = client + .get(url) + .send()?; + + let body = response.text()?; + + let path = format!("./data/{}/day{:02}", year, day); + + let mut output = File::create(path)?; + + output.write_all(body.as_bytes())?; + + Ok(()) +} diff --git a/src/main.rs b/src/main.rs index e65dc88..0edfabb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,20 +4,24 @@ use solution::solution; mod input_data; use input_data::load_actual; -use reqwest::{blocking::Client, Url}; +mod fetch_input; +use fetch_input::fetch_input; -use std::fs::File; -use std::io::prelude::*; -use std::path::Path; -use std::sync::Arc; -use std::{time::Instant, env}; +use std::{path::Path, time::Instant, env}; fn main() { - let year = 2024; - let day = 1; + let year = env::var("ADVENT_YEAR") + .unwrap() + .parse() + .unwrap_or(2024); + let day = env::var("ADVENT_DAY") + .unwrap() + .parse() + .unwrap_or(1); - if ! Path::new(&format!("./data/{}/day{:02}", year, day)).exists() { - fetch_data(year, day).unwrap(); + if ! Path::new(&format!("./data/{}/day{:02}", year, day)).exists() + && env::var("ADVENT_TOKEN").is_ok() { + fetch_input(year, day).expect("Set ADVENT_TOKEN to the correct session cookie to fetch input automatically"); } let Ok(data) = load_actual(year, day) @@ -39,26 +43,3 @@ fn main() { println!("Part 2 result is {}, took {}ms", part2, elapsed2.as_millis()); } - -fn fetch_data(year: usize, day: usize) -> Result<(), Box> { - let url = format!("https://adventofcode.com/{year}/day/{day}/input"); - let session_cookie = env::var("ADVENT_TOKEN")?; - - let jar = reqwest::cookie::Jar::default(); - jar.add_cookie_str(&format!("session={session_cookie}; Domain=.adventofcode.com"), &"https://adventofcode.com".parse::().unwrap()); - - let client = Client::builder().cookie_provider(Arc::new(jar)).build().unwrap(); - let response = client - .get(url) - .send()?; - - let body = response.text()?; - - let path = format!("./data/{}/day{:02}", year, day); - - let mut output = File::create(path)?; - - output.write_all(body.as_bytes())?; - - Ok(()) -} From 19fe0a53ffd4f9691e9d67466d49e7ee7ff08919 Mon Sep 17 00:00:00 2001 From: Spectre Date: Tue, 3 Dec 2024 01:28:22 +0100 Subject: [PATCH 2/4] main.rs --- .envrc | 6 ++++++ src/main.rs | 11 ++++++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/.envrc b/.envrc index 3550a30..b524e39 100644 --- a/.envrc +++ b/.envrc @@ -1 +1,7 @@ use flake + +if [[ $(date +'%m') -eq 12 ]] +then + export ADVENT_YEAR=$(date +'%Y') + export ADVENT_DAY=$(date +'%d') +fi diff --git a/src/main.rs b/src/main.rs index 0edfabb..52bf882 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,18 +11,20 @@ use std::{path::Path, time::Instant, env}; fn main() { let year = env::var("ADVENT_YEAR") - .unwrap() + .unwrap_or("2024".into()) .parse() - .unwrap_or(2024); + .unwrap(); let day = env::var("ADVENT_DAY") - .unwrap() + .unwrap_or("1".into()) .parse() - .unwrap_or(1); + .unwrap(); if ! Path::new(&format!("./data/{}/day{:02}", year, day)).exists() && env::var("ADVENT_TOKEN").is_ok() { fetch_input(year, day).expect("Set ADVENT_TOKEN to the correct session cookie to fetch input automatically"); } + + println!("Attempting to run {year}/{day}"); let Ok(data) = load_actual(year, day) else { panic!("No Input Data"); }; @@ -41,5 +43,4 @@ fn main() { println!("Part 1 result is {}, took {}ms", part1, elapsed1.as_millis()); println!("Part 2 result is {}, took {}ms", part2, elapsed2.as_millis()); - } From 2c9790a690e8e2487d2189957a351a30a00eeb0a Mon Sep 17 00:00:00 2001 From: Spectre Date: Tue, 3 Dec 2024 02:06:24 +0100 Subject: [PATCH 3/4] qol --- README.md | 2 +- aoc2023/src/day01.rs | 2 +- aoc2024/src/day01.rs | 2 +- data/README.md | 13 +++++++++++++ src/input_data.rs | 7 ++++--- src/main.rs | 46 ++++++++++++++++++++++++++------------------ src/solution.rs | 2 +- 7 files changed, 48 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 80c58b2..b9f9596 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ # My Advent of Code solutions, written as an exercise to learn Rust. -To run, simply edit ´src/main.rs´ and run it. Optionally, set the year and day via ´ADVENT_YEAR´ and ´ADVENT_DAY´ environment variables. By setting ´ADVENT_TOKEN´ to your browser session token, your personal input can optionally be fetched automatically. +To run, simply edit `src/main.rs` and run it. Optionally, set the year and day via `ADVENT_YEAR` and `ADVENT_DAY` environment variables. By setting `ADVENT_TOKEN` to your browser session token, your personal input can optionally be fetched automatically. diff --git a/aoc2023/src/day01.rs b/aoc2023/src/day01.rs index 3955f1a..49cc0c6 100644 --- a/aoc2023/src/day01.rs +++ b/aoc2023/src/day01.rs @@ -22,7 +22,7 @@ impl Solution for Day01 { } } - sum += 10 * first.unwrap() + last.unwrap() + sum += 10 * first.expect(word) + last.expect(word) } Answer::from(sum) diff --git a/aoc2024/src/day01.rs b/aoc2024/src/day01.rs index 5b1cab5..a901811 100644 --- a/aoc2024/src/day01.rs +++ b/aoc2024/src/day01.rs @@ -37,7 +37,7 @@ impl Solution for Day01 { fn parse(input: &str) -> (Vec, Vec) { input.lines() .map(|line| line.split_once(" ") - .unwrap() + .expect(line) ) .map(|(x, y)| (x.parse::().unwrap(), y.parse::().unwrap())) .unzip() diff --git a/data/README.md b/data/README.md index df9e854..3c85c67 100644 --- a/data/README.md +++ b/data/README.md @@ -1 +1,14 @@ ## The author of adventofcode.com, Eric Wastl, does not want puzzle input to be shared: https://adventofcode.com/about + +Either manually place it here, with the folder structure + +``` +data/ + 2024/ + day01 + day02 + day03 + ... +``` + +or set ADVENT_TOKEN to your session cookie to automatically fetch your input at runtime. diff --git a/src/input_data.rs b/src/input_data.rs index 5b4e611..131bbf6 100644 --- a/src/input_data.rs +++ b/src/input_data.rs @@ -5,7 +5,8 @@ pub fn load_actual(year: usize, day: usize) -> io::Result { fs::read_to_string(path) } -pub fn load_test(year: usize, day: usize) -> io::Result { - let path = format!("./examples/{year}/day{:02}", day); - fs::read_to_string(path) +pub fn load_test(year: usize, day: usize) -> (io::Result, io::Result) { + let input_path = format!("./examples/{year}/day{:02}", day); + let result_path = format!("./examples/{year}/day{:02}_solution", day); + (fs::read_to_string(input_path), fs::read_to_string(result_path)) } diff --git a/src/main.rs b/src/main.rs index 52bf882..563d75f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -24,23 +24,31 @@ fn main() { fetch_input(year, day).expect("Set ADVENT_TOKEN to the correct session cookie to fetch input automatically"); } - println!("Attempting to run {year}/{day}"); - - let Ok(data) = load_actual(year, day) - else { panic!("No Input Data"); }; - - let now = Instant::now(); - - let part1 = solution(&data, year, day, 1).unwrap(); - - let elapsed1 = now.elapsed(); - - let now = Instant::now(); - - let part2 = solution(&data, year, day, 2).unwrap(); - - let elapsed2 = now.elapsed(); - - println!("Part 1 result is {}, took {}ms", part1, elapsed1.as_millis()); - println!("Part 2 result is {}, took {}ms", part2, elapsed2.as_millis()); + run_all(); +} + +fn run_all() { + let years_to_run = [2023, 2024]; + + if env::var("ADVENT_TOKEN").is_ok() { + for year in years_to_run { + for day in 1..=25 { + println!("Pre-fetching input for {year}/{:02}", day); + fetch_input(year, day).expect("Set ADVENT_TOKEN to the correct session cookie to fetch input automatically"); + } + } + } + + for year in years_to_run { + for day in 1..=25 { + for part in [1, 2] { + let input = load_actual(year, day).unwrap_or_else(|_| panic!("Missing input for {}/{:02}", year, day)); + + let now = Instant::now(); + let result = solution(&input, year, day, part).unwrap_or_else(|| panic!("No solution at {}/{:02}", year, day)); + let time_passed = now.elapsed().as_millis(); + println!("Running Year {}, Day {:02}, Part {} - Result {} - took {}ms", year, day, part, result, time_passed); + } + } + } } diff --git a/src/solution.rs b/src/solution.rs index 98b3843..76cc7ed 100644 --- a/src/solution.rs +++ b/src/solution.rs @@ -3,7 +3,7 @@ use shared::Answer; pub fn solution(input: &str, year: usize, day: usize, part: usize) -> Option { match year { - 2023 => aoc2024::solution(input, day, part), + 2023 => aoc2023::solution(input, day, part), 2024 => aoc2024::solution(input, day, part), _ => None, } From 83f51b44520599140295fcd5802e5469e9ee1df4 Mon Sep 17 00:00:00 2001 From: Spectre Date: Tue, 3 Dec 2024 02:06:44 +0100 Subject: [PATCH 4/4] fix --- src/fetch_input.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/fetch_input.rs b/src/fetch_input.rs index cfa89fb..589ad61 100644 --- a/src/fetch_input.rs +++ b/src/fetch_input.rs @@ -2,7 +2,6 @@ use reqwest::{blocking::Client, Url}; use std::fs::File; use std::io::prelude::*; -use std::path::Path; use std::sync::Arc; use std::env;