Skip to content

Commit 2657df0

Browse files
committed
Tweak hash function to save an instruction
1 parent b4d3362 commit 2657df0

File tree

2 files changed

+21
-14
lines changed

2 files changed

+21
-14
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ Performance is reasonable even on older hardware, for example a 2011 MacBook Pro
9090
| 16 | [Reindeer Maze](https://adventofcode.com/2024/day/16) | [Source](src/year2024/day16.rs) | 390 |
9191
| 17 | [Chronospatial Computer](https://adventofcode.com/2024/day/17) | [Source](src/year2024/day17.rs) | 2 |
9292
| 18 | [RAM Run](https://adventofcode.com/2024/day/18) | [Source](src/year2024/day18.rs) | 42 |
93-
| 19 | [Linen Layout](https://adventofcode.com/2024/day/19) | [Source](src/year2024/day19.rs) | 121 |
93+
| 19 | [Linen Layout](https://adventofcode.com/2024/day/19) | [Source](src/year2024/day19.rs) | 118 |
9494

9595
## 2023
9696

src/year2024/day19.rs

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
//!
1414
//! Additionally we store the Trie in a flat `vec`. This is simpler and faster than creating
1515
//! objects on the heap using [`Box`].
16-
type Input = (u64, u64);
16+
type Input = (usize, usize);
1717

1818
pub fn parse(input: &str) -> Input {
1919
let (prefix, suffix) = input.split_once("\n\n").unwrap();
@@ -37,7 +37,7 @@ pub fn parse(input: &str) -> Input {
3737
}
3838
}
3939

40-
trie[i].towel = true;
40+
trie[i].set_towel();
4141
}
4242

4343
let mut part_one = 0;
@@ -70,44 +70,51 @@ pub fn parse(input: &str) -> Input {
7070
}
7171

7272
// Add the number of possible ways this prefix can be reached.
73-
if trie[i].towel {
74-
ways[end + 1] += ways[start];
75-
}
73+
ways[end + 1] += trie[i].towels() * ways[start];
7674
}
7775
}
7876
}
7977

8078
// Last element is the total possible combinations.
8179
let total = ways[size];
82-
part_one += (total > 0) as u64;
80+
part_one += (total > 0) as usize;
8381
part_two += total;
8482
}
8583

8684
(part_one, part_two)
8785
}
8886

89-
pub fn part1(input: &Input) -> u64 {
87+
pub fn part1(input: &Input) -> usize {
9088
input.0
9189
}
9290

93-
pub fn part2(input: &Input) -> u64 {
91+
pub fn part2(input: &Input) -> usize {
9492
input.1
9593
}
9694

9795
/// Hashes the five possible color values white (w), blue (u), black (b), red (r), or green (g)
98-
/// to 6, 4, 0, 1 and 5 respectively. This compresses the range to fit into an array of 7 elements.
96+
/// to 0, 2, 4, 5 and 1 respectively. This compresses the range to fit into an array of 6 elements.
9997
fn perfect_hash(b: u8) -> usize {
100-
(b as usize + (b as usize >> 4)) % 8
98+
let n = b as usize;
99+
(n ^ (n >> 4)) % 8
101100
}
102101

103102
/// Simple Node object that uses indices to link to other nodes.
104103
struct Node {
105-
towel: bool,
106-
next: [usize; 7],
104+
next: [usize; 6],
107105
}
108106

109107
impl Node {
110108
fn new() -> Self {
111-
Node { towel: false, next: [0; 7] }
109+
Node { next: [0; 6] }
110+
}
111+
112+
// Index 3 is not used by the hash, so we cheekily repurpose for the number of towels.
113+
fn set_towel(&mut self) {
114+
self.next[3] = 1;
115+
}
116+
117+
fn towels(&self) -> usize {
118+
self.next[3]
112119
}
113120
}

0 commit comments

Comments
 (0)