auto grab input & day 5
This commit is contained in:
parent
4f15848269
commit
b7a13cbc27
10 changed files with 171 additions and 50 deletions
7
.gitignore
vendored
7
.gitignore
vendored
|
@ -1,9 +1,10 @@
|
|||
# temporary files
|
||||
/target
|
||||
/input
|
||||
session.txt
|
||||
|
||||
# secrets
|
||||
.env
|
||||
|
||||
# don't include inputs
|
||||
/input
|
||||
session.txt
|
||||
# editors
|
||||
.vscode
|
||||
|
|
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -12,7 +12,7 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "aoc-2022"
|
||||
name = "aoc"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"eyes",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
[package]
|
||||
name = "aoc-2022"
|
||||
name = "aoc"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
|
@ -8,6 +8,4 @@ regex = "1"
|
|||
itertools = "0.10"
|
||||
rayon = "1"
|
||||
eyes = "1"
|
||||
|
||||
[build-dependencies]
|
||||
reqwest = { version = "0.11", features = ["blocking", "cookies"] }
|
||||
|
|
39
build.rs
39
build.rs
|
@ -1,39 +0,0 @@
|
|||
use reqwest::{blocking::Client, cookie::Jar};
|
||||
use std::{collections::HashMap, env, fs, path::PathBuf, sync::Arc};
|
||||
|
||||
const BASE_URL: &str = "https://adventofcode.com";
|
||||
const YEAR: &str = "2022";
|
||||
|
||||
fn main() {
|
||||
// get env and dotenv into hashmap
|
||||
let file = fs::read_to_string(".env").unwrap_or(String::new());
|
||||
let env = file
|
||||
.lines()
|
||||
.filter_map(|line| line.split_once('='))
|
||||
.map(|(key, value)| (key.to_string(), value.to_string()))
|
||||
.chain(env::vars())
|
||||
.collect::<HashMap<_, _>>();
|
||||
|
||||
// create session cookie
|
||||
let session = env
|
||||
.get("SESSION")
|
||||
.expect("SESSION environment variable not set, retrieve it from https://adventofcode.com");
|
||||
let cookie = format!("session={session}");
|
||||
|
||||
// setup client
|
||||
let jar = Arc::new(Jar::default());
|
||||
jar.add_cookie_str(&cookie, &BASE_URL.parse().unwrap());
|
||||
let client = Client::builder().cookie_provider(jar).build().unwrap();
|
||||
|
||||
// download until day fails
|
||||
for day in 1..=25 {
|
||||
let path = PathBuf::from(format!("input/day{day}.txt"));
|
||||
if path.try_exists().is_err() {
|
||||
let url = format!("{BASE_URL}/{YEAR}/day/{day}/input");
|
||||
let Ok(res) = client.get(url).send() else {
|
||||
break
|
||||
};
|
||||
fs::write(path, res.text().unwrap()).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
use itertools::Itertools;
|
||||
|
||||
fn main() {
|
||||
let input = std::fs::read_to_string("input/day1.txt").unwrap();
|
||||
let input = aoc::input!();
|
||||
println!("part 1: {}", part1(&input));
|
||||
println!("part 1: {}", part2(&input));
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
use eyes::parse;
|
||||
|
||||
fn main() {
|
||||
let input = std::fs::read_to_string("input/day2.txt").unwrap();
|
||||
let input = aoc::input!();
|
||||
println!("part 1: {}", part1(&input));
|
||||
println!("part 1: {}", part2(&input));
|
||||
}
|
|
@ -2,7 +2,7 @@ use itertools::Itertools;
|
|||
use std::collections::HashSet;
|
||||
|
||||
fn main() {
|
||||
let input = std::fs::read_to_string("input/day3.txt").unwrap();
|
||||
let input = aoc::input!();
|
||||
println!("part 1: {}", part1(&input));
|
||||
println!("part 1: {}", part2(&input));
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
use eyes::parse;
|
||||
|
||||
fn main() {
|
||||
let input = std::fs::read_to_string("input/day4.txt").unwrap();
|
||||
let input = aoc::input!();
|
||||
println!("part 1: {}", part1(&input));
|
||||
println!("part 1: {}", part2(&input));
|
||||
}
|
109
src/bin/2022-5.rs
Normal file
109
src/bin/2022-5.rs
Normal file
|
@ -0,0 +1,109 @@
|
|||
use eyes::parse;
|
||||
use itertools::Itertools;
|
||||
|
||||
fn main() {
|
||||
let input = aoc::input!();
|
||||
println!("part 1: {}", part1(&input));
|
||||
println!("part 1: {}", part2(&input));
|
||||
}
|
||||
|
||||
fn part1(input: &str) -> String {
|
||||
// parsing challenge..... yay......
|
||||
let (crates, instructions) = input.split_once("\n\n").unwrap();
|
||||
let mut stacks = crates
|
||||
.lines()
|
||||
.rev()
|
||||
.skip(1)
|
||||
.map(|line| {
|
||||
line.chars()
|
||||
.chunks(4)
|
||||
.into_iter()
|
||||
.map(|mut cr| (cr.next() == Some('[')).then(|| cr.next().unwrap()))
|
||||
.collect::<Vec<_>>()
|
||||
})
|
||||
.fold(vec![vec![]; 9], |mut stacks, crates| {
|
||||
for (i, c) in crates.into_iter().enumerate() {
|
||||
if let Some(c) = c {
|
||||
stacks[i].push(c)
|
||||
}
|
||||
}
|
||||
stacks
|
||||
});
|
||||
|
||||
// perform instructions
|
||||
instructions
|
||||
.lines()
|
||||
.map(|line| parse!(line, "move {} from {} to {}", usize, usize, usize))
|
||||
.for_each(|(n, from, to)| {
|
||||
(0..n).for_each(|_| {
|
||||
if let Some(c) = stacks[from - 1].pop() {
|
||||
stacks[to - 1].push(c)
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
// get message
|
||||
stacks
|
||||
.into_iter()
|
||||
.filter_map(|mut stack| stack.pop())
|
||||
.collect::<String>()
|
||||
}
|
||||
|
||||
fn part2(input: &str) -> String {
|
||||
let (crates, instructions) = input.split_once("\n\n").unwrap();
|
||||
let mut stacks = crates
|
||||
.lines()
|
||||
.rev()
|
||||
.skip(1)
|
||||
.map(|line| {
|
||||
line.chars()
|
||||
.chunks(4)
|
||||
.into_iter()
|
||||
.map(|mut cr| (cr.next() == Some('[')).then(|| cr.next().unwrap()))
|
||||
.collect::<Vec<_>>()
|
||||
})
|
||||
.fold(vec![vec![]; 9], |mut stacks, crates| {
|
||||
for (i, c) in crates.into_iter().enumerate() {
|
||||
if let Some(c) = c {
|
||||
stacks[i].push(c)
|
||||
}
|
||||
}
|
||||
stacks
|
||||
});
|
||||
|
||||
// perform instructions
|
||||
instructions
|
||||
.lines()
|
||||
.map(|line| parse!(line, "move {} from {} to {}", usize, usize, usize))
|
||||
.for_each(|(n, from, to)| {
|
||||
let len = stacks[from - 1].len();
|
||||
let split = stacks[from - 1].split_off(len - n);
|
||||
stacks[to - 1].extend(split);
|
||||
});
|
||||
|
||||
// get message
|
||||
stacks
|
||||
.into_iter()
|
||||
.filter_map(|mut stack| stack.pop())
|
||||
.collect::<String>()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn examples() {
|
||||
let example = r#" [D]
|
||||
[N] [C]
|
||||
[Z] [M] [P]
|
||||
1 2 3
|
||||
|
||||
move 1 from 2 to 1
|
||||
move 3 from 1 to 3
|
||||
move 2 from 2 to 1
|
||||
move 1 from 1 to 2"#;
|
||||
assert_eq!(part1(example), "CMZ".to_string());
|
||||
assert_eq!(part2(example), "MCD".to_string());
|
||||
}
|
||||
}
|
52
src/lib.rs
52
src/lib.rs
|
@ -1 +1,53 @@
|
|||
use reqwest::{blocking::Client, cookie::Jar};
|
||||
use std::{env, error::Error, fs, path::PathBuf, sync::Arc};
|
||||
|
||||
const BASE_URL: &str = "https://adventofcode.com";
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! input {
|
||||
() => {{
|
||||
let stem = std::path::Path::new(file!())
|
||||
.file_stem()
|
||||
.unwrap()
|
||||
.to_string_lossy();
|
||||
let (year, day) = stem.split_once('-').unwrap();
|
||||
$crate::get_day(year, day).unwrap()
|
||||
}};
|
||||
}
|
||||
|
||||
pub fn get_day(year: &str, day: &str) -> Result<String, Box<dyn Error>> {
|
||||
let path = PathBuf::from(format!("input/{year}/day{day}.txt"));
|
||||
fs::create_dir_all(path.parent().unwrap())?;
|
||||
|
||||
if let Ok(input) = fs::read_to_string(&path) {
|
||||
Ok(input)
|
||||
} else {
|
||||
// get session token
|
||||
let file = fs::read_to_string(".env").unwrap_or(String::new());
|
||||
let session = file
|
||||
.lines()
|
||||
.filter_map(|line| line.split_once('='))
|
||||
.map(|(key, value)| (key.to_string(), value.to_string()))
|
||||
.chain(env::vars())
|
||||
.find_map(|(k, v)| (k == "SESSION").then_some(v))
|
||||
.ok_or(
|
||||
"SESSION environment variable not set, retrieve it from https://adventofcode.com",
|
||||
)?;
|
||||
|
||||
// create session cookie
|
||||
let cookie = format!("session={session}");
|
||||
|
||||
// setup client
|
||||
let jar = Arc::new(Jar::default());
|
||||
jar.add_cookie_str(&cookie, &BASE_URL.parse()?);
|
||||
let client = Client::builder().cookie_provider(jar).build()?;
|
||||
|
||||
// download until day fails
|
||||
let url = format!("{BASE_URL}/{year}/day/{day}/input");
|
||||
let text = client.get(url).send()?.text()?;
|
||||
fs::create_dir_all(path.parent().unwrap())?;
|
||||
fs::write(path, &text)?;
|
||||
|
||||
Ok(text)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue