day3: optimize

This commit is contained in:
Ishan Jain 2023-12-03 12:02:49 +05:30
parent 12140eb77e
commit a9788018c6
Signed by: ishan
GPG Key ID: 0506DB2A1CC75C27
2 changed files with 88 additions and 88 deletions

View File

@ -1,4 +1,6 @@
#![feature(test)] #![feature(test)]
use std::ops::RangeBounds;
extern crate test; extern crate test;
const INPUTS: [&[u8]; 2] = [ const INPUTS: [&[u8]; 2] = [
@ -6,6 +8,17 @@ const INPUTS: [&[u8]; 2] = [
include_bytes!("./input.txt"), include_bytes!("./input.txt"),
]; ];
const DIRS: [(i32, i32); 8] = [
(0, 1),
(1, 0),
(0, -1),
(-1, 0),
(1, 1),
(-1, 1),
(1, -1),
(-1, -1),
];
fn process(data: &[u8]) -> u64 { fn process(data: &[u8]) -> u64 {
let mut total = 0; let mut total = 0;
@ -20,31 +33,22 @@ fn process(data: &[u8]) -> u64 {
for i in 0..m { for i in 0..m {
let mut j = 0; let mut j = 0;
while j < n { while j < n {
if (b'1'..=b'9').contains(&grid[i][j]) { if !(b'1'..=b'9').contains(&grid[i][j]) {
let int: Vec<u8> = grid[i] j += 1;
.iter() continue;
.skip(j) }
.take_while(|&c| c.is_ascii_digit())
.cloned() let mut ey = j;
.collect(); while ey < n && grid[i][ey].is_ascii_digit() {
ey += 1;
}
let mut valid = false; let mut valid = false;
let dirs = [ 'outer: for (a, b) in DIRS.iter() {
(0, 1),
(1, 0),
(0, -1),
(-1, 0),
(1, 1),
(-1, 1),
(1, -1),
(-1, -1),
];
'outer: for (a, b) in dirs {
let x = i as i32 + a; let x = i as i32 + a;
for p in j..j + int.len() { for p in j..ey {
let y = p as i32 + b; let y = p as i32 + b;
if x < 0 || y < 0 || x >= m as i32 || y >= n as i32 { if x < 0 || y < 0 || x >= m as i32 || y >= n as i32 {
@ -60,14 +64,13 @@ fn process(data: &[u8]) -> u64 {
} }
if valid { if valid {
let num = String::from_utf8_lossy(&int).parse::<u64>().unwrap(); let num = String::from_utf8_lossy(&grid[i][j..ey])
.parse::<u64>()
.unwrap();
total += num total += num
} }
j += int.len(); j += ey - j;
} else {
j += 1;
}
} }
} }

View File

@ -8,6 +8,17 @@ const INPUTS: [&[u8]; 2] = [
include_bytes!("./input.txt"), include_bytes!("./input.txt"),
]; ];
const DIRS: [(i32, i32); 8] = [
(0, 1),
(1, 0),
(0, -1),
(-1, 0),
(1, 1),
(-1, 1),
(1, -1),
(-1, -1),
];
fn process(data: &[u8]) -> u64 { fn process(data: &[u8]) -> u64 {
let mut total = 0; let mut total = 0;
@ -19,72 +30,58 @@ fn process(data: &[u8]) -> u64 {
let m = grid.len(); let m = grid.len();
let n = grid[0].len(); let n = grid[0].len();
let mut map = HashMap::new(); let mut map = HashMap::with_capacity(200);
for i in 0..m { for i in 0..m {
let mut j = 0; for j in 0..n {
while j < n { let c = grid[i][j];
if (b'1'..=b'9').contains(&grid[i][j]) {
let int: Vec<u8> = grid[i]
.iter()
.skip(j)
.take_while(|&c| c.is_ascii_digit())
.cloned()
.collect();
let num = String::from_utf8_lossy(&int).parse::<u64>().unwrap(); if c != b'*' {
let mut count = 0;
let dirs = [
(0, 1),
(1, 0),
(0, -1),
(-1, 0),
(1, 1),
(-1, 1),
(1, -1),
(-1, -1),
];
'outer: for (a, b) in dirs {
let x = (i as i32 + a);
for p in j..j + int.len() {
let y = (p as i32 + b);
if x < 0 || y < 0 || x >= m as i32 || y >= n as i32 {
continue; continue;
} }
let c = grid[x as usize][y as usize]; for (p, q) in DIRS.iter() {
let x = i as i32 + p;
let y = j as i32 + q;
if c == b'*' { if x < 0
map.entry((x, y)) || y < 0
|| x >= m as i32
|| y >= n as i32
|| !grid[x as usize][y as usize].is_ascii_digit()
{
continue;
}
let x = x as usize;
let y = y as usize;
let mut sy = y;
let mut ey = y;
while sy > 0 && grid[x][sy - 1].is_ascii_digit() {
sy -= 1;
}
while ey < n && grid[x][ey].is_ascii_digit() {
ey += 1;
}
let num = String::from_utf8_lossy(&grid[x][sy..ey])
.parse::<u64>()
.unwrap();
map.entry((i, j))
.or_insert_with(HashSet::new) .or_insert_with(HashSet::new)
.insert((num, i, j)); .insert((num, x, sy, ey));
} }
} }
} }
j += int.len(); for v in map.into_values() {
} else {
j += 1;
}
}
}
for v in map.values() {
if v.len() < 2 { if v.len() < 2 {
continue; continue;
} }
let mut product = 1; total += v.into_iter().fold(1, |a, (b, _, _, _)| a * b);
for (num, _, _) in v.iter() {
product *= num;
}
total += product;
} }
total total