Compare commits
No commits in common. "1c4bf97e07d666f6e6952bf5a9bfbb102a72d55b" and "bece6b708b5a72b6b79afaad47c5c947f3880e7e" have entirely different histories.
1c4bf97e07
...
bece6b708b
7
Cargo.lock
generated
7
Cargo.lock
generated
@ -8,7 +8,6 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"aoc-runner",
|
"aoc-runner",
|
||||||
"aoc-runner-derive",
|
"aoc-runner-derive",
|
||||||
"array2d",
|
|
||||||
"itertools",
|
"itertools",
|
||||||
"rust-crypto",
|
"rust-crypto",
|
||||||
]
|
]
|
||||||
@ -42,12 +41,6 @@ dependencies = [
|
|||||||
"serde_json",
|
"serde_json",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "array2d"
|
|
||||||
version = "0.3.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d8b39cb2c1bf5a7c0dd097aa95ab859cf87dab5a4328900f5388942dc1889f74"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "either"
|
name = "either"
|
||||||
version = "1.9.0"
|
version = "1.9.0"
|
||||||
|
@ -11,4 +11,3 @@ rust-crypto = "0.2.36"
|
|||||||
aoc-runner = "0.3.0"
|
aoc-runner = "0.3.0"
|
||||||
aoc-runner-derive = "0.3.0"
|
aoc-runner-derive = "0.3.0"
|
||||||
itertools = "0.12.0"
|
itertools = "0.12.0"
|
||||||
array2d = "0.3.0"
|
|
7
old/day01/Cargo.lock
generated
Normal file
7
old/day01/Cargo.lock
generated
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "day1"
|
||||||
|
version = "0.1.0"
|
8
old/day01/Cargo.toml
Normal file
8
old/day01/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "day1"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
48
old/day01/src/main.rs
Normal file
48
old/day01/src/main.rs
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
use std::fs;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let input = fs::read_to_string("input.txt").unwrap();
|
||||||
|
let input = input.split('\n');
|
||||||
|
let mut sum = 0;
|
||||||
|
for line in input {
|
||||||
|
let str_nums: Vec<(&str, &str)> = vec![("one", "1"), ("two", "2"), ("three", "3"), ("four", "4"), ("five", "5"), ("six", "6"), ("seven", "7"), ("eight", "8"), ("nine", "9")];
|
||||||
|
let mut matches: Vec<(usize, &str)> = vec![];
|
||||||
|
for str_num in str_nums {
|
||||||
|
// Get every alphabetic number in the string with it's index
|
||||||
|
let str_match: Vec<_> = line.match_indices(str_num.0).collect();
|
||||||
|
// convert the string to a numeral
|
||||||
|
let mut str_match: Vec<_> = str_match.iter().map(|x| return (x.0, str_num.1)).collect();
|
||||||
|
matches.append(&mut str_match);
|
||||||
|
}
|
||||||
|
// get the numerials from the line with their index
|
||||||
|
let mut num_matches: Vec<(usize, &str)> = line.match_indices(|x: char| x.is_numeric()).collect();
|
||||||
|
matches.append(&mut num_matches);
|
||||||
|
// sort by index
|
||||||
|
matches.sort_by(|lhs, rhs| lhs.cmp(rhs));
|
||||||
|
let num = (matches.first().unwrap().1).to_owned() + (matches.last().unwrap().1);
|
||||||
|
sum += num.parse::<i32>().unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("{}", sum);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// use std::fs;
|
||||||
|
|
||||||
|
// fn main() {
|
||||||
|
// let input = fs::read_to_string("input.txt").unwrap();
|
||||||
|
// let input = input.split('\n');
|
||||||
|
// let mut sum = 0;
|
||||||
|
// for line in input {
|
||||||
|
// let chars: Vec<char>= line.chars().filter(|x| x.is_numeric()).collect();
|
||||||
|
// let mut num = chars.first().unwrap().to_string();
|
||||||
|
// num += &chars.last().unwrap().to_string();
|
||||||
|
// let num: u32 = num.parse().unwrap();
|
||||||
|
// sum += num;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// println!("{}", sum);
|
||||||
|
// }
|
7
old/day02/Cargo.lock
generated
Normal file
7
old/day02/Cargo.lock
generated
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "day2"
|
||||||
|
version = "0.1.0"
|
8
old/day02/Cargo.toml
Normal file
8
old/day02/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "day2"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
83
old/day02/src/main.rs
Normal file
83
old/day02/src/main.rs
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
use std::{fs, cmp::max};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let input = fs::read_to_string("input.txt").unwrap();
|
||||||
|
let input: Vec<_> = input.split('\n').collect();
|
||||||
|
let mut sum = 0;
|
||||||
|
for line in input {
|
||||||
|
let split:Vec<_> = line.split(':').collect();
|
||||||
|
let rounds: Vec<_> = split.last().unwrap().split(';').collect();
|
||||||
|
let rounds: Vec<_> = rounds.iter()
|
||||||
|
.map(|x| {
|
||||||
|
x.split(',').collect::<Vec<_>>()
|
||||||
|
}).collect();
|
||||||
|
|
||||||
|
let rounds: Vec<_> = rounds.iter()
|
||||||
|
.map(|x| {
|
||||||
|
x.iter().map(|x| {
|
||||||
|
x.trim().split(' ').collect::<Vec<_>>()
|
||||||
|
}).collect::<Vec<_>>()
|
||||||
|
}).collect();
|
||||||
|
let (mut r_max, mut g_max, mut b_max) = (0, 0, 0);
|
||||||
|
for round in rounds {
|
||||||
|
for set in round {
|
||||||
|
let color = set.last().unwrap();
|
||||||
|
let num: i32 = set.first().unwrap().parse().unwrap();
|
||||||
|
match *color {
|
||||||
|
"red" => r_max = max(num, r_max),
|
||||||
|
"blue" => b_max = max(num, b_max),
|
||||||
|
"green" => g_max = max(num, g_max),
|
||||||
|
&_ => todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
//println!("{}", r_max);
|
||||||
|
sum += r_max * g_max * b_max;
|
||||||
|
}
|
||||||
|
println!("{}", sum);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// use std::fs;
|
||||||
|
|
||||||
|
// fn main() {
|
||||||
|
// let input = fs::read_to_string("input.txt").unwrap();
|
||||||
|
// let input: Vec<_> = input.split('\n').collect();
|
||||||
|
// let mut game_id = 0;
|
||||||
|
// let (r_max, g_max, b_max) = (12, 13, 14);
|
||||||
|
// let mut sum = 0;
|
||||||
|
// for line in input {
|
||||||
|
// game_id += 1;
|
||||||
|
// let split:Vec<_> = line.split(':').collect();
|
||||||
|
// let rounds: Vec<_> = split.last().unwrap().split(';').collect();
|
||||||
|
// let rounds: Vec<_> = rounds.iter().map(|x| x.split(',').collect::<Vec<_>>()).collect();
|
||||||
|
// let rounds: Vec<_> = rounds.iter().map(|x| x.iter().map(|x| x.trim().split(' ').collect::<Vec<_>>()).collect::<Vec<_>>()).collect();
|
||||||
|
// let mut sad = false;
|
||||||
|
|
||||||
|
// for round in rounds {
|
||||||
|
// let (mut r_cur, mut g_cur, mut b_cur) = (0, 0, 0);
|
||||||
|
// for set in round {
|
||||||
|
// let color = set.last().unwrap();
|
||||||
|
// let num: i32 = set.first().unwrap().parse().unwrap();
|
||||||
|
// match *color {
|
||||||
|
// "red" => r_cur += num,
|
||||||
|
// "blue" => b_cur += num,
|
||||||
|
// "green" => g_cur += num,
|
||||||
|
// &_ => todo!()
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if r_cur > r_max || b_cur > b_max || g_cur > g_max {
|
||||||
|
// sad = true;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// if !sad {
|
||||||
|
// sum += game_id;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// println!("{}", sum);
|
||||||
|
|
||||||
|
// }
|
16
old/day03/Cargo.lock
generated
Normal file
16
old/day03/Cargo.lock
generated
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "array2d"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "79093d31d0a9c7832c71ad74dd945b7861f721e6f242aa67be253a5eecbac937"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "day3"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"array2d",
|
||||||
|
]
|
9
old/day03/Cargo.toml
Normal file
9
old/day03/Cargo.toml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
[package]
|
||||||
|
name = "day3"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
array2d = "0.3.0"
|
@ -1,22 +1,51 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::fs;
|
||||||
|
|
||||||
use aoc_runner_derive::{aoc, aoc_generator};
|
|
||||||
use array2d::Array2D;
|
use array2d::Array2D;
|
||||||
|
|
||||||
#[aoc_generator(day3)]
|
// pub fn main() {
|
||||||
fn parse(input: &str) -> Array2D<char> {
|
// let input = fs::read_to_string("input.txt").unwrap();
|
||||||
let rows: Vec<&str> = input.split("\n").collect();
|
// let array_2d = get_map(&input);
|
||||||
let mut array = Vec::new();
|
// // let mut r = Vec::new();
|
||||||
for row in rows {
|
// let mut stars_count: HashMap<(usize, usize), Vec<u32>> = HashMap::new();
|
||||||
let row_vec: Vec<char> = row.chars().collect();
|
// for (y, row_iter) in array_2d.rows_iter().enumerate() {
|
||||||
array.push(row_vec);
|
// let mut checked = false;
|
||||||
}
|
// for (x, element) in row_iter.enumerate() {
|
||||||
|
// let d: char = element.clone();
|
||||||
|
// if d.is_digit(10) && !checked {
|
||||||
|
// let star_vec = get_neighboring_star(x, y, &array_2d);
|
||||||
|
// if !star_vec.is_empty() {
|
||||||
|
// let (x_star, y_star, _) = star_vec.first().unwrap().clone();
|
||||||
|
// let key = (x_star, y_star);
|
||||||
|
// let gear = get_number(x, y, &array_2d);
|
||||||
|
// if stars_count.contains_key(&key) {
|
||||||
|
// let mut v: Vec<u32> = stars_count.get(&(x_star, y_star)).unwrap().clone();
|
||||||
|
// v.push(gear);
|
||||||
|
// stars_count.insert(key, v);
|
||||||
|
// } else {
|
||||||
|
// stars_count.insert(key, vec![gear]);
|
||||||
|
// }
|
||||||
|
// checked = true
|
||||||
|
// }
|
||||||
|
// } else if !d.is_digit(10) {
|
||||||
|
// checked = false;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// let r = stars_count.iter().fold(0u32, |acc, (_, gears)| {
|
||||||
|
// if gears.len() == 2 {
|
||||||
|
// acc + gears.first().unwrap() * gears.last().unwrap()
|
||||||
|
// } else {
|
||||||
|
// acc
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
Array2D::from_rows(&array).unwrap()
|
// println!("{}", r);
|
||||||
}
|
// }
|
||||||
|
|
||||||
#[aoc(day3, part1)]
|
pub fn main() {
|
||||||
fn part1(array_2d: &Array2D<char>) -> u32 {
|
let input = fs::read_to_string("input.txt").unwrap();
|
||||||
|
let array_2d = get_map(&input);
|
||||||
let mut r = 0;
|
let mut r = 0;
|
||||||
for (y, row_iter) in array_2d.rows_iter().enumerate() {
|
for (y, row_iter) in array_2d.rows_iter().enumerate() {
|
||||||
let mut checked = false;
|
let mut checked = false;
|
||||||
@ -34,7 +63,18 @@ fn part1(array_2d: &Array2D<char>) -> u32 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r
|
println!("{}", r);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_map(input: &str) -> Array2D<char> {
|
||||||
|
let rows: Vec<&str> = input.split("\n").collect();
|
||||||
|
let mut array = Vec::new();
|
||||||
|
for row in rows {
|
||||||
|
let row_vec: Vec<char> = row.chars().collect();
|
||||||
|
array.push(row_vec);
|
||||||
|
}
|
||||||
|
|
||||||
|
Array2D::from_rows(&array).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_number(x: usize, y: usize, array2d: &Array2D<char>) -> u32 {
|
fn get_number(x: usize, y: usize, array2d: &Array2D<char>) -> u32 {
|
||||||
@ -90,10 +130,31 @@ fn get_neighbors(x: usize, y: usize, array2d: &Array2D<char>) -> Vec<&char> {
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_neighboring_star(x: usize, y: usize, array2d: &Array2D<char>) -> Vec<(usize, usize, Option<&char>)> {
|
||||||
|
let mut neighbors: Vec<(usize, usize, Option<&char>)> = Vec::new();
|
||||||
|
neighbors.push((x.checked_add(1).unwrap(), y, array2d.get(y, x.checked_add(1).unwrap())));
|
||||||
|
if x > 0 {
|
||||||
|
neighbors.push((x.checked_sub(1).unwrap(), y, array2d.get(y, x.checked_sub(1).unwrap())));
|
||||||
|
neighbors.push((x.checked_sub(1).unwrap(), y.checked_add(1).unwrap(), array2d.get(y.checked_add(1).unwrap(), x.checked_sub(1).unwrap())));
|
||||||
|
}
|
||||||
|
if y > 0 {
|
||||||
|
neighbors.push((x, y.checked_sub(1).unwrap(), array2d.get(y.checked_sub(1).unwrap(), x)));
|
||||||
|
neighbors.push((x.checked_add(1).unwrap(), y.checked_sub(1).unwrap(), array2d.get(y.checked_sub(1).unwrap(), x.checked_add(1).unwrap())));
|
||||||
|
}
|
||||||
|
if x > 0 && y > 0 {
|
||||||
|
neighbors.push((x.checked_sub(1).unwrap(), y.checked_sub(1).unwrap(), array2d.get(y.checked_sub(1).unwrap(), x.checked_sub(1).unwrap())));
|
||||||
|
}
|
||||||
|
neighbors.push((x, y.checked_add(1).unwrap(), array2d.get(y.checked_add(1).unwrap(), x)));
|
||||||
|
neighbors.push((x.checked_add(1).unwrap(), y.checked_add(1).unwrap(), array2d.get(y.checked_add(1).unwrap(), x.checked_add(1).unwrap())));
|
||||||
|
|
||||||
|
neighbors
|
||||||
|
.into_iter()
|
||||||
|
.filter(|(_, _, c)| c.is_some() && c.unwrap() == &'*')
|
||||||
|
.collect::<Vec<(usize, usize, Option<&char>)>>()
|
||||||
|
}
|
||||||
|
|
||||||
#[aoc(day3, part2)]
|
pub fn part_two(input: &str) -> Option<u32> {
|
||||||
fn part2(array_2d: &Array2D<char>) -> u32 {
|
let array_2d = get_map(input);
|
||||||
// let mut r = Vec::new();
|
// let mut r = Vec::new();
|
||||||
let mut stars_count: HashMap<(usize, usize), Vec<u32>> = HashMap::new();
|
let mut stars_count: HashMap<(usize, usize), Vec<u32>> = HashMap::new();
|
||||||
for (y, row_iter) in array_2d.rows_iter().enumerate() {
|
for (y, row_iter) in array_2d.rows_iter().enumerate() {
|
||||||
@ -128,54 +189,5 @@ fn part2(array_2d: &Array2D<char>) -> u32 {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
r
|
Some(r)
|
||||||
}
|
|
||||||
|
|
||||||
fn get_neighboring_star(x: usize, y: usize, array2d: &Array2D<char>) -> Vec<(usize, usize, Option<&char>)> {
|
|
||||||
let mut neighbors: Vec<(usize, usize, Option<&char>)> = Vec::new();
|
|
||||||
neighbors.push((x.checked_add(1).unwrap(), y, array2d.get(y, x.checked_add(1).unwrap())));
|
|
||||||
if x > 0 {
|
|
||||||
neighbors.push((x.checked_sub(1).unwrap(), y, array2d.get(y, x.checked_sub(1).unwrap())));
|
|
||||||
neighbors.push((x.checked_sub(1).unwrap(), y.checked_add(1).unwrap(), array2d.get(y.checked_add(1).unwrap(), x.checked_sub(1).unwrap())));
|
|
||||||
}
|
|
||||||
if y > 0 {
|
|
||||||
neighbors.push((x, y.checked_sub(1).unwrap(), array2d.get(y.checked_sub(1).unwrap(), x)));
|
|
||||||
neighbors.push((x.checked_add(1).unwrap(), y.checked_sub(1).unwrap(), array2d.get(y.checked_sub(1).unwrap(), x.checked_add(1).unwrap())));
|
|
||||||
}
|
|
||||||
if x > 0 && y > 0 {
|
|
||||||
neighbors.push((x.checked_sub(1).unwrap(), y.checked_sub(1).unwrap(), array2d.get(y.checked_sub(1).unwrap(), x.checked_sub(1).unwrap())));
|
|
||||||
}
|
|
||||||
neighbors.push((x, y.checked_add(1).unwrap(), array2d.get(y.checked_add(1).unwrap(), x)));
|
|
||||||
neighbors.push((x.checked_add(1).unwrap(), y.checked_add(1).unwrap(), array2d.get(y.checked_add(1).unwrap(), x.checked_add(1).unwrap())));
|
|
||||||
|
|
||||||
neighbors
|
|
||||||
.into_iter()
|
|
||||||
.filter(|(_, _, c)| c.is_some() && c.unwrap() == &'*')
|
|
||||||
.collect::<Vec<(usize, usize, Option<&char>)>>()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
const EX: &str = r"467..114..
|
|
||||||
...*......
|
|
||||||
..35..633.
|
|
||||||
......#...
|
|
||||||
617*......
|
|
||||||
.....+.58.
|
|
||||||
..592.....
|
|
||||||
......755.
|
|
||||||
...$.*....
|
|
||||||
.664.598..";
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn part1_example() {
|
|
||||||
assert_eq!(part1(&parse(EX)), 4361);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn part2_example() {
|
|
||||||
assert_eq!(part2(&parse(EX)), 467835);
|
|
||||||
}
|
|
||||||
}
|
}
|
7
old/day04/Cargo.lock
generated
Normal file
7
old/day04/Cargo.lock
generated
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "day4"
|
||||||
|
version = "0.1.0"
|
8
old/day04/Cargo.toml
Normal file
8
old/day04/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "day4"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
99
old/day04/src/main.rs
Normal file
99
old/day04/src/main.rs
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
use std::fs;
|
||||||
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let input = fs::read_to_string("input.txt").unwrap();
|
||||||
|
|
||||||
|
// an array in this format [[card 1: [winning nums][ our nums]]]
|
||||||
|
let input: Vec<_> = input.split('\n') // split days
|
||||||
|
.map(|card| &card[(card.find(':').unwrap() + 1)..]) // remove day numbers
|
||||||
|
.map(|card| card.trim()) // trim extra whitespace
|
||||||
|
.map(|card| {
|
||||||
|
card.split('|') // split winning/own numbers
|
||||||
|
.map(|numbers| {
|
||||||
|
numbers.trim() // trim whitespace
|
||||||
|
.split(' ') // split into individual nums
|
||||||
|
.filter(|x| !x.is_empty()) // remove empty strings
|
||||||
|
.map(|x| {return x.parse::<i32>().unwrap()}) // convert to i32
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let mut queue = VecDeque::from((0..input.len()).collect::<Vec<usize>>());
|
||||||
|
|
||||||
|
let mut total_cards = 0;
|
||||||
|
while !queue.is_empty() {
|
||||||
|
let card_num = queue.pop_front().unwrap();
|
||||||
|
let card = input.get(card_num).unwrap();
|
||||||
|
total_cards += 1;
|
||||||
|
let mut dup_cards = 0;
|
||||||
|
let winning_nums = card.first().unwrap();
|
||||||
|
let our_nums = card.last().unwrap();
|
||||||
|
|
||||||
|
//dp would kill here, but im lazy
|
||||||
|
for num in our_nums {
|
||||||
|
if winning_nums.contains(num) {
|
||||||
|
dup_cards += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for card in (card_num + 1)..=(card_num + dup_cards) {
|
||||||
|
if card < input.len() {
|
||||||
|
queue.push_back(card);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
println!("{:?}", total_cards);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// use std::fs;
|
||||||
|
|
||||||
|
// fn main() {
|
||||||
|
// let input = fs::read_to_string("input.txt").unwrap();
|
||||||
|
|
||||||
|
// // an array in this format [[card 1: [winning nums][ our nums]]]
|
||||||
|
// let input: Vec<_> = input.split('\n') // split days
|
||||||
|
// .map(|card| &card[(card.find(':').unwrap() + 1)..]) // remove day numbers
|
||||||
|
// .map(|card| card.trim()) // trim extra whitespace
|
||||||
|
// .map(|card| {
|
||||||
|
// card.split('|') // split winning/own numbers
|
||||||
|
// .map(|numbers| {
|
||||||
|
// numbers.trim() // trim whitespace
|
||||||
|
// .split(' ') // split into individual nums
|
||||||
|
// .filter(|x| !x.is_empty()) // remove empty strings
|
||||||
|
// .map(|x| {return x.parse::<i32>().unwrap()}) // convert to i32
|
||||||
|
// .collect::<Vec<_>>()
|
||||||
|
// })
|
||||||
|
// .collect::<Vec<_>>()
|
||||||
|
// })
|
||||||
|
// .collect();
|
||||||
|
|
||||||
|
// let mut total_pts = 0;
|
||||||
|
// for card in input {
|
||||||
|
// let mut card_pts = 0;
|
||||||
|
// let winning_nums = card.first().unwrap();
|
||||||
|
// let our_nums = card.last().unwrap();
|
||||||
|
|
||||||
|
// for num in our_nums {
|
||||||
|
// if winning_nums.contains(num) {
|
||||||
|
// if card_pts == 0 {
|
||||||
|
// card_pts = 1;
|
||||||
|
// } else {
|
||||||
|
// card_pts *= 2;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //println!("{}", card_pts);
|
||||||
|
// total_pts += card_pts;
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// println!("{:?}", total_pts);
|
||||||
|
// }
|
7
old/day05/Cargo.lock
generated
Normal file
7
old/day05/Cargo.lock
generated
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "day5"
|
||||||
|
version = "0.1.0"
|
8
old/day05/Cargo.toml
Normal file
8
old/day05/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "day5"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
93
old/day05/src/main.rs
Normal file
93
old/day05/src/main.rs
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
use std::fs;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let input = fs::read_to_string("input.txt").unwrap();
|
||||||
|
let mut mappers: Vec<_> = input.split("\n\n")
|
||||||
|
.map(|maps| &maps[(maps.find(':').unwrap() + 1)..])
|
||||||
|
.map(|maps| maps.trim())
|
||||||
|
.map(|maps| {
|
||||||
|
maps.split('\n')
|
||||||
|
.map(|range| {
|
||||||
|
range.split(' ')
|
||||||
|
.map(|num| num.parse::<i64>().unwrap())
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let seeds = mappers.first().unwrap().first().unwrap().clone();
|
||||||
|
let mappers: &mut [Vec<Vec<i64>>] = mappers.get_mut(1..).unwrap();
|
||||||
|
|
||||||
|
for mapper in mappers.into_iter() {
|
||||||
|
for range in mapper {
|
||||||
|
range[2] = range[1] + range[2] - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut cur_vals: Vec<_> = Vec::new();
|
||||||
|
for i in 0..seeds.len() / 2 {
|
||||||
|
let end = seeds[i * 2] + seeds[(i * 2) + 1];
|
||||||
|
let mut range: Vec<_> = (seeds[i * 2]..end).collect();
|
||||||
|
cur_vals.append(&mut range);
|
||||||
|
}
|
||||||
|
println!("{}", cur_vals.len());
|
||||||
|
for mapper in mappers {
|
||||||
|
for val in cur_vals.iter_mut() {
|
||||||
|
println!("{}", val);
|
||||||
|
for range in mapper.into_iter() {
|
||||||
|
if range[1] <= *val && *val <= range[2] {
|
||||||
|
let diff = *val - range[1];
|
||||||
|
*val = range[0] + diff;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("{:?}", cur_vals.into_iter().min().unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// use std::fs;
|
||||||
|
|
||||||
|
// fn main() {
|
||||||
|
// let input = fs::read_to_string("input.txt").unwrap();
|
||||||
|
// let mut mappers: Vec<_> = input.split("\n\n")
|
||||||
|
// .map(|maps| &maps[(maps.find(':').unwrap() + 1)..])
|
||||||
|
// .map(|maps| maps.trim())
|
||||||
|
// .map(|maps| {
|
||||||
|
// maps.split('\n')
|
||||||
|
// .map(|range| {
|
||||||
|
// range.split(' ')
|
||||||
|
// .map(|num| num.parse::<i64>().unwrap())
|
||||||
|
// .collect::<Vec<_>>()
|
||||||
|
// })
|
||||||
|
// .collect::<Vec<_>>()
|
||||||
|
// })
|
||||||
|
// .collect();
|
||||||
|
|
||||||
|
// let seeds = mappers.first().unwrap().first().unwrap().clone();
|
||||||
|
// let mappers: &mut [Vec<Vec<i64>>] = mappers.get_mut(1..).unwrap();
|
||||||
|
|
||||||
|
// for mapper in mappers.into_iter() {
|
||||||
|
// for range in mapper {
|
||||||
|
// range[2] = range[1] + range[2] - 1;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// let mut cur_vals: Vec<_> = seeds;
|
||||||
|
// for mapper in mappers {
|
||||||
|
// for val in cur_vals.iter_mut() {
|
||||||
|
// for range in mapper.into_iter() {
|
||||||
|
// if range[1] <= *val && *val <= range[2] {
|
||||||
|
// let diff = *val - range[1];
|
||||||
|
// *val = range[0] + diff;
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// println!("{:?}", cur_vals.into_iter().min().unwrap())
|
||||||
|
// }
|
7
old/day06/Cargo.lock
generated
Normal file
7
old/day06/Cargo.lock
generated
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "day6"
|
||||||
|
version = "0.1.0"
|
8
old/day06/Cargo.toml
Normal file
8
old/day06/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "day6"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
56
old/day06/src/main.rs
Normal file
56
old/day06/src/main.rs
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
use std::fs;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let input = fs::read_to_string("input.txt").unwrap();
|
||||||
|
let input: Vec<_> = input.split('\n') // Separate the Time and Distance lines
|
||||||
|
.map(|line| {
|
||||||
|
line[line.find(':').unwrap() + 1..] // Drop "Time:" and "Distance:"
|
||||||
|
.split_whitespace() // Split the numbers into their own elements
|
||||||
|
.flat_map(|s| s.chars()).collect::<String>() // Combine the strings into a single one
|
||||||
|
.parse::<i64>().expect("Couldn't parse number") // Parse numbers into i32
|
||||||
|
}).collect(); // Collect into Vec
|
||||||
|
|
||||||
|
let time = input[0];
|
||||||
|
let dist = input[1];
|
||||||
|
let mut valid = 0;
|
||||||
|
|
||||||
|
for remaining_time in 0..time {
|
||||||
|
if (time - remaining_time) * remaining_time > dist {
|
||||||
|
valid += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("{}", valid);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// use std::fs;
|
||||||
|
|
||||||
|
// fn main() {
|
||||||
|
// let input = fs::read_to_string("input.txt").unwrap();
|
||||||
|
// let input: Vec<_> = input.split('\n') // Separate the Time and Distance lines
|
||||||
|
// .map(|line| {
|
||||||
|
// line[line.find(':').unwrap() + 1..] // Drop "Time:" and "Distance:"
|
||||||
|
// .split_whitespace() // Split the numbers into their own elements.
|
||||||
|
// .map(|num| num.parse::<i32>().expect("Couldn't parse number")) // Parse numbers into i32
|
||||||
|
// .collect::<Vec<_>>()
|
||||||
|
// }).collect(); // collect into Vec
|
||||||
|
|
||||||
|
// let mut valid_total = 1;
|
||||||
|
|
||||||
|
// for round in 0..input.first().unwrap().len() {
|
||||||
|
// let time = input[0][round];
|
||||||
|
// let dist = input[1][round];
|
||||||
|
// let mut valid = 0;
|
||||||
|
|
||||||
|
// for remaining_time in 0..time {
|
||||||
|
// if (time - remaining_time) * remaining_time > dist {
|
||||||
|
// valid += 1;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// valid_total *= valid;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// println!("{}", valid_total);
|
||||||
|
// }
|
7
old/day07/Cargo.lock
generated
Normal file
7
old/day07/Cargo.lock
generated
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "day07"
|
||||||
|
version = "0.1.0"
|
8
old/day07/Cargo.toml
Normal file
8
old/day07/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "day07"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
183
old/day07/src/main.rs
Normal file
183
old/day07/src/main.rs
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
use std::{fs, collections::HashMap};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let input = fs::read_to_string("input.txt").unwrap();
|
||||||
|
let mut input: Vec<_> = input.split('\n')
|
||||||
|
.map(|line| line.split(' ').collect::<Vec<_>>())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
for line in 0..input.len() {
|
||||||
|
let hand = input[line][0];
|
||||||
|
if hand == "JJJJJ" {
|
||||||
|
input[line].push("7");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let mut card_freq: HashMap<char, i16> = HashMap::new();
|
||||||
|
let joker_count: i16 = hand.chars().filter(|c| c == &'J').count().try_into().unwrap();
|
||||||
|
for card in hand.chars().filter(|c| c != &'J') {
|
||||||
|
card_freq.entry(card)
|
||||||
|
.and_modify(|count| *count += 1)
|
||||||
|
.or_insert(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The most helpful place for the jokers will always be with the max card count
|
||||||
|
let max = card_freq.clone().into_iter().max_by(|a, b| a.1.cmp(&b.1)).unwrap();
|
||||||
|
card_freq.entry(max.0)
|
||||||
|
.and_modify(|count| *count += joker_count);
|
||||||
|
|
||||||
|
let mut set_count: HashMap<i16, i16> = HashMap::new();
|
||||||
|
for i in 1..=5 {
|
||||||
|
let card_count = card_freq.values().filter(|x| **x == i).count().try_into().unwrap();
|
||||||
|
if card_count != 0 {
|
||||||
|
set_count.insert(i, card_count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let power = match set_count {
|
||||||
|
x if x.contains_key(&5) => "7",
|
||||||
|
x if x.contains_key(&4) => "6",
|
||||||
|
x if x.contains_key(&3) && x.contains_key(&2) => "5",
|
||||||
|
x if x.contains_key(&3) => "4",
|
||||||
|
x if x.get(&2).unwrap_or(&0) >= &2 => "3",
|
||||||
|
x if x.get(&2).unwrap_or(&0) == &1 => "2",
|
||||||
|
HashMap { .. } => "1"
|
||||||
|
};
|
||||||
|
|
||||||
|
input[line].push(power);
|
||||||
|
}
|
||||||
|
|
||||||
|
input.sort_by(|lhs, rhs| {
|
||||||
|
let lhs_power: i32 = lhs[2].parse().unwrap();
|
||||||
|
let rhs_power: i32 = rhs[2].parse().unwrap();
|
||||||
|
if lhs_power != rhs_power {
|
||||||
|
return lhs_power.cmp(&rhs_power);
|
||||||
|
}
|
||||||
|
|
||||||
|
let lhs_hand: Vec<i32> = lhs[0].chars().map(card_value).collect();
|
||||||
|
let rhs_hand: Vec<i32> = rhs[0].chars().map(card_value).collect();
|
||||||
|
for i in 0..5 {
|
||||||
|
if lhs_hand[i] == rhs_hand[i] { continue; }
|
||||||
|
return lhs_hand[i].cmp(&rhs_hand[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
panic!("Should not be reachable");
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
let mut total_winnings = 0;
|
||||||
|
for i in 0..input.len() {
|
||||||
|
let bid: usize = input[i][1].parse().unwrap();
|
||||||
|
total_winnings += (i + 1) * bid;
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("{}", total_winnings);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn card_value(card: char) -> i32 {
|
||||||
|
match card {
|
||||||
|
'A' => 13,
|
||||||
|
'K' => 12,
|
||||||
|
'Q' => 11,
|
||||||
|
'T' => 10,
|
||||||
|
'9' => 9,
|
||||||
|
'8' => 8,
|
||||||
|
'7' => 7,
|
||||||
|
'6' => 6,
|
||||||
|
'5' => 5,
|
||||||
|
'4' => 4,
|
||||||
|
'3' => 3,
|
||||||
|
'2' => 2,
|
||||||
|
'J' => 1,
|
||||||
|
_ => panic!("invalid card")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// use std::{fs, collections::HashMap};
|
||||||
|
|
||||||
|
// fn main() {
|
||||||
|
// let input = fs::read_to_string("input.txt").unwrap();
|
||||||
|
// let mut input: Vec<_> = input.split('\n')
|
||||||
|
// .map(|line| line.split(' ').collect::<Vec<_>>())
|
||||||
|
// .collect();
|
||||||
|
|
||||||
|
// for line in 0..input.len() {
|
||||||
|
// let hand = input[line][0];
|
||||||
|
// let mut card_freq: HashMap<char, i16> = HashMap::new();
|
||||||
|
// for card in hand.chars() {
|
||||||
|
// card_freq.entry(card)
|
||||||
|
// .and_modify(|count| *count += 1)
|
||||||
|
// .or_insert(1);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// let mut set_count: HashMap<i16, i16> = HashMap::new();
|
||||||
|
// for i in 1..=5 {
|
||||||
|
// let card_count = card_freq.values().filter(|x| **x == i).count().try_into().unwrap();
|
||||||
|
// if card_count != 0 {
|
||||||
|
// set_count.insert(i, card_count);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// let power = match set_count {
|
||||||
|
// x if x.contains_key(&5) => "7",
|
||||||
|
// x if x.contains_key(&4) => "6",
|
||||||
|
// x if x.contains_key(&3) && x.contains_key(&2) => "5",
|
||||||
|
// x if x.contains_key(&3) => "4",
|
||||||
|
// x if x.get(&2).unwrap_or(&0) >= &2 => "3",
|
||||||
|
// x if x.get(&2).unwrap_or(&0) == &1 => "2",
|
||||||
|
// HashMap { .. } => "1"
|
||||||
|
// };
|
||||||
|
|
||||||
|
// input[line].push(power);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// input.sort_by(|lhs, rhs| {
|
||||||
|
// let lhs_power: i32 = lhs[2].parse().unwrap();
|
||||||
|
// let rhs_power: i32 = rhs[2].parse().unwrap();
|
||||||
|
// if lhs_power != rhs_power {
|
||||||
|
// return lhs_power.cmp(&rhs_power);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// let lhs_hand: Vec<i32> = lhs[0].chars().map(card_value).collect();
|
||||||
|
// let rhs_hand: Vec<i32> = rhs[0].chars().map(card_value).collect();
|
||||||
|
// for i in 0..5 {
|
||||||
|
// if lhs_hand[i] == rhs_hand[i] { continue; }
|
||||||
|
// return lhs_hand[i].cmp(&rhs_hand[i]);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// panic!("Should not be reachable");
|
||||||
|
// });
|
||||||
|
|
||||||
|
|
||||||
|
// let mut total_winnings = 0;
|
||||||
|
// for i in 0..input.len() {
|
||||||
|
// let bid: usize = input[i][1].parse().unwrap();
|
||||||
|
// total_winnings += (i + 1) * bid;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// println!("{}", total_winnings);
|
||||||
|
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// fn card_value(card: char) -> i32 {
|
||||||
|
// match card {
|
||||||
|
// 'A' => 13,
|
||||||
|
// 'K' => 12,
|
||||||
|
// 'Q' => 11,
|
||||||
|
// 'J' => 10,
|
||||||
|
// 'T' => 9,
|
||||||
|
// '9' => 8,
|
||||||
|
// '8' => 7,
|
||||||
|
// '7' => 6,
|
||||||
|
// '6' => 5,
|
||||||
|
// '5' => 4,
|
||||||
|
// '4' => 3,
|
||||||
|
// '3' => 2,
|
||||||
|
// '2' => 1,
|
||||||
|
// _ => panic!("invalid card")
|
||||||
|
// }
|
||||||
|
// }
|
136
src/day5.rs
136
src/day5.rs
@ -1,136 +0,0 @@
|
|||||||
use aoc_runner_derive::{aoc, aoc_generator};
|
|
||||||
|
|
||||||
|
|
||||||
#[aoc_generator(day5)]
|
|
||||||
fn parse(input: &str) -> Vec<Vec<Vec<i64>>> {
|
|
||||||
let mappers: Vec<Vec<Vec<i64>>> = input.split("\n\n")
|
|
||||||
.map(|maps| &maps[(maps.find(':').unwrap() + 1)..])
|
|
||||||
.map(|maps| maps.trim())
|
|
||||||
.map(|maps| {
|
|
||||||
maps.split('\n')
|
|
||||||
.map(|range| {
|
|
||||||
range.split(' ')
|
|
||||||
.map(|num| num.parse::<i64>().unwrap())
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
mappers
|
|
||||||
}
|
|
||||||
|
|
||||||
#[aoc(day5, part1)]
|
|
||||||
fn part1(mappers: &Vec<Vec<Vec<i64>>>) -> i64 {
|
|
||||||
let seeds = mappers.first().unwrap().first().unwrap().clone();
|
|
||||||
let mut borrow_work_around: Vec<Vec<Vec<i64>>> = Vec::new();
|
|
||||||
mappers.clone_into(&mut borrow_work_around);
|
|
||||||
let mappers: &mut [Vec<Vec<i64>>] = &mut borrow_work_around.get_mut(1..).unwrap();
|
|
||||||
|
|
||||||
for mapper in mappers.into_iter() {
|
|
||||||
for range in mapper {
|
|
||||||
range[2] = range[1] + range[2] - 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut cur_vals: Vec<_> = seeds;
|
|
||||||
for mapper in mappers {
|
|
||||||
for val in cur_vals.iter_mut() {
|
|
||||||
for range in mapper.into_iter() {
|
|
||||||
if range[1] <= *val && *val <= range[2] {
|
|
||||||
let diff = *val - range[1];
|
|
||||||
*val = range[0] + diff;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cur_vals.into_iter().min().unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[aoc(day5, part2)]
|
|
||||||
fn part2(mappers: &Vec<Vec<Vec<i64>>>) -> i64 {
|
|
||||||
let seeds = mappers.first().unwrap().first().unwrap().clone();
|
|
||||||
let mut borrow_work_around: Vec<Vec<Vec<i64>>> = Vec::new();
|
|
||||||
mappers.clone_into(&mut borrow_work_around);
|
|
||||||
let mappers: &mut [Vec<Vec<i64>>] = &mut borrow_work_around.get_mut(1..).unwrap();
|
|
||||||
|
|
||||||
for mapper in mappers.into_iter() {
|
|
||||||
for range in mapper {
|
|
||||||
range[2] = range[1] + range[2] - 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut cur_vals: Vec<_> = Vec::new();
|
|
||||||
for i in 0..seeds.len() / 2 {
|
|
||||||
let end = seeds[i * 2] + seeds[(i * 2) + 1];
|
|
||||||
let mut range: Vec<_> = (seeds[i * 2]..end).collect();
|
|
||||||
cur_vals.append(&mut range);
|
|
||||||
}
|
|
||||||
println!("{}", cur_vals.len());
|
|
||||||
for mapper in mappers {
|
|
||||||
for val in cur_vals.iter_mut() {
|
|
||||||
println!("{}", val);
|
|
||||||
for range in mapper.into_iter() {
|
|
||||||
if range[1] <= *val && *val <= range[2] {
|
|
||||||
let diff = *val - range[1];
|
|
||||||
*val = range[0] + diff;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cur_vals.into_iter().min().unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
const EX: &str = r"seeds: 79 14 55 13
|
|
||||||
|
|
||||||
seed-to-soil map:
|
|
||||||
50 98 2
|
|
||||||
52 50 48
|
|
||||||
|
|
||||||
soil-to-fertilizer map:
|
|
||||||
0 15 37
|
|
||||||
37 52 2
|
|
||||||
39 0 15
|
|
||||||
|
|
||||||
fertilizer-to-water map:
|
|
||||||
49 53 8
|
|
||||||
0 11 42
|
|
||||||
42 0 7
|
|
||||||
57 7 4
|
|
||||||
|
|
||||||
water-to-light map:
|
|
||||||
88 18 7
|
|
||||||
18 25 70
|
|
||||||
|
|
||||||
light-to-temperature map:
|
|
||||||
45 77 23
|
|
||||||
81 45 19
|
|
||||||
68 64 13
|
|
||||||
|
|
||||||
temperature-to-humidity map:
|
|
||||||
0 69 1
|
|
||||||
1 0 69
|
|
||||||
|
|
||||||
humidity-to-location map:
|
|
||||||
60 56 37
|
|
||||||
56 93 4";
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn part1_example() {
|
|
||||||
assert_eq!(part1(&parse(EX)), 35);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn part2_example() {
|
|
||||||
assert_eq!(part2(&parse(EX)), 46);
|
|
||||||
}
|
|
||||||
}
|
|
80
src/day6.rs
80
src/day6.rs
@ -1,80 +0,0 @@
|
|||||||
use aoc_runner_derive::{aoc, aoc_generator};
|
|
||||||
#[aoc_generator(day6, part1)]
|
|
||||||
fn parse(input: &str) -> Vec<Vec<i32>> {
|
|
||||||
let input: Vec<Vec<i32>> = input.split('\n') // Separate the Time and Distance lines
|
|
||||||
.map(|line| {
|
|
||||||
line[line.find(':').unwrap() + 1..] // Drop "Time:" and "Distance:"
|
|
||||||
.split_whitespace() // Split the numbers into their own elements.
|
|
||||||
.map(|num| num.parse::<i32>().expect("Couldn't parse number")) // Parse numbers into i32
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
}).collect::<Vec<_>>(); // collect into Vec
|
|
||||||
|
|
||||||
input
|
|
||||||
}
|
|
||||||
|
|
||||||
#[aoc(day6, part1)]
|
|
||||||
fn part1(input: &Vec<Vec<i32>>) -> i32 {
|
|
||||||
let mut valid_total = 1;
|
|
||||||
|
|
||||||
for round in 0..input.first().unwrap().len() {
|
|
||||||
let time = input[0][round];
|
|
||||||
let dist = input[1][round];
|
|
||||||
let mut valid = 0;
|
|
||||||
|
|
||||||
for remaining_time in 0..time {
|
|
||||||
if (time - remaining_time) * remaining_time > dist {
|
|
||||||
valid += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
valid_total *= valid;
|
|
||||||
}
|
|
||||||
|
|
||||||
valid_total
|
|
||||||
}
|
|
||||||
|
|
||||||
#[aoc_generator(day6, part2)]
|
|
||||||
fn parse_part2(input: &str) -> Vec<i64> {
|
|
||||||
let input: Vec<i64> = input.split('\n') // Separate the Time and Distance lines
|
|
||||||
.map(|line| {
|
|
||||||
line[line.find(':').unwrap() + 1..] // Drop "Time:" and "Distance:"
|
|
||||||
.split_whitespace() // Split the numbers into their own elements
|
|
||||||
.flat_map(|s| s.chars()).collect::<String>() // Combine the strings into a single one
|
|
||||||
.parse::<i64>().expect("Couldn't parse number") // Parse numbers into i32
|
|
||||||
}).collect(); // Collect into Vec
|
|
||||||
|
|
||||||
input
|
|
||||||
}
|
|
||||||
|
|
||||||
#[aoc(day6, part2)]
|
|
||||||
fn part2(input: &Vec<i64>) -> i32 {
|
|
||||||
let time = input[0];
|
|
||||||
let dist = input[1];
|
|
||||||
let mut valid = 0;
|
|
||||||
|
|
||||||
for remaining_time in 0..time {
|
|
||||||
if (time - remaining_time) * remaining_time > dist {
|
|
||||||
valid += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
valid
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
const EX: &str = r"Time: 7 15 30
|
|
||||||
Distance: 9 40 200";
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn part1_example() {
|
|
||||||
assert_eq!(part1(&parse(EX)), 288);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn part2_example() {
|
|
||||||
assert_eq!(part2(&parse_part2(EX)), 71503);
|
|
||||||
}
|
|
||||||
}
|
|
207
src/day7.rs
207
src/day7.rs
@ -1,207 +0,0 @@
|
|||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
use aoc_runner_derive::{aoc, aoc_generator};
|
|
||||||
#[aoc_generator(day7)]
|
|
||||||
fn parse(input: &str) -> Vec<Vec<String>> {
|
|
||||||
let input: Vec<Vec<String>> = input.split('\n')
|
|
||||||
.map(|line| line.split(' ').map(|x| x.into()).collect::<Vec<String>>())
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
input
|
|
||||||
}
|
|
||||||
|
|
||||||
#[aoc(day7, part1)]
|
|
||||||
fn part1(input: &Vec<Vec<String>>) -> usize {
|
|
||||||
let mut tmp: Vec<Vec<String>> = Vec::new();
|
|
||||||
input.clone_into(&mut tmp);
|
|
||||||
let mut input = tmp;
|
|
||||||
|
|
||||||
for line in 0..input.len() {
|
|
||||||
let hand = &input[line][0];
|
|
||||||
let mut card_freq: HashMap<char, i16> = HashMap::new();
|
|
||||||
for card in hand.chars() {
|
|
||||||
card_freq.entry(card)
|
|
||||||
.and_modify(|count| *count += 1)
|
|
||||||
.or_insert(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut set_count: HashMap<i16, i16> = HashMap::new();
|
|
||||||
for i in 1..=5 {
|
|
||||||
let card_count = card_freq.values().filter(|x| **x == i).count().try_into().unwrap();
|
|
||||||
if card_count != 0 {
|
|
||||||
set_count.insert(i, card_count);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let power = match set_count {
|
|
||||||
x if x.contains_key(&5) => "7",
|
|
||||||
x if x.contains_key(&4) => "6",
|
|
||||||
x if x.contains_key(&3) && x.contains_key(&2) => "5",
|
|
||||||
x if x.contains_key(&3) => "4",
|
|
||||||
x if x.get(&2).unwrap_or(&0) >= &2 => "3",
|
|
||||||
x if x.get(&2).unwrap_or(&0) == &1 => "2",
|
|
||||||
HashMap { .. } => "1"
|
|
||||||
};
|
|
||||||
|
|
||||||
input[line].push(power.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
input.sort_by(|lhs, rhs| {
|
|
||||||
let lhs_power: i32 = lhs[2].parse().unwrap();
|
|
||||||
let rhs_power: i32 = rhs[2].parse().unwrap();
|
|
||||||
if lhs_power != rhs_power {
|
|
||||||
return lhs_power.cmp(&rhs_power);
|
|
||||||
}
|
|
||||||
|
|
||||||
let lhs_hand: Vec<i32> = lhs[0].chars().map(card_value).collect();
|
|
||||||
let rhs_hand: Vec<i32> = rhs[0].chars().map(card_value).collect();
|
|
||||||
for i in 0..5 {
|
|
||||||
if lhs_hand[i] == rhs_hand[i] { continue; }
|
|
||||||
return lhs_hand[i].cmp(&rhs_hand[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
panic!("Should not be reachable");
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
let mut total_winnings = 0;
|
|
||||||
for i in 0..input.len() {
|
|
||||||
let bid: usize = input[i][1].parse().unwrap();
|
|
||||||
total_winnings += (i + 1) * bid;
|
|
||||||
}
|
|
||||||
|
|
||||||
total_winnings
|
|
||||||
}
|
|
||||||
|
|
||||||
fn card_value(card: char) -> i32 {
|
|
||||||
match card {
|
|
||||||
'A' => 13,
|
|
||||||
'K' => 12,
|
|
||||||
'Q' => 11,
|
|
||||||
'J' => 10,
|
|
||||||
'T' => 9,
|
|
||||||
'9' => 8,
|
|
||||||
'8' => 7,
|
|
||||||
'7' => 6,
|
|
||||||
'6' => 5,
|
|
||||||
'5' => 4,
|
|
||||||
'4' => 3,
|
|
||||||
'3' => 2,
|
|
||||||
'2' => 1,
|
|
||||||
_ => panic!("invalid card")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[aoc(day7, part2)]
|
|
||||||
fn part2(input: &Vec<Vec<String>>) -> usize {
|
|
||||||
let mut tmp: Vec<Vec<String>> = Vec::new();
|
|
||||||
input.clone_into(&mut tmp);
|
|
||||||
let mut input = tmp;
|
|
||||||
|
|
||||||
for line in 0..input.len() {
|
|
||||||
let hand = &input[line][0];
|
|
||||||
if hand == "JJJJJ" {
|
|
||||||
input[line].push("7".to_string());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let mut card_freq: HashMap<char, i16> = HashMap::new();
|
|
||||||
let joker_count: i16 = hand.chars().filter(|c| c == &'J').count().try_into().unwrap();
|
|
||||||
for card in hand.chars().filter(|c| c != &'J') {
|
|
||||||
card_freq.entry(card)
|
|
||||||
.and_modify(|count| *count += 1)
|
|
||||||
.or_insert(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// The most helpful place for the jokers will always be with the max card count
|
|
||||||
let max = card_freq.clone().into_iter().max_by(|a, b| a.1.cmp(&b.1)).unwrap();
|
|
||||||
card_freq.entry(max.0)
|
|
||||||
.and_modify(|count| *count += joker_count);
|
|
||||||
|
|
||||||
let mut set_count: HashMap<i16, i16> = HashMap::new();
|
|
||||||
for i in 1..=5 {
|
|
||||||
let card_count = card_freq.values().filter(|x| **x == i).count().try_into().unwrap();
|
|
||||||
if card_count != 0 {
|
|
||||||
set_count.insert(i, card_count);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let power = match set_count {
|
|
||||||
x if x.contains_key(&5) => "7",
|
|
||||||
x if x.contains_key(&4) => "6",
|
|
||||||
x if x.contains_key(&3) && x.contains_key(&2) => "5",
|
|
||||||
x if x.contains_key(&3) => "4",
|
|
||||||
x if x.get(&2).unwrap_or(&0) >= &2 => "3",
|
|
||||||
x if x.get(&2).unwrap_or(&0) == &1 => "2",
|
|
||||||
HashMap { .. } => "1"
|
|
||||||
};
|
|
||||||
|
|
||||||
input[line].push(power.to_string());
|
|
||||||
}
|
|
||||||
|
|
||||||
input.sort_by(|lhs, rhs| {
|
|
||||||
let lhs_power: i32 = lhs[2].parse().unwrap();
|
|
||||||
let rhs_power: i32 = rhs[2].parse().unwrap();
|
|
||||||
if lhs_power != rhs_power {
|
|
||||||
return lhs_power.cmp(&rhs_power);
|
|
||||||
}
|
|
||||||
|
|
||||||
let lhs_hand: Vec<i32> = lhs[0].chars().map(card_value_pt2).collect();
|
|
||||||
let rhs_hand: Vec<i32> = rhs[0].chars().map(card_value_pt2).collect();
|
|
||||||
for i in 0..5 {
|
|
||||||
if lhs_hand[i] == rhs_hand[i] { continue; }
|
|
||||||
return lhs_hand[i].cmp(&rhs_hand[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
panic!("Should not be reachable");
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
let mut total_winnings = 0;
|
|
||||||
for i in 0..input.len() {
|
|
||||||
let bid: usize = input[i][1].parse().unwrap();
|
|
||||||
total_winnings += (i + 1) * bid;
|
|
||||||
}
|
|
||||||
|
|
||||||
total_winnings
|
|
||||||
}
|
|
||||||
|
|
||||||
fn card_value_pt2(card: char) -> i32 {
|
|
||||||
match card {
|
|
||||||
'A' => 13,
|
|
||||||
'K' => 12,
|
|
||||||
'Q' => 11,
|
|
||||||
'T' => 10,
|
|
||||||
'9' => 9,
|
|
||||||
'8' => 8,
|
|
||||||
'7' => 7,
|
|
||||||
'6' => 6,
|
|
||||||
'5' => 5,
|
|
||||||
'4' => 4,
|
|
||||||
'3' => 3,
|
|
||||||
'2' => 2,
|
|
||||||
'J' => 1,
|
|
||||||
_ => panic!("invalid card")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
const EX: &str = r"32T3K 765
|
|
||||||
T55J5 684
|
|
||||||
KK677 28
|
|
||||||
KTJJT 220
|
|
||||||
QQQJA 483";
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn part1_example() {
|
|
||||||
assert_eq!(part1(&parse(EX)), 6440);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn part2_example() {
|
|
||||||
assert_eq!(part2(&parse(EX)), 5905);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +1,3 @@
|
|||||||
mod day7;
|
|
||||||
mod day6;
|
|
||||||
mod day5;
|
|
||||||
mod day3;
|
|
||||||
mod day14;
|
mod day14;
|
||||||
mod day13;
|
mod day13;
|
||||||
mod day12;
|
mod day12;
|
||||||
|
Loading…
Reference in New Issue
Block a user