61 lines
1.4 KiB
Rust
61 lines
1.4 KiB
Rust
use std::io::{stdin, BufRead};
|
|
use anyhow::{anyhow, Result};
|
|
|
|
fn collect_list(prefix: &str, buf: &str) -> Result<Vec<usize>> {
|
|
Ok(buf.strip_prefix(prefix)
|
|
.ok_or(anyhow!("Incorrect line: {buf:?}"))?
|
|
.split_whitespace()
|
|
.map(|v| v.parse::<usize>())
|
|
.collect::<Result<_,_>>()?)
|
|
}
|
|
|
|
fn aggregate(nums: &[usize]) -> usize {
|
|
nums.iter().fold(0, |acc, d| { acc * (10u64.pow(d.ilog10() + 1) as usize) + d } )
|
|
}
|
|
|
|
fn ways((t,d) : (usize, usize)) -> usize {
|
|
if t*t < 4*d { return 0; }
|
|
let dq = t*t - 4*d;
|
|
|
|
let delta = (dq as f64).sqrt();
|
|
let b1 = ((t as f64 - delta)/2f64).floor() as usize + 1;
|
|
let b2 = ((t as f64 + delta)/2f64).ceil() as usize - 1;
|
|
|
|
if b2 < b1 { return 0; }
|
|
|
|
eprintln!("t={t} d={d} b1={b1} b2={b2}");
|
|
|
|
b2 - b1 + 1
|
|
}
|
|
|
|
fn main() -> Result<()> {
|
|
let mut stdin = stdin().lock();
|
|
|
|
let mut buf = String::with_capacity(1024);
|
|
|
|
stdin.read_line(&mut buf)?;
|
|
let times = collect_list("Time:", &buf)?;
|
|
buf.clear();
|
|
|
|
stdin.read_line(&mut buf)?;
|
|
let distances = collect_list("Distance:", &buf)?;
|
|
buf.clear();
|
|
|
|
|
|
let ways1: usize = times.iter().copied()
|
|
.zip(distances.iter().copied())
|
|
.map(ways)
|
|
.product();
|
|
|
|
println!("Part 1: {ways1} ways.");
|
|
|
|
let time2 = aggregate(×);
|
|
let dist2 = aggregate(&distances);
|
|
|
|
let ways2 = ways((time2, dist2));
|
|
|
|
println!("Part 2: {ways2} ways.");
|
|
|
|
Ok(())
|
|
}
|