day5-6
This commit is contained in:
parent
7feae9f1aa
commit
d3c428c84b
|
@ -48,6 +48,7 @@ dependencies = [
|
||||||
"aoc-runner-derive",
|
"aoc-runner-derive",
|
||||||
"nom",
|
"nom",
|
||||||
"regex",
|
"regex",
|
||||||
|
"topological-sort",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -185,6 +186,12 @@ dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "topological-sort"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ea68304e134ecd095ac6c3574494fc62b909f416c4fca77e440530221e549d3d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.14"
|
version = "1.0.14"
|
||||||
|
|
|
@ -8,3 +8,4 @@ aoc-runner = "0.3.0"
|
||||||
aoc-runner-derive = "0.3.0"
|
aoc-runner-derive = "0.3.0"
|
||||||
nom = "7.1.3"
|
nom = "7.1.3"
|
||||||
regex = "1.11.1"
|
regex = "1.11.1"
|
||||||
|
topological-sort = "0.2.2"
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
max_width = 200
|
# max_width = 1000
|
||||||
|
|
112
src/day4.rs
112
src/day4.rs
|
@ -1,21 +1,39 @@
|
||||||
use aoc_runner_derive::{aoc, aoc_generator};
|
use aoc_runner_derive::{aoc, aoc_generator};
|
||||||
#[aoc_generator(day4)]
|
#[aoc_generator(day4)]
|
||||||
fn parse(input: &str) -> Vec<Vec<char>> {
|
fn parse(input: &str) -> Vec<Vec<char>> {
|
||||||
input.split("\n").map(|line| line.chars().collect()).collect()
|
input
|
||||||
|
.split("\n")
|
||||||
|
.map(|line| line.chars().collect())
|
||||||
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[aoc(day4, part1)]
|
#[aoc(day4, part1)]
|
||||||
fn part1(d: &[Vec<char>]) -> usize {
|
fn part1(d: &[Vec<char>]) -> usize {
|
||||||
(0..d.len())
|
(0..d.len()).fold(0, |z, i| {
|
||||||
.flat_map(|i| (0..d[0].len()).map(move |j| (j as i64, i as i64, j > 2, j < d.len() - 3, i > 2, i < d[0].len() - 3)))
|
z + (0..d[0].len())
|
||||||
.filter(|p| d[p.1 as usize][p.0 as usize] == 'X')
|
.map(move |j| {
|
||||||
.flat_map(|p| {
|
(
|
||||||
(-1..=1)
|
j as i64,
|
||||||
.flat_map(|dx| (-1..=1).filter(move |i| dx != 0 || *i != 0).map(move |i| (dx, i)))
|
i as i64,
|
||||||
.filter(move |(a, b)| (*a == 0 || (*a == -1 && p.2) || (*a == 1 && p.3)) && (*b == 0 || (*b == -1 && p.4) || (*b == 1 && p.5)))
|
j > 2,
|
||||||
.filter(move |r| (1..=3).zip("MAS".chars()).all(|v| d[(p.1 + v.0 * r.1) as usize][(p.0 + v.0 * r.0) as usize] == v.1))
|
j < d.len() - 3,
|
||||||
})
|
i > 2,
|
||||||
.count()
|
i < d[0].len() - 3,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.fold(0, |z, p| {
|
||||||
|
z + (-1..=1).fold(0, |z, f| {
|
||||||
|
z + (-1..=1).fold(0, move |z, g| {
|
||||||
|
z + ((f != 0 || g != 0)
|
||||||
|
&& (f == 0 || (f == -1 && p.2) || (f == 1 && p.3))
|
||||||
|
&& (g == 0 || (g == -1 && p.4) || (g == 1 && p.5))
|
||||||
|
&& (0..=3).zip("XMAS".chars()).all(|v| {
|
||||||
|
d[(p.1 + v.0 * g) as usize][(p.0 + v.0 * f) as usize] == v.1
|
||||||
|
})) as usize
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn _part1(input: &[Vec<char>]) -> u64 {
|
fn _part1(input: &[Vec<char>]) -> u64 {
|
||||||
|
@ -25,36 +43,72 @@ fn _part1(input: &[Vec<char>]) -> u64 {
|
||||||
for y in 0..h {
|
for y in 0..h {
|
||||||
for x in 0..w {
|
for x in 0..w {
|
||||||
if input[y][x] == 'S' {
|
if input[y][x] == 'S' {
|
||||||
if x < w - 3 && input[y][x + 1] == 'A' && input[y][x + 2] == 'M' && input[y][x + 3] == 'X' {
|
if x < w - 3
|
||||||
|
&& input[y][x + 1] == 'A'
|
||||||
|
&& input[y][x + 2] == 'M'
|
||||||
|
&& input[y][x + 3] == 'X'
|
||||||
|
{
|
||||||
// println!("rev X {} {}", x, y);
|
// println!("rev X {} {}", x, y);
|
||||||
sum += 1
|
sum += 1
|
||||||
}
|
}
|
||||||
if y < h - 3 && input[y + 1][x] == 'A' && input[y + 2][x] == 'M' && input[y + 3][x] == 'X' {
|
if y < h - 3
|
||||||
|
&& input[y + 1][x] == 'A'
|
||||||
|
&& input[y + 2][x] == 'M'
|
||||||
|
&& input[y + 3][x] == 'X'
|
||||||
|
{
|
||||||
// println!("rev Y {} {}", x, y);
|
// println!("rev Y {} {}", x, y);
|
||||||
sum += 1
|
sum += 1
|
||||||
}
|
}
|
||||||
if x < w - 3 && y < h - 3 && input[y + 1][x + 1] == 'A' && input[y + 2][x + 2] == 'M' && input[y + 3][x + 3] == 'X' {
|
if x < w - 3
|
||||||
|
&& y < h - 3
|
||||||
|
&& input[y + 1][x + 1] == 'A'
|
||||||
|
&& input[y + 2][x + 2] == 'M'
|
||||||
|
&& input[y + 3][x + 3] == 'X'
|
||||||
|
{
|
||||||
// println!("rdi Y {} {}", x, y);
|
// println!("rdi Y {} {}", x, y);
|
||||||
sum += 1
|
sum += 1
|
||||||
}
|
}
|
||||||
if x >= 3 && y < h - 3 && input[y + 1][x - 1] == 'A' && input[y + 2][x - 2] == 'M' && input[y + 3][x - 3] == 'X' {
|
if x >= 3
|
||||||
|
&& y < h - 3
|
||||||
|
&& input[y + 1][x - 1] == 'A'
|
||||||
|
&& input[y + 2][x - 2] == 'M'
|
||||||
|
&& input[y + 3][x - 3] == 'X'
|
||||||
|
{
|
||||||
// println!("rdi Y {} {}", x, y);
|
// println!("rdi Y {} {}", x, y);
|
||||||
sum += 1
|
sum += 1
|
||||||
}
|
}
|
||||||
} else if input[y][x] == 'X' {
|
} else if input[y][x] == 'X' {
|
||||||
if x < w - 3 && input[y][x + 1] == 'M' && input[y][x + 2] == 'A' && input[y][x + 3] == 'S' {
|
if x < w - 3
|
||||||
|
&& input[y][x + 1] == 'M'
|
||||||
|
&& input[y][x + 2] == 'A'
|
||||||
|
&& input[y][x + 3] == 'S'
|
||||||
|
{
|
||||||
// println!(" X {} {}", x, y);
|
// println!(" X {} {}", x, y);
|
||||||
sum += 1
|
sum += 1
|
||||||
}
|
}
|
||||||
if y < h - 3 && input[y + 1][x] == 'M' && input[y + 2][x] == 'A' && input[y + 3][x] == 'S' {
|
if y < h - 3
|
||||||
|
&& input[y + 1][x] == 'M'
|
||||||
|
&& input[y + 2][x] == 'A'
|
||||||
|
&& input[y + 3][x] == 'S'
|
||||||
|
{
|
||||||
// println!(" Y {} {}", x, y);
|
// println!(" Y {} {}", x, y);
|
||||||
sum += 1
|
sum += 1
|
||||||
}
|
}
|
||||||
if x < w - 3 && y < h - 3 && input[y + 1][x + 1] == 'M' && input[y + 2][x + 2] == 'A' && input[y + 3][x + 3] == 'S' {
|
if x < w - 3
|
||||||
|
&& y < h - 3
|
||||||
|
&& input[y + 1][x + 1] == 'M'
|
||||||
|
&& input[y + 2][x + 2] == 'A'
|
||||||
|
&& input[y + 3][x + 3] == 'S'
|
||||||
|
{
|
||||||
// println!("dia Y {} {}", x, y);
|
// println!("dia Y {} {}", x, y);
|
||||||
sum += 1
|
sum += 1
|
||||||
}
|
}
|
||||||
if x >= 3 && y < h - 3 && input[y + 1][x - 1] == 'M' && input[y + 2][x - 2] == 'A' && input[y + 3][x - 3] == 'S' {
|
if x >= 3
|
||||||
|
&& y < h - 3
|
||||||
|
&& input[y + 1][x - 1] == 'M'
|
||||||
|
&& input[y + 2][x - 2] == 'A'
|
||||||
|
&& input[y + 3][x - 3] == 'S'
|
||||||
|
{
|
||||||
// println!("dia Y {} {}", x, y);
|
// println!("dia Y {} {}", x, y);
|
||||||
sum += 1
|
sum += 1
|
||||||
}
|
}
|
||||||
|
@ -72,8 +126,10 @@ fn part2(input: &[Vec<char>]) -> u64 {
|
||||||
for y in 1..h - 1 {
|
for y in 1..h - 1 {
|
||||||
for x in 1..w - 1 {
|
for x in 1..w - 1 {
|
||||||
if input[y][x] == 'A' {
|
if input[y][x] == 'A' {
|
||||||
let diag1 = (input[y - 1][x - 1] == 'M' && input[y + 1][x + 1] == 'S') || (input[y - 1][x - 1] == 'S' && input[y + 1][x + 1] == 'M');
|
let diag1 = (input[y - 1][x - 1] == 'M' && input[y + 1][x + 1] == 'S')
|
||||||
let diag2 = (input[y - 1][x + 1] == 'M' && input[y + 1][x - 1] == 'S') || (input[y - 1][x + 1] == 'S' && input[y + 1][x - 1] == 'M');
|
|| (input[y - 1][x - 1] == 'S' && input[y + 1][x + 1] == 'M');
|
||||||
|
let diag2 = (input[y - 1][x + 1] == 'M' && input[y + 1][x - 1] == 'S')
|
||||||
|
|| (input[y - 1][x + 1] == 'S' && input[y + 1][x - 1] == 'M');
|
||||||
if diag1 && diag2 {
|
if diag1 && diag2 {
|
||||||
sum += 1;
|
sum += 1;
|
||||||
}
|
}
|
||||||
|
@ -89,22 +145,12 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn part1_example() {
|
fn part1_example() {
|
||||||
assert_eq!(
|
assert_eq!(part1(&parse("MMMSXXMASM\nMSAMXMSMSA\nAMXSXMAAMM\nMSAMASMSMX\nXMASAMXAMM\nXXAMMXXAMA\nSMSMSASXSS\nSAXAMASAAA\nMAMMMXMMMM\nMXMXAXMASX")), 18);
|
||||||
part1(&parse(
|
|
||||||
"MMMSXXMASM\nMSAMXMSMSA\nAMXSXMAAMM\nMSAMASMSMX\nXMASAMXAMM\nXXAMMXXAMA\nSMSMSASXSS\nSAXAMASAAA\nMAMMMXMMMM\nMXMXAXMASX"
|
|
||||||
)),
|
|
||||||
18
|
|
||||||
);
|
|
||||||
assert_eq!(part1(&parse(include_str!("../input/2024/day4.txt"))), 2406);
|
assert_eq!(part1(&parse(include_str!("../input/2024/day4.txt"))), 2406);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn part2_example() {
|
fn part2_example() {
|
||||||
assert_eq!(
|
assert_eq!(part2(&parse(".M.S......\n..A..MSMS.\n.M.S.MAA..\n..A.ASMSM.\n.M.S.M....\n..........\nS.S.S.S.S.\n.A.A.A.A..\nM.M.M.M.M.\n..........")), 9);
|
||||||
part2(&parse(
|
|
||||||
".M.S......\n..A..MSMS.\n.M.S.MAA..\n..A.ASMSM.\n.M.S.M....\n..........\nS.S.S.S.S.\n.A.A.A.A..\nM.M.M.M.M.\n.........."
|
|
||||||
)),
|
|
||||||
9
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,125 @@
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use aoc_runner_derive::{aoc, aoc_generator};
|
||||||
|
use nom::character::complete::u64 as parse_u64;
|
||||||
|
use nom::multi::separated_list1;
|
||||||
|
use nom::IResult;
|
||||||
|
use nom::{
|
||||||
|
bytes::complete::tag, character::complete::newline, multi::separated_list0,
|
||||||
|
sequence::separated_pair,
|
||||||
|
};
|
||||||
|
use topological_sort::TopologicalSort;
|
||||||
|
|
||||||
|
type Input = (Vec<(u64, u64)>, Vec<Vec<u64>>);
|
||||||
|
|
||||||
|
#[aoc_generator(day5)]
|
||||||
|
fn parse(input: &str) -> Input {
|
||||||
|
parse_lines(input).unwrap().1
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_lines(input: &str) -> IResult<&str, Input> {
|
||||||
|
let (input, rules) =
|
||||||
|
separated_list0(newline, separated_pair(parse_u64, tag("|"), parse_u64))(input)?;
|
||||||
|
let (input, _) = newline(input)?;
|
||||||
|
let (input, _) = newline(input)?;
|
||||||
|
let (input, records) = separated_list0(newline, separated_list1(tag(","), parse_u64))(input)?;
|
||||||
|
Ok((input, (rules, records)))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[aoc(day5, part1)]
|
||||||
|
fn part1(input: &Input) -> u64 {
|
||||||
|
let rules = input.0.clone();
|
||||||
|
let records = input.1.clone();
|
||||||
|
|
||||||
|
let mut rules_map: HashMap<u64, Vec<u64>> = HashMap::new();
|
||||||
|
rules.iter().for_each(|rule| {
|
||||||
|
if let std::collections::hash_map::Entry::Vacant(e) = rules_map.entry(rule.1) {
|
||||||
|
e.insert(vec![rule.0]);
|
||||||
|
} else {
|
||||||
|
rules_map.get_mut(&rule.1).unwrap().push(rule.0);
|
||||||
|
rules_map.get_mut(&rule.1).unwrap().sort();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut correct = 0;
|
||||||
|
records.iter().for_each(|record| {
|
||||||
|
let mut forbidden = vec![];
|
||||||
|
let valid = record.iter().all(|page| {
|
||||||
|
let allowed = !forbidden.contains(page);
|
||||||
|
if rules_map.contains_key(page) {
|
||||||
|
let mut new_forbidden = rules_map.get(page).unwrap().clone();
|
||||||
|
forbidden.append(&mut new_forbidden);
|
||||||
|
}
|
||||||
|
allowed
|
||||||
|
});
|
||||||
|
if valid {
|
||||||
|
correct += record[record.len() >> 1]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
correct
|
||||||
|
}
|
||||||
|
|
||||||
|
#[aoc(day5, part2)]
|
||||||
|
fn part2(input: &Input) -> u64 {
|
||||||
|
let rules = input.0.clone();
|
||||||
|
let records = input.1.clone();
|
||||||
|
|
||||||
|
let mut rules_map: HashMap<u64, Vec<u64>> = HashMap::new();
|
||||||
|
rules.iter().for_each(|rule| {
|
||||||
|
if let std::collections::hash_map::Entry::Vacant(e) = rules_map.entry(rule.1) {
|
||||||
|
e.insert(vec![rule.0]);
|
||||||
|
} else {
|
||||||
|
rules_map.get_mut(&rule.1).unwrap().push(rule.0);
|
||||||
|
rules_map.get_mut(&rule.1).unwrap().sort();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut correct = 0;
|
||||||
|
records.iter().for_each(|record| {
|
||||||
|
let mut forbidden = vec![];
|
||||||
|
let valid = record.iter().all(|page| {
|
||||||
|
let allowed = !forbidden.contains(page);
|
||||||
|
if rules_map.contains_key(page) {
|
||||||
|
let mut new_forbidden = rules_map.get(page).unwrap().clone();
|
||||||
|
forbidden.append(&mut new_forbidden);
|
||||||
|
}
|
||||||
|
allowed
|
||||||
|
});
|
||||||
|
if !valid {
|
||||||
|
// dbg!(&record);
|
||||||
|
let mut ts = TopologicalSort::<u64>::new();
|
||||||
|
for i in record {
|
||||||
|
ts.insert(*i);
|
||||||
|
if let Some(rules) = rules_map.get(i) {
|
||||||
|
for rule in rules {
|
||||||
|
ts.add_dependency(*rule, *i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let sorted = ts
|
||||||
|
.clone()
|
||||||
|
.filter(|a| record.contains(a))
|
||||||
|
.collect::<Vec<u64>>();
|
||||||
|
correct += sorted[sorted.len() >> 1]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
correct
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part1_example() {
|
||||||
|
assert_eq!(part1(&parse("47|53\n97|13\n97|61\n97|47\n75|29\n61|13\n75|53\n29|13\n97|29\n53|29\n61|53\n97|53\n61|29\n47|13\n75|47\n97|75\n47|61\n75|61\n47|29\n75|13\n53|13\n\n75,47,61,53,29\n97,61,53,29,13\n75,29,13\n75,97,47,61,53\n61,13,29\n97,13,75,29,47")), 143);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part2_example() {
|
||||||
|
assert_eq!(part2(&parse("47|53\n97|13\n97|61\n97|47\n75|29\n61|13\n75|53\n29|13\n97|29\n53|29\n61|53\n97|53\n61|29\n47|13\n75|47\n97|75\n47|61\n75|61\n47|29\n75|13\n53|13\n\n75,47,61,53,29\n97,61,53,29,13\n75,29,13\n75,97,47,61,53\n61,13,29\n97,13,75,29,47")), 123);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,173 @@
|
||||||
|
type Input = ((usize, usize), Vec<Vec<u8>>);
|
||||||
|
|
||||||
|
use aoc_runner_derive::{aoc, aoc_generator};
|
||||||
|
#[aoc_generator(day6)]
|
||||||
|
fn parse(input: &str) -> Input {
|
||||||
|
let lines = input.split("\n");
|
||||||
|
let mut pos = (0, 0);
|
||||||
|
let map = lines
|
||||||
|
.enumerate()
|
||||||
|
.map(|(y, line)| {
|
||||||
|
line.chars()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(x, c)| match c {
|
||||||
|
'.' => 0,
|
||||||
|
'#' => 1,
|
||||||
|
'^' => {
|
||||||
|
pos = (x, y);
|
||||||
|
0
|
||||||
|
}
|
||||||
|
_ => todo!(),
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
(pos, map)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[aoc(day6, part1)]
|
||||||
|
fn part1(input: &Input) -> u64 {
|
||||||
|
let h = input.1.len();
|
||||||
|
let w = input.1[0].len();
|
||||||
|
let mut map = input.1.clone();
|
||||||
|
let mut pos = input.0;
|
||||||
|
let mut dir = (0, -1);
|
||||||
|
let mut count = 0;
|
||||||
|
loop {
|
||||||
|
if map[pos.1][pos.0] == 0 {
|
||||||
|
map[pos.1][pos.0] = 2;
|
||||||
|
count += 1;
|
||||||
|
};
|
||||||
|
if pos.0 as isize + dir.0 < 0
|
||||||
|
|| pos.0 as isize + dir.0 >= w as isize
|
||||||
|
|| pos.1 as isize + dir.1 < 0
|
||||||
|
|| pos.1 as isize + dir.1 >= h as isize
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
while map[(pos.1 as isize + dir.1) as usize][(pos.0 as isize + dir.0) as usize] == 1 {
|
||||||
|
if dir.0 == 1 {
|
||||||
|
dir = (0, 1);
|
||||||
|
} else if dir.0 == -1 {
|
||||||
|
dir = (0, -1);
|
||||||
|
} else if dir.1 == 1 {
|
||||||
|
dir = (-1, 0);
|
||||||
|
} else if dir.1 == -1 {
|
||||||
|
dir = (1, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pos = (
|
||||||
|
(pos.0 as isize + dir.0) as usize,
|
||||||
|
(pos.1 as isize + dir.1) as usize,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
count
|
||||||
|
}
|
||||||
|
|
||||||
|
#[aoc(day6, part2)]
|
||||||
|
fn part2(input: &Input) -> u64 {
|
||||||
|
let initial = input.0;
|
||||||
|
let h = input.1.len();
|
||||||
|
let w = input.1[0].len();
|
||||||
|
let mut map = input.1.clone();
|
||||||
|
let mut pos = input.0;
|
||||||
|
let mut dir = (0, -1);
|
||||||
|
let mut loops = vec![];
|
||||||
|
loop {
|
||||||
|
if pos.0 as isize + dir.0 < 0
|
||||||
|
|| pos.0 as isize + dir.0 >= w as isize
|
||||||
|
|| pos.1 as isize + dir.1 < 0
|
||||||
|
|| pos.1 as isize + dir.1 >= h as isize
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
while map[(pos.1 as isize + dir.1) as usize][(pos.0 as isize + dir.0) as usize] == 1 {
|
||||||
|
if dir.0 == 1 {
|
||||||
|
dir = (0, 1);
|
||||||
|
} else if dir.0 == -1 {
|
||||||
|
dir = (0, -1);
|
||||||
|
} else if dir.1 == 1 {
|
||||||
|
dir = (-1, 0);
|
||||||
|
} else if dir.1 == -1 {
|
||||||
|
dir = (1, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let next_pos = (
|
||||||
|
(pos.0 as isize + dir.0) as usize,
|
||||||
|
(pos.1 as isize + dir.1) as usize,
|
||||||
|
);
|
||||||
|
if map[next_pos.1][next_pos.0] != 1 {
|
||||||
|
map[next_pos.1][next_pos.0] = 1;
|
||||||
|
if check_loop(initial, (0, -1), &map) {
|
||||||
|
// count += 1;
|
||||||
|
if !(loops.contains(&next_pos)) && next_pos != initial {
|
||||||
|
loops.push(next_pos);
|
||||||
|
}
|
||||||
|
// println!("{} {}", nexts_pos.0 + 1, next_pos.1 + 1);
|
||||||
|
}
|
||||||
|
map[next_pos.1][next_pos.0] = 0;
|
||||||
|
}
|
||||||
|
pos = next_pos;
|
||||||
|
}
|
||||||
|
loops.len() as u64
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_loop(pos: (usize, usize), dir: (isize, isize), map: &[Vec<u8>]) -> bool {
|
||||||
|
let mut visited = vec![];
|
||||||
|
|
||||||
|
let h = map.len();
|
||||||
|
let w = map[0].len();
|
||||||
|
|
||||||
|
let mut dir = dir;
|
||||||
|
let mut pos = pos;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
if pos.0 as isize + dir.0 < 0
|
||||||
|
|| pos.0 as isize + dir.0 >= w as isize
|
||||||
|
|| pos.1 as isize + dir.1 < 0
|
||||||
|
|| pos.1 as isize + dir.1 >= h as isize
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
let mut turns = 0;
|
||||||
|
while map[(pos.1 as isize + dir.1) as usize][(pos.0 as isize + dir.0) as usize] == 1 {
|
||||||
|
if dir.0 == 1 {
|
||||||
|
dir = (0, 1);
|
||||||
|
} else if dir.0 == -1 {
|
||||||
|
dir = (0, -1);
|
||||||
|
} else if dir.1 == 1 {
|
||||||
|
dir = (-1, 0);
|
||||||
|
} else if dir.1 == -1 {
|
||||||
|
dir = (1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
turns += 1;
|
||||||
|
}
|
||||||
|
pos = (
|
||||||
|
(pos.0 as isize + dir.0) as usize,
|
||||||
|
(pos.1 as isize + dir.1) as usize,
|
||||||
|
);
|
||||||
|
if visited.contains(&(pos.0, pos.1, dir.0, dir.1)) {
|
||||||
|
return true;
|
||||||
|
} else if turns > 0 {
|
||||||
|
visited.push((pos.0, pos.1, dir.0, dir.1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part1_example() {
|
||||||
|
assert_eq!(part1(&parse("....#.....\n.........#\n..........\n..#.......\n.......#..\n..........\n.#..^.....\n........#.\n#.........\n......#...")), 41);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part2_example() {
|
||||||
|
assert_eq!(part2(&parse("....#.....\n.........#\n..........\n..#.......\n.......#..\n..........\n.#..^.....\n........#.\n#.........\n......#...")), 6);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,3 +1,5 @@
|
||||||
|
mod day6;
|
||||||
|
mod day5;
|
||||||
mod day4;
|
mod day4;
|
||||||
mod day1;
|
mod day1;
|
||||||
mod day2;
|
mod day2;
|
||||||
|
|
Loading…
Reference in New Issue