Skip to content

Instantly share code, notes, and snippets.

@qubyte
Last active August 18, 2022 12:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save qubyte/d259676b4927a6fbe8fd5f99e61d2e62 to your computer and use it in GitHub Desktop.
Save qubyte/d259676b4927a6fbe8fd5f99e61d2e62 to your computer and use it in GitHub Desktop.
My revised solution to Advent of code 2018 day 10 (both parts) in Rust, this time using recap.
[package]
name = "task-1"
version = "0.1.0"
authors = ["Mark S. Everitt <mark.s.everitt@gmail.com>"]
edition = "2018"
[dependencies]
recap = "0.1"
serde = "1.0.90"
use std::{
io::{stdin, BufRead},
cmp::{max, min}
};
use recap::Recap;
use serde::Deserialize;
const IMAX: isize = isize::max_value();
const IMIN: isize = isize::min_value();
#[derive(Debug, Clone, Deserialize, Recap)]
#[recap(regex = r"<\s*(?P<position_x>-?\d+),\s*(?P<position_y>-?\d+)>.*<\s*(?P<velocity_x>-?\d+),\s*(?P<velocity_y>-?\d)>")]
struct Particle {
position_x: isize,
position_y: isize,
velocity_x: isize,
velocity_y: isize
}
fn tick(particles: &Vec<Particle>) -> Vec<Particle> {
particles.iter().map(|particle| Particle {
position_x: particle.position_x + particle.velocity_x,
position_y: particle.position_y + particle.velocity_y,
velocity_x: particle.velocity_x,
velocity_y: particle.velocity_y
}).collect()
}
fn get_bounds(particles: &Vec<Particle>) -> (isize, isize, isize, isize) {
particles.iter().fold((IMAX, IMAX, IMIN, IMIN), |(least_x, least_y, most_x, most_y), particle| {
let px = particle.position_x;
let py = particle.position_y;
(min(least_x, px), min(least_y, py), max(most_x, px), max(most_y, py))
})
}
fn render(particles: &Vec<Particle>) -> String {
let (least_x, least_y, most_x, most_y) = get_bounds(particles);
let mut message = String::from("");
for j in least_y..=most_y {
for i in least_x..=most_x {
if particles.iter().any(|p| p.position_x == i && p.position_y == j) {
message.push_str("#");
} else {
message.push_str("-");
}
}
message.push_str("\n");
}
message
}
fn main() {
let mut particles: Vec<Particle> = stdin()
.lock()
.lines()
.filter_map(|line| line.ok())
.filter_map(|line| line.parse().ok())
.collect();
let mut seconds = 0;
// I assume the message is when the particles occupy the tightest bounding
// box (they have converged). This is not true for some known inputs. A
// better approach might be to look for lines in the grid of particles.
let message = loop {
let (least_x, least_y, most_x, most_y) = get_bounds(&particles);
let last_area = (most_y - least_y) * (most_x - least_x);
let last_particles = particles;
seconds += 1;
particles = tick(&last_particles);
let (least_x, least_y, most_x, most_y) = get_bounds(&particles);
let area = (most_y - least_y) * (most_x - least_x);
if last_area > 0 && last_area < area {
break render(&last_particles);
}
};
println!("Second {}", seconds - 1);
println!("{}", message);
}
@AiyionPrime
Copy link

Thank you, I really like the approach to use regex for more robust struct parsing.
Now parsing a config-file-format (looks similar to nginx but isn't) with this.

https://github.com/AiyionPrime/gluon-mesh-vpn-key-translate/blob/f3538a359f74788ed96a4241a3ddd62f75098fd9/src/fastd_key.rs#L5-L10

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment