mirror of
https://github.com/kristoferssolo/Advent-of-Code.git
synced 2026-03-22 00:26:24 +00:00
create 2023 folder
This commit is contained in:
9
2023/day-02/src/bin/part1.rs
Normal file
9
2023/day-02/src/bin/part1.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
use color_eyre::Result;
|
||||
use day_02::part1::process;
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let file = include_str!("../../input1.txt");
|
||||
let result = process(file)?;
|
||||
println!("{}", result);
|
||||
Ok(())
|
||||
}
|
||||
9
2023/day-02/src/bin/part2.rs
Normal file
9
2023/day-02/src/bin/part2.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
use color_eyre::Result;
|
||||
use day_02::part2::process;
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let file = include_str!("../../input2.txt");
|
||||
let result = process(file)?;
|
||||
println!("{}", result);
|
||||
Ok(())
|
||||
}
|
||||
2
2023/day-02/src/lib.rs
Normal file
2
2023/day-02/src/lib.rs
Normal file
@@ -0,0 +1,2 @@
|
||||
pub mod part1;
|
||||
pub mod part2;
|
||||
125
2023/day-02/src/part1.rs
Normal file
125
2023/day-02/src/part1.rs
Normal file
@@ -0,0 +1,125 @@
|
||||
use color_eyre::Result;
|
||||
|
||||
enum Color {
|
||||
Red,
|
||||
Green,
|
||||
Blue,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct Game {
|
||||
id: u32,
|
||||
bags: Vec<Bag>,
|
||||
}
|
||||
|
||||
impl Game {
|
||||
fn new(id: u32) -> Self {
|
||||
Game {
|
||||
id,
|
||||
bags: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Clone, Debug)]
|
||||
struct Bag {
|
||||
red: u32,
|
||||
green: u32,
|
||||
blue: u32,
|
||||
}
|
||||
|
||||
impl Bag {
|
||||
fn new(red: u32, green: u32, blue: u32) -> Self {
|
||||
Bag { red, green, blue }
|
||||
}
|
||||
|
||||
fn add_red(&mut self, num: u32) {
|
||||
self.red += num;
|
||||
}
|
||||
|
||||
fn add_green(&mut self, num: u32) {
|
||||
self.green += num;
|
||||
}
|
||||
|
||||
fn add_blue(&mut self, num: u32) {
|
||||
self.blue += num;
|
||||
}
|
||||
|
||||
fn compare(&self, other: &Self) -> bool {
|
||||
self.red <= other.red && (self.green <= other.green) && self.blue <= other.blue
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_color(color: &str) -> Option<Color> {
|
||||
let color = color.to_lowercase();
|
||||
if color.contains("red") {
|
||||
Some(Color::Red)
|
||||
} else if color.contains("green") {
|
||||
Some(Color::Green)
|
||||
} else if color.contains("blue") {
|
||||
Some(Color::Blue)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_line(line: &str) -> Result<Game> {
|
||||
let mut parts: Vec<_> = line.split(|c| c == ';' || c == ':').collect();
|
||||
let id: u32 = parts
|
||||
.remove(0)
|
||||
.split_whitespace()
|
||||
.last()
|
||||
.unwrap_or("ID not found")
|
||||
.parse()?;
|
||||
|
||||
let mut game = Game::new(id);
|
||||
|
||||
parts.iter().for_each(|part| {
|
||||
let colors: Vec<_> = part.split_whitespace().collect();
|
||||
let mut bag = Bag::default();
|
||||
for chunk in colors.chunks_exact(2).into_iter() {
|
||||
if let Some(parsed_color) = parse_color(chunk[1]) {
|
||||
if let Ok(amount) = chunk.get(0).unwrap_or(&"ID not found").parse::<u32>() {
|
||||
match parsed_color {
|
||||
Color::Red => bag.add_red(amount),
|
||||
Color::Green => bag.add_green(amount),
|
||||
Color::Blue => bag.add_blue(amount),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
game.bags.push(bag);
|
||||
});
|
||||
|
||||
Ok(game)
|
||||
}
|
||||
|
||||
pub fn process(input: &str) -> Result<u32> {
|
||||
let max_bag = Bag::new(12, 13, 14);
|
||||
|
||||
let games: Vec<Game> = input.lines().flat_map(|line| parse_line(line)).collect();
|
||||
|
||||
let sum = games
|
||||
.iter()
|
||||
.filter(|game| game.bags.iter().all(|bag| bag.compare(&max_bag)))
|
||||
.map(|game| game.id)
|
||||
.sum();
|
||||
|
||||
Ok(sum)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_process() -> Result<()> {
|
||||
let input = "Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green
|
||||
Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue
|
||||
Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red
|
||||
Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red
|
||||
Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green";
|
||||
assert_eq!(8, process(input)?);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
117
2023/day-02/src/part2.rs
Normal file
117
2023/day-02/src/part2.rs
Normal file
@@ -0,0 +1,117 @@
|
||||
use color_eyre::Result;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
enum Color {
|
||||
Red,
|
||||
Green,
|
||||
Blue,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct Game {
|
||||
bags: Vec<Bag>,
|
||||
}
|
||||
|
||||
impl Game {
|
||||
fn new() -> Self {
|
||||
Game { bags: Vec::new() }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
struct Bag {
|
||||
red: u32,
|
||||
green: u32,
|
||||
blue: u32,
|
||||
}
|
||||
|
||||
impl Bag {
|
||||
fn new(red: u32, green: u32, blue: u32) -> Self {
|
||||
Bag { red, green, blue }
|
||||
}
|
||||
|
||||
fn add_red(&mut self, num: u32) {
|
||||
self.red += num;
|
||||
}
|
||||
|
||||
fn add_green(&mut self, num: u32) {
|
||||
self.green += num;
|
||||
}
|
||||
|
||||
fn add_blue(&mut self, num: u32) {
|
||||
self.blue += num;
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_color(color: &str) -> Option<Color> {
|
||||
let color = color.to_lowercase();
|
||||
if color.contains("red") {
|
||||
Some(Color::Red)
|
||||
} else if color.contains("green") {
|
||||
Some(Color::Green)
|
||||
} else if color.contains("blue") {
|
||||
Some(Color::Blue)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_line(line: &str) -> Result<Game> {
|
||||
let mut parts: Vec<_> = line.split(|c| c == ';' || c == ':').collect();
|
||||
parts.remove(0);
|
||||
|
||||
let mut game = Game::new();
|
||||
|
||||
parts.iter().for_each(|part| {
|
||||
let colors: Vec<_> = part.split_whitespace().collect();
|
||||
let mut bag = Bag::default();
|
||||
for chunk in colors.chunks_exact(2).into_iter() {
|
||||
if let Some(parsed_color) = parse_color(chunk[1]) {
|
||||
if let Ok(amount) = chunk.get(0).unwrap_or(&"ID not found").parse::<u32>() {
|
||||
match parsed_color {
|
||||
Color::Red => bag.add_red(amount),
|
||||
Color::Green => bag.add_green(amount),
|
||||
Color::Blue => bag.add_blue(amount),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
game.bags.push(bag);
|
||||
});
|
||||
|
||||
Ok(game)
|
||||
}
|
||||
|
||||
pub fn process(input: &str) -> Result<u32> {
|
||||
let games: Vec<Game> = input.lines().flat_map(|line| parse_line(line)).collect();
|
||||
let sum: u32 = games
|
||||
.iter()
|
||||
.map(|game| {
|
||||
let max_bag = game.bags.iter().cloned().fold(Bag::default(), |acc, bag| {
|
||||
Bag::new(
|
||||
acc.red.max(bag.red),
|
||||
acc.green.max(bag.green),
|
||||
acc.blue.max(bag.blue),
|
||||
)
|
||||
});
|
||||
max_bag.red * max_bag.green * max_bag.blue
|
||||
})
|
||||
.sum();
|
||||
Ok(sum)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_process() -> Result<()> {
|
||||
let input = "Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green
|
||||
Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue
|
||||
Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red
|
||||
Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red
|
||||
Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green";
|
||||
assert_eq!(2286, process(input)?);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user