Skip to content

Commit

Permalink
[2023] Day 19: Remove unnecessary string allocs
Browse files Browse the repository at this point in the history
  • Loading branch information
connorslade committed Dec 19, 2023
1 parent a60c07f commit 52ebadb
Showing 1 changed file with 38 additions and 32 deletions.
70 changes: 38 additions & 32 deletions aoc_2023/src/day_19.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,10 @@ impl Solution for Day19 {
}
}

fn solve_b(rules: &HashMap<String, Vec<Rule>>, mut range: ShapeRange, map: &str) -> u64 {
fn solve_b(rules: &HashMap<&str, Vec<Rule>>, mut range: ShapeRange, map: &str) -> u64 {
let mut out = 0;

let mut common = |range: ShapeRange, destination: &str| {
let mut solve = |range: ShapeRange, destination: &str| {
if destination == "A" {
out += calc_size(&range);
} else if destination != "R" {
Expand Down Expand Up @@ -102,9 +102,9 @@ fn solve_b(rules: &HashMap<String, Vec<Rule>>, mut range: ShapeRange, map: &str)
_ => continue,
}

common(new_range, destination);
solve(new_range, destination);
}
Rule::Default { destination } => common(range, destination),
Rule::Default { destination } => solve(range, destination),
}
}

Expand Down Expand Up @@ -135,15 +135,15 @@ enum Field {
}

#[derive(Debug, Clone)]
enum Rule {
enum Rule<'a> {
Comparison {
field: Field,
comparison: Comparison,
value: u32,
destination: String,
destination: &'a str,
},
Default {
destination: String,
destination: &'a str,
},
}

Expand All @@ -163,32 +163,21 @@ struct ShapeRange {
s: (u32, u32),
}

fn parse(input: &str) -> (HashMap<String, Vec<Rule>>, Vec<Shape>) {
fn parse(input: &str) -> (HashMap<&str, Vec<Rule>>, Vec<Shape>) {
let mut rules_out = HashMap::new();
let mut shapes = Vec::new();

let (rule, shape) = input.split_once("\n\n").unwrap();
for rule in rule.lines() {
let (name, rule) = rule.split_once('{').unwrap();
let rule = rule.split_once('}').unwrap().0;

let mut rules = Vec::new();
for i in rule.split(',') {
if !i.contains(':') {
rules.push(Rule::Default {
destination: i.to_string(),
});
for destination in rule[..rule.len() - 1].split(',') {
let Some((comparison, destination)) = destination.split_once(':') else {
rules.push(Rule::Default { destination });
continue;
}

let (comparison, destination) = i.split_once(':').unwrap();
let field = match &comparison[0..1] {
"x" => Field::X,
"m" => Field::M,
"a" => Field::A,
"s" => Field::S,
_ => panic!("Invalid field"),
};
let field = Field::from_str(&comparison[0..1]);
let comp = match &comparison[1..2] {
"<" => Comparison::LessThan,
">" => Comparison::GreaterThan,
Expand All @@ -199,11 +188,11 @@ fn parse(input: &str) -> (HashMap<String, Vec<Rule>>, Vec<Shape>) {
field,
comparison: comp,
value,
destination: destination.to_string(),
destination,
});
}

rules_out.insert(name.to_string(), rules);
rules_out.insert(name, rules);
}

for shape in shape.lines() {
Expand All @@ -212,20 +201,28 @@ fn parse(input: &str) -> (HashMap<String, Vec<Rule>>, Vec<Shape>) {
for field in shape.split(',') {
let (field, value) = field.split_once('=').unwrap();
let value = value.parse().unwrap();
match field {
"x" => x.x = value,
"m" => x.m = value,
"a" => x.a = value,
"s" => x.s = value,
_ => panic!("Invalid field"),
}

let field = Field::from_str(field);
*x.get_mut(&field) = value;
}
shapes.push(x);
}

(rules_out, shapes)
}

impl Field {
fn from_str(from: &str) -> Self {
match from {
"x" => Self::X,
"m" => Self::M,
"a" => Self::A,
"s" => Self::S,
_ => panic!("Invalid field"),
}
}
}

impl Shape {
fn get(&self, field: &Field) -> u32 {
match field {
Expand All @@ -235,6 +232,15 @@ impl Shape {
Field::S => self.s,
}
}

fn get_mut(&mut self, field: &Field) -> &mut u32 {
match field {
Field::X => &mut self.x,
Field::M => &mut self.m,
Field::A => &mut self.a,
Field::S => &mut self.s,
}
}
}

impl ShapeRange {
Expand Down

0 comments on commit 52ebadb

Please sign in to comment.