diff --git a/storage/zeta/rs/completed/12100.rs b/storage/zeta/rs/completed/12100.rs new file mode 100644 index 0000000..36dafa1 --- /dev/null +++ b/storage/zeta/rs/completed/12100.rs @@ -0,0 +1,226 @@ +use std::io::stdin; + +#[derive(PartialEq, Eq)] +enum InstructionType { + Move, + Restore, +} + +enum Direction { + Up, + Down, + Left, + Right, +} + +struct Instruction { + instruction_type: InstructionType, + direction: Direction, +} + +impl Instruction { + fn new(instruction_type: InstructionType, direction: Direction) -> Self { + Instruction { + instruction_type, + direction, + } + } +} + +fn move_board(board: &Vec>, direction: &Direction) -> Vec> { + let n = board.len(); + let mut new_board = vec![vec![0; n]; n]; + + match direction { + Direction::Up => { + for col in 0..n { + let mut position = 0; + let mut last_merged = false; + for row in 0..n { + if board[row][col] != 0 { + if position > 0 + && new_board[position - 1][col] == board[row][col] + && !last_merged + { + new_board[position - 1][col] *= 2; + last_merged = true; + } else { + new_board[position][col] = board[row][col]; + position += 1; + last_merged = false; + } + } + } + } + } + Direction::Down => { + for col in 0..n { + let mut position = n - 1; + let mut last_merged = false; + for row in (0..n).rev() { + if board[row][col] != 0 { + if position < n - 1 + && new_board[position + 1][col] == board[row][col] + && !last_merged + { + new_board[position + 1][col] *= 2; + last_merged = true; + } else { + new_board[position][col] = board[row][col]; + if position > 0 { + position -= 1; + } + last_merged = false; + } + } + } + } + } + Direction::Left => { + for row in 0..n { + let mut position = 0; + let mut last_merged = false; + for col in 0..n { + if board[row][col] != 0 { + if position > 0 + && new_board[row][position - 1] == board[row][col] + && !last_merged + { + new_board[row][position - 1] *= 2; + last_merged = true; + } else { + new_board[row][position] = board[row][col]; + position += 1; + last_merged = false; + } + } + } + } + } + Direction::Right => { + for row in 0..n { + let mut position = n - 1; + let mut last_merged = false; + for col in (0..n).rev() { + if board[row][col] != 0 { + if position < n - 1 + && new_board[row][position + 1] == board[row][col] + && !last_merged + { + new_board[row][position + 1] *= 2; + last_merged = true; + } else { + new_board[row][position] = board[row][col]; + if position > 0 { + position -= 1; + } + last_merged = false; + } + } + } + } + } + } + + new_board +} + +fn max_element_of(board: &Vec>) -> u64 { + let mut max_val: u64 = 0; + for row in board { + for &val in row { + if val > max_val { + max_val = val; + } + } + } + max_val +} + +#[allow(dead_code)] +fn print_board(board: &Vec>) { + for row in board { + for &val in row { + print!("{} ", val); + } + println!(); + } +} + +const MAX_DEPTH: u64 = 4; + +fn get_maximum_2048_value(original_board: &Vec>) -> u64 { + let mut history: Vec>> = vec![]; + let mut maxima: u64 = 0; + let mut stack: Vec<(Instruction, u64)> = vec![]; + + history.push(original_board.clone()); + stack.push((Instruction::new(InstructionType::Restore, Direction::Up), 0)); + stack.push((Instruction::new(InstructionType::Move, Direction::Up), 0)); + stack.push((Instruction::new(InstructionType::Move, Direction::Down), 0)); + stack.push((Instruction::new(InstructionType::Move, Direction::Left), 0)); + stack.push((Instruction::new(InstructionType::Move, Direction::Right), 0)); + + while !stack.is_empty() { + let (inst, depth) = stack.pop().unwrap(); + + if inst.instruction_type == InstructionType::Restore { + history.pop().unwrap(); + continue; + } else { + let current_board = history.last().unwrap(); + let new_board = move_board(current_board, &inst.direction); + if depth == MAX_DEPTH { + let local_max = max_element_of(&new_board); + + if local_max > maxima { + maxima = local_max; + } + } else if depth < MAX_DEPTH { + history.push(new_board); + stack.push(( + Instruction::new(InstructionType::Restore, Direction::Up), + depth, + )); + stack.push(( + Instruction::new(InstructionType::Move, Direction::Up), + depth + 1, + )); + stack.push(( + Instruction::new(InstructionType::Move, Direction::Down), + depth + 1, + )); + stack.push(( + Instruction::new(InstructionType::Move, Direction::Left), + depth + 1, + )); + stack.push(( + Instruction::new(InstructionType::Move, Direction::Right), + depth + 1, + )); + } + } + } + + maxima +} + +fn main() { + let mut line = String::new(); + stdin().read_line(&mut line).unwrap(); + + let n: usize = line.trim().parse().unwrap(); + + let board = (0..n) + .map(|_| { + line.clear(); + stdin().read_line(&mut line).unwrap(); + line.split(' ') + .map(|s| s.trim().parse::().unwrap()) + .collect::>() + }) + .collect::>>(); + + let result = get_maximum_2048_value(&board); + println!("{}", result); +}