mirror of
https://github.com/RussellChamp/advent-of-code-2024-rust.git
synced 2026-10-27 23:52:29 +00:00
fix clippy issues and update benchmarks
This commit is contained in:
1 parent
6502e63efe
commit
ee6c70ef8a
11 files changed
+101
-97
No files matched your search
@@ -27,18 +27,21 @@ Solutions for [Advent of Code](https://adventofcode.com/) in [Rust](https://www.
|
|||||||
|
|
||||||
| Day | Part 1 | Part 2 |
|
| Day | Part 1 | Part 2 |
|
||||||
| :---: | :---: | :---: |
|
| :---: | :---: | :---: |
|
||||||
| [Day 1](./src/bin/01.rs) | `131.2µs` | `206.6µs` |
|
| [Day 1](./src/bin/01.rs) | `126.9µs` | `218.4µs` |
|
||||||
| [Day 2](./src/bin/02.rs) | `179.9µs` | `474.6µs` |
|
| [Day 2](./src/bin/02.rs) | `190.5µs` | `487.3µs` |
|
||||||
| [Day 3](./src/bin/03.rs) | `465.1µs` | `666.7µs` |
|
| [Day 3](./src/bin/03.rs) | `524.3µs` | `678.5µs` |
|
||||||
| [Day 4](./src/bin/04.rs) | `3.4ms` | `476.1µs` |
|
| [Day 4](./src/bin/04.rs) | `3.7ms` | `495.5µs` |
|
||||||
| [Day 6](./src/bin/06.rs) | `65.5µs` | `-` |
|
| [Day 5](./src/bin/05.rs) | `43.2ms` | `-` |
|
||||||
| [Day 7](./src/bin/07.rs) | `12.2ms` | `-` |
|
| [Day 6](./src/bin/06.rs) | `59.8µs` | `-` |
|
||||||
| [Day 8](./src/bin/08.rs) | `109.7µs` | `-` |
|
| [Day 7](./src/bin/07.rs) | `11.9ms` | `-` |
|
||||||
| [Day 9](./src/bin/09.rs) | `1.1ms` | `-` |
|
| [Day 8](./src/bin/08.rs) | `106.2µs` | `-` |
|
||||||
| [Day 10](./src/bin/10.rs) | `5.7ms` | `-` |
|
| [Day 9](./src/bin/09.rs) | `1.0ms` | `-` |
|
||||||
| [Day 13](./src/bin/13.rs) | `2.9ms` | `-` |
|
| [Day 10](./src/bin/10.rs) | `10.1ms` | `-` |
|
||||||
|
| [Day 11](./src/bin/11.rs) | `6.0s` | `-` |
|
||||||
|
| [Day 12](./src/bin/12.rs) | `4.5ms` | `-` |
|
||||||
|
| [Day 13](./src/bin/13.rs) | `3.1ms` | `-` |
|
||||||
|
|
||||||
**Total: 28.08ms**
|
**Total: 6080.39ms**
|
||||||
<!--- benchmarking table --->
|
<!--- benchmarking table --->
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
File renamed without changes.
+9
-9
@@ -35,9 +35,13 @@ pub fn part_one(input: &str) -> Option<u32> {
|
|||||||
Some(total)
|
Some(total)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn part_two(input: &str) -> Option<u32> {
|
#[allow(unreachable_code)]
|
||||||
|
pub fn part_two(_input: &str) -> Option<u32> {
|
||||||
|
// TODO: Fix this
|
||||||
|
return None;
|
||||||
|
|
||||||
// Parse the rules
|
// Parse the rules
|
||||||
let mut reader = input.lines();
|
let mut reader = _input.lines();
|
||||||
let rules: Vec<_> = reader.by_ref().take_while(|l| !l.is_empty()).map(|r| r.split('|').collect::<Vec<&str>>()).collect();
|
let rules: Vec<_> = reader.by_ref().take_while(|l| !l.is_empty()).map(|r| r.split('|').collect::<Vec<&str>>()).collect();
|
||||||
|
|
||||||
// println!("{} lines", rules.len());
|
// println!("{} lines", rules.len());
|
||||||
@@ -52,7 +56,7 @@ pub fn part_two(input: &str) -> Option<u32> {
|
|||||||
let is_valid = get_is_valid(&rules, &pages);
|
let is_valid = get_is_valid(&rules, &pages);
|
||||||
|
|
||||||
if is_valid {
|
if is_valid {
|
||||||
return t
|
t
|
||||||
} else {
|
} else {
|
||||||
// println!("Invalid pages {:?}", pages);
|
// println!("Invalid pages {:?}", pages);
|
||||||
|
|
||||||
@@ -75,7 +79,7 @@ pub fn part_two(input: &str) -> Option<u32> {
|
|||||||
Some(total)
|
Some(total)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_is_valid(rules: &Vec<Vec<&str>>, pages: &Vec<&str>) -> bool {
|
fn get_is_valid(rules: &[Vec<&str>], pages: &[&str]) -> bool {
|
||||||
for (page_a_idx, page_a) in pages.iter().enumerate() {
|
for (page_a_idx, page_a) in pages.iter().enumerate() {
|
||||||
for page_b in &pages[page_a_idx..] {
|
for page_b in &pages[page_a_idx..] {
|
||||||
// check for a violation of the rules!
|
// check for a violation of the rules!
|
||||||
@@ -91,7 +95,7 @@ fn find_valid_book<'a>(rules: &Vec<Vec<&str>>, pages: Vec<&'a str>, remaining_pa
|
|||||||
|
|
||||||
let is_valid = get_is_valid(rules, &pages);
|
let is_valid = get_is_valid(rules, &pages);
|
||||||
|
|
||||||
if remaining_pages.len() == 0 && is_valid {
|
if remaining_pages.is_empty() && is_valid {
|
||||||
|
|
||||||
return Some(pages)
|
return Some(pages)
|
||||||
}
|
}
|
||||||
@@ -110,10 +114,6 @@ fn find_valid_book<'a>(rules: &Vec<Vec<&str>>, pages: Vec<&'a str>, remaining_pa
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn factorial(n: usize) -> Option<usize> {
|
|
||||||
(1..n).try_fold(n, usize::checked_mul)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|||||||
+5
-5
@@ -3,8 +3,8 @@ use itertools::Itertools;
|
|||||||
advent_of_code::solution!(6);
|
advent_of_code::solution!(6);
|
||||||
|
|
||||||
pub fn part_one(input: &str) -> Option<u32> {
|
pub fn part_one(input: &str) -> Option<u32> {
|
||||||
let mut pos = (0 as isize, 0 as isize);
|
let mut pos = (0_isize, 0_isize);
|
||||||
let mut dir = (-1 as isize, 0 as isize);
|
let mut dir = (-1_isize, 0_isize);
|
||||||
|
|
||||||
let grid = input.lines().enumerate().map(|(line_idx, line)| {
|
let grid = input.lines().enumerate().map(|(line_idx, line)| {
|
||||||
let chars = line.chars().enumerate().map(|(char_idx, char)| {
|
let chars = line.chars().enumerate().map(|(char_idx, char)| {
|
||||||
@@ -34,8 +34,8 @@ pub fn part_one(input: &str) -> Option<u32> {
|
|||||||
|
|
||||||
if grid[new_pos.0 as usize][new_pos.1 as usize] == '#' {
|
if grid[new_pos.0 as usize][new_pos.1 as usize] == '#' {
|
||||||
// if it is a blocker, turn 90deg
|
// if it is a blocker, turn 90deg
|
||||||
let directions = vec![(-1, 0), (0, 1), (1, 0), (0, -1), (-1, 0)];
|
let directions = [(-1, 0), (0, 1), (1, 0), (0, -1), (-1, 0)];
|
||||||
let new_dir = *directions.iter().skip_while(|d| **d != dir).skip(1).next().unwrap();
|
let new_dir = *directions.iter().skip_while(|d| **d != dir).nth(1).unwrap();
|
||||||
dir.0 = new_dir.0;
|
dir.0 = new_dir.0;
|
||||||
dir.1 = new_dir.1;
|
dir.1 = new_dir.1;
|
||||||
} else {
|
} else {
|
||||||
@@ -51,7 +51,7 @@ pub fn part_one(input: &str) -> Option<u32> {
|
|||||||
Some(count_spaces(visited) as u32)
|
Some(count_spaces(visited) as u32)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn part_two(input: &str) -> Option<u32> {
|
pub fn part_two(_input: &str) -> Option<u32> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+12
-12
@@ -9,15 +9,15 @@ pub fn part_one(input: &str) -> Option<usize> {
|
|||||||
|
|
||||||
// println!("LINE: {} = {:?}", total, values);
|
// println!("LINE: {} = {:?}", total, values);
|
||||||
|
|
||||||
if can_calc(total, values) { Some(total) } else { None }
|
if can_calc(total, &values) { Some(total) } else { None }
|
||||||
// Some(total)
|
// Some(total)
|
||||||
}).sum();
|
}).sum();
|
||||||
// println!("TOTAL: {}", total);
|
// println!("TOTAL: {}", total);
|
||||||
|
|
||||||
return Some(total);
|
Some(total)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn part_two(input: &str) -> Option<u32> {
|
pub fn part_two(_input: &str) -> Option<u32> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,16 +26,16 @@ pub fn part_two(input: &str) -> Option<u32> {
|
|||||||
// eg 190: 10 19 -- has TWO possible paths, 10 + 19 and 10 * 19
|
// eg 190: 10 19 -- has TWO possible paths, 10 + 19 and 10 * 19
|
||||||
// eg 123: 4 5 6 3 -- has 8 possible paths; 4+5+6+3, 4+5+6*3, ... 4*5*6*3
|
// eg 123: 4 5 6 3 -- has 8 possible paths; 4+5+6+3, 4+5+6*3, ... 4*5*6*3
|
||||||
|
|
||||||
fn can_calc(total: usize, values: Vec<usize>) -> bool {
|
fn can_calc(total: usize, values: &[usize]) -> bool {
|
||||||
let is_valid = values.into_iter().fold(vec![0 as usize], |subtotals, next_value| {
|
let is_valid = values.iter().fold(vec![0_usize], |subtotals, next_value| {
|
||||||
process(&subtotals, next_value)
|
process(&subtotals, next_value)
|
||||||
}).iter().any(|t| *t == total);
|
}).iter().any(|t| *t == total);
|
||||||
|
|
||||||
is_valid
|
is_valid
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process(sum: &Vec<usize>, next_value: usize) -> Vec<usize> {
|
fn process(sum: &[usize], next_value: &usize) -> Vec<usize> {
|
||||||
sum.into_iter().flat_map(|v| {
|
sum.iter().flat_map(|v| {
|
||||||
vec![v + next_value, v * next_value]
|
vec![v + next_value, v * next_value]
|
||||||
}).collect()
|
}).collect()
|
||||||
}
|
}
|
||||||
@@ -46,19 +46,19 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_process() {
|
fn test_process() {
|
||||||
let sum: Vec<u32> = vec![1];
|
let sum = [1];
|
||||||
let next_value = 10;
|
let next_value = 10;
|
||||||
|
|
||||||
let result = process(&sum, next_value);
|
let result = process(&sum, &next_value);
|
||||||
assert_eq!(result, vec![11, 10]);
|
assert_eq!(result, vec![11, 10]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_can_calc() {
|
fn test_can_calc() {
|
||||||
let values: Vec<u32> = vec![1,2,3,4];
|
let values = [1,2,3,4];
|
||||||
let total: u32 = 10;
|
let total = 10;
|
||||||
|
|
||||||
let result = can_calc(total, values);
|
let result = can_calc(total, &values);
|
||||||
assert_eq!(result, true);
|
assert_eq!(result, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -14,10 +14,10 @@ pub fn part_one(input: &str) -> Option<u32> {
|
|||||||
|
|
||||||
for (col_idx, c) in line.chars().enumerate(){
|
for (col_idx, c) in line.chars().enumerate(){
|
||||||
if c != '.' {
|
if c != '.' {
|
||||||
if antennas.contains_key(&c) {
|
if let std::collections::hash_map::Entry::Vacant(_e) = antennas.entry(c) {
|
||||||
antennas.entry(c).and_modify(|v| v.push((row_idx as u32, col_idx as u32)));
|
|
||||||
} else {
|
|
||||||
antennas.insert(c, vec![(row_idx as u32, col_idx as u32)]);
|
antennas.insert(c, vec![(row_idx as u32, col_idx as u32)]);
|
||||||
|
} else {
|
||||||
|
antennas.entry(c).and_modify(|v| v.push((row_idx as u32, col_idx as u32)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -39,7 +39,7 @@ pub fn part_one(input: &str) -> Option<u32> {
|
|||||||
Some(locations.count() as u32)
|
Some(locations.count() as u32)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn part_two(input: &str) -> Option<u32> {
|
pub fn part_two(_input: &str) -> Option<u32> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+8
-11
@@ -23,7 +23,7 @@ pub fn part_one(input: &str) -> Option<u32> {
|
|||||||
Some(checksum as u32)
|
Some(checksum as u32)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn part_two(input: &str) -> Option<u32> {
|
pub fn part_two(_input: &str) -> Option<u32> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,18 +45,18 @@ fn move_blocks(mut blocks: Vec<Option<usize>>) -> Vec<Option<usize>>{
|
|||||||
let mut head_ptr = 0;
|
let mut head_ptr = 0;
|
||||||
let mut tail_ptr = blocks.len() - 1;
|
let mut tail_ptr = blocks.len() - 1;
|
||||||
|
|
||||||
while blocks[tail_ptr] == None {
|
while Option::is_none(&blocks[tail_ptr]) {
|
||||||
tail_ptr -= 1;
|
tail_ptr -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
while head_ptr <= tail_ptr {
|
while head_ptr <= tail_ptr {
|
||||||
if blocks[head_ptr] == None {
|
if Option::is_none(&blocks[head_ptr]) {
|
||||||
blocks.swap(head_ptr, tail_ptr);
|
blocks.swap(head_ptr, tail_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
head_ptr += 1;
|
head_ptr += 1;
|
||||||
|
|
||||||
while blocks[tail_ptr] == None {
|
while Option::is_none(&blocks[tail_ptr]) {
|
||||||
tail_ptr -= 1;
|
tail_ptr -= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -65,16 +65,13 @@ fn move_blocks(mut blocks: Vec<Option<usize>>) -> Vec<Option<usize>>{
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_checksum(blocks: Vec<Option<usize>>) -> usize {
|
fn get_checksum(blocks: Vec<Option<usize>>) -> usize {
|
||||||
let checksum = blocks.into_iter().enumerate().fold(0 as usize, |sum, (idx, id)| {
|
blocks.into_iter().enumerate().fold(0_usize, |sum, (idx, id)| {
|
||||||
if id == None {
|
if Option::is_none(&id) {
|
||||||
sum
|
sum
|
||||||
} else {
|
} else {
|
||||||
let total = sum + idx.mul(id.unwrap() as usize);
|
sum + idx.mul(id.unwrap())
|
||||||
total
|
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
checksum
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|||||||
+3
-3
@@ -37,7 +37,7 @@ pub fn part_one(input: &str) -> Option<u32> {
|
|||||||
Some(total_score as u32)
|
Some(total_score as u32)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn part_two(input: &str) -> Option<u32> {
|
pub fn part_two(_input: &str) -> Option<u32> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,9 +51,9 @@ fn can_navigate(grid: &Vec<Vec<u32>>, start: &Path, end: &Path) -> bool {
|
|||||||
if start == end { return true }
|
if start == end { return true }
|
||||||
|
|
||||||
DIRECTIONS.iter().any(|d| {
|
DIRECTIONS.iter().any(|d| {
|
||||||
let next_step = Path { row: &start.row + d.0, col: &start.col + d.1, elevation: start.elevation + 1 };
|
let next_step = Path { row: start.row + d.0, col: start.col + d.1, elevation: start.elevation + 1 };
|
||||||
// println!("{:?} ==> {:?} ?", start, end);
|
// println!("{:?} ==> {:?} ?", start, end);
|
||||||
is_valid(&next_step) && can_navigate(&grid, &next_step, &end)
|
is_valid(&next_step) && can_navigate(grid, &next_step, end)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -1,4 +1,4 @@
|
|||||||
use std::ops::{Div, Mul};
|
use std::ops::Mul;
|
||||||
|
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
|
||||||
@@ -14,7 +14,7 @@ pub fn part_one(input: &str) -> Option<u32> {
|
|||||||
Some(total_count as u32)
|
Some(total_count as u32)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn part_two(input: &str) -> Option<u32> {
|
pub fn part_two(_input: &str) -> Option<u32> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@ fn step_stones(stones: &mut Vec<String>, max_steps: usize) {
|
|||||||
if stone == "0" {
|
if stone == "0" {
|
||||||
stones[idx] = String::from("1");
|
stones[idx] = String::from("1");
|
||||||
} else if stone_length % 2 == 0 {
|
} else if stone_length % 2 == 0 {
|
||||||
let mut stone_iter = stone.chars().into_iter();
|
let mut stone_iter = stone.chars();
|
||||||
let first_half = stone_iter.by_ref().take(stone_length/2).collect::<String>();
|
let first_half = stone_iter.by_ref().take(stone_length/2).collect::<String>();
|
||||||
let second_half = stone_iter.by_ref().take(stone_length/2).collect::<String>().parse::<usize>().unwrap().to_string();
|
let second_half = stone_iter.by_ref().take(stone_length/2).collect::<String>().parse::<usize>().unwrap().to_string();
|
||||||
|
|
||||||
|
|||||||
+40
-35
@@ -26,6 +26,7 @@ type Direction = (isize, isize);
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
#[allow(dead_code)]
|
||||||
struct Region {
|
struct Region {
|
||||||
id: u32,
|
id: u32,
|
||||||
edges: usize,
|
edges: usize,
|
||||||
@@ -37,7 +38,7 @@ pub fn part_one(input: &str) -> Option<u32> {
|
|||||||
let mut regions: HashMap<u32, Region> = HashMap::new();
|
let mut regions: HashMap<u32, Region> = HashMap::new();
|
||||||
let mut next_region_id = 1;
|
let mut next_region_id = 1;
|
||||||
|
|
||||||
while let Some(plot) = find_plot(&plots, |p| p.region_id == None) {
|
while let Some(plot) = find_plot(&plots, |p| Option::is_none(&p.region_id)) {
|
||||||
plots[plot.0][plot.1].region_id = Some(next_region_id);
|
plots[plot.0][plot.1].region_id = Some(next_region_id);
|
||||||
|
|
||||||
let edge_count = count_edges(&plots, &plot);
|
let edge_count = count_edges(&plots, &plot);
|
||||||
@@ -56,12 +57,16 @@ pub fn part_one(input: &str) -> Option<u32> {
|
|||||||
Some(total as u32)
|
Some(total as u32)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn part_two(input: &str) -> Option<u32> {
|
#[allow(unreachable_code)]
|
||||||
let mut plots = input.lines().map(|l| l.chars().map(|c| Plot { letter: c, region_id: None }).collect_vec()).collect_vec();
|
pub fn part_two(_input: &str) -> Option<u32> {
|
||||||
|
// TODO: Get this working
|
||||||
|
return None;
|
||||||
|
|
||||||
|
let mut plots = _input.lines().map(|l| l.chars().map(|c| Plot { letter: c, region_id: None }).collect_vec()).collect_vec();
|
||||||
let mut regions: HashMap<u32, Region> = HashMap::new();
|
let mut regions: HashMap<u32, Region> = HashMap::new();
|
||||||
let mut next_region_id = 1;
|
let mut next_region_id = 1;
|
||||||
|
|
||||||
while let Some(plot) = find_plot(&plots, |p| p.region_id == None) {
|
while let Some(plot) = find_plot(&plots, |p| Option::is_none(&p.region_id)) {
|
||||||
plots[plot.0][plot.1].region_id = Some(next_region_id);
|
plots[plot.0][plot.1].region_id = Some(next_region_id);
|
||||||
|
|
||||||
let edge_count = count_edges(&plots, &plot);
|
let edge_count = count_edges(&plots, &plot);
|
||||||
@@ -71,22 +76,21 @@ pub fn part_two(input: &str) -> Option<u32> {
|
|||||||
update_neighbors(&mut plots, &plot, &mut regions);
|
update_neighbors(&mut plots, &plot, &mut regions);
|
||||||
}
|
}
|
||||||
|
|
||||||
let w = plots.iter().map(|p| p.iter().map(|p| p.letter).collect::<String>()).join("\n");
|
// let w = plots.iter().map(|p| p.iter().map(|p| p.letter).collect::<String>()).join("\n");
|
||||||
// println!("{}", w);
|
// println!("{}", w);
|
||||||
|
|
||||||
let total = regions.iter().sorted_by_key(|r| r.0).fold(0, |sum, (region_id, region)| {
|
let total = regions.iter().sorted_by_key(|r| r.0).fold(0, |sum, (region_id, region)| {
|
||||||
let start_plot = find_plot(&plots, |p| p.region_id == Some(*region_id)).unwrap();
|
let start_plot = find_plot(&plots, |p| p.region_id == Some(*region_id)).unwrap();
|
||||||
print!("REGION {}:", region.id);
|
// print!("REGION {}:", region.id);
|
||||||
let edges = traverse_start(&plots, &start_plot);
|
let edges = traverse_start(&plots, &start_plot);
|
||||||
let total = sum + (region.count * edges);
|
sum + (region.count * edges)
|
||||||
// println!(" = {} * {} = {}", region.count, edges, region.count * edges);
|
// println!(" = {} * {} = {}", region.count, edges, region.count * edges);
|
||||||
total
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Some(total as u32)
|
Some(total as u32)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_plot<F>(plots: &Vec<Vec<Plot>>, predicate: F) -> Option<(usize, usize)> where
|
fn find_plot<F>(plots: &[Vec<Plot>], predicate: F) -> Option<(usize, usize)> where
|
||||||
F: Fn(&Plot) -> bool {
|
F: Fn(&Plot) -> bool {
|
||||||
for (row_idx, row) in plots.iter().enumerate() {
|
for (row_idx, row) in plots.iter().enumerate() {
|
||||||
for (col_idx, plot) in row.iter().enumerate() {
|
for (col_idx, plot) in row.iter().enumerate() {
|
||||||
@@ -96,7 +100,7 @@ F: Fn(&Plot) -> bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_neighbors(plots: &mut Vec<Vec<Plot>>, plot: &(usize, usize), regions: &mut HashMap<u32, Region>) {
|
fn update_neighbors(plots: &mut Vec<Vec<Plot>>, plot: &(usize, usize), regions: &mut HashMap<u32, Region>) {
|
||||||
@@ -116,7 +120,7 @@ fn update_neighbors(plots: &mut Vec<Vec<Plot>>, plot: &(usize, usize), regions:
|
|||||||
(0..grid_height as isize).contains(new_row_idx) &&
|
(0..grid_height as isize).contains(new_row_idx) &&
|
||||||
(0..grid_width as isize).contains(new_col_idx) &&
|
(0..grid_width as isize).contains(new_col_idx) &&
|
||||||
plots[*new_row_idx as usize][*new_col_idx as usize].letter == current_region_letter &&
|
plots[*new_row_idx as usize][*new_col_idx as usize].letter == current_region_letter &&
|
||||||
plots[*new_row_idx as usize][*new_col_idx as usize].region_id == None;
|
Option::is_none(&plots[*new_row_idx as usize][*new_col_idx as usize].region_id);
|
||||||
|
|
||||||
if should_update {
|
if should_update {
|
||||||
let next_plot: (usize, usize) = (*new_row_idx as usize, *new_col_idx as usize);
|
let next_plot: (usize, usize) = (*new_row_idx as usize, *new_col_idx as usize);
|
||||||
@@ -131,13 +135,13 @@ fn update_neighbors(plots: &mut Vec<Vec<Plot>>, plot: &(usize, usize), regions:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn count_edges(plots: &Vec<Vec<Plot>>, plot: &(usize, usize)) -> usize {
|
fn count_edges(plots: &[Vec<Plot>], plot: &(usize, usize)) -> usize {
|
||||||
let grid_height = plots.len();
|
let grid_height = plots.len();
|
||||||
let grid_width = plots[0].len();
|
let grid_width = plots[0].len();
|
||||||
|
|
||||||
vec![(-1, 0), (1, 0), (0, -1), (0, 1)].iter().filter(|d| {
|
[(-1, 0), (1, 0), (0, -1), (0, 1)].iter().filter(|d| {
|
||||||
let new_row = plot.0 as isize + &d.0;
|
let new_row = plot.0 as isize + d.0;
|
||||||
let new_col = plot.1 as isize + &d.1;
|
let new_col = plot.1 as isize + d.1;
|
||||||
|
|
||||||
!(0..grid_height as isize).contains(&new_row) ||
|
!(0..grid_height as isize).contains(&new_row) ||
|
||||||
!(0..grid_width as isize).contains(&new_col) ||
|
!(0..grid_width as isize).contains(&new_col) ||
|
||||||
@@ -145,13 +149,13 @@ fn count_edges(plots: &Vec<Vec<Plot>>, plot: &(usize, usize)) -> usize {
|
|||||||
}).count()
|
}).count()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn traverse_start(plots: &Vec<Vec<Plot>>, plot: &(usize, usize)) -> usize {
|
fn traverse_start(plots: &[Vec<Plot>], plot: &(usize, usize)) -> usize {
|
||||||
let start_direction: Direction = (0, 1);
|
let start_direction: Direction = (0, 1);
|
||||||
|
|
||||||
let mut prior_plot = plot.clone();
|
let mut prior_plot = *plot;
|
||||||
let mut prior_direction = start_direction.clone();
|
let mut prior_direction = start_direction;
|
||||||
|
|
||||||
println!(" at {:?} going {}", plot, debug_direction(start_direction));
|
// println!(" at {:?} going {}", plot, debug_direction(start_direction));
|
||||||
|
|
||||||
// count the number of times we turn a corner
|
// count the number of times we turn a corner
|
||||||
let mut corners = 0;
|
let mut corners = 0;
|
||||||
@@ -167,7 +171,7 @@ fn traverse_start(plots: &Vec<Vec<Plot>>, plot: &(usize, usize)) -> usize {
|
|||||||
corners
|
corners
|
||||||
}
|
}
|
||||||
|
|
||||||
fn traverse_step(plots: &Vec<Vec<Plot>>, plot: &(usize, usize), direction: Direction) -> Option<((usize, usize), Direction)> {
|
fn traverse_step(plots: &[Vec<Plot>], plot: &(usize, usize), direction: Direction) -> Option<((usize, usize), Direction)> {
|
||||||
let grid_height = plots.len();
|
let grid_height = plots.len();
|
||||||
let grid_width = plots[0].len();
|
let grid_width = plots[0].len();
|
||||||
|
|
||||||
@@ -181,34 +185,35 @@ fn traverse_step(plots: &Vec<Vec<Plot>>, plot: &(usize, usize), direction: Direc
|
|||||||
};
|
};
|
||||||
|
|
||||||
let ccw_curve = directions.windows(2).find(|dd| dd[0] == direction).map(|dd| dd[1]).unwrap();
|
let ccw_curve = directions.windows(2).find(|dd| dd[0] == direction).map(|dd| dd[1]).unwrap();
|
||||||
let ccw_plot = get_at(plot.0 as isize + ccw_curve.0 as isize, plot.1 as isize + ccw_curve.1 as isize);
|
let ccw_plot = get_at(plot.0 as isize + ccw_curve.0, plot.1 as isize + ccw_curve.1);
|
||||||
let next_plot = get_at(plot.0 as isize + direction.0 as isize, plot.1 as isize + direction.1 as isize);
|
let next_plot = get_at(plot.0 as isize + direction.0, plot.1 as isize + direction.1);
|
||||||
|
|
||||||
// TODO - fix this traversal code
|
// TODO - fix this traversal code
|
||||||
if ccw_plot != None {
|
if Option::is_some(&ccw_plot) {
|
||||||
// if the CCW plot IS in the region, ROTATE CCW
|
// if the CCW plot IS in the region, ROTATE CCW
|
||||||
print!("↺ ");
|
// print!("↺ ");
|
||||||
return Some((*plot, ccw_curve));
|
Some((*plot, ccw_curve))
|
||||||
} else if next_plot != None {
|
} else if Option::is_some(&next_plot) {
|
||||||
// if the NEXT plot IS in the region, MOVE NEXT
|
// if the NEXT plot IS in the region, MOVE NEXT
|
||||||
print!("{} ", debug_direction(direction));
|
// print!("{} ", debug_direction(direction));
|
||||||
return Some((((plot.0 as isize + direction.0 as isize) as usize, (plot.1 as isize + direction.1 as isize) as usize), direction));
|
Some((((plot.0 as isize + direction.0) as usize, (plot.1 as isize + direction.1) as usize), direction))
|
||||||
} else {
|
} else {
|
||||||
// if the NEXT plot is NOT in the region, ROTATE CW
|
// if the NEXT plot is NOT in the region, ROTATE CW
|
||||||
let cw_curve = directions.iter().rev().collect_vec().windows(2).find(|dd| *dd[0] == direction).map(|dd| *dd[1]).unwrap();
|
let cw_curve = directions.iter().rev().collect_vec().windows(2).find(|dd| *dd[0] == direction).map(|dd| *dd[1]).unwrap();
|
||||||
print!("↻ ");
|
// print!("↻ ");
|
||||||
return Some((*plot, cw_curve ))
|
Some((*plot, cw_curve ))
|
||||||
}
|
}
|
||||||
|
|
||||||
// When we get back to the FIRST plot and are at the same direction, stop counting
|
// When we get back to the FIRST plot and are at the same direction, stop counting
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
fn debug_direction(d: Direction) -> char {
|
fn debug_direction(d: Direction) -> char {
|
||||||
let arrows = HashMap::from([
|
let arrows: HashMap<(isize, isize), char> = HashMap::from([
|
||||||
((-1 as isize, 0 as isize), '↑'),
|
((-1, 0), '↑'),
|
||||||
((1 as isize, 0 as isize), '↓'),
|
((1, 0), '↓'),
|
||||||
((0 as isize, -1 as isize), '←'),
|
((0, -1), '←'),
|
||||||
((0 as isize, 1 as isize), '→')
|
((0, 1), '→')
|
||||||
]);
|
]);
|
||||||
|
|
||||||
*arrows.get(&d).unwrap_or(&'X')
|
*arrows.get(&d).unwrap_or(&'X')
|
||||||
|
|||||||
+3
-4
@@ -48,13 +48,13 @@ pub fn part_one(input: &str) -> Option<u32> {
|
|||||||
Some(total_tokens)
|
Some(total_tokens)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn part_two(input: &str) -> Option<u32> {
|
pub fn part_two(_input: &str) -> Option<u32> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO figure out how to reference-ify this
|
// TODO figure out how to reference-ify this
|
||||||
fn find_matches(machine: Machine) -> impl Iterator<Item=(u32, u32)> {
|
fn find_matches(machine: Machine) -> impl Iterator<Item=(u32, u32)> {
|
||||||
let result = (0..=100).flat_map(move |a_presses| {
|
(0..=100).flat_map(move |a_presses| {
|
||||||
(0..=100).filter_map(move |b_presses| {
|
(0..=100).filter_map(move |b_presses| {
|
||||||
let pos_x = machine.a_button.x * a_presses + machine.b_button.x * b_presses;
|
let pos_x = machine.a_button.x * a_presses + machine.b_button.x * b_presses;
|
||||||
let pos_y = machine.a_button.y * a_presses + machine.b_button.y * b_presses;
|
let pos_y = machine.a_button.y * a_presses + machine.b_button.y * b_presses;
|
||||||
@@ -65,8 +65,7 @@ fn find_matches(machine: Machine) -> impl Iterator<Item=(u32, u32)> {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
});
|
})
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|||||||
Reference in new issue
Block a user