2024-12-01 15:10:20 +03:00
|
|
|
use std::{
|
|
|
|
fs::File,
|
2024-12-02 20:42:43 +03:00
|
|
|
io::{BufRead as _, BufReader},
|
2024-12-01 15:10:20 +03:00
|
|
|
};
|
|
|
|
|
2024-12-02 20:42:43 +03:00
|
|
|
fn get_lines(name: &str) -> impl Iterator<Item = String> {
|
|
|
|
BufReader::new(File::open(name).unwrap())
|
|
|
|
.lines()
|
|
|
|
.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}");
|
2024-12-01 15:10:20 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-12-02 20:42:43 +03:00
|
|
|
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}");
|
2024-12-01 15:10:20 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-12-03 21:27:56 +03:00
|
|
|
mod day3 {
|
|
|
|
use std::fs::read_to_string;
|
|
|
|
|
|
|
|
use regex::Regex;
|
|
|
|
|
2024-12-04 18:26:28 +03:00
|
|
|
#[allow(dead_code)]
|
2024-12-03 21:27:56 +03:00
|
|
|
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}");
|
|
|
|
}
|
|
|
|
|
2024-12-04 18:26:28 +03:00
|
|
|
#[allow(dead_code)]
|
2024-12-03 21:27:56 +03:00
|
|
|
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}");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-12-04 18:26:28 +03:00
|
|
|
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}");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-12-01 15:10:20 +03:00
|
|
|
fn main() {
|
2024-12-02 20:42:43 +03:00
|
|
|
// day1::task1();
|
|
|
|
// day1::task1();
|
2024-12-03 21:27:56 +03:00
|
|
|
// day2::task1();
|
|
|
|
// day2::task2();
|
2024-12-04 18:26:28 +03:00
|
|
|
// day3::task1();
|
|
|
|
// day3::task2();
|
|
|
|
day4::task1();
|
|
|
|
day4::task2();
|
2024-12-01 15:10:20 +03:00
|
|
|
}
|