summary refs log tree commit diff
path: root/20/src/main.rs
blob: 1b4fc51f1fc90ba0a02972df4fb380a62ff4f035 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
use advent_lib::prelude::*;


fn main() -> Result<()> {
  let mut args = std::env::args();
  if args.len() != 2 {
    eprintln!("Usage: advent input");
  }
  let _ = args.next();
  let filename = args.next().unwrap();

  let input = advent_lib::read_lines_file(&filename)?;

  let mut iterator = input.iter();

  let mut dictionary = Vec::new();
  for c in iterator.next().unwrap().chars() {
    dictionary.push(match c {
      '#' => 1,
      '.' => 0,
      _ => panic!("unexpected character"),
    });
  }

  let _ = iterator.next();

  let mut image = Vec::new();
  for line in iterator {
    let mut row = Vec::new();
    for c in line.chars() {
      row.push(match c {
        '#' => 1,
        '.' => 0,
        _ => panic!("unexpected character"),
      });
    }
    image.push(row);
  }

  let mut background = 0;
  for _ in 0 .. 2 {
    let (new_image, new_background) =
      iterate(&image, background, &dictionary);
    image = new_image;
    background = new_background;
  }
  println!("{}", count_pixels(&image));

  for _ in 2 .. 50 {
    let (new_image, new_background) =
      iterate(&image, background, &dictionary);
    image = new_image;
    background = new_background;
  }
  println!("{}", count_pixels(&image));

  Ok(())
}


fn iterate(input: &Vec<Vec<u8>>, background: u8, dictionary: &Vec<u8>)
  -> (Vec<Vec<u8>>, u8)
{
  let height = input.len() as i64;
  let width = input[0].len() as i64;

  let mut output = Vec::new();
  for y in -2 .. height+2 {
    let mut row = Vec::new();
    for x in -2 .. width+2 {
      let mut index: usize = 0;

      for offset_y in -1 .. 2 {
        for offset_x in -1 .. 2 {
          let computed_y: i64 = y + offset_y;
          let computed_x: i64 = x + offset_x;


          index *= 2;
          if (computed_y >= 0) && (computed_y < height)
            && (computed_x >= 0) && (computed_x < width)
          {
            index += input[computed_y as usize][computed_x as usize] as usize;
          } else {
            index += background as usize;
          }
        }
      }

      row.push(dictionary[index]);
    }
    output.push(row);
  }

  let output_background = dictionary[background as usize];

  (output, output_background)
}


fn count_pixels(image: &Vec<Vec<u8>>) -> i64 {
  let mut count = 0;

  for row in image {
    for cell in row {
      count += *cell as i64;
    }
  }

  count
}


#[allow(dead_code)]
fn debug_image(image: &Vec<Vec<u8>>) {
  for row in image {
    for cell in row {
      if *cell == 1 {
        print!("#");
      } else {
        print!(".");
      }
    }
    println!("");
  }
  println!("");
}