use std::io; #[derive(PartialEq)] enum Dir { North, South, East, West, } fn visit(board: &Vec>, x: i64, y: i64, dir: Dir, visited: &mut Vec>) { if x < 0 || x >= board.len() as i64 { return; } if y < 0 || y >= board[x as usize].len() as i64 { return; } match board[x as usize][y as usize] { '.' => match dir { Dir::North | Dir::South => { if visited[x as usize][y as usize].0 { return; } visited[x as usize][y as usize].0 = true; if dir == Dir::North { visit(board, x - 1, y, dir, visited); } else { visit(board, x + 1, y, dir, visited); } } Dir::West | Dir::East => { if visited[x as usize][y as usize].1 { return; } visited[x as usize][y as usize].1 = true; if dir == Dir::West { visit(board, x, y - 1, dir, visited); } else { visit(board, x, y + 1, dir, visited); } } }, '\\' => { visited[x as usize][y as usize].0 = true; match dir { Dir::North => visit(board, x, y - 1, Dir::West, visited), Dir::South => visit(board, x, y + 1, Dir::East, visited), Dir::West => visit(board, x - 1, y, Dir::North, visited), Dir::East => visit(board, x + 1, y, Dir::South, visited), } } '/' => { visited[x as usize][y as usize].0 = true; match dir { Dir::North => visit(board, x, y + 1, Dir::East, visited), Dir::South => visit(board, x, y - 1, Dir::West, visited), Dir::West => visit(board, x + 1, y, Dir::South, visited), Dir::East => visit(board, x - 1, y, Dir::North, visited), } } '|' => { visited[x as usize][y as usize].0 = true; match dir { Dir::North => visit(board, x - 1, y, Dir::North, visited), Dir::South => visit(board, x + 1, y, Dir::South, visited), Dir::West | Dir::East => { visit(board, x + 1, y, Dir::South, visited); visit(board, x - 1, y, Dir::North, visited); } } } '-' => { visited[x as usize][y as usize].0 = true; match dir { Dir::North | Dir::South => { visit(board, x, y + 1, Dir::East, visited); visit(board, x, y - 1, Dir::West, visited); } Dir::West => visit(board, x, y - 1, Dir::West, visited), Dir::East => visit(board, x, y + 1, Dir::East, visited), } } c => panic!("Unhandled character {}", c), } } fn count_energized(board: &Vec>, locx: i64, locy: i64, dir: Dir) -> usize { let mut visited = Vec::new(); for _ in 0..board.len() { visited.push(vec![(false, false); board[0].len()]); } visit(board, locx, locy, dir, &mut visited); visited .iter() .fold(0, |acc, v| acc + v.iter().filter(|(a, b)| *a || *b).count()) } pub fn solve() -> usize { let mut buffer = String::new(); while io::stdin().read_line(&mut buffer).unwrap() > 0 {} count_energized( &buffer .trim() .split("\n") .map(|s| s.chars().collect()) .collect(), 0, 0, Dir::East, ) } fn best_case(board: &Vec>) -> usize { let mut best = 0; for r in 0..board.len() { best = best.max(count_energized(board, r as i64, 0, Dir::East)); best = best.max(count_energized( board, r as i64, (board[r].len() - 1) as i64, Dir::West, )); } for c in 0..board[0].len() { best = best.max(count_energized(board, 0, c as i64, Dir::South)); best = best.max(count_energized( board, (board.len() - 1) as i64, c as i64, Dir::North, )); } best } pub fn find_best() -> usize { let mut buffer = String::new(); while io::stdin().read_line(&mut buffer).unwrap() > 0 {} let board = buffer .trim() .split("\n") .map(|s| s.chars().collect()) .collect(); best_case(&board) }