Actual cli + day2 moment

This commit is contained in:
Tyler Beckman 2023-12-01 22:34:54 -07:00
parent ee572e5e06
commit d00d157fb5
Signed by: Ty
GPG key ID: 2813440C772555A4
6 changed files with 1465 additions and 14 deletions

1299
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -6,3 +6,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
clap = { version = "4.4.10", features = ["derive"] }
regex = "1.10.2"
reqwest = "0.11.22"
tokio = { version = "1.34.0", features = ["macros", "rt-multi-thread"] }

View file

@ -1,6 +1,4 @@
pub fn part1() {
let input = include_str!("input.txt");
pub fn part1(input: String) {
let mut values = Vec::<usize>::new();
for line in input.lines() {
@ -12,9 +10,7 @@ pub fn part1() {
println!("{}", values.into_iter().reduce(|acc, e| acc + e).unwrap());
}
pub fn part2() {
let input = include_str!("input.txt");
pub fn part2(input: String) {
let mut values = Vec::<usize>::new();
for line in input.lines() {

100
src/day2/mod.rs Normal file
View file

@ -0,0 +1,100 @@
use regex::Regex;
#[derive(Debug)]
struct Game {
id: usize,
picks: Vec<CubeCombo>
}
#[derive(Debug)]
struct CubeCombo {
red: usize,
blue: usize,
green: usize
}
fn parse_games(input: String) -> Vec<Game> {
let game_re = Regex::new(r"Game (\d+): (.+)").unwrap();
let pick_re = Regex::new(r"(?<first>\d+ (?:red|green|blue))(?:, (?<second>\d+ (?:red|green|blue)))?(?:, (?<third>\d+ (?:red|green|blue)))?").unwrap();
let mut games = Vec::<Game>::new();
for line in input.lines() {
let line = line.to_string();
let captures = game_re.captures(&line).unwrap();
let mut game = Game {
id: captures.get(1).unwrap().as_str().parse().unwrap(),
picks: vec![]
};
let picks = captures.get(2).unwrap().as_str().split("; ");
for pick in picks {
let captures = pick_re.captures(pick).unwrap();
let captures = vec![
captures.name("first"),
captures.name("second"),
captures.name("third"),
];
let mut pick = CubeCombo {
red: 0,
blue: 0,
green: 0
};
for capture in captures.iter().filter(|e| e.is_some()).map(|e| e.unwrap()) {
let split = capture.as_str().split(" ").collect::<Vec<_>>();
match split[1] {
"red" => pick.red = split[0].parse().unwrap(),
"blue" => pick.blue = split[0].parse().unwrap(),
"green" => pick.green = split[0].parse().unwrap(),
_ => panic!("impossible wtf")
}
}
game.picks.push(pick);
}
games.push(game);
}
games
}
pub fn part1(input: String) {
let games = parse_games(input);
// Sum the illegal game IDs
let sum = games
.iter()
.filter(|g|
g.picks.iter().all(|pick| pick.red <= 12 && pick.blue <= 14 && pick.green <= 13 )
)
.fold(0, |acc, e| acc + e.id);
println!("{sum}");
}
pub fn part2(input: String) {
let games = parse_games(input);
// Calculate the least amount of dice possible for all games
let sum = games.iter().map(|game| {
let mut combo = CubeCombo {
red: 0,
green: 0,
blue: 0
};
for pick in &game.picks {
if combo.red < pick.red {
combo.red = pick.red;
}
if combo.green < pick.green {
combo.green = pick.green;
}
if combo.blue < pick.blue {
combo.blue = pick.blue;
}
}
combo
}).fold(0, |acc, combo| acc + (combo.red * combo.blue * combo.green));
println!("{sum}");
}

View file

@ -1,13 +1,57 @@
use clap::{Parser, Subcommand};
pub mod utils;
pub mod day1;
pub mod day2;
fn main() {
let args = std::env::args().collect::<Vec<_>>();
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
struct Cli {
/// Sets the cookie to send to fetch input data
#[arg(short, long, value_name = "AUTH")]
auth: String,
/// The subcommand to run
#[command(subcommand)]
subcommand: Subcommands
}
let day = args[1].as_str();
let part = args[2].as_str();
match day {
"1" => match part { "1" => day1::part1(), "2" => day1::part2(), _ => panic!("Invalid part #") },
_ => panic!("Invalid day #")
#[derive(Subcommand)]
enum Subcommands {
/// Solves the specified part for the specified day, after fetching the input
Solve {
/// The day to solve for
day: u8,
/// The part to solve for
part: u8
}
}
#[tokio::main]
async fn main() {
let cli = Cli::parse();
let client = reqwest::Client::new();
match cli.subcommand {
Subcommands::Solve { day, part } => {
let response = client
.get(format!("https://adventofcode.com/2023/day/{day}/input"))
.header("Cookie", format!("session={auth}", auth = cli.auth))
.send()
.await
.unwrap()
.text()
.await
.unwrap()
.trim_end()
.to_owned();
match (day, part) {
(1, 1) => day1::part1(response),
(1, 2) => day1::part2(response),
(2, 1) => day2::part1(response),
(2, 2) => day2::part2(response),
_ => panic!("Invalid day or part #")
}
},
}
}

8
src/utils.rs Normal file
View file

@ -0,0 +1,8 @@
pub enum CoroutineYield {
Data,
Output(String)
}
pub enum CoroutineYieldResponse {
Data(String),
}