You can’t really blame that on rust.
Yeah ngl it’s very ugly. But hey as long as it works it’s not stupid amirite?
Rust borrows a lot of it’s design from functional programming languages like Haskell, which has its good and bad. You could also choose to implement this behavior iteratively like typical C programs, but that tends to be ugly in other ways.
Personally, I’ve grown fond of the functional style. You see it in other places too, like the higher order functions in JavaScript. What’s good about them in Rust is you still get amazing performance due to zero-cost abstraction. Trying to implement it yourself would likely be slower, so use them any chance you get.
Show the alternative, I’ll have a good laugh.
It’s Nim, but I have no idea why you can’t do this in Rust:
var seeds = lines[0].split(": ")[1].splitWhitespace().mapIt(it.parseInt)
Full solution: https://codeberg.org/Archargelod/aoc23-nim/src/branch/master/day_05/solution.nim
The
collect
’s in the middle aren’t necessary, neither is splitting by": "
. Here’s a simpler versionfn main() { let text = "seeds: 79 14 55 13\nwhatever"; let seeds: Vec<_> = text .lines() .next() .unwrap() .split_whitespace() .skip(1) .map(|x| x.parse::<u32>().unwrap()) .collect(); println!("seeds: {:?}", seeds); }
It is simpler to bang out a
[int(num) for num in text.splitlines()[0].split(' ')[1:]]
in Python, but that just shows the happy path with no error handling, and does a bunch of allocations that the Rust version doesn’t. You can also get slightly fancier in the Rust version by collecting into aResult
for more succinct error handling if you’d like.EDIT: Here’s also a version using
anyhow
for error handling, and the aforementionedResult
collecting:use anyhow::{anyhow, Result}; fn main() -> Result<()> { let text = "seeds: 79 14 55 13\nwhatever"; let seeds: Vec<u32> = text .lines() .next() .ok_or(anyhow!("No first line!"))? .split_whitespace() .skip(1) .map(str::parse) .collect::<Result<_, _>>()?; println!("seeds: {:?}", seeds); Ok(()) }