day 4 part 1 and two
This commit is contained in:
parent
99d91ab254
commit
41604e606a
3 changed files with 337 additions and 23 deletions
|
@ -30,21 +30,18 @@ impl Grid {
|
|||
}
|
||||
}
|
||||
|
||||
fn get_adjacent_items(&self, row: usize, start: usize, end: usize) -> Vec<(&Item, usize, usize)> {
|
||||
fn get_adjacent_items(
|
||||
&self,
|
||||
row: usize,
|
||||
start: usize,
|
||||
end: usize,
|
||||
) -> Vec<(&Item, usize, usize)> {
|
||||
// println!("\tget adj: r{} s{} e{}", row, start, end);
|
||||
let row_start = if row > 0 {
|
||||
row - 1
|
||||
} else {
|
||||
0
|
||||
};
|
||||
let col_start = if start > 0 {
|
||||
start - 1
|
||||
} else {
|
||||
0
|
||||
};
|
||||
let row_start = if row > 0 { row - 1 } else { 0 };
|
||||
let col_start = if start > 0 { start - 1 } else { 0 };
|
||||
let mut items: Vec<(&Item, usize, usize)> = vec![];
|
||||
for row_i in row_start ..= row + 1 {
|
||||
for col_i in col_start ..= end + 1 {
|
||||
for row_i in row_start..=row + 1 {
|
||||
for col_i in col_start..=end + 1 {
|
||||
if row_i != row || col_i < start || col_i > end {
|
||||
let item = self.get_item(row_i, col_i);
|
||||
|
||||
|
@ -63,14 +60,17 @@ impl Grid {
|
|||
for item in self.get_adjacent_items(row, col, col) {
|
||||
match item {
|
||||
(Item::Digit(_), r, c) => {
|
||||
if let Some(number_at) =
|
||||
self.numbers.iter().find(|n| n.row_index == r && c >= n.char_start && c <= n.char_end) {
|
||||
if let Some(number_at) = self
|
||||
.numbers
|
||||
.iter()
|
||||
.find(|n| n.row_index == r && c >= n.char_start && c <= n.char_end)
|
||||
{
|
||||
if unique_numbers.iter().all(|n| n.value != number_at.value) {
|
||||
unique_numbers.push(number_at);
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => { },
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
unique_numbers
|
||||
|
@ -136,8 +136,11 @@ fn part1(input: String) -> Result<usize> {
|
|||
let grid: Grid = input.parse()?;
|
||||
let mut sum = 0;
|
||||
for number in grid.numbers.iter() {
|
||||
let adjacent = grid.get_adjacent_items(number.row_index, number.char_start, number.char_end);
|
||||
let is_part_no = adjacent.iter().any(|item| matches!(item, (Item::Symbol(_), _, _)));
|
||||
let adjacent =
|
||||
grid.get_adjacent_items(number.row_index, number.char_start, number.char_end);
|
||||
let is_part_no = adjacent
|
||||
.iter()
|
||||
.any(|item| matches!(item, (Item::Symbol(_), _, _)));
|
||||
|
||||
// ```
|
||||
// println!(
|
||||
|
@ -160,11 +163,16 @@ fn part2(input: String) -> Result<usize> {
|
|||
let mut sum = 0;
|
||||
let mut used: Vec<(usize, usize)> = vec![];
|
||||
for number in grid.numbers.iter() {
|
||||
let is_used =
|
||||
used.iter().any(|(row, char_start)| number.row_index == *row && number.char_start == *char_start);
|
||||
let is_used = used
|
||||
.iter()
|
||||
.any(|(row, char_start)| number.row_index == *row && number.char_start == *char_start);
|
||||
if !is_used {
|
||||
let adjacent = grid.get_adjacent_items(number.row_index, number.char_start, number.char_end);
|
||||
if let Some((_, row, col)) = adjacent.iter().find(|item| matches!(item.0, Item::Symbol(true))) {
|
||||
let adjacent =
|
||||
grid.get_adjacent_items(number.row_index, number.char_start, number.char_end);
|
||||
if let Some((_, row, col)) = adjacent
|
||||
.iter()
|
||||
.find(|item| matches!(item.0, Item::Symbol(true)))
|
||||
{
|
||||
let gear_nums = grid.get_adjacent_numbers(*row, *col);
|
||||
if gear_nums.len() >= 2 {
|
||||
// this is lazy.. adds duplicates but w/e
|
||||
|
|
104
src/bin/day4.rs
Normal file
104
src/bin/day4.rs
Normal file
|
@ -0,0 +1,104 @@
|
|||
use aoc23::prelude::*;
|
||||
use itertools::Itertools;
|
||||
use std::{
|
||||
collections::{HashMap, VecDeque},
|
||||
str::FromStr,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Card {
|
||||
id: usize,
|
||||
winning_numbers: Vec<usize>,
|
||||
numbers: Vec<usize>,
|
||||
matches: usize,
|
||||
score: usize,
|
||||
}
|
||||
|
||||
impl FromStr for Card {
|
||||
type Err = BoxE;
|
||||
|
||||
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
|
||||
let mut id: Option<usize> = None;
|
||||
let mut winning_numbers: Vec<usize> = vec![];
|
||||
let mut numbers: Vec<usize> = vec![];
|
||||
let mut score = 0;
|
||||
let mut matches = 0;
|
||||
for part in s.split(':') {
|
||||
if id.is_some() {
|
||||
for (num_mode, wins_or_nums) in part.split('|').enumerate() {
|
||||
wins_or_nums
|
||||
.trim()
|
||||
.split_whitespace()
|
||||
.into_iter()
|
||||
.map(|num| {
|
||||
num.parse::<usize>()
|
||||
.expect(&format!("could not parse number: {}", num))
|
||||
})
|
||||
.for_each(|num| {
|
||||
if num_mode == 0 {
|
||||
winning_numbers.push(num);
|
||||
} else {
|
||||
numbers.push(num);
|
||||
if winning_numbers.iter().any(|winner| winner == &num) {
|
||||
matches += 1;
|
||||
score = if score == 0 { 1 } else { score * 2 };
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
id = Some(
|
||||
part.split_whitespace()
|
||||
.last()
|
||||
.ok_or("Failed to get last item")?
|
||||
.parse()?,
|
||||
)
|
||||
}
|
||||
}
|
||||
Ok(Card {
|
||||
id: id.ok_or("no id found")?,
|
||||
winning_numbers,
|
||||
numbers,
|
||||
score,
|
||||
matches,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn part1(input: String) -> Result<usize> {
|
||||
Ok(input
|
||||
.lines()
|
||||
.map(|line| line.parse::<Card>())
|
||||
.filter_map(|card| card.ok())
|
||||
.fold(0, |sum, card| sum + card.score))
|
||||
}
|
||||
|
||||
fn part2(input: String) -> Result<usize> {
|
||||
let mut sum = 0;
|
||||
let cards = input
|
||||
.lines()
|
||||
.map(|line| line.parse::<Card>())
|
||||
.filter_map(|card| card.ok())
|
||||
.collect_vec();
|
||||
let mut queue: VecDeque<&Card> = cards.iter().collect();
|
||||
let mut counts: HashMap<usize, usize> = HashMap::new();
|
||||
while let Some(card) = queue.pop_front() {
|
||||
let counter = counts.entry(card.id).or_insert(0);
|
||||
*counter += 1;
|
||||
sum += 1;
|
||||
for card_index in card.id..card.id + card.matches {
|
||||
cards.get(card_index).map(|c| queue.push_back(&c));
|
||||
}
|
||||
}
|
||||
Ok(sum)
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
println!("Day 4");
|
||||
println!("=====");
|
||||
let input = utils::aoc::get_puzzle_input(4).await?;
|
||||
println!("part 1: {}", part1(input.clone())?);
|
||||
println!("part 2: {}", part2(input.clone())?);
|
||||
Ok(())
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue