Skip to content

Commit c428547

Browse files
committed
Improve day24
1 parent 9a8bd99 commit c428547

File tree

1 file changed

+36
-41
lines changed

1 file changed

+36
-41
lines changed

2024/day24/src/main.rs

Lines changed: 36 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::cell::RefCell;
12
use std::time::Instant;
23
use std::io::{self, Read};
34

@@ -23,7 +24,7 @@ fn get_input() -> (Vec<(String, bool)>, Vec<(String, Operation, String, String)>
2324
let gates = gates.lines().map(|line| {
2425
let (input, output) = line.split_once(" -> ").unwrap();
2526

26-
let input = input.split(" ").collect::<Vec<&str>>();
27+
let input = input.split(' ').collect::<Vec<&str>>();
2728
assert_eq!(input.len(), 3);
2829

2930
let a = input[0].to_string();
@@ -44,7 +45,7 @@ fn get_input() -> (Vec<(String, bool)>, Vec<(String, Operation, String, String)>
4445
#[derive(Debug)]
4546
struct Node<'a> {
4647
name: &'a String,
47-
id: usize,
48+
value: RefCell<Option<bool>>,
4849
depends_on: Option<usize>
4950
}
5051

@@ -57,9 +58,9 @@ struct Gate {
5758
}
5859

5960
impl Gate {
60-
pub fn get_output(&self, nodes: &[Node], gates: &[Gate], values: &mut [Option<bool>]) -> bool {
61-
let a = nodes[self.a].get_output(nodes, gates, values);
62-
let b = nodes[self.b].get_output(nodes, gates, values);
61+
pub fn get_output(&self, nodes: &[Node], gates: &[Gate]) -> bool {
62+
let a = nodes[self.a].get_output(nodes, gates);
63+
let b = nodes[self.b].get_output(nodes, gates);
6364

6465
return match self.op {
6566
Operation::And => a & b,
@@ -69,28 +70,26 @@ impl Gate {
6970
}
7071
}
7172

72-
impl<'a> Node<'a> {
73-
pub fn get_output(&self, nodes: &[Node], gates: &[Gate], values: &mut [Option<bool>]) -> bool {
74-
if let Some(value) = values[self.id] {
73+
impl Node<'_> {
74+
pub fn get_output(&self, nodes: &[Node], gates: &[Gate]) -> bool {
75+
if let Some(value) = *self.value.borrow() {
7576
return value;
7677
}
7778

7879
if let Some(depends_on) = self.depends_on {
7980
let gate = &gates[depends_on];
80-
values[self.id] = Some(gate.get_output(nodes, gates, values));
81-
return values[self.id].unwrap();
81+
*self.value.borrow_mut() = Some(gate.get_output(nodes, gates));
82+
return self.value.borrow().unwrap();
8283
}
8384

84-
println!("{:?}", self);
85-
println!("{:?}", values[self.id]);
8685
panic!("Unknowable node");
8786
}
8887
}
8988

9089
fn char2ind(c: u8) -> usize {
91-
if c >= b'0' && c <= b'9' {
90+
if c.is_ascii_digit() {
9291
return (c - b'0') as usize;
93-
} else if c >= b'a' && c <= b'z' {
92+
} else if c.is_ascii_lowercase() {
9493
return (c - b'a' + 10) as usize;
9594
}
9695

@@ -102,17 +101,17 @@ fn hash(s: &str) -> usize {
102101
return char2ind(bytes[0]) * 36 * 36 + char2ind(bytes[1]) * 36 + char2ind(bytes[2]);
103102
}
104103

105-
fn str2id(s: &str, table: &mut [Option<usize>; 36 * 36 * 36], table_ind: &mut usize) -> (usize, bool) {
104+
fn maybe_insert_new_string(s: &str, table: &mut [Option<usize>; 36 * 36 * 36], table_ind: &mut usize) -> bool {
106105
let h = hash(s);
107-
if let Some(id) = table[h] {
108-
return (id, false);
106+
if table[h].is_some() {
107+
return false;
109108
}
110109
table[h] = Some(*table_ind);
111110
*table_ind += 1;
112-
return (*table_ind - 1, true);
111+
return true;
113112
}
114113

115-
fn str2id_get(s: &str, table: &[Option<usize>; 36 * 36 * 36]) -> usize {
114+
fn str2id(s: &str, table: &[Option<usize>; 36 * 36 * 36]) -> usize {
116115
let h = hash(s);
117116
return table[h].unwrap();
118117
}
@@ -121,37 +120,33 @@ fn part1(inputs: &[(String, bool)], gates: &[(String, Operation, String, String)
121120
let mut name_table = [None; 36 * 36 * 36];
122121
let mut table_ind = 0;
123122

124-
let (mut nodes, mut values): (Vec<Node>, Vec<Option<bool>>) = inputs.iter().map(|(name, value)|
125-
(
126-
Node {
127-
name,
128-
id: str2id(name, &mut name_table, &mut table_ind).0,
129-
depends_on: None
130-
},
131-
Some(*value)
132-
)
133-
).unzip();
123+
let mut nodes = inputs.iter().map(|(name, value)| {
124+
assert!(maybe_insert_new_string(name, &mut name_table, &mut table_ind));
125+
return Node {
126+
name,
127+
value: RefCell::new(Some(*value)),
128+
depends_on: None
129+
};
130+
}).collect::<Vec<Node>>();
134131

135132
for (a, _, b, out) in gates {
136-
for x in [a, b, out].iter() {
137-
let (id, new) = str2id(x, &mut name_table, &mut table_ind);
138-
if new {
133+
for x in &[a, b, out] {
134+
if maybe_insert_new_string(x, &mut name_table, &mut table_ind) {
139135
nodes.push(Node {
140136
name: x,
141-
id,
137+
value: RefCell::new(None),
142138
depends_on: None
143139
});
144-
values.push(None);
145140
}
146141
}
147142
}
148143

149144
let gates = gates.iter().map(|(a, op, b, out)|
150145
Gate {
151-
a: str2id_get(a, &name_table),
152-
b: str2id_get(b, &name_table),
146+
a: str2id(a, &name_table),
147+
b: str2id(b, &name_table),
153148
op: *op,
154-
out: str2id_get(out, &name_table)
149+
out: str2id(out, &name_table)
155150
}
156151
).collect::<Vec<Gate>>();
157152

@@ -161,12 +156,12 @@ fn part1(inputs: &[(String, bool)], gates: &[(String, Operation, String, String)
161156

162157

163158
let mut result = nodes.iter()
164-
.filter(|node| node.name.starts_with("z"))
159+
.filter(|node| node.name.starts_with('z'))
165160
.map(|node| {
166-
(node.name, node.get_output(&nodes, &gates, &mut values))
161+
(node.name, node.get_output(&nodes, &gates))
167162
}).collect::<Vec<(&String, bool)>>();
168163

169-
result.sort_by(|a, b| b.0.cmp(a.0));
164+
result.sort_unstable_by(|a, b| b.0.cmp(a.0));
170165

171166
return result.iter().fold(0, |acc, (_, value)| {
172167
acc << 1 | (*value as u64)
@@ -185,7 +180,7 @@ fn part2(_inputs: &[(String, bool)], _gates: &[(String, Operation, String, Strin
185180
.flat_map(|(a, b)| vec![*a, *b])
186181
.collect::<Vec<&str>>();
187182

188-
result.sort();
183+
result.sort_unstable();
189184

190185
return result.join(",");
191186
}

0 commit comments

Comments
 (0)