summary refs log tree commit diff
path: root/25/src/main.rs
blob: 2e137c72e8fdd0555b06e5f5ac0cb95449204014 (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
use advent_lib::prelude::*;

#[derive(Debug,Clone,Eq,PartialEq)]
enum Cell {
  Empty,
  East,
  South,
}


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 initial_grid = Vec::new();
  for line in &input {
    let mut row = Vec::new();
    for c in line.chars() {
      row.push(match c {
        '.' => Cell::Empty,
        '>' => Cell::East,
        'v' => Cell::South,
        _ => panic!("Unrecognized character."),
      });
    }
    initial_grid.push(row);
  }

  let mut i = 0;
  let mut grid = initial_grid.clone();
  loop {
    i += 1;
    let (anything_moved, new_grid) = iterate(&grid);
    grid = new_grid;

    println!("iteration {}", i);
    debug_grid(&grid);

    if !anything_moved {
      break;
    }
  }
  println!("{}", i);

  Ok(())
}


fn iterate(grid: &Vec<Vec<Cell>>) -> (bool, Vec<Vec<Cell>>) {
  let mut anything_moved = false;

  let height = grid.len();
  let width = grid[0].len();

  let mut new_grid = Vec::new();
  for _ in 0 .. height {
    let mut row = Vec::new();
    for _ in 0 .. width {
      row.push(Cell::Empty);
    }
    new_grid.push(row);
  }

  for y in 0 .. height {
    for x in 0 .. width {
      if grid[y][x] == Cell::East {
        let new_x = (x + 1) % width;
        if grid[y][new_x] == Cell::Empty {
          new_grid[y][new_x] = Cell::East;
          anything_moved = true;
        } else {
          new_grid[y][x] = Cell::East;
        }
      }
    }
  }

  for y in 0 .. height {
    for x in 0 .. width {
      if grid[y][x] == Cell::South {
        let new_y = (y + 1) % height;
        if new_grid[new_y][x] == Cell::Empty
          && grid[new_y][x] != Cell::South
        {
          new_grid[new_y][x] = Cell::South;
          anything_moved = true;
        } else {
          new_grid[y][x] = Cell::South;
        }
      }
    }
  }

  (anything_moved, new_grid)
}


#[allow(dead_code)]
fn debug_grid(grid: &Vec<Vec<Cell>>) {
  for row in grid {
    for cell in row {
      match cell {
        Cell::Empty => print!("."),
        Cell::East => print!(">"),
        Cell::South => print!("v"),
      }
    }
    println!("");
  }
  println!("");
}