add: more days
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
use advent_of_code_2024::{make_main, SResult};
|
||||
use regex::Regex;
|
||||
|
||||
make_main!();
|
||||
|
||||
fn solve(lines: Vec<String>) -> SResult<usize> {
|
||||
let mut result = 0;
|
||||
let re = Regex::new(r"mul\((?<mul1>\d{1,3}),(?<mul2>\d{1,3})\)")?;
|
||||
for line in lines {
|
||||
for caps in re.captures_iter(&line) {
|
||||
result += caps["mul1"].parse::<usize>().unwrap() * caps["mul2"].parse::<usize>().unwrap();
|
||||
}
|
||||
}
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use advent_of_code_2024::input;
|
||||
|
||||
use super::*;
|
||||
#[test]
|
||||
fn sample_input() {
|
||||
let strings: Vec<String> = input!("d3p1.txt");
|
||||
let got = solve(strings).unwrap();
|
||||
assert_eq!(got, 161);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5))
|
||||
@@ -0,0 +1,94 @@
|
||||
use advent_of_code_2024::{make_main, SResult};
|
||||
|
||||
make_main!();
|
||||
|
||||
type PResult<'a, T> = Result<(&'a str, T), ()>;
|
||||
|
||||
fn literal<'a, 'b>(p: &'a str, lit: &'b str) -> PResult<'a, ()> {
|
||||
if p.len() < lit.len() {
|
||||
Err(())
|
||||
} else {
|
||||
let (found, rest) = p.split_at(lit.len());
|
||||
if found == lit {
|
||||
Ok((rest, ()))
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn next(p: &str) -> PResult<char> {
|
||||
let mut chars = p.chars();
|
||||
let next = chars.next().ok_or(())?;
|
||||
Ok((chars.as_str(), next))
|
||||
}
|
||||
|
||||
fn int(mut p: &str) -> PResult<usize> {
|
||||
let (_p, total) = next(p)?;
|
||||
let mut total = total.to_digit(10).ok_or(())?;
|
||||
p = _p;
|
||||
let mut i = 1;
|
||||
while let Ok((_p, digit)) = next(p) {
|
||||
if !digit.is_digit(10) {
|
||||
break;
|
||||
}
|
||||
total = (total * 10) + digit.to_digit(10).ok_or(())?;
|
||||
p = _p;
|
||||
|
||||
// We only accept integers between 1 and 3 digits
|
||||
i += 1;
|
||||
if i > 3 {
|
||||
return Err(());
|
||||
}
|
||||
}
|
||||
Ok((p, total as usize))
|
||||
}
|
||||
|
||||
fn mul(p: &str) -> PResult<usize> {
|
||||
let (p, _) = literal(p, "mul(")?;
|
||||
let (p, mul1) = int(p)?;
|
||||
let (p, _) = literal(p, ",")?;
|
||||
let (p, mul2) = int(p)?;
|
||||
let (p, _) = literal(p, ")")?;
|
||||
Ok((p, mul1*mul2))
|
||||
}
|
||||
|
||||
fn solve(lines: Vec<String>) -> SResult<usize> {
|
||||
let mut result = 0;
|
||||
let mut enabled = true;
|
||||
for line in lines {
|
||||
let mut line = line.as_str();
|
||||
while line.len() > 0 {
|
||||
if let Ok(val) = mul(&line) {
|
||||
if enabled {
|
||||
result += val.1;
|
||||
}
|
||||
line = val.0;
|
||||
} else if let Ok(val) = literal(&line, "do()") {
|
||||
enabled = true;
|
||||
line = val.0;
|
||||
} else if let Ok(val) = literal(&line, "don't()") {
|
||||
enabled = false;
|
||||
line = val.0;
|
||||
} else {
|
||||
let n = next(line).unwrap();
|
||||
line = n.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use advent_of_code_2024::input;
|
||||
|
||||
use super::*;
|
||||
#[test]
|
||||
fn sample_input() {
|
||||
let strings: Vec<String> = input!("d3p2.txt");
|
||||
let got = solve(strings).unwrap();
|
||||
assert_eq!(got, 48);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
use advent_of_code_2024::{make_main, SResult};
|
||||
use regex::Regex;
|
||||
|
||||
make_main!();
|
||||
|
||||
fn solve(lines: Vec<String>) -> SResult<usize> {
|
||||
let mut result = 0;
|
||||
let re = Regex::new(r"(?<do>do\(\))|(?<dont>don't\(\))|mul\(((?<mul1>\d{1,3})),((?<mul2>\d{1,3}))\)")?;
|
||||
let mut enabled = true;
|
||||
for line in lines {
|
||||
for caps in re.captures_iter(&line) {
|
||||
if caps.name("do").is_some() {
|
||||
enabled = true;
|
||||
} else if caps.name("dont").is_some() {
|
||||
enabled = false;
|
||||
} else if caps.name("mul1").is_some() && enabled {
|
||||
result += caps["mul1"].parse::<usize>().unwrap() * caps["mul2"].parse::<usize>().unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use advent_of_code_2024::input;
|
||||
|
||||
use super::*;
|
||||
#[test]
|
||||
fn sample_input() {
|
||||
let strings: Vec<String> = input!("d3p2.txt");
|
||||
let got = solve(strings).unwrap();
|
||||
assert_eq!(got, 48);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))
|
||||
@@ -0,0 +1,61 @@
|
||||
use advent_of_code_2024::{make_main, SResult};
|
||||
|
||||
make_main!();
|
||||
|
||||
fn solve(lines: Vec<String>) -> SResult<usize> {
|
||||
// Convert to a grid of chars for easy searching
|
||||
let mut grid = vec!();
|
||||
for line in lines {
|
||||
let line: Vec<char> = line.chars().collect();
|
||||
grid.push(line);
|
||||
}
|
||||
let mut total = 0;
|
||||
let word: Vec<char> = "XMAS".chars().collect();
|
||||
for x in 0..grid.len() {
|
||||
for y in 0..grid[x].len() {
|
||||
for vel in [(1, 0), (-1, 0), (0, 1), (0, -1), (1, 1), (-1, -1), (-1, 1), (1, -1)] {
|
||||
let mut matches = 0;
|
||||
let mut pos = (x, y);
|
||||
for c in &word {
|
||||
if grid[pos.0][pos.1] != *c {
|
||||
break;
|
||||
}
|
||||
matches += 1;
|
||||
if let Some(_pos) = next(pos, vel, grid.len()) {
|
||||
pos = _pos;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if matches == word.len() {
|
||||
total += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(total)
|
||||
}
|
||||
|
||||
fn next((x, y): (usize, usize), (xvel, yvel): (i64, i64), width: usize) -> Option<(usize, usize)> {
|
||||
let x = x as i64 + xvel;
|
||||
let y = y as i64 + yvel;
|
||||
if x < 0 || y < 0 || x == width as i64 || y == width as i64 {
|
||||
None
|
||||
} else {
|
||||
Some((x as usize, y as usize))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use advent_of_code_2024::input;
|
||||
|
||||
use super::*;
|
||||
#[test]
|
||||
fn sample_input() {
|
||||
let strings: Vec<String> = input!("d4p1.txt");
|
||||
let got = solve(strings).unwrap();
|
||||
assert_eq!(got, 18);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
MMMSXXMASM
|
||||
MSAMXMSMSA
|
||||
AMXSXMAAMM
|
||||
MSAMASMSMX
|
||||
XMASAMXAMM
|
||||
XXAMMXXAMA
|
||||
SMSMSASXSS
|
||||
SAXAMASAAA
|
||||
MAMMMXMMMM
|
||||
MXMXAXMASX
|
||||
@@ -0,0 +1,73 @@
|
||||
use advent_of_code_2024::{make_main, SResult};
|
||||
|
||||
make_main!();
|
||||
|
||||
fn solve(lines: Vec<String>) -> SResult<usize> {
|
||||
// Convert to a grid of chars for easy searching
|
||||
let mut grid = vec!();
|
||||
for line in lines {
|
||||
let line: Vec<char> = line.chars().collect();
|
||||
grid.push(line);
|
||||
}
|
||||
let mut total = 0;
|
||||
let word: Vec<char> = "XMAS".chars().collect();
|
||||
for x in 0..grid.len() {
|
||||
for y in 0..grid[x].len() {
|
||||
if grid[x][y] != 'A' {
|
||||
continue;
|
||||
}
|
||||
let mut count = 0;
|
||||
for vel in [(1, 1), (1, -1), (-1, -1), (-1, 1)] {
|
||||
if let Some(pos) = next((x, y), vel, grid.len()) {
|
||||
if check_mas(&grid, pos, (-1*vel.0, -1*vel.1)) {
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if count == 2 {
|
||||
total += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(total)
|
||||
}
|
||||
|
||||
fn check_mas(grid: &[Vec<char>], mut pos: (usize, usize), vel: (i64, i64)) -> bool {
|
||||
let mut matches = 0;
|
||||
for c in "MAS".chars() {
|
||||
if c != grid[pos.0][pos.1] {
|
||||
break;
|
||||
}
|
||||
matches += 1;
|
||||
if let Some(_pos) = next(pos, vel, grid.len()) {
|
||||
pos = _pos;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
matches == "MAS".len()
|
||||
}
|
||||
|
||||
fn next((x, y): (usize, usize), (xvel, yvel): (i64, i64), width: usize) -> Option<(usize, usize)> {
|
||||
let x = x as i64 + xvel;
|
||||
let y = y as i64 + yvel;
|
||||
if x < 0 || y < 0 || x == width as i64 || y == width as i64 {
|
||||
None
|
||||
} else {
|
||||
Some((x as usize, y as usize))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use advent_of_code_2024::input;
|
||||
|
||||
use super::*;
|
||||
#[test]
|
||||
fn sample_input() {
|
||||
let strings: Vec<String> = input!("d4p1.txt");
|
||||
let got = solve(strings).unwrap();
|
||||
assert_eq!(got, 9);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user