diff options
Diffstat (limited to '2018/src')
| -rw-r--r-- | 2018/src/day10.rs | 73 | ||||
| -rw-r--r-- | 2018/src/main.rs | 4 | 
2 files changed, 76 insertions, 1 deletions
| diff --git a/2018/src/day10.rs b/2018/src/day10.rs new file mode 100644 index 0000000..28da8de --- /dev/null +++ b/2018/src/day10.rs @@ -0,0 +1,73 @@ +use std::io; +use std::io::BufRead; +use std::collections::HashSet; + +fn parse_pt(l: &str) -> ((i32, i32), (i32, i32)) { +    let i1 = l.find('<').unwrap(); +    let i2 = l[i1..].find(',').unwrap() + i1; +    let i3 = l[i2..].find('>').unwrap() + i2; +    let i4 = l[i3..].find('<').unwrap() + i3; +    let i5 = l[i4..].find(',').unwrap() + i4; +    let i6 = l[i5..].find('>').unwrap() + i5; + +    let s1 = &l[i1+1..i2]; +    let s2 = &l[i2+1..i3]; +    let s3 = &l[i4+1..i5]; +    let s4 = &l[i5+1..i6]; + +    ((s1.trim().parse().unwrap(), s2.trim().parse().unwrap()), +        (s3.trim().parse().unwrap(), s4.trim().parse().unwrap())) +} + +pub fn main<T: BufRead>(reader: T) -> io::Result<(String, String)> { +    let dots: Vec<((i32, i32), (i32, i32))> = +        reader.lines().map(|l| l.unwrap()) +            .map(|l| parse_pt(&l)) +            .collect(); + +    let mut pts: Vec<_> = dots.iter().map(|&(xy, _)| xy).collect(); +    let vels: Vec<_> = dots.iter().map(|&(_, v)| v).collect(); + +    let mut maxscore = -1; +    let mut maxat = (-1, vec![], HashSet::new()); +    for iter in 0..20000 { +        let mut has_dot: HashSet<(i32, i32)> = HashSet::new(); +        let mut score = 0; +        for &xy in &pts { +            if has_dot.contains(&xy) { score += 1; } +            has_dot.insert(xy); +        } + +        if score > maxscore { +            maxscore = score; +            maxat = (iter, pts.clone(), has_dot.clone()); +            if maxscore > dots.len() as i32 / 2 { +                break; +            } +        } + +        for i in 0..dots.len() { +            pts[i].0 += vels[i].0; +            pts[i].1 += vels[i].1; +        } +    } + +    let mut part1 = String::new(); + +    let part2 = maxat.0.to_string(); +    let pts = maxat.1; +    let has_dot = maxat.2; +    let minx = pts.iter().map(|&(x, _)| x).min().unwrap(); +    let miny = pts.iter().map(|&(_, y)| y).min().unwrap(); +    let maxx = pts.iter().map(|&(x, _)| x).max().unwrap(); +    let maxy = pts.iter().map(|&(_, y)| y).max().unwrap(); +    for y in miny..maxy+1 { +        if y != miny { part1 += "\n"; } +        for x in minx..maxx + 1 { +            if has_dot.contains(&(x, y)) { part1 += "#"; } +            else { part1 += "."; } +        } +    } + +    Ok((part1, part2)) +} diff --git a/2018/src/main.rs b/2018/src/main.rs index 70e7a79..3e9756b 100644 --- a/2018/src/main.rs +++ b/2018/src/main.rs @@ -14,8 +14,9 @@ mod day6;  mod day7;  mod day8;  mod day9; +mod day10; -static NUM_DAYS: i32 = 9; +static NUM_DAYS: i32 = 10;  fn day_switch<T: BufRead>(day: i32, reader: T) -> io::Result<(String, String)> {      match day { @@ -28,6 +29,7 @@ fn day_switch<T: BufRead>(day: i32, reader: T) -> io::Result<(String, String)> {          7 => day7::main(reader),          8 => day8::main(reader),          9 => day9::main(reader), +        10 => day10::main(reader),          _ => Err(Error::new(ErrorKind::Other, "Invalid day"))      }  } | 
