Cleanup
This commit is contained in:
parent
432e17c124
commit
94e2a83fd6
32
src/day1.rs
Normal file
32
src/day1.rs
Normal file
@ -0,0 +1,32 @@
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::get_lines;
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn task1() {
|
||||
let mut a = Vec::<i32>::new();
|
||||
let mut b = Vec::<i32>::new();
|
||||
for line in get_lines("input.txt") {
|
||||
let (a1, b1) = line.trim_end().split_once(" ").unwrap();
|
||||
a.push(a1.parse().unwrap());
|
||||
b.push(b1.parse().unwrap());
|
||||
}
|
||||
a.sort_unstable();
|
||||
b.sort_unstable();
|
||||
let result: i32 = a.into_iter().zip(b).map(|(a, b)| (a - b).abs()).sum();
|
||||
println!("{result}");
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn task2() {
|
||||
let mut a = Vec::<u32>::new();
|
||||
let mut b = HashMap::<u32, u32>::new();
|
||||
for line in get_lines("input.txt") {
|
||||
let (a1, b1) = line.trim_end().split_once(" ").unwrap();
|
||||
a.push(a1.parse().unwrap());
|
||||
*b.entry(b1.parse().unwrap()).or_insert(0) += 1;
|
||||
}
|
||||
let result: u32 = a.into_iter().map(|a| a * *b.get(&a).unwrap_or(&0)).sum();
|
||||
println!("{result}");
|
||||
}
|
49
src/day2.rs
Normal file
49
src/day2.rs
Normal file
@ -0,0 +1,49 @@
|
||||
use itertools::Itertools;
|
||||
|
||||
use crate::{get_lines, parse_line};
|
||||
|
||||
fn safe(iter: impl Iterator<Item = i32>) -> bool {
|
||||
let mut order = None;
|
||||
for (a, b) in iter.tuple_windows() {
|
||||
if !(1..4).contains(&(a - b).abs()) {
|
||||
return false;
|
||||
}
|
||||
if order.is_none() {
|
||||
order = Some(a.cmp(&b));
|
||||
} else if order != Some(a.cmp(&b)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn task1() {
|
||||
let result = get_lines("input.txt")
|
||||
.filter(|line| safe(parse_line(line, ' ')))
|
||||
.count();
|
||||
println!("{result}");
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn task2() {
|
||||
let result = get_lines("input.txt")
|
||||
.filter(|line| {
|
||||
let numbers = parse_line(line, ' ').collect_vec();
|
||||
if safe(numbers.iter().copied()) {
|
||||
return true;
|
||||
}
|
||||
let mut test = Vec::with_capacity(numbers.len() - 1);
|
||||
for i in 0..numbers.len() {
|
||||
test.extend_from_slice(&numbers[..i]);
|
||||
test.extend_from_slice(&numbers[i + 1..]);
|
||||
if safe(test.iter().copied()) {
|
||||
return true;
|
||||
}
|
||||
test.clear();
|
||||
}
|
||||
false
|
||||
})
|
||||
.count();
|
||||
println!("{result}");
|
||||
}
|
34
src/day3.rs
Normal file
34
src/day3.rs
Normal file
@ -0,0 +1,34 @@
|
||||
use std::fs::read_to_string;
|
||||
|
||||
use regex::Regex;
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn task1() {
|
||||
let rx = Regex::new(r"mul\((\d{1,3}),(\d{1,3})\)").unwrap();
|
||||
let mut result: i64 = 0;
|
||||
for c in rx.captures_iter(&read_to_string("input.txt").unwrap()) {
|
||||
let (_, [a, b]) = c.extract();
|
||||
result += a.parse::<i64>().unwrap() * b.parse::<i64>().unwrap();
|
||||
}
|
||||
println!("{result}");
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn task2() {
|
||||
let rx = Regex::new(r"(mul)\((\d{1,3}),(\d{1,3})\)|do()()()\(\)|do(n't)()()\(\)").unwrap();
|
||||
let mut enabled = true;
|
||||
let mut result: i64 = 0;
|
||||
for c in rx.captures_iter(&read_to_string("input.txt").unwrap()) {
|
||||
let (_, [op, a, b]) = c.extract();
|
||||
match op {
|
||||
"" => enabled = true,
|
||||
"n't" => enabled = false,
|
||||
"mul" if enabled => {
|
||||
result += a.parse::<i64>().unwrap() * b.parse::<i64>().unwrap();
|
||||
}
|
||||
"mul" => {}
|
||||
_ => unreachable!("{op}"),
|
||||
}
|
||||
}
|
||||
println!("{result}");
|
||||
}
|
62
src/day4.rs
Normal file
62
src/day4.rs
Normal file
@ -0,0 +1,62 @@
|
||||
use itertools::Itertools;
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn task1() {
|
||||
fn check(vals: &[u8]) -> usize {
|
||||
(vals == b"XMAS" || vals == b"SAMX").into()
|
||||
}
|
||||
|
||||
let data = std::fs::read_to_string("input.txt").unwrap();
|
||||
let mut lines = Vec::new();
|
||||
let mut count = 0;
|
||||
for line in data.lines() {
|
||||
count += line.matches("XMAS").count();
|
||||
count += line.matches("SAMX").count();
|
||||
lines.push(line.as_bytes());
|
||||
}
|
||||
for (i, &line) in lines[0..lines.len() - 3].iter().enumerate() {
|
||||
for j in 0..line.len() {
|
||||
count += check(&[
|
||||
lines[i][j],
|
||||
lines[i + 1][j],
|
||||
lines[i + 2][j],
|
||||
lines[i + 3][j],
|
||||
]);
|
||||
if j + 3 < line.len() {
|
||||
count += check(&[
|
||||
lines[i][j],
|
||||
lines[i + 1][j + 1],
|
||||
lines[i + 2][j + 2],
|
||||
lines[i + 3][j + 3],
|
||||
]);
|
||||
}
|
||||
if j > 2 {
|
||||
count += check(&[
|
||||
lines[i][j],
|
||||
lines[i + 1][j - 1],
|
||||
lines[i + 2][j - 2],
|
||||
lines[i + 3][j - 3],
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
println!("{count}");
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn task2() {
|
||||
fn check(vals: &[u8]) -> usize {
|
||||
(vals == b"MAS" || vals == b"SAM").into()
|
||||
}
|
||||
|
||||
let data = std::fs::read_to_string("input.txt").unwrap();
|
||||
let lines = data.lines().map(str::as_bytes).collect_vec();
|
||||
let mut count: usize = 0;
|
||||
for i in 0..lines[..lines.len() - 2].len() {
|
||||
for j in 0..lines[i].len() - 2 {
|
||||
count += check(&[lines[i][j], lines[i + 1][j + 1], lines[i + 2][j + 2]])
|
||||
* check(&[lines[i][j + 2], lines[i + 1][j + 1], lines[i + 2][j]]);
|
||||
}
|
||||
}
|
||||
println!("{count}");
|
||||
}
|
79
src/day5.rs
Normal file
79
src/day5.rs
Normal file
@ -0,0 +1,79 @@
|
||||
use std::{
|
||||
cmp::Ordering,
|
||||
collections::{HashMap, HashSet},
|
||||
};
|
||||
|
||||
use itertools::Itertools;
|
||||
|
||||
use crate::parse_line;
|
||||
|
||||
type Rules = HashMap<i32, HashSet<i32>>;
|
||||
|
||||
fn parse_rules<'a>(lines: &mut impl Iterator<Item = &'a str>) -> Rules {
|
||||
let mut rules: Rules = HashMap::new();
|
||||
for rule in lines.by_ref().take_while(|s| !s.is_empty()) {
|
||||
let vals = rule.split_once('|').unwrap();
|
||||
let (before, after) = (vals.0.parse().unwrap(), vals.1.parse().unwrap());
|
||||
rules.entry(before).or_default().insert(after);
|
||||
}
|
||||
rules
|
||||
}
|
||||
|
||||
fn parse_updates<'a>(
|
||||
lines: impl Iterator<Item = &'a str> + 'a,
|
||||
) -> impl Iterator<Item = Vec<i32>> + 'a {
|
||||
lines.map(|line| parse_line(line, ',').collect_vec())
|
||||
}
|
||||
|
||||
fn check_update(update: &[i32], rules: &Rules) -> bool {
|
||||
for (i, val) in update.iter().enumerate() {
|
||||
let Some(local_rules) = rules.get(val) else {
|
||||
continue;
|
||||
};
|
||||
if update[..i].iter().any(|elem| local_rules.contains(elem)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn task1() {
|
||||
let data = std::fs::read_to_string("input.txt").unwrap();
|
||||
let mut lines = data.lines();
|
||||
let rules = parse_rules(&mut lines);
|
||||
let result: i32 = parse_updates(lines)
|
||||
.filter(|u| check_update(u, &rules))
|
||||
.map(|u| u[u.len() / 2])
|
||||
.sum();
|
||||
println!("{result}");
|
||||
}
|
||||
|
||||
fn compare(a: i32, b: i32, rules: &Rules) -> Ordering {
|
||||
if let Some(rule) = rules.get(&a) {
|
||||
if rule.contains(&b) {
|
||||
return Ordering::Less;
|
||||
}
|
||||
}
|
||||
if let Some(rule) = rules.get(&b) {
|
||||
if rule.contains(&a) {
|
||||
return Ordering::Greater;
|
||||
}
|
||||
}
|
||||
Ordering::Equal
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn task2() {
|
||||
let data = std::fs::read_to_string("input.txt").unwrap();
|
||||
let mut lines = data.lines();
|
||||
let rules = parse_rules(&mut lines);
|
||||
let result: i32 = parse_updates(lines)
|
||||
.filter(|u| !check_update(u, &rules))
|
||||
.map(|mut u| {
|
||||
u.sort_unstable_by(|a, b| compare(*a, *b, &rules));
|
||||
u[u.len() / 2]
|
||||
})
|
||||
.sum();
|
||||
println!("{result}");
|
||||
}
|
285
src/main.rs
285
src/main.rs
@ -1,3 +1,9 @@
|
||||
mod day1;
|
||||
mod day2;
|
||||
mod day3;
|
||||
mod day4;
|
||||
mod day5;
|
||||
|
||||
use std::{
|
||||
fs::File,
|
||||
io::{BufRead as _, BufReader},
|
||||
@ -9,283 +15,8 @@ fn get_lines(name: &str) -> impl Iterator<Item = String> {
|
||||
.map(|line| line.unwrap())
|
||||
}
|
||||
|
||||
mod day1 {
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::get_lines;
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn task1() {
|
||||
let mut a = Vec::<i32>::new();
|
||||
let mut b = Vec::<i32>::new();
|
||||
for line in get_lines("input.txt") {
|
||||
let (a1, b1) = line.trim_end().split_once(" ").unwrap();
|
||||
a.push(a1.parse().unwrap());
|
||||
b.push(b1.parse().unwrap());
|
||||
}
|
||||
a.sort_unstable();
|
||||
b.sort_unstable();
|
||||
let result: i32 = a.into_iter().zip(b).map(|(a, b)| (a - b).abs()).sum();
|
||||
println!("{result}");
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn task2() {
|
||||
let mut a = Vec::<u32>::new();
|
||||
let mut b = HashMap::<u32, u32>::new();
|
||||
for line in get_lines("input.txt") {
|
||||
let (a1, b1) = line.trim_end().split_once(" ").unwrap();
|
||||
a.push(a1.parse().unwrap());
|
||||
*b.entry(b1.parse().unwrap()).or_insert(0) += 1;
|
||||
}
|
||||
let result: u32 = a.into_iter().map(|a| a * *b.get(&a).unwrap_or(&0)).sum();
|
||||
println!("{result}");
|
||||
}
|
||||
}
|
||||
|
||||
mod day2 {
|
||||
use itertools::Itertools;
|
||||
|
||||
use crate::get_lines;
|
||||
|
||||
fn safe(iter: impl Iterator<Item = i32>) -> bool {
|
||||
let mut order = None;
|
||||
for (a, b) in iter.tuple_windows() {
|
||||
if !(1..4).contains(&(a - b).abs()) {
|
||||
return false;
|
||||
}
|
||||
if order.is_none() {
|
||||
order = Some(a.cmp(&b));
|
||||
} else if order != Some(a.cmp(&b)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
fn parse_line(line: &str) -> impl Iterator<Item = i32> + '_ {
|
||||
line.trim()
|
||||
.split(' ')
|
||||
.map(|num| num.parse::<i32>().unwrap())
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn task1() {
|
||||
let result = get_lines("input.txt")
|
||||
.filter(|line| safe(parse_line(line)))
|
||||
.count();
|
||||
println!("{result}");
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn task2() {
|
||||
let result = get_lines("input.txt")
|
||||
.filter(|line| {
|
||||
let numbers = parse_line(line).collect_vec();
|
||||
if safe(numbers.iter().copied()) {
|
||||
return true;
|
||||
}
|
||||
let mut test = Vec::with_capacity(numbers.len() - 1);
|
||||
for i in 0..numbers.len() {
|
||||
test.extend_from_slice(&numbers[..i]);
|
||||
test.extend_from_slice(&numbers[i + 1..]);
|
||||
if safe(test.iter().copied()) {
|
||||
return true;
|
||||
}
|
||||
test.clear();
|
||||
}
|
||||
false
|
||||
})
|
||||
.count();
|
||||
println!("{result}");
|
||||
}
|
||||
}
|
||||
|
||||
mod day3 {
|
||||
use std::fs::read_to_string;
|
||||
|
||||
use regex::Regex;
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn task1() {
|
||||
let rx = Regex::new(r"mul\((\d{1,3}),(\d{1,3})\)").unwrap();
|
||||
let mut result: i64 = 0;
|
||||
for c in rx.captures_iter(&read_to_string("input.txt").unwrap()) {
|
||||
let (_, [a, b]) = c.extract();
|
||||
result += a.parse::<i64>().unwrap() * b.parse::<i64>().unwrap();
|
||||
}
|
||||
println!("{result}");
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn task2() {
|
||||
let rx = Regex::new(r"(mul)\((\d{1,3}),(\d{1,3})\)|do()()()\(\)|do(n't)()()\(\)").unwrap();
|
||||
let mut enabled = true;
|
||||
let mut result: i64 = 0;
|
||||
for c in rx.captures_iter(&read_to_string("input.txt").unwrap()) {
|
||||
let (_, [op, a, b]) = c.extract();
|
||||
match op {
|
||||
"" => enabled = true,
|
||||
"n't" => enabled = false,
|
||||
"mul" if enabled => {
|
||||
result += a.parse::<i64>().unwrap() * b.parse::<i64>().unwrap();
|
||||
}
|
||||
"mul" => {}
|
||||
_ => unreachable!("{op}"),
|
||||
}
|
||||
}
|
||||
println!("{result}");
|
||||
}
|
||||
}
|
||||
|
||||
mod day4 {
|
||||
use itertools::Itertools;
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn task1() {
|
||||
fn check(vals: &[u8]) -> usize {
|
||||
(vals == b"XMAS" || vals == b"SAMX").into()
|
||||
}
|
||||
|
||||
let data = std::fs::read_to_string("input.txt").unwrap();
|
||||
let mut lines = Vec::new();
|
||||
let mut count = 0;
|
||||
for line in data.lines() {
|
||||
count += line.matches("XMAS").count();
|
||||
count += line.matches("SAMX").count();
|
||||
lines.push(line.as_bytes());
|
||||
}
|
||||
for (i, &line) in lines[0..lines.len() - 3].iter().enumerate() {
|
||||
for j in 0..line.len() {
|
||||
count += check(&[
|
||||
lines[i][j],
|
||||
lines[i + 1][j],
|
||||
lines[i + 2][j],
|
||||
lines[i + 3][j],
|
||||
]);
|
||||
if j + 3 < line.len() {
|
||||
count += check(&[
|
||||
lines[i][j],
|
||||
lines[i + 1][j + 1],
|
||||
lines[i + 2][j + 2],
|
||||
lines[i + 3][j + 3],
|
||||
]);
|
||||
}
|
||||
if j > 2 {
|
||||
count += check(&[
|
||||
lines[i][j],
|
||||
lines[i + 1][j - 1],
|
||||
lines[i + 2][j - 2],
|
||||
lines[i + 3][j - 3],
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
println!("{count}");
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn task2() {
|
||||
fn check(vals: &[u8]) -> usize {
|
||||
(vals == b"MAS" || vals == b"SAM").into()
|
||||
}
|
||||
|
||||
let data = std::fs::read_to_string("input.txt").unwrap();
|
||||
let lines = data.lines().map(str::as_bytes).collect_vec();
|
||||
let mut count: usize = 0;
|
||||
for i in 0..lines[..lines.len() - 2].len() {
|
||||
for j in 0..lines[i].len() - 2 {
|
||||
count += check(&[lines[i][j], lines[i + 1][j + 1], lines[i + 2][j + 2]])
|
||||
* check(&[lines[i][j + 2], lines[i + 1][j + 1], lines[i + 2][j]]);
|
||||
}
|
||||
}
|
||||
println!("{count}");
|
||||
}
|
||||
}
|
||||
|
||||
mod day5 {
|
||||
use std::{
|
||||
cmp::Ordering,
|
||||
collections::{HashMap, HashSet},
|
||||
};
|
||||
|
||||
use itertools::Itertools;
|
||||
|
||||
type Rules = HashMap<i32, HashSet<i32>>;
|
||||
|
||||
fn parse_rules<'a>(lines: &mut impl Iterator<Item = &'a str>) -> Rules {
|
||||
let mut rules: Rules = HashMap::new();
|
||||
for rule in lines.by_ref().take_while(|s| !s.is_empty()) {
|
||||
let vals = rule.split_once('|').unwrap();
|
||||
let (before, after) = (vals.0.parse().unwrap(), vals.1.parse().unwrap());
|
||||
rules.entry(before).or_default().insert(after);
|
||||
}
|
||||
rules
|
||||
}
|
||||
|
||||
fn parse_updates<'a>(
|
||||
lines: impl Iterator<Item = &'a str> + 'a,
|
||||
) -> impl Iterator<Item = Vec<i32>> + 'a {
|
||||
lines.map(|line| {
|
||||
line.trim()
|
||||
.split(',')
|
||||
.map(|num| num.parse::<i32>().unwrap())
|
||||
.collect_vec()
|
||||
})
|
||||
}
|
||||
|
||||
fn check_update(update: &[i32], rules: &Rules) -> bool {
|
||||
for (i, val) in update.iter().enumerate() {
|
||||
let Some(local_rules) = rules.get(val) else {
|
||||
continue;
|
||||
};
|
||||
if update[..i].iter().any(|elem| local_rules.contains(elem)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn task1() {
|
||||
let data = std::fs::read_to_string("input.txt").unwrap();
|
||||
let mut lines = data.lines();
|
||||
let rules = parse_rules(&mut lines);
|
||||
let result: i32 = parse_updates(lines)
|
||||
.filter(|u| check_update(u, &rules))
|
||||
.map(|u| u[u.len() / 2])
|
||||
.sum();
|
||||
println!("{result}");
|
||||
}
|
||||
|
||||
fn compare(a: i32, b: i32, rules: &Rules) -> Ordering {
|
||||
if let Some(rule) = rules.get(&a) {
|
||||
if rule.contains(&b) {
|
||||
return Ordering::Less;
|
||||
}
|
||||
}
|
||||
if let Some(rule) = rules.get(&b) {
|
||||
if rule.contains(&a) {
|
||||
return Ordering::Greater;
|
||||
}
|
||||
}
|
||||
Ordering::Equal
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn task2() {
|
||||
let data = std::fs::read_to_string("input.txt").unwrap();
|
||||
let mut lines = data.lines();
|
||||
let rules = parse_rules(&mut lines);
|
||||
let result: i32 = parse_updates(lines)
|
||||
.filter(|u| !check_update(u, &rules))
|
||||
.map(|mut u| {
|
||||
u.sort_unstable_by(|a, b| compare(*a, *b, &rules));
|
||||
u[u.len() / 2]
|
||||
})
|
||||
.sum();
|
||||
println!("{result}");
|
||||
}
|
||||
fn parse_line(line: &str, pattern: char) -> impl Iterator<Item = i32> + '_ {
|
||||
line.trim().split(pattern).map(|num| num.parse().unwrap())
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user