diff options
Diffstat (limited to '2018/src')
| -rw-r--r-- | 2018/src/day3.rs | 92 | ||||
| -rw-r--r-- | 2018/src/main.rs | 4 | 
2 files changed, 95 insertions, 1 deletions
| diff --git a/2018/src/day3.rs b/2018/src/day3.rs new file mode 100644 index 0000000..15a4dc2 --- /dev/null +++ b/2018/src/day3.rs @@ -0,0 +1,92 @@ +use std::io; +use std::io::BufRead; +use std::str::FromStr; + +struct Point { +    x: usize, +    y: usize +} + +struct Claim { +    id: i16, +    origin: Point, +    size: Point +} + +impl FromStr for Claim { +    type Err = std::num::ParseIntError; + +    fn from_str(s: &str) -> Result<Self, Self::Err> { +        let bytes = s.as_bytes(); +        let mut cursor = 1; +        let mut idx = 1; + +        while bytes[idx].is_ascii_digit() { idx += 1; } +        let id = s[cursor..idx].parse()?; + +        idx = idx + 3; +        cursor = idx; +        while bytes[idx].is_ascii_digit() { idx += 1; } +        let ox = s[cursor..idx].parse()?; + +        idx = idx + 1; +        cursor = idx; +        while bytes[idx].is_ascii_digit() { idx += 1; } +        let oy = s[cursor..idx].parse()?; + +        idx = idx + 2; +        cursor = idx; +        while bytes[idx].is_ascii_digit() { idx += 1; } +        let sx = s[cursor..idx].parse()?; + +        let sy = s[idx+1..].parse()?; + +        Ok(Claim { +            id: id, +            origin: Point {x: ox, y: oy}, +            size: Point {x: sx, y: sy} +        }) +    } +} + +pub fn main<T: BufRead>(reader: T) -> io::Result<()> { +    let w = 1000; +    let maxnum = 1500; + +    let mut sheet: Vec<i16> = vec![0; w * w]; +    let mut double: i64 = 0; +    let mut free: Vec<bool> = vec![false; maxnum as usize]; + +    for line in reader.lines() { +        let claim = line.unwrap().parse::<Claim>().unwrap(); +        assert!(0 < claim.id && claim.id < maxnum); + +        free[claim.id as usize] = true; + +        for y in claim.origin.y .. claim.origin.y + claim.size.y { +            for x in claim.origin.x .. claim.origin.x + claim.size.x { +                let val = sheet[w * y + x]; +                if val > 0 { +                    free[val as usize] = false; +                    free[claim.id as usize] = false; +                    double += 1; +                    sheet[w * y + x] = -1; +                } else if val == 0 { +                    sheet[w * y + x] = claim.id; +                } else { +                    free[claim.id as usize] = false; +                } +            } +        } +    } + +    println!("{}", double); + +    for i in 1 .. maxnum as usize { +        if free[i] { +            println!("{}", i); +        } +    } + +    Ok(()) +} diff --git a/2018/src/main.rs b/2018/src/main.rs index 162a56e..349d857 100644 --- a/2018/src/main.rs +++ b/2018/src/main.rs @@ -8,11 +8,13 @@ use argparse::{ArgumentParser, StoreTrue, Store};  mod day1;  mod day2; +mod day3;  fn day_switch<T: BufRead>(day: i32, reader: T) -> io::Result<()> {      match day {          1 => day1::main(reader),          2 => day2::main(reader), +        3 => day3::main(reader),          _ => Err(Error::new(ErrorKind::Other, "Invalid day"))      }  } @@ -68,7 +70,7 @@ fn main() -> io::Result<()> {      error_handler(||          if day_string.len() == 0 { -            for day in 1..3 { +            for day in 1..4 {                  run_day(day, &options)?;              }              Ok(()) | 
