From e0b243fe51a3ce65c6d3269788983abef12d86ed Mon Sep 17 00:00:00 2001 From: Kevin Caffrey Date: Wed, 13 Dec 2023 11:17:41 -0500 Subject: [PATCH] day 13 optimizations. turns out that being clever was bad today --- README.md | 30 +++++++++--------- src/bin/13.rs | 88 ++++++++++++++++++++++++--------------------------- 2 files changed, 57 insertions(+), 61 deletions(-) diff --git a/README.md b/README.md index 30c7e29..d0f72d2 100644 --- a/README.md +++ b/README.md @@ -29,21 +29,21 @@ Solutions for [Advent of Code](https://adventofcode.com/) in [Rust](https://www. | Day | Part 1 | Part 2 | | :---: | :---: | :---: | -| [Day 1](./src/bin/01.rs) | `27.6µs` | `39.7µs` | -| [Day 2](./src/bin/02.rs) | `43.1µs` | `42.7µs` | -| [Day 3](./src/bin/03.rs) | `83.8µs` | `100.4µs` | -| [Day 4](./src/bin/04.rs) | `48.4µs` | `51.9µs` | -| [Day 5](./src/bin/05.rs) | `20.8µs` | `24.2µs` | -| [Day 6](./src/bin/06.rs) | `202.0ns` | `102.0ns` | -| [Day 7](./src/bin/07.rs) | `94.4µs` | `94.2µs` | -| [Day 8](./src/bin/08.rs) | `75.3µs` | `160.8µs` | -| [Day 9](./src/bin/09.rs) | `58.2µs` | `58.3µs` | -| [Day 10](./src/bin/10.rs) | `262.3µs` | `274.2µs` | -| [Day 11](./src/bin/11.rs) | `16.4µs` | `16.0µs` | -| [Day 12](./src/bin/12.rs) | `132.6µs` | `678.2µs` | -| [Day 13](./src/bin/13.rs) | `66.9µs` | `66.9µs` | - -**Total: 2.54ms** +| [Day 1](./src/bin/01.rs) | `28.7µs` | `36.3µs` | +| [Day 2](./src/bin/02.rs) | `42.5µs` | `42.0µs` | +| [Day 3](./src/bin/03.rs) | `84.3µs` | `99.5µs` | +| [Day 4](./src/bin/04.rs) | `48.1µs` | `50.9µs` | +| [Day 5](./src/bin/05.rs) | `20.7µs` | `24.4µs` | +| [Day 6](./src/bin/06.rs) | `205.0ns` | `102.0ns` | +| [Day 7](./src/bin/07.rs) | `93.9µs` | `92.7µs` | +| [Day 8](./src/bin/08.rs) | `75.1µs` | `159.3µs` | +| [Day 9](./src/bin/09.rs) | `58.9µs` | `58.4µs` | +| [Day 10](./src/bin/10.rs) | `257.9µs` | `275.7µs` | +| [Day 11](./src/bin/11.rs) | `16.5µs` | `15.8µs` | +| [Day 12](./src/bin/12.rs) | `135.9µs` | `647.1µs` | +| [Day 13](./src/bin/13.rs) | `12.4µs` | `40.5µs` | + +**Total: 2.42ms** --- diff --git a/src/bin/13.rs b/src/bin/13.rs index 1c62379..89675c4 100644 --- a/src/bin/13.rs +++ b/src/bin/13.rs @@ -1,5 +1,3 @@ -use smallvec::SmallVec; - advent_of_code::solution!(13); pub fn part_one(input: &str) -> Option { @@ -7,25 +5,20 @@ pub fn part_one(input: &str) -> Option { input .split("\n\n") .map(|pattern| { - let mut row_values = SmallVec::<[u32; 32]>::new(); - let mut col_values = SmallVec::<[u32; 32]>::new(); - for line in pattern.lines() { - let mut row_encoded = 0; - if col_values.is_empty() { - col_values.resize(line.len(), 0); - } - for (col, ch) in line.char_indices() { - let encoded_val = if ch == '#' { 1 } else { 0 }; - col_values[col] = (col_values[col] << 1) + encoded_val; - row_encoded = (row_encoded << 1) + encoded_val; - } - row_values.push(row_encoded); - } + let pattern = pattern.as_bytes(); + let cols = pattern + .iter() + .position(|&ch| ch == b'\n') + .expect("should be more than one row"); + let rows = (pattern.len() + 1) / (cols + 1); // Try column mirroring. - let col_mirror = (1..col_values.len()).find(|&col_split| { - (0..col_split.min(col_values.len() - col_split)).all(|offset| { - col_values[col_split - offset - 1] == col_values[col_split + offset] + let col_mirror = (1..cols).find(|&col_split| { + (0..col_split.min(cols - col_split)).all(|offset| { + (0..rows).all(|r| { + pattern[r * (cols + 1) + col_split - offset - 1] + == pattern[r * (cols + 1) + col_split + offset] + }) }) }); if let Some(col_mirror) = col_mirror { @@ -33,9 +26,12 @@ pub fn part_one(input: &str) -> Option { } // Try row mirroring. - let row_mirror = (1..row_values.len()).find(|&row_split| { - (0..row_split.min(row_values.len() - row_split)).all(|offset| { - row_values[row_split - offset - 1] == row_values[row_split + offset] + let row_mirror = (1..rows).find(|&row_split| { + (0..row_split.min(rows - row_split)).all(|offset| { + (0..cols).all(|c| { + pattern[(row_split - offset - 1) * (cols + 1) + c] + == pattern[(row_split + offset) * (cols + 1) + c] + }) }) }); if let Some(row_mirror) = row_mirror { @@ -53,27 +49,23 @@ pub fn part_two(input: &str) -> Option { input .split("\n\n") .map(|pattern| { - let mut row_values = SmallVec::<[u32; 32]>::new(); - let mut col_values = SmallVec::<[u32; 32]>::new(); - for line in pattern.lines() { - let mut row_encoded = 0u32; - if col_values.is_empty() { - col_values.resize(line.len(), 0u32); - } - for (col, ch) in line.char_indices() { - let encoded_val = if ch == '#' { 1 } else { 0 }; - col_values[col] = (col_values[col] << 1) + encoded_val; - row_encoded = (row_encoded << 1) + encoded_val; - } - row_values.push(row_encoded); - } + let pattern = pattern.as_bytes(); + let cols = pattern + .iter() + .position(|&ch| ch == b'\n') + .expect("should be more than one row"); + let rows = (pattern.len() + 1) / (cols + 1); - // Try column mirroring. - let col_mirror = (1..col_values.len()).find(|&col_split| { - (0..col_split.min(col_values.len() - col_split)) + let col_mirror = (1..cols).find(|&col_split| { + (0..col_split.min(cols - col_split)) .map(|offset| { - (col_values[col_split - offset - 1] ^ col_values[col_split + offset]) - .count_ones() + (0..rows) + .map(|r| -> u32 { + (pattern[r * (cols + 1) + col_split - offset - 1] + != pattern[r * (cols + 1) + col_split + offset]) + .into() + }) + .sum::() }) .sum::() == 1 @@ -82,12 +74,16 @@ pub fn part_two(input: &str) -> Option { return col_mirror as u32; } - // Try row mirroring. - let row_mirror = (1..row_values.len()).find(|&row_split| { - (0..row_split.min(row_values.len() - row_split)) + let row_mirror = (1..rows).find(|&row_split| { + (0..row_split.min(rows - row_split)) .map(|offset| { - (row_values[row_split - offset - 1] ^ row_values[row_split + offset]) - .count_ones() + (0..cols) + .map(|c| -> u32 { + (pattern[(row_split - offset - 1) * (cols + 1) + c] + != pattern[(row_split + offset) * (cols + 1) + c]) + .into() + }) + .sum::() }) .sum::() == 1