Лабиринт - Найди Сыр

  • Автор темы Flashlite
  • Обновлено
  • 22, Oct 2024
  • #1

Обновлять: Есть 6 лабиринтов. Они включены в контроллер. Существует tar.gz лабиринтов и их файлы .bmp. здесь (дропбокс). По этой ссылке также есть утилита для создания дополнительных лабиринтов (в архиве файл maze_4.txt неверный). На этом этапе вы можете создать собственную запись и обновить свой результат. Подробности о том, как это сделать, приведены внизу. Если у вас есть вопросы или проблемы, пожалуйста, свяжитесь со мной в чате.


Ты мышь. Вы в лабиринте. Найдите сыр.

Концепция

Вы находитесь в лабиринте, состоящем из прямоугольной сетки. Каждое пространство сетки содержит одну из нескольких вещей:

  •  
     
     
     
     
     
     
     
     play 
    - An impassable wall
  • - Пустое пространство, которое можно пройти
  • display_maze(&maze, position) - You, the mouse
  • transcript.txt - The cheese, your goal

Пожалуйста, используйте те же символы, чтобы мне не пришлось модифицировать контроллер.

На каждом ходу вам будут даваться плитки, расположенные к северу, югу, востоку и западу от вашей текущей позиции. Затем вы должны указать направление, в котором хотите двигаться. Вы выиграете, когда доберетесь до сыра. Меньше шагов — лучше.

Вход

Вам будут предоставлены входные данные через стандартный ввод следующим образом: ./script 1 2 3 4 5 6 , where each letter represents the tile at that compass point. For example, if the current state looks like

./script <mazes to test>

тогда вам будет дана строка #!/bin/bash mkfifo /tmp/pipe1 mkfifo /tmp/pipe2 for arg in "$@"; do ./maze/target/release/maze $arg < /tmp/pipe1 | tee /tmp/pipe2 trascript.txt & ( ./maze_test/main < /tmp/pipe2 | tee /tmp/pipe1 ) > /dev/null done rm /tmp/pipe1 rm /tmp/pipe2 .

В конце игры контроллер отправит вам строку из четырёх нулей: #!/bin/bash mkfifo /tmp/pipe1 mkfifo /tmp/pipe2 for arg in "$@"; do <path to controller> $arg < /tmp/pipe1 | tee /tmp/pipe2 trascript.txt & ( <path to entry> < /tmp/pipe2 | tee /tmp/pipe1 ) > /dev/null done rm /tmp/pipe1 rm /tmp/pipe2 . После получения этой строки ваша программа должна завершить работу. Никакие другие введенные данные не будут содержать #\ character.

Пожалуйста, игнорируйте все остальные входные данные.

Выход

Вам нужно вывести одну букву maze_1 , type Maze = Vec<Vec<char>>; fn str_to_maze(input: &str) -> Result<Maze,i32> { let mut maze: Vec<Vec<char>> = vec![ vec![] ]; let mut row: Vec<char> = vec![]; for c in input.chars() { if c == '!' || c == '+' || c == 'O' || c == ' ' { row.push(c); } else if c =='.' { row.push(' '); } else if c == '#' { maze.push(row); row = vec![]; } else if c =='\0' { break; } else { println!("Bad character in maze: {}, exiting.", c); return Err(1); } } return Ok(maze); } fn display_maze(maze: &Maze, position: [usize;2]) { for y in 0..maze.len() { for x in 0..maze[y].len() { if [x,y] == position { print!("O"); } else if maze[y][x] == '#' { println!("\n"); } else { print!("{}",maze[y][x]); } } println!(""); } println!("\n"); } fn get_starting_position(maze: &mut Maze) -> Result<[usize;2],&str> { for y in 0..maze.len() { for x in 0..maze[y].len() { if maze[y][x] == 'O' { maze[y][x] = ' '; return Ok([x,y]); } } } return Err("No mouse found"); } enum State { Continue([char;4]), Win, Disqualify, } fn output(maze: &Maze, position: [usize;2]) -> State { let x = position[0]; let y = position[1]; if maze[y][x] == '+' { return State::Win; } else if maze[y][x] == '!' { return State::Disqualify; } let n = maze[y-1][x]; assert!(y+1<maze.len()); let s = maze[y+1][x]; let w = maze[y][x-1]; assert!(x+1<maze[y].len()); let e = maze[y][x+1]; return State::Continue([n,e,s,w]); } fn get_input() -> char { use std::io; use std::io::Read; let mut buffer: [u8;2] = [0;2]; io::stdin().read_exact(&mut buffer).unwrap(); //println!("{:?}", buffer); // to see exactly what the input is return buffer[0] as char; } fn next_position(current_position: [usize;2], direction: char) -> Result<[usize;2],char> { let mut x = current_position[0]; let mut y = current_position[1]; if direction == 'n' { y -= 1; } else if direction == 'e' { x += 1; } else if direction == 's' { y += 1; } else if direction == 'w' { x -= 1; } else { return Err(direction); } return Ok([x,y]); } fn play(maze: &mut Maze) -> (State, usize) { let mut position: [usize;2]; match get_starting_position(maze) { Ok(pos) => position = pos, Err(s) => { println!("{}",s); std::process::exit(2); } } let mut moves = 0; loop { let state = output(maze, position); /* uncomment below to view the maze at each step */ //display_maze(&maze, position); /* ----------------------------------------------*/ match state { State::Win => { //println!("You found the cheese"); return(State::Win, moves); } State::Disqualify => { //println!("You were disqualified"); return(State::Disqualify, moves); } State::Continue(out) => { println!("{}{}{}{}",out[0],out[1],out[2],out[3]); } } // only get here with Continue let input = get_input(); moves += 1; match next_position(position, input) { Err(c) => { println!("Invalid input: {}", c as u8); return (State::Disqualify, moves); } Ok(next_pos) => position = next_pos, } } } fn main() { let mut arg_counter = 0; for argument in std::env::args() { if arg_counter != 0 { let mut maze = match argument.as_str(){ "1" => maze_1(), "2" => maze_2(), "3" => maze_3(), "4" => maze_4(), "5" => maze_5(), "6" => maze_6(), _ => { println!("invalid input: {}, breaking", argument); break; } }; let game_result = play(&mut maze); println!("0000"); match game_result.0 { State::Win => println!("WIN"), State::Disqualify => println!("DISQUALIFY"), _ => println!("Error"), } println!("moves: {}", game_result.1 ); } arg_counter += 1; } } fn maze_1() -> Maze { let maze_str = "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#\ !O ! ! !#\ !. ! !!!!!!!!!!!!!!!!!! ! !!!!!!#\ !. ! ! ! !#\ !. ! !!!!!!!!!!!!!!!!!!!! ! !! !#\ !. !........... ! !!.+#\ !. !.!!!!!!!!!.!!!!!!!!!!!!!!!.!#\ !.!..! ...............!.!#\ !.!.!! !!!!!!!!!!!!!!!!!!!!!.!.!#\ !.!.!! !!! ! .!.!#\ !.!.!! !!! !!!!!!!!!!!!!!!!.!.!#\ !...!! !!! .!.!#\ ! ! !! !!! .!.!#\ ! ! !! !!! !!!!!!!!! !!!!!!.!.!#\ ! ! !! !!! ! !! ! .!.!#\ ! ! !! !!! ! !!!!!!! ! .!.!#\ ! ! !! !!! ! !! ! .!.!#\ ! ! !! !!! ! !! ! .!.!#\ ! ! !! ! ! !! ! .!.!#\ ! ! !! ! ! !!!!!! !! ! .!.!#\ ! ! !! ! ! ! !! ! ...!#\ ! ! !! ! ! ! !! ! !#\ ! ! !! ! ! ! !! ! ! !#\ ! ! !! ! ! ! !!!!!! ! ! !#\ ! ! !! ! ! ! !! ! ! !#\ ! ! ! ! !! ! ! !#\ ! !!!!!! !!!!!!!! !! ! ! !#\ ! ! !! ! ! !#\ ! !!!!!!!!!!! !!!! !! ! ! !#\ ! ! ! !#\ ! !!!!!!!! !!!! ! !#\ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#\ "; match str_to_maze(&maze_str) { Ok(x) => return x, Err(i) => std::process::exit(i), } } fn maze_2() -> Maze { let maze_str = "!!!!!!!!!!!!!!!#\ ! .......!#\ ! !!! !.!!!! .!#\ ! ! !.!!O!!.!#\ !!! !....! .!#\ ! !!!!!!!!!.!#\ ! !! ..!#\ ! !!!!!!!!!.!!#\ ! ..+#\ !!!!!!!!!!!!!!!#\ "; match str_to_maze(&maze_str) { Ok(x) => return x, Err(i) => std::process::exit(i), } } fn maze_3() -> Maze { let maze_str = "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#\ ! !!!#\ ! ! !!! !!!!!!!!!!!!!!!!!! !#\ ! ! ! !!! !!! ! !#\ ! ! ! !!!!!!!!!!!!!!!! !! !#\ ! ! ! !!!! !#\ ! !! !!!!!!!!!! !! ! !#\ ! ! ! !!!! !!!!! !!! !#\ !! ! ! !!!! ! ! !#\ !! ! ! !!!! !!!!!!!!!!!!!! ! !#\ !! ! ! !!!! ! ! ! !#\ !! ! ! !!!! ! ! !!!! ! ! !#\ !! ! ! !!!! ! ! ! !!! ! ! !#\ ! ! ! !!!! ! ! ! !!! ! ! !#\ ! ! ! !!!! ! ! !!!!! ! !#\ ! ! ! !!!! !!! ! !! ! !!!#\ ! ! ! !!! !! ! !!! ! !!!#\ ! ! ! ! !! !!!! !! ! !!!#\ ! ! !! ! !! ! !! ! !!!#\ ! ! ! !! !! !!! ! !!!#\ ! !! !!!! !!! !! ! !#\ !! ! !! ! !!! !! !!! !#\ !! ! ! ! ! !#\ !! !!!!!! !! !!!!!!!!!!! !#\ ! !!!! !!!!!!!!!!! !#\ ! ..........O!!!! !!!!!!!!!!!.+#\ !! .!!!!!! !! !!!!!!!!!!!.!#\ !! .! ! ! ! .!#\ !!..! !! ! !!! !! !!!.!#\ ! .!! !!!! !!! !! !...!#\ ! .! ! !! !! !!! !.!!!#\ ! .! !! ! !! ! !! !.!!!#\ ! .! ! ! !! !!!! !! !.!!!#\ ! .! ! !!! !! ! !!! !.!!!#\ ! .! ! !!!! !!! ! !! !.!!!#\ ! .! ! !!!! ! ! !!!!! !...!#\ ! .! ! !!!! ! ! ! !!! ! !.!#\ !!.! ! !!!! ! ! ! !!! ! !.!#\ !!.! ! !!!! ! ! !!!! ! !.!#\ !!.! ! !!!! ! ! !.!#\ !!.! ! !!!! !!!!!!!!!!!!!! !.!#\ !!.! ! !!!! ! ! .!#\ !..! ! !!!! !!!!! !!!.!#\ !.!! !!!!!!!!!! !! !.!#\ !.! ! !!!! .!#\ !.! ! !!!!!!!!!!!!!!!! !!.!#\ !.! ! !!! !!! !.!#\ !.! !!! !!!!!!!!!!!!!!!!!!...!#\ !............................!!!#\ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#\ "; match str_to_maze(&maze_str) { Ok(x) => return x, Err(i) => std::process::exit(i), } } fn maze_4() -> Maze { let maze_str = "!!!!!!!!!!!!!!!!!+!!!!!!!!!!!!!!#\ !................. !!!#\ !.! !!! !!!!!!!!!!!!!!!!!! !#\ !.! ! !!! !!! ! !#\ !.! ! !!!!!!!!!!!!!!!! !! !#\ !.! ! !!!! !#\ !.!! !!!!!!!!!! !! ! !#\ !..! ! !!!! !!!!! !!! !#\ !!.! ! !!!! ! ! !#\ !!.! ! !!!! !!!!!!!!!!!!!! ! !#\ !!.! ! !!!! ! ! ! !#\ !!.! ! !!!! ! ! !!!! ! ! !#\ !!.! ! !!!! ! ! ! !!! ! ! !#\ ! .! ! !!!! ! ! ! !!! ! ! !#\ ! .! ! !!!! ! ! !!!!! ! !#\ ! .! ! !!!! !!! ! !! ! !!!#\ ! .! ! !!! !! ! !!! ! !!!#\ ! .! ! ! !! !!!! !! ! !!!#\ ! .! !! ! !! ! !! ! !!!#\ ! .! ! !! !! !!! ! !!!#\ ! .!! !!!! !!! !! ! !#\ !!. ! !! ! !!! !! !!! !#\ !!. ! ! ! ! !#\ !!. !!!!!! !! !!!!!!!!!!! !#\ ! ........... !!!! !!!!!!!!!!! !#\ ! . !!!! !!!!!!!!!!! !#\ !! !!!!!! . !! !!!!!!!!!!! !#\ !! ! ! . ! ! !#\ !! ! !! ! . !!! !! !!! !#\ ! !! !!!! . !!! !! ! !#\ ! ! ! !!.!! !!! ! !!!#\ ! ! !! !.!! ! !! ! !!!#\ ! ! ! !.!! !!!! !! ! !!!#\ ! ! ! !!!..!! ! !!! ! !!!#\ ! ! ! !!!!.!!! ! !! ! !!!#\ ! ! ! !!!!.! ! !!!!! ! !#\ ! ! ! !!!!.! ! ! !!! ! ! !#\ !! ! ! !!!!.! ! ! !!! ! ! !#\ !! ! ! !!!!.! ! !!!! ! ! !#\ !! ! ! !!!!.! ! ! !#\ !! ! ! !!!!. !!!!!!!!!!!!!! ! !#\ !! ! ! !!!!.....O! ! !#\ ! ! ! !!!! !!!!! !!! !#\ ! !! !!!!!!!!!! !! ! !#\ ! ! ! !!!! !#\ ! ! ! !!!!!!!!!!!!!!!! !! !#\ ! ! ! !!! !!! ! !#\ ! ! !!! !!!!!!!!!!!!!!!!!! !#\ ! !!!#\ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#\ "; match str_to_maze(&maze_str) { Ok(x) => return x, Err(i) => std::process::exit(i), } } fn maze_5() -> Maze { let maze_str = "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#\ +......!!!! !!! !!! !!!! !!#\ ! .! !! !!!!!#\ ! !!!.! !! !!! !!!! !!!!!!!!! !!! !#\ ! !!...! !!!!! !! ! !! !! !#\ !!!..!! ! !! ! ! ! !!#\ !! .!!........ !! !!! ! ! ! ! !!#\ !!!. !. ! !. ! !!!!! !! ! ! !! !!!#\ !!!. !. ! !. ! !!!!! ! !! ! !!!#\ !!.. !. ! !.. ! ! ! !! ! ! !!#\ !!.! !.! ! ! .. ! !!!!!! ! ! ! ! !!#\ !!.! !.! ! !! . ! ! ! ! ! ! !!#\ !!.! !.! ! ! . ! !! !! !!!! ! ! ! !!#\ !!.! !.!! ! ! . ! !!! !!!! ! ! !! !!#\ !!.! !. ! ! ! . ! !! ! ! ! ! !!#\ ! .!!!. ! ! !!. ! ! ! ! ! ! !#\ ! .!!!. ! ! !. ! ! ! ! ! ! !#\ ! .! !. ! ! !. ! ! ! ! ! ! !#\ ! .! !. ! !! !....!!! ! !! ! ! ! !#\ ! .! ..! ! ! ...!!!! ! ! ! ! ! !#\ ! .! .! ! !!!!!!.... !!!!!!! ! ! !#\ ! .! !!.! !! ! !!!! .! !#\ ! .!!!!.! !!!! !!! .! !!!!! !!!!!!!!!!! !#\ ! .. !!.! !!! !! !.!! !#\ !!!.. !. ! !!! !..! !!! ! ! !#\ !!! .... ! !!!! ! .! ! !!#\ !!!!!!!!!!!!!!!!!!!!!!! .! !!!!!!!!!!!!!!!!!!!! !!#\ !!! ! .! !!!#\ !! ! !!! !! .! !!#\ !! ! ! !! !!!!!!.! !!!!!! !!#\ !! ! ! !! !!!!!!.! !!!!!!!! ! !!#\ !! ! ! !! !!!!!!!.! !!!!!! !! ! ! !!#\ !! ! ! ! !!!!!!!!.! !!! ! ! ! !!#\ !! ! ! ! !!!!!!!!!.! !!!! ! ! ! ! ! !!#\ !! ! ! ! .! !! ! ! ! ! !!#\ !! !!! ! ! !!!!!! .! ! !! !!#\ !! ! ! ! ! ! !!. ! !!! ! ! !!#\ !! ! ! ! ! ! ! . ! ! !! ! ! !!#\ !! ! ! ! ! ! !! !!. !!! !! ! ! ! !!#\ !! ! ! ! !! ! !!! ! ..... !! ! ! !!#\ !! ! ! ! ! ! !!!!!!! . ! ! !!#\ ! ! ! ! ! ! !!! ! .!!!! ! ! !#\ ! ! ! ! !! ! ! .! !!.......... !#\ ! !! ! ! ! !!!!!!!!! .! !! .! !!!!. !#\ ! ! ! ! !! !!! .!!!!! .. ! . !#\ ! ! ! !! !!! !!! .......... !!!! . !#\ ! ! ! !! !!!! !!!!!!!!!!!! !. !#\ ! ! ! !!!!!! O. !#\ ! ! !#\ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#\ "; match str_to_maze(&maze_str) { Ok(x) => return x, Err(i) => std::process::exit(i), } } fn maze_6() -> Maze { let maze_str = "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#\ ! !!!! ....!!! !!! !!!! !!#\ ! ! .!!.......... !!!!!#\ ! !!! ! !! ...!!! !!!!. !!!!!!!!! !!! !#\ ! !! ! !!!!!.. !! !. !! !! !#\ !!! !! !. !! !..... ! ! !!#\ !! !! .. !! !!! . ! ! ! ! !!#\ !!! ! ! ! .! !!!!! . !! ! ! !! !!!#\ !!! ! ! ! .! !!!!!. ! !! ! !!!#\ !! ! ! ! .! ! !. !! ! ! !!#\ !! ! ! ! ! ! . ! !!!!!! ! .. ! ! ! !!#\ !! ! ! ! ! !! . ! ! ! .....! ! ! !!#\ !! ! ! ! ! ! . ! !! !! !!!!.! ! ! !!#\ !! ! ! !! ! ! ..! !!! !!!! .! ! !! !!#\ !! ! ! ! ! ! .! !! ! .! ! ! !!#\ ! !!! ! ! !! . ! ! ! .! ! ! !#\ ! !!! ! ! ! ..! ! ! . ! ! ! !#\ ! ! ! ! ! ! .! ! ! . ! ! ! !#\ ! ! ! ! !! ! .!!! ! !! . ! ! ! !#\ ! ! ! ! ! ...!!!! ! . ! ! ! ! !#\ ! ! ! ! !!!!!!.... !!!!!!! . ! ! !#\ ! ! !! ! !! ! !!!! .! . !#\ ! !!!! ! !!!! !!! .! !!!!! .!!!!!!!!!!! !#\ ! !! ! !!! !! !.!!.......... !#\ !!! ! ! !!! !. !. !!! ! ! !#\ !!! ! !!!! !. !. ! !!#\ !!!!!!!!!!!!!!!!!!!!!!!. !.!!!!!!!!!!!!!!!!!!!! !!#\ !!! ! . !.....................!!!#\ !! ! !!! !! O..... ! ..!!#\ !! ! ! !! !!!!!! ! !!!!!! .!!#\ !! ! ! !! !!!!!! ! !!!!!!!! ! .!!#\ !! ! ! !! !!!!!!! ! !!!!!! !! ! ! .!!#\ !! ! ! ! !!!!!!!! ! !!! ! ! ! .!!#\ !! ! ! ! !!!!!!!!! ! !!!! ! ! ! ! ! .!!#\ !! ! ! ! ! !! ! ! ! ! .!!#\ !! !!! ! ! !!!!!! ! ! !! .!!#\ !! ! ! ! ! ! !! ! !!! ! ! .!!#\ !! ! ! ! ! ! ! ! ! !! ! ! .!!#\ !! ! ! ! ! ! !! !! !!! !! ! ! ! .!!#\ !! ! ! ! !! ! !!! ! !! ! !.!!#\ !! ! ! ! ! ! !!!!!!! ! ! .!!#\ ! ! ! ! ! ! !!! ! !!!! ! ! . !#\ ! ! ! ! !! ! ! ! !! . !#\ ! !! ! ! ! !!!!!!!!! ! !! ! !!!!. !#\ ! ! ! ! !! !!! !!!!! ! . !#\ ! ! ! !! !!! !!! ! !!!! . !#\ ! ! ! !! !!!! !!!!!!!!!!!! !..+#\ ! ! ! !!!!!! !#\ ! ! ! !#\ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#\ "; match str_to_maze(&maze_str) { Ok(x) => return x, Err(i) => std::process::exit(i), } } , !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! O...!.......! ! .....!.....! ! ! ! !!!!!.!.! !!!.! !!! !.!!!.!.!!!.!!!!!!! !!! !!!!!!!!! !!! ! ! ! ! !...! !.! !.! !.!.! !.! ! ! ! ! ! ! ! !!!!! !!! !.!!!!!!!.! !.!.! !.! !!!!!!! !!! ! !!!!!!! !!! ! ! ! ! !.........! !...!...! ! ! ! ! ! ! ! ! ! !!! !!!!!!!!!!!!!!!!! !!!!!.!!! !!! !!! ! ! !!! !!! !!! !!! ! ! ! ! ! !.....! ! ! ! ! ! ! ! ! ! !!!!!!!!!!! ! ! !!! !!! !.!!!!!!!!!!!!! ! !!! ! !!!!!!! !!! ! ! ! ! ! !.! ! ! ! ! ! ! !!!!!!! !!!!!!! !!!!!!!.! !!!!!!!!!!!!!!! !!!!!!! !!!!!!!!!!! ! ! ! ! ! !...!.! ! ! ! ! ! ! !!! ! ! ! ! !!!!!!!.!.!.! !!!!!!!!! ! ! !!!!!!! ! ! !!!!!!! ! ! ! ! ! ! !.!...! ! ! ! ! ! ! ! ! ! !!! ! !!!!! !!!!!!! !.!!!!!!! !!!!!!!!! !!! !!!!! ! !!! ! !!! ! ! ! ! ! ! !...! ! ! ! ! ! ! ! ! ! !!!!! ! ! ! !!!!!!!!!.! !!!!! !!! !!!!! !!!!!!!!!!! ! ! ! ! ! ! ! ! ! ! !...! ! ! ! ! ! ! ! ! ! ! ! !!!!!!!!! !!! ! ! !.!!! !!!!!!! ! !!!!!!! ! ! !!!!!!! !!! ! ! ! ! ! !...! ! ! ! ! ! ! ! !!!!!!!!!!!!!!!!!!! !!!.!!!!!!! ! !!!!! ! !!! !!!!!!!!!!!!!!! ! ! ! !...! ! ! ! ! ! ! ! !!!!!!!!!!!!! ! ! !.!!! !!!!!!! !!!!!!!!! !!! !!! !!! ! !!! ! ! ! ! ! ! !.! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !!!!! !!!!!!! !.! ! !!! ! ! ! ! !!! !!!!!!! !!! !!!!! !!! ! ! ! ! ! !.! ! ! ! ! ! ! ! ! ! !!!!! ! ! !!! !!! ! !.!!!!!!! !!!!!!! ! ! !!! ! !!!!!!!!! !!! ! ! ! ! ! ! !.......! ! ! ! ! ! ! ! ! ! !!!!! !!! !!! !!!!!!!!!!!.!!!!!!! ! ! ! !!!!!!! ! !!!!!!! ! ! ! ! ! !...! ! ! ! ! ! ! ! ! !!!!!!!!!!! !!!!!!!!!!! !.!!! !!!!!!! ! !!!!! ! !!! !!!!!!!!! ! ! ! ! ! !.! ! ! ! ! ! ! ! !!!!!!! !!!!! ! !!! !!!.!!!!!!! ! !!!!! ! ! !!!!! ! !!!!!!!!! ! ! ! ! ! ! !.......! ! ! ! ! ! ! ! !!! !!!!! ! !!! !!! !!!!!!!.! !!!!!!!!! !!!!!!!!!!!!!!!!! ! ! ! ! ! ! ! ! !.! ! ! ! ! ! !!!!!!!!!!! ! !!! !!! ! ! ! !!!.! ! !!!!! !!! ! !!! ! !!!!!!! ! ! ! ! ! ! !...! ! ! ! ! ! ! ! ! ! !!!!!!!!!!! !!!!!!!!!!!!! !.!!! !!!!!!!!!!! ! ! ! ! !!! ! !!! ! ! ! ! !.! ! ! ! ! ! ! ! ! ! !!!!!!! !!! !!!!!!!!!!!!! ! !.! !!! ! !!!!!!! ! !!! !!!!! ! ! ! ! ! ! ! ! !.! ! ! ! ! ! ! ! ! !!!!!!! !!!!!!! ! !!!!! ! !.!!! !!!!!!! ! ! !!! !!!!!!!!!!!!! ! ! ! ! ! !.! ! ! ! ! ! ! ! !!!!!!! ! ! !!! !!!!!!!.! !!!!!!!!!!! ! !!!!!!!!!!!!!!! ! ! ! ! ! ! ! ! ! !.....! ! ! ! !...............! ! ! !!! !!! ! !!!!! !!! !.!!!!! ! ! ! !!!!!!! !.!!!!!!!!!!!!!.! ! ! ! ! ! ! !...! ! ! !.! !...! !!!!! !!! ! !!! ! !!!!!!!!!.!!!!!!! !!!!!!!!!!!.!!!!! !!!!!.!!! ! ! ! ! ! !.......! !...!.....! .! ! ! !!!!! !!!!! !!!!! !!!!! !!!!!!!.!!!!!!!!!.!.!!!!!.!!!!!!!.! ! ! ! ! ! ! ! !...........!...!...!.....!...! ! !!!!!!!!! !!!!! ! !!! ! !!! ! !!!!!!!!!!!!!!!.!.!!!.!!!.!!!.! ! ! ! ! ! ! ! ! !.!..... !...!.! !!! !!! !!!!!!!!! !!!!! !!!!!!!!! ! !!!!!!! !!!.! !!!!!!!!!.!.! ! ! ! ! ! ! ! ! ! !...! !.........!.! ! !!!!!!! ! ! ! ! !!! ! !!!!!!! ! !!!!!!!!! !.!!!!!.!!!!!!!!!.! ! ! ! ! ! ! ! ! ! ! !.!.....! !.! ! !!!!! !!!!!!!!! ! !!!!!!!!!!! !!! ! ! ! ! !.!.!!!!! !!!!! !.! ! ! ! ! ! ! ! ! ! !.!...! ! !.! ! ! !!!!!!!!!!!!!!!!! !!! !!!!! ! ! !!!!!!!!!.!!!.! !!!!!!!!!.! ! ! ! ! .....! .! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!+! , or !!!!!!!!+! !O..!....! ! !.!.! !! ! !.!.! ! ! !.!.!! ! !!!.!.!! ! ! .!.! !! !!!... ! !!!!!!!!!! , чтобы указать, в каком направлении вы хотите двигаться, за которым следует символ новой строки.

Подсчет очков

Ваш результат в каждом тесте — это количество шагов, которые вам нужно сделать, чтобы найти сыр.

Ваш общий балл будет представлять собой сумму вашего среднего балла за лабиринт в группе лабиринтов разных размеров, каждый из которых поместится в квадрат длиной 50.

Например, если вашему боту потребуется 100 ходов, чтобы пройти каждый из 6 лабиринтов, то ваш результат составит 600.

Если ваш бот не детерминирован, попробуйте каждый лабиринт 10 раз и используйте среднее значение для этого лабиринта. Ваш окончательный результат будет суммой всех средних значений.

Правила

  • Каждый лабиринт поместится внутри квадрата 50х50.
  • В каждом лабиринте будет хотя бы один допустимый путь от начала до сыра.
  • Каждый лабиринт будет полностью обнесен стеной, за исключением сыр всегда будет на внешней стенке так что по сути он служит выходом из лабиринта.
  • Если вы столкнетесь со стеной, ваша работа будет дисквалифицирована.
  • Если ваша заявка займет слишком много времени (по моему мнению, когда я начинаю тестирование), она будет дисквалифицирована. Во многом это сделано для предотвращения бесконечных циклов. Мягкое ограничение будет составлять одну минуту на лабиринт, хотя я оставляю за собой право изменить его в любое время в любом направлении.
  • Заявки не обязательно должны быть детерминированными, но если вы будете слишком случайными, вы, скорее всего, будете дисквалифицированы по вышеуказанному пункту.
  • В какой-то момент батарея лабиринтов будет освобождена, будущие ответы могут не оптимизироваться под них, и они могут быть изменены.

Материалы:

Ваша заявка представляет собой полноценную программу, которая принимает ввод через стандартный ввод и вывод через стандартный вывод. Это важно, поскольку отправка будет взаимодействовать с контроллером лабиринта. Я не собираюсь запрещать языки, которые не находятся в свободном доступе, но знаю, что кому-то другому придется потратить свое время на проведение тестов, если у меня не будет доступа к языку.

Пожалуйста, включите инструкции о том, как подать заявку.

Укажите, является ли ваша заявка детерминированной или нет, чтобы я знал, нужно ли мне запускать ее несколько раз.

Тестовые лабиринты

В тестовых лабиринтах, . characters outline the shortest route to the cheese. They are the same as the (space) character. They are not visible to your submission. The controller replaces them with spaces.

w

Тестовый лабиринт 31х31. Бесстыдно украдено.

e

Контроллер

Контроллер находится в Ржавчина (1.11 Ночью)

s

Чтобы проверить лабиринт большего размера, просто замените строку лабиринта в n function. Make sure to append the correct 0 символы в каждой строке.

Тестирование вашей записи

Этот скрипт можно использовать для проверки записей

0000

Например, мой сценарий выглядит так:

! +!

Его используют следующим образом:

! <--- Wall !O <--- You + <--- Cheese

Например

nesw

Он выведет все на консоль, а также запишет все в файл с именем +

В целях развития вашей записи вы можете раскомментировать

O

линия в ! function. This will cause the controller to display the maze at each step.

#лабиринт #наименьшее количество операций

Flashlite


Рег
15 Oct, 2009

Тем
71

Постов
192

Баллов
557
  • 26, Oct 2024
  • #2

Бот для поиска границ, Java 1.5+, 124 + 37 + 206 + 324 + 248 + 223 = 1172 шага

Этот бот пытается найти границы лабиринта и следовать за ними, зная, что сыр всегда будет находиться на границе.

Он делает это путем обновления своего внутреннего вида лабиринта и построения текущих кандидатов на роль северной, южной, восточной и западной пограничных стен.

Поиск пути A* выполняется для любых неисследованных ячеек в этих стенах, и для следования выбирается кратчайший путь. Однако только те кандидатные граничные стены, которые не содержат пустых пространств, могут быть «истинными» граничными стенами, и поэтому те, которые содержат пустые ячейки, не учитываются при поиске пути. Неисследованным ячейкам внутри пути присваивается менее желательный балл, а последовательные неисследованные ячейки усугубляют нежелательность.

В этом последнем редактировании бот теперь имеет отрицательный вес для уже посещенных ячеек. Это дает небольшое улучшение.

Существует отказоустойчивый механизм выбора движения, который гарантирует выбор допустимого движения в случае, если пути не могут быть найдены.

Обратите внимание, что эта реализация весьма неэффективна и в худшем случае решение лабиринта может занять много секунд.

Детерминистический. Беги с

 
 
 
 
 
 
 
 import java.io.IOException;
import java.io.InputStream;

public class SimpleBot 
{

private static final char[] DIRECTION = {'n','e','s','w'};

public static void main(String[] args) throws Exception

{

int[][] stepMap = new int[100][100];

int mx=49, my=49;

int[][] offsets = new int[][]{{0,-1},{1,0},{0,1},{-1,0}};

String line=readLine(System.in);

int step=0;

while (line!=null && !"0000".equals(line))

{

stepMap[mx][my]=step++;

int minStep = Integer.MAX_VALUE;

int minIndex = -1;

for (int i=0;i<4;i++)

{

if (line.charAt(i) == '+')

{

minIndex=i;

break;

}

else if (line.charAt(i) == ' ')

{

if (stepMap[mx+offsets[i][0]][my+offsets[i][1]]<minStep)

{

minStep = stepMap[mx+offsets[i][0]][my+offsets[i][1]];

minIndex=i;

}

}

}

mx +=offsets[minIndex][0];

my +=offsets[minIndex][1];

System.out.println(DIRECTION[minIndex]);

line=readLine(System.in);

}

}

/**

* Reads a line of text from the input stream. Blocks until a new line character is read.

* NOTE: This method is used in favor of BufferedReader.readLine(...) as BufferedReader buffers data before performing

* text line tokenization. This means that BufferedReader.readLine() will block until sufficient input have been received. 

* @param in a InputStream, nominally System.in

* @return a line of text or null if end of stream.

* @throws IOException

*/

private static String readLine(InputStream in) throws IOException

{

StringBuilder sb = new StringBuilder();

int readByte = in.read();

while (readByte>-1 && readByte!= '\n')

{

sb.append((char) readByte);

readByte = in.read();

}

return readByte==-1?null:sb.toString();

}

}
 

java SimpleBot ||answer||

Python, 132 + 23 + 228 + 218 + 764 + 213 = 1578 шагов

Это следует по кратчайшему пути, который проходит через известные пустые и неизвестные пространства к ограничивающему прямоугольнику известного мира, пока сыр не станет видимым.

Детерминистический. Беги с %replace dot with space maze(maze=='.')=' '; %position of mouse [u,v]=find(maze=='O'); maze(maze=='O') = ' '; step_counter = 0; while true; %game loop %test if mouse found cheese if maze(u,v) == '+'; disp(['mouse found cheese after ', num2str(step_counter), ' steps']); break; end %extract NESW tiles nesw = [maze(u-1,v),maze(u,v+1),maze(u+1,v),maze(u,v-1)]; %get result and move accordingly answer = find_the_cheese(nesw); switch answer; case 'n'; u = u-1; case 'e'; v = v+1; case 's'; u = u+1; otherwise; v = v-1; end %make sure, mouse did not run into wall assert(maze(u,v) ~= '!','mouse ran into wall!'); step_counter = step_counter + 1; end end function step = find_the_cheese(nesw) global State; NESW = 'nesw'; NESW_REVERSE = 'swne'; if all(nesw == '0000'); return; elseif ~isfield(State,'maze'); State = struct('maze', zeros(140)+' ','u',75,'v',75,'state','E'); State.maze(State.u,State.v) = 'S'; end if State.maze(State.u-1,State.v) == ' ' State.maze(State.u-1,State.v) = nesw(1); end if State.maze(State.u,State.v+1) == ' ' State.maze(State.u,State.v+1) = nesw(2); end if State.maze(State.u+1,State.v) == ' ' State.maze(State.u+1,State.v) = nesw(3); end if State.maze(State.u,State.v-1) == ' ' State.maze(State.u,State.v-1) = nesw(4); end current_nesw = [State.maze(State.u-1,State.v),State.maze(State.u,State.v+1),State.maze(State.u+1,State.v),State.maze(State.u,State.v-1)]; if any(current_nesw == '+'); % if there is cheese, go there nesw_index = find(current_nesw == '+',1); elseif any(current_nesw == ' '); % if there is a path that we did not walk, go there nesw_index = find(current_nesw == ' ',1); State.state = 'E'; else % return to previous crossing nesw_index = find(NESW == State.maze(State.u,State.v),1); assert(numel(nesw_index)>0,'not enough indices') State.state = 'R'; end %execute the step if State.state == 'E'; step = NESW(nesw_index); else %State.state = 'R' step = State.maze(State.u, State.v); end switch step; case 'n'; State.u = State.u-1; case 'e'; State.v = State.v+1; case 's'; State.u = State.u+1; otherwise; State.v = State.v-1; end if State.maze(State.u,State.v) == ' '; %if we do not have a reverse poniter yet State.maze(State.u,State.v) = NESW_REVERSE(nesw_index); %reverse pointer end %disp_important(State.maze); %uncomment for display end function disp_important(m) %just show the important stuff of the maze if any(m(:) ~= ' '); for k=1:4 m = rot90(m); while all(m(:,1) == ' '); m = m(:,2:end); end end end if numel(m) == 0; m = 'X'; end m = padarray(m,[1,1],35,'both'); disp([m,'']); end or function find_the_cheese_controller() clc;clear; global State; clearvars -global State; %uncomment the maze you want to test %maze=['!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!';'!O ! ! !';'!. ! !!!!!!!!!!!!!!!!!! ! !!!!!!';'!. ! ! ! !';'!. ! !!!!!!!!!!!!!!!!!!!! ! !! !';'!. !........... ! !!.+';'!. !.!!!!!!!!!.!!!!!!!!!!!!!!!.!';'!.!..! ...............!.!';'!.!.!! !!!!!!!!!!!!!!!!!!!!!.!.!';'!.!.!! !!! ! .!.!';'!.!.!! !!! !!!!!!!!!!!!!!!!.!.!';'!...!! !!! .!.!';'! ! !! !!! .!.!';'! ! !! !!! !!!!!!!!! !!!!!!.!.!';'! ! !! !!! ! !! ! .!.!';'! ! !! !!! ! !!!!!!! ! .!.!';'! ! !! !!! ! !! ! .!.!';'! ! !! !!! ! !! ! .!.!';'! ! !! ! ! !! ! .!.!';'! ! !! ! ! !!!!!! !! ! .!.!';'! ! !! ! ! ! !! ! ...!';'! ! !! ! ! ! !! ! !';'! ! !! ! ! ! !! ! ! !';'! ! !! ! ! ! !!!!!! ! ! !';'! ! !! ! ! ! !! ! ! !';'! ! ! ! !! ! ! !';'! !!!!!! !!!!!!!! !! ! ! !';'! ! !! ! ! !';'! !!!!!!!!!!! !!!! !! ! ! !';'! ! ! !';'! !!!!!!!! !!!! ! !';'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!']; %maze=['!!!!!!!!!!!!!!!';'! .......!';'! !!! !.!!!! .!';'! ! !.!!O!!.!';'!!! !....! .!';'! !!!!!!!!!.!';'! !! ..!';'! !!!!!!!!!.!!';'! ..+';'!!!!!!!!!!!!!!!']; %maze=['!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!';'! !!!';'! ! !!! !!!!!!!!!!!!!!!!!! !';'! ! ! !!! !!! ! !';'! ! ! !!!!!!!!!!!!!!!! !! !';'! ! ! !!!! !';'! !! !!!!!!!!!! !! ! !';'! ! ! !!!! !!!!! !!! !';'!! ! ! !!!! ! ! !';'!! ! ! !!!! !!!!!!!!!!!!!! ! !';'!! ! ! !!!! ! ! ! !';'!! ! ! !!!! ! ! !!!! ! ! !';'!! ! ! !!!! ! ! ! !!! ! ! !';'! ! ! !!!! ! ! ! !!! ! ! !';'! ! ! !!!! ! ! !!!!! ! !';'! ! ! !!!! !!! ! !! ! !!!';'! ! ! !!! !! ! !!! ! !!!';'! ! ! ! !! !!!! !! ! !!!';'! ! !! ! !! ! !! ! !!!';'! ! ! !! !! !!! ! !!!';'! !! !!!! !!! !! ! !';'!! ! !! ! !!! !! !!! !';'!! ! ! ! ! !';'!! !!!!!! !! !!!!!!!!!!! !';'! !!!! !!!!!!!!!!! !';'! ..........O!!!! !!!!!!!!!!!.+';'!! .!!!!!! !! !!!!!!!!!!!.!';'!! .! ! ! ! .!';'!!..! !! ! !!! !! !!!.!';'! .!! !!!! !!! !! !...!';'! .! ! !! !! !!! !.!!!';'! .! !! ! !! ! !! !.!!!';'! .! ! ! !! !!!! !! !.!!!';'! .! ! !!! !! ! !!! !.!!!';'! .! ! !!!! !!! ! !! !.!!!';'! .! ! !!!! ! ! !!!!! !...!';'! .! ! !!!! ! ! ! !!! ! !.!';'!!.! ! !!!! ! ! ! !!! ! !.!';'!!.! ! !!!! ! ! !!!! ! !.!';'!!.! ! !!!! ! ! !.!';'!!.! ! !!!! !!!!!!!!!!!!!! !.!';'!!.! ! !!!! ! ! .!';'!..! ! !!!! !!!!! !!!.!';'!.!! !!!!!!!!!! !! !.!';'!.! ! !!!! .!';'!.! ! !!!!!!!!!!!!!!!! !!.!';'!.! ! !!! !!! !.!';'!.! !!! !!!!!!!!!!!!!!!!!!...!';'!............................!!!';'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!']; %maze=['!!!!!!!!!!!!!!!!!+!!!!!!!!!!!!!!';'!................. !!!';'!.! !!! !!!!!!!!!!!!!!!!!! !';'!.! ! !!! !!! ! !';'!.! ! !!!!!!!!!!!!!!!! !! !';'!.! ! !!!! !';'!.!! !!!!!!!!!! !! ! !';'!..! ! !!!! !!!!! !!! !';'!!.! ! !!!! ! ! !';'!!.! ! !!!! !!!!!!!!!!!!!! ! !';'!!.! ! !!!! ! ! ! !';'!!.! ! !!!! ! ! !!!! ! ! !';'!!.! ! !!!! ! ! ! !!! ! ! !';'! .! ! !!!! ! ! ! !!! ! ! !';'! .! ! !!!! ! ! !!!!! ! !';'! .! ! !!!! !!! ! !! ! !!!';'! .! ! !!! !! ! !!! ! !!!';'! .! ! ! !! !!!! !! ! !!!';'! .! !! ! !! ! !! ! !!!';'! .! ! !! !! !!! ! !!!';'! .!! !!!! !!! !! ! !';'!!. ! !! ! !!! !! !!! !';'!!. ! ! ! ! !';'!!. !!!!!! !! !!!!!!!!!!! !';'! ........... !!!! !!!!!!!!!!! !';'! . !!!! !!!!!!!!!!! !';'!! !!!!!! . !! !!!!!!!!!!! !';'!! ! ! . ! ! !';'!! ! !! ! . !!! !! !!! !';'! !! !!!! . !!! !! ! !';'! ! ! !!.!! !!! ! !!!';'! ! !! !.!! ! !! ! !!!';'! ! ! !.!! !!!! !! ! !!!';'! ! ! !!!..!! ! !!! ! !!!';'! ! ! !!!!.!!! ! !! ! !!!';'! ! ! !!!!.! ! !!!!! ! !';'! ! ! !!!!.! ! ! !!! ! ! !';'!! ! ! !!!!.! ! ! !!! ! ! !';'!! ! ! !!!!.! ! !!!! ! ! !';'!! ! ! !!!!.! ! ! !';'!! ! ! !!!!. !!!!!!!!!!!!!! ! !';'!! ! ! !!!!.....O! ! !';'! ! ! !!!! !!!!! !!! !';'! !! !!!!!!!!!! !! ! !';'! ! ! !!!! !';'! ! ! !!!!!!!!!!!!!!!! !! !';'! ! ! !!! !!! ! !';'! ! !!! !!!!!!!!!!!!!!!!!! !';'! !!!';'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!']; %maze=['!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!';'+......!!!! !!! !!! !!!! !!';'! .! !! !!!!!';'! !!!.! !! !!! !!!! !!!!!!!!! !!! !';'! !!...! !!!!! !! ! !! !! !';'!!!..!! ! !! ! ! ! !!';'!! .!!........ !! !!! ! ! ! ! !!';'!!!. !. ! !. ! !!!!! !! ! ! !! !!!';'!!!. !. ! !. ! !!!!! ! !! ! !!!';'!!.. !. ! !.. ! ! ! !! ! ! !!';'!!.! !.! ! ! .. ! !!!!!! ! ! ! ! !!';'!!.! !.! ! !! . ! ! ! ! ! ! !!';'!!.! !.! ! ! . ! !! !! !!!! ! ! ! !!';'!!.! !.!! ! ! . ! !!! !!!! ! ! !! !!';'!!.! !. ! ! ! . ! !! ! ! ! ! !!';'! .!!!. ! ! !!. ! ! ! ! ! ! !';'! .!!!. ! ! !. ! ! ! ! ! ! !';'! .! !. ! ! !. ! ! ! ! ! ! !';'! .! !. ! !! !....!!! ! !! ! ! ! !';'! .! ..! ! ! ...!!!! ! ! ! ! ! !';'! .! .! ! !!!!!!.... !!!!!!! ! ! !';'! .! !!.! !! ! !!!! .! !';'! .!!!!.! !!!! !!! .! !!!!! !!!!!!!!!!! !';'! .. !!.! !!! !! !.!! !';'!!!.. !. ! !!! !..! !!! ! ! !';'!!! .... ! !!!! ! .! ! !!';'!!!!!!!!!!!!!!!!!!!!!!! .! !!!!!!!!!!!!!!!!!!!! !!';'!!! ! .! !!!';'!! ! !!! !! .! !!';'!! ! ! !! !!!!!!.! !!!!!! !!';'!! ! ! !! !!!!!!.! !!!!!!!! ! !!';'!! ! ! !! !!!!!!!.! !!!!!! !! ! ! !!';'!! ! ! ! !!!!!!!!.! !!! ! ! ! !!';'!! ! ! ! !!!!!!!!!.! !!!! ! ! ! ! ! !!';'!! ! ! ! .! !! ! ! ! ! !!';'!! !!! ! ! !!!!!! .! ! !! !!';'!! ! ! ! ! ! !!. ! !!! ! ! !!';'!! ! ! ! ! ! ! . ! ! !! ! ! !!';'!! ! ! ! ! ! !! !!. !!! !! ! ! ! !!';'!! ! ! ! !! ! !!! ! ..... !! ! ! !!';'!! ! ! ! ! ! !!!!!!! . ! ! !!';'! ! ! ! ! ! !!! ! .!!!! ! ! !';'! ! ! ! !! ! ! .! !!.......... !';'! !! ! ! ! !!!!!!!!! .! !! .! !!!!. !';'! ! ! ! !! !!! .!!!!! .. ! . !';'! ! ! !! !!! !!! .......... !!!! . !';'! ! ! !! !!!! !!!!!!!!!!!! !. !';'! ! ! !!!!!! O. !';'! ! !';'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!']; %maze=['!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!';'! !!!! ....!!! !!! !!!! !!';'! ! .!!.......... !!!!!';'! !!! ! !! ...!!! !!!!. !!!!!!!!! !!! !';'! !! ! !!!!!.. !! !. !! !! !';'!!! !! !. !! !..... ! ! !!';'!! !! .. !! !!! . ! ! ! ! !!';'!!! ! ! ! .! !!!!! . !! ! ! !! !!!';'!!! ! ! ! .! !!!!!. ! !! ! !!!';'!! ! ! ! .! ! !. !! ! ! !!';'!! ! ! ! ! ! . ! !!!!!! ! .. ! ! ! !!';'!! ! ! ! ! !! . ! ! ! .....! ! ! !!';'!! ! ! ! ! ! . ! !! !! !!!!.! ! ! !!';'!! ! ! !! ! ! ..! !!! !!!! .! ! !! !!';'!! ! ! ! ! ! .! !! ! .! ! ! !!';'! !!! ! ! !! . ! ! ! .! ! ! !';'! !!! ! ! ! ..! ! ! . ! ! ! !';'! ! ! ! ! ! .! ! ! . ! ! ! !';'! ! ! ! !! ! .!!! ! !! . ! ! ! !';'! ! ! ! ! ...!!!! ! . ! ! ! ! !';'! ! ! ! !!!!!!.... !!!!!!! . ! ! !';'! ! !! ! !! ! !!!! .! . !';'! !!!! ! !!!! !!! .! !!!!! .!!!!!!!!!!! !';'! !! ! !!! !! !.!!.......... !';'!!! ! ! !!! !. !. !!! ! ! !';'!!! ! !!!! !. !. ! !!';'!!!!!!!!!!!!!!!!!!!!!!!. !.!!!!!!!!!!!!!!!!!!!! !!';'!!! ! . !.....................!!!';'!! ! !!! !! O..... ! ..!!';'!! ! ! !! !!!!!! ! !!!!!! .!!';'!! ! ! !! !!!!!! ! !!!!!!!! ! .!!';'!! ! ! !! !!!!!!! ! !!!!!! !! ! ! .!!';'!! ! ! ! !!!!!!!! ! !!! ! ! ! .!!';'!! ! ! ! !!!!!!!!! ! !!!! ! ! ! ! ! .!!';'!! ! ! ! ! !! ! ! ! ! .!!';'!! !!! ! ! !!!!!! ! ! !! .!!';'!! ! ! ! ! ! !! ! !!! ! ! .!!';'!! ! ! ! ! ! ! ! ! !! ! ! .!!';'!! ! ! ! ! ! !! !! !!! !! ! ! ! .!!';'!! ! ! ! !! ! !!! ! !! ! !.!!';'!! ! ! ! ! ! !!!!!!! ! ! .!!';'! ! ! ! ! ! !!! ! !!!! ! ! . !';'! ! ! ! !! ! ! ! !! . !';'! !! ! ! ! !!!!!!!!! ! !! ! !!!!. !';'! ! ! ! !! !!! !!!!! ! . !';'! ! ! !! !!! !!! ! !!!! . !';'! ! ! !! !!!! !!!!!!!!!!!! !..+';'! ! ! !!!!!! !';'! ! ! !';'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'] (проверено в версиях 2.7 и 3.5).

NSFW ||answer||

MATLAB, 210 + 23 + 394 + 270 + 1272 + 707 = 2876 шагов

Этот подход является модификацией моего другого подхода. Представление MATLAB. (Однако они используют один и тот же контроллер.)

При таком подходе мышь следует по возможному пути, пока не находит тупик. Затем он возвращается на предыдущий перекресток, где был еще не исследованный путь. Однако на каждом этапе мышь проверяет, есть ли закрытые неисследованные области. Внутри них сыра явно быть не может (так как он всегда на границе). Если такая область найдена, в дальнейшем она игнорируется.

Он детерминирован. Из доступных путей он всегда выбирает в порядке NESW .

Поскольку я не могу компилировать сценарии Matlab, я перевел контроллер в MATLAB. «Программа» теперь представляет собой просто функцию, которая обращается к глобальным переменным для промежуточного хранения.

<?php class Maze { public $map, $pos; public $prevPos = FALSE; public $intersections = []; public $n = 75, $e = 75, $w = 75, $s = 75; public function __construct() { // since we don't know where we start, build a 150x150 map and position ourselves at the middle $this->map = array_pad([], 150, array_pad([], 150, 0)); // 0 is unknown $this->pos = ['x'=> 75, 'y'=> 75]; } public function play($input){ $this->updateMap($input); $this->move(); } private function updateField($x, $y, $inData) { if ($inData == '!' || $this->map[$x][$y] >= 1000) { // avoid overwriting our observations $this->map[$x][$y] = 1000; return; } // update our known borders if ($x <= $this->w) { $this->w = $x - 1; } elseif ($x >= $this->e) { $this->e = $x + 1; } elseif ($y <= $this->n) { $this->n = $y - 1; } elseif ($y >= $this->s) { $this->s = $y + 1; } if (!$this->map[$x][$y]) { $this->map[$x][$y] = $inData == '+' ? -1 : 1; } } private function checkForIntersection($input) { if (array_key_exists('x' . $this->pos['x'] . 'y' . $this->pos['y'], $this->intersections)) { if ($this->intersections['x' . $this->pos['x'] . 'y' . $this->pos['y']] > 0) { $this->intersections['x' . $this->pos['x'] . 'y' . $this->pos['y']] --; return TRUE; // intersection already crossed } } elseif ($c = substr_count($input, ' ') > 2) { $this->intersections['x' . $this->pos['x'] . 'y' . $this->pos['y']] = $c - 1; } return FALSE; } private function updateMap($input) { if ($this->checkForIntersection($input)) { // if we're at a known intersection, we know that the path we come from lead nowhere $this->updateField($this->prevPos['x'], $this->prevPos['y'], '!'); } // update discovered information $this->updateField($this->pos['x'], $this->pos['y'] - 1, $input[0]); $this->updateField($this->pos['x'] + 1, $this->pos['y'], $input[1]); $this->updateField($this->pos['x'], $this->pos['y'] + 1, $input[2]); $this->updateField($this->pos['x'] - 1, $this->pos['y'], $input[3]); } private function move() { if ($this->prevPos) { $this->map[$this->prevPos['x']][$this->prevPos['y']] ++; // count times stepped on } $best = ['w' => 1000]; foreach ([ ['x' => $this->pos['x'], 'y' => $this->pos['y'] - 1, 'w' => $this->map[$this->pos['x']][$this->pos['y'] - 1], 'd' => 'n'], ['x' => $this->pos['x'] + 1, 'y' => $this->pos['y'], 'w' => $this->map[$this->pos['x'] + 1][$this->pos['y']], 'd' => 'e'], ['x' => $this->pos['x'], 'y' => $this->pos['y'] + 1, 'w' => $this->map[$this->pos['x']][$this->pos['y'] + 1], 'd' => 's'], ['x' => $this->pos['x'] - 1, 'y' => $this->pos['y'], 'w' => $this->map[$this->pos['x'] - 1][$this->pos['y']], 'd' => 'w']] as $direction) { if ($direction['w'] < $best['w'] || ($direction['w'] == $best['w'] && $best['w'] < 1000 && max($this->e - $direction['x'], $direction['x'] - $this->w, $direction['y'] - $this->n, $this->s - $direction['y']) > max($best['x'] - $this->e, $this->w - $best['x'], $best['y'] - $this->n, $this->s - $best['y']))) { // encourage searching for borders which will later allow to block certain dead end paths without walking them // testing with middle search instead $best = $direction; } } echo $best['d'] . "\n"; $this->prevPos = $this->pos; $this->pos = $best; } } $maze = new Maze(); while (strncmp(($input = fgets(STDIN)), '0000', 4)) { $len = strlen($input); if (($len > 6) || $len < 3) { continue; } $maze->play($input); } ||answer||

Python 3, 156 байт, 37692 + 715 + 50626 + 27806 + 148596 + 172675 = 438110 шагов

Это не код-гольф, но гольф в любом случае — это весело. Это переходит к сыру или выбирает наименее пройденный исходящий путь, аналогично Идея mbomb007 (не полностью реализованная), но при этом связи разрываются при переходе к последнему в алфавитном порядке названию направления.

Детерминированный. Беги с x=y=0 f={} for l in iter(input,'0000'):c,d,x,y=p=max((f.setdefault(p,0),p)for p in zip(l,'nesw',[x,x+1,x,x-1],[y+1,y,y-1,y])if'!'!=p[0])[1];print(d);f[p]-=1 (tested in 3.5).

python3 SCRIPT ||answer||

PHP 362 + 37 + 1638 + 1508 + 6696 + 1613 = 11854 шагов

Запустил тест для исправленного кода:

function find_the_cheese_controller() clc;clear; global State; clearvars -global State; %uncomment the maze you want to test %maze=['!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!';'!O ! ! !';'!. ! !!!!!!!!!!!!!!!!!! ! !!!!!!';'!. ! ! ! !';'!. ! !!!!!!!!!!!!!!!!!!!! ! !! !';'!. !........... ! !!.+';'!. !.!!!!!!!!!.!!!!!!!!!!!!!!!.!';'!.!..! ...............!.!';'!.!.!! !!!!!!!!!!!!!!!!!!!!!.!.!';'!.!.!! !!! ! .!.!';'!.!.!! !!! !!!!!!!!!!!!!!!!.!.!';'!...!! !!! .!.!';'! ! !! !!! .!.!';'! ! !! !!! !!!!!!!!! !!!!!!.!.!';'! ! !! !!! ! !! ! .!.!';'! ! !! !!! ! !!!!!!! ! .!.!';'! ! !! !!! ! !! ! .!.!';'! ! !! !!! ! !! ! .!.!';'! ! !! ! ! !! ! .!.!';'! ! !! ! ! !!!!!! !! ! .!.!';'! ! !! ! ! ! !! ! ...!';'! ! !! ! ! ! !! ! !';'! ! !! ! ! ! !! ! ! !';'! ! !! ! ! ! !!!!!! ! ! !';'! ! !! ! ! ! !! ! ! !';'! ! ! ! !! ! ! !';'! !!!!!! !!!!!!!! !! ! ! !';'! ! !! ! ! !';'! !!!!!!!!!!! !!!! !! ! ! !';'! ! ! !';'! !!!!!!!! !!!! ! !';'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!']; %maze=['!!!!!!!!!!!!!!!';'! .......!';'! !!! !.!!!! .!';'! ! !.!!O!!.!';'!!! !....! .!';'! !!!!!!!!!.!';'! !! ..!';'! !!!!!!!!!.!!';'! ..+';'!!!!!!!!!!!!!!!']; %maze=['!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!';'! !!!';'! ! !!! !!!!!!!!!!!!!!!!!! !';'! ! ! !!! !!! ! !';'! ! ! !!!!!!!!!!!!!!!! !! !';'! ! ! !!!! !';'! !! !!!!!!!!!! !! ! !';'! ! ! !!!! !!!!! !!! !';'!! ! ! !!!! ! ! !';'!! ! ! !!!! !!!!!!!!!!!!!! ! !';'!! ! ! !!!! ! ! ! !';'!! ! ! !!!! ! ! !!!! ! ! !';'!! ! ! !!!! ! ! ! !!! ! ! !';'! ! ! !!!! ! ! ! !!! ! ! !';'! ! ! !!!! ! ! !!!!! ! !';'! ! ! !!!! !!! ! !! ! !!!';'! ! ! !!! !! ! !!! ! !!!';'! ! ! ! !! !!!! !! ! !!!';'! ! !! ! !! ! !! ! !!!';'! ! ! !! !! !!! ! !!!';'! !! !!!! !!! !! ! !';'!! ! !! ! !!! !! !!! !';'!! ! ! ! ! !';'!! !!!!!! !! !!!!!!!!!!! !';'! !!!! !!!!!!!!!!! !';'! ..........O!!!! !!!!!!!!!!!.+';'!! .!!!!!! !! !!!!!!!!!!!.!';'!! .! ! ! ! .!';'!!..! !! ! !!! !! !!!.!';'! .!! !!!! !!! !! !...!';'! .! ! !! !! !!! !.!!!';'! .! !! ! !! ! !! !.!!!';'! .! ! ! !! !!!! !! !.!!!';'! .! ! !!! !! ! !!! !.!!!';'! .! ! !!!! !!! ! !! !.!!!';'! .! ! !!!! ! ! !!!!! !...!';'! .! ! !!!! ! ! ! !!! ! !.!';'!!.! ! !!!! ! ! ! !!! ! !.!';'!!.! ! !!!! ! ! !!!! ! !.!';'!!.! ! !!!! ! ! !.!';'!!.! ! !!!! !!!!!!!!!!!!!! !.!';'!!.! ! !!!! ! ! .!';'!..! ! !!!! !!!!! !!!.!';'!.!! !!!!!!!!!! !! !.!';'!.! ! !!!! .!';'!.! ! !!!!!!!!!!!!!!!! !!.!';'!.! ! !!! !!! !.!';'!.! !!! !!!!!!!!!!!!!!!!!!...!';'!............................!!!';'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!']; %maze=['!!!!!!!!!!!!!!!!!+!!!!!!!!!!!!!!';'!................. !!!';'!.! !!! !!!!!!!!!!!!!!!!!! !';'!.! ! !!! !!! ! !';'!.! ! !!!!!!!!!!!!!!!! !! !';'!.! ! !!!! !';'!.!! !!!!!!!!!! !! ! !';'!..! ! !!!! !!!!! !!! !';'!!.! ! !!!! ! ! !';'!!.! ! !!!! !!!!!!!!!!!!!! ! !';'!!.! ! !!!! ! ! ! !';'!!.! ! !!!! ! ! !!!! ! ! !';'!!.! ! !!!! ! ! ! !!! ! ! !';'! .! ! !!!! ! ! ! !!! ! ! !';'! .! ! !!!! ! ! !!!!! ! !';'! .! ! !!!! !!! ! !! ! !!!';'! .! ! !!! !! ! !!! ! !!!';'! .! ! ! !! !!!! !! ! !!!';'! .! !! ! !! ! !! ! !!!';'! .! ! !! !! !!! ! !!!';'! .!! !!!! !!! !! ! !';'!!. ! !! ! !!! !! !!! !';'!!. ! ! ! ! !';'!!. !!!!!! !! !!!!!!!!!!! !';'! ........... !!!! !!!!!!!!!!! !';'! . !!!! !!!!!!!!!!! !';'!! !!!!!! . !! !!!!!!!!!!! !';'!! ! ! . ! ! !';'!! ! !! ! . !!! !! !!! !';'! !! !!!! . !!! !! ! !';'! ! ! !!.!! !!! ! !!!';'! ! !! !.!! ! !! ! !!!';'! ! ! !.!! !!!! !! ! !!!';'! ! ! !!!..!! ! !!! ! !!!';'! ! ! !!!!.!!! ! !! ! !!!';'! ! ! !!!!.! ! !!!!! ! !';'! ! ! !!!!.! ! ! !!! ! ! !';'!! ! ! !!!!.! ! ! !!! ! ! !';'!! ! ! !!!!.! ! !!!! ! ! !';'!! ! ! !!!!.! ! ! !';'!! ! ! !!!!. !!!!!!!!!!!!!! ! !';'!! ! ! !!!!.....O! ! !';'! ! ! !!!! !!!!! !!! !';'! !! !!!!!!!!!! !! ! !';'! ! ! !!!! !';'! ! ! !!!!!!!!!!!!!!!! !! !';'! ! ! !!! !!! ! !';'! ! !!! !!!!!!!!!!!!!!!!!! !';'! !!!';'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!']; %maze=['!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!';'+......!!!! !!! !!! !!!! !!';'! .! !! !!!!!';'! !!!.! !! !!! !!!! !!!!!!!!! !!! !';'! !!...! !!!!! !! ! !! !! !';'!!!..!! ! !! ! ! ! !!';'!! .!!........ !! !!! ! ! ! ! !!';'!!!. !. ! !. ! !!!!! !! ! ! !! !!!';'!!!. !. ! !. ! !!!!! ! !! ! !!!';'!!.. !. ! !.. ! ! ! !! ! ! !!';'!!.! !.! ! ! .. ! !!!!!! ! ! ! ! !!';'!!.! !.! ! !! . ! ! ! ! ! ! !!';'!!.! !.! ! ! . ! !! !! !!!! ! ! ! !!';'!!.! !.!! ! ! . ! !!! !!!! ! ! !! !!';'!!.! !. ! ! ! . ! !! ! ! ! ! !!';'! .!!!. ! ! !!. ! ! ! ! ! ! !';'! .!!!. ! ! !. ! ! ! ! ! ! !';'! .! !. ! ! !. ! ! ! ! ! ! !';'! .! !. ! !! !....!!! ! !! ! ! ! !';'! .! ..! ! ! ...!!!! ! ! ! ! ! !';'! .! .! ! !!!!!!.... !!!!!!! ! ! !';'! .! !!.! !! ! !!!! .! !';'! .!!!!.! !!!! !!! .! !!!!! !!!!!!!!!!! !';'! .. !!.! !!! !! !.!! !';'!!!.. !. ! !!! !..! !!! ! ! !';'!!! .... ! !!!! ! .! ! !!';'!!!!!!!!!!!!!!!!!!!!!!! .! !!!!!!!!!!!!!!!!!!!! !!';'!!! ! .! !!!';'!! ! !!! !! .! !!';'!! ! ! !! !!!!!!.! !!!!!! !!';'!! ! ! !! !!!!!!.! !!!!!!!! ! !!';'!! ! ! !! !!!!!!!.! !!!!!! !! ! ! !!';'!! ! ! ! !!!!!!!!.! !!! ! ! ! !!';'!! ! ! ! !!!!!!!!!.! !!!! ! ! ! ! ! !!';'!! ! ! ! .! !! ! ! ! ! !!';'!! !!! ! ! !!!!!! .! ! !! !!';'!! ! ! ! ! ! !!. ! !!! ! ! !!';'!! ! ! ! ! ! ! . ! ! !! ! ! !!';'!! ! ! ! ! ! !! !!. !!! !! ! ! ! !!';'!! ! ! ! !! ! !!! ! ..... !! ! ! !!';'!! ! ! ! ! ! !!!!!!! . ! ! !!';'! ! ! ! ! ! !!! ! .!!!! ! ! !';'! ! ! ! !! ! ! .! !!.......... !';'! !! ! ! ! !!!!!!!!! .! !! .! !!!!. !';'! ! ! ! !! !!! .!!!!! .. ! . !';'! ! ! !! !!! !!! .......... !!!! . !';'! ! ! !! !!!! !!!!!!!!!!!! !. !';'! ! ! !!!!!! O. !';'! ! !';'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!']; %maze=['!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!';'! !!!! ....!!! !!! !!!! !!';'! ! .!!.......... !!!!!';'! !!! ! !! ...!!! !!!!. !!!!!!!!! !!! !';'! !! ! !!!!!.. !! !. !! !! !';'!!! !! !. !! !..... ! ! !!';'!! !! .. !! !!! . ! ! ! ! !!';'!!! ! ! ! .! !!!!! . !! ! ! !! !!!';'!!! ! ! ! .! !!!!!. ! !! ! !!!';'!! ! ! ! .! ! !. !! ! ! !!';'!! ! ! ! ! ! . ! !!!!!! ! .. ! ! ! !!';'!! ! ! ! ! !! . ! ! ! .....! ! ! !!';'!! ! ! ! ! ! . ! !! !! !!!!.! ! ! !!';'!! ! ! !! ! ! ..! !!! !!!! .! ! !! !!';'!! ! ! ! ! ! .! !! ! .! ! ! !!';'! !!! ! ! !! . ! ! ! .! ! ! !';'! !!! ! ! ! ..! ! ! . ! ! ! !';'! ! ! ! ! ! .! ! ! . ! ! ! !';'! ! ! ! !! ! .!!! ! !! . ! ! ! !';'! ! ! ! ! ...!!!! ! . ! ! ! ! !';'! ! ! ! !!!!!!.... !!!!!!! . ! ! !';'! ! !! ! !! ! !!!! .! . !';'! !!!! ! !!!! !!! .! !!!!! .!!!!!!!!!!! !';'! !! ! !!! !! !.!!.......... !';'!!! ! ! !!! !. !. !!! ! ! !';'!!! ! !!!! !. !. ! !!';'!!!!!!!!!!!!!!!!!!!!!!!. !.!!!!!!!!!!!!!!!!!!!! !!';'!!! ! . !.....................!!!';'!! ! !!! !! O..... ! ..!!';'!! ! ! !! !!!!!! ! !!!!!! .!!';'!! ! ! !! !!!!!! ! !!!!!!!! ! .!!';'!! ! ! !! !!!!!!! ! !!!!!! !! ! ! .!!';'!! ! ! ! !!!!!!!! ! !!! ! ! ! .!!';'!! ! ! ! !!!!!!!!! ! !!!! ! ! ! ! ! .!!';'!! ! ! ! ! !! ! ! ! ! .!!';'!! !!! ! ! !!!!!! ! ! !! .!!';'!! ! ! ! ! ! !! ! !!! ! ! .!!';'!! ! ! ! ! ! ! ! ! !! ! ! .!!';'!! ! ! ! ! ! !! !! !!! !! ! ! ! .!!';'!! ! ! ! !! ! !!! ! !! ! !.!!';'!! ! ! ! ! ! !!!!!!! ! ! .!!';'! ! ! ! ! ! !!! ! !!!! ! ! . !';'! ! ! ! !! ! ! ! !! . !';'! !! ! ! ! !!!!!!!!! ! !! ! !!!!. !';'! ! ! ! !! !!! !!!!! ! . !';'! ! ! !! !!! !!! ! !!!! . !';'! ! ! !! !!!! !!!!!!!!!!!! !..+';'! ! ! !!!!!! !';'! ! ! !';'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'] %replace dot with space maze(maze=='.')=' '; %position of mouse [u,v]=find(maze=='O'); maze(maze=='O') = ' '; step_counter = 0; while true; %game loop %test if mouse found cheese if maze(u,v) == '+'; disp(['mouse found cheese after ', num2str(step_counter), ' steps']); break; end %extract NESW tiles nesw = [maze(u-1,v),maze(u,v+1),maze(u+1,v),maze(u,v-1)]; %get result and move accordingly answer = find_the_cheese(nesw); switch answer; case 'n'; u = u-1; case 'e'; v = v+1; case 's'; u = u+1; otherwise; v = v-1; end %make sure, mouse did not run into wall assert(maze(u,v) ~= '!','mouse ran into wall!'); step_counter = step_counter + 1; end end function step = find_the_cheese(nesw) global State; NESW = 'nesw'; NESW_REVERSE = 'swne'; if all(nesw == '0000'); return; elseif ~isfield(State,'maze'); State = struct('maze', zeros(140)+' ','u',75,'v',75,'state','E'); State.maze(State.u,State.v) = 'S'; end if State.maze(State.u-1,State.v) == ' ' State.maze(State.u-1,State.v) = nesw(1); end if State.maze(State.u,State.v+1) == ' ' State.maze(State.u,State.v+1) = nesw(2); end if State.maze(State.u+1,State.v) == ' ' State.maze(State.u+1,State.v) = nesw(3); end if State.maze(State.u,State.v-1) == ' ' State.maze(State.u,State.v-1) = nesw(4); end current_nesw = [State.maze(State.u-1,State.v),State.maze(State.u,State.v+1),State.maze(State.u+1,State.v),State.maze(State.u,State.v-1)]; if any(current_nesw == '+'); % if there is cheese, go there nesw_index = find(current_nesw == '+',1); elseif any(current_nesw == ' '); % if there is a path that we did not walk, go there nesw_index = find(current_nesw == ' ',1); State.state = 'E'; else % return to previous crossing nesw_index = find(NESW == State.maze(State.u,State.v),1); assert(numel(nesw_index)>0,'not enough indices') State.state = 'R'; end %execute the step if State.state == 'E'; step = NESW(nesw_index); else %State.state = 'R' step = State.maze(State.u, State.v); end switch step; case 'n'; State.u = State.u-1; case 'e'; State.v = State.v+1; case 's'; State.u = State.u+1; otherwise; State.v = State.v-1; end if State.maze(State.u,State.v) == ' '; %if we do not have a reverse poniter yet State.maze(State.u,State.v) = NESW_REVERSE(nesw_index); %reverse pointer end %check whether we have any enclosed areas, where the cheese obviously cannot be M = imfill(State.maze ~= ' ','holes'); %fill those areas with walls State.maze(M & State.maze == ' ') = '!'; %disp_important(State.maze); %uncomment for display end function disp_important(m) %just show the important stuff of the maze if any(m(:) ~= ' '); for k=1:4 m = rot90(m); while all(m(:,1) == ' '); m = m(:,2:end); end end end if numel(m) == 0; m = 'X'; end m = padarray(m,[1,1],35,'both'); disp([m,'']); end ||answer||

MATLAB, 212 + 23 + 416 + 300 + 1806 + 757 = 3514 шагов

При таком подходе мышь следует по возможному пути, пока не находит тупик. Затем он возвращается на предыдущий перекресток, где был еще не исследованный путь. Это детерминированный подход. Из доступных путей он всегда выбирает в порядке NESW (not import collections, sys def neighbors(p): x, y = p return [("n", (x, y + 1)), ("e", (x + 1, y)), ("s", (x, y - 1)), ("w", (x - 1, y))] ne = sw = loc = 0, 0 maze = {loc: ' '} while True: cells = sys.stdin.readline() if cells == '0000\n': break for (dir1, loc1), cell in zip(neighbors(loc), cells): maze[loc1] = cell if cell == ' ': ne = tuple(map(max, loc1, ne)) sw = tuple(map(min, loc1, sw)) visited = {loc} queue = collections.deque() for dir1, loc1 in neighbors(loc): visited.add(loc1) queue.append((dir1, loc1, loc1)) while True: dir1, loc1, loc2 = queue.popleft() if maze.get(loc2, ' ') == ' ': if loc2 not in maze and \ (any(a >= b for a, b in zip(loc2, ne)) or any(a <= b for a, b in zip(loc2, sw))): break for dir3, loc3 in neighbors(loc2): if loc3 not in visited: visited.add(loc3) queue.append((dir1, loc1, loc3)) elif maze[loc2] == '+': break sys.stdout.write(dir1 + "\n") sys.stdout.flush() loc = loc1 , как мне всегда хотелось написать =)

Поскольку я не могу компилировать сценарии Matlab, я перевел контроллер в MATLAB. «Программа» теперь представляет собой просто функцию, которая обращается к глобальным переменным для промежуточного хранения.

python3 SCRIPT

;

python SCRIPT ||answer||

Простой бот, Java 1.4+, 176 + 25 + 1118 + 486 + 10944 + 1847 = 14596 шагов

Этот бот подсчитывает и записывает количество шагов, предпринятых для достижения каждой посещенной ячейки, а затем, решая, в каком направлении двигаться, выбирает направление с наименьшим количеством шагов. В случае ничьей выбирает направление в порядке С, В, Ю, З.

У меня не установлен Rust, поэтому мне пришлось реализовать контроллер в Java, и это был бот, который я использовал для его тестирования. Скоро я попробую более умный решатель.

Детерминированный. Беги с import java.io.IOException; import java.io.InputStream; public class BoundryFindingBot { private static final char[] DIRECTION = {'n','e','s','w'}; private static final int MAP_SIZE = 102; private static final int PATH_FINDING_MAX_STEPS = 50000; private static final int[][] offsets = new int[][]{{0,-1},{1,0},{0,1},{-1,0}}; public static void main(String[] args) throws Exception { char[][] map = new char[MAP_SIZE][MAP_SIZE]; int[][] visitCount = new int[MAP_SIZE][MAP_SIZE]; int mx=MAP_SIZE/2-1, my=MAP_SIZE/2-1; int direction=0; String line=readLine(System.in); out: while (line!=null && !"0000".equals(line)) { // update map with new information for (int i=0;i<4;i++) { map[mx+offsets[i][0]][my+offsets[i][1]] = line.charAt(i); // immediately move toward cheese if found. if (line.charAt(i) == '+') { System.out.println(DIRECTION[i]); break out; } } // determine the current boundary walls information int currentNorthWallY=-1,currentSouthWallY=-1,currentWestWallX=-1,currentEastWallX=-1; boolean currentNorthWallHasBlanks=false,currentSouthWallHasBlanks=false,currentEastWallHasBlanks=false,currentWestWallHasBlanks=false; for (int y=0;y<MAP_SIZE;y++) { for (int x=0;x<MAP_SIZE;x++) { if (map[x][y]!=0) { if (currentNorthWallY > -1) { if (currentSouthWallY !=y) { currentSouthWallHasBlanks = false; } currentSouthWallY=y; currentSouthWallHasBlanks|=map[x][y]==' '; } else { currentNorthWallY=y; } if (currentNorthWallY == y) { currentNorthWallHasBlanks|=map[x][y]==' '; } } } } for (int x=0;x<MAP_SIZE;x++) { for (int y=0;y<MAP_SIZE;y++) { if (map[x][y]!=0) { if (currentWestWallX > -1) { if (currentEastWallX !=x) { currentEastWallHasBlanks = false; } currentEastWallX=x; currentEastWallHasBlanks|=map[x][y]==' '; } else { currentWestWallX=x; } if (currentWestWallX == x) { currentWestWallHasBlanks|=map[x][y]==' '; } } } } int closestUnvisitedWallCellResult =0xFFFFFF; // attempt to find paths to undiscovered cells in the current north wall, setting the shortest path if shortest of any path if (!currentNorthWallHasBlanks) { for (int x=currentWestWallX;x<=currentEastWallX;x++) { if (map[x][currentNorthWallY] == 0) { int result = pathFind(mx, my, x, currentNorthWallY, map,visitCount,currentWestWallX,currentNorthWallY,currentEastWallX,currentSouthWallY); if ((result &0xFFFFFF) <(closestUnvisitedWallCellResult &0xFFFFFF)) { closestUnvisitedWallCellResult = result; } } } } // attempt to find paths to undiscovered cells in the current south wall, setting the shortest path if shortest of any path if (!currentSouthWallHasBlanks) { for (int x=currentWestWallX;x<=currentEastWallX;x++) { if (map[x][currentSouthWallY] == 0) { int result = pathFind(mx, my, x, currentSouthWallY, map,visitCount,currentWestWallX,currentNorthWallY,currentEastWallX,currentSouthWallY); if ((result &0xFFFFFF) <(closestUnvisitedWallCellResult &0xFFFFFF)) { closestUnvisitedWallCellResult = result; } } } } // attempt to find paths to undiscovered cells in the current east wall, setting the shortest path if shortest of any path if (!currentEastWallHasBlanks) { for (int y=currentNorthWallY;y<=currentSouthWallY;y++) { if (map[currentEastWallX][y] == 0) { int result = pathFind(mx, my, currentEastWallX, y, map,visitCount,currentWestWallX,currentNorthWallY,currentEastWallX,currentSouthWallY); if ((result &0xFFFFFF) <(closestUnvisitedWallCellResult &0xFFFFFF)) { closestUnvisitedWallCellResult = result; } } } } // attempt to find paths to undiscovered cells in the current west wall, setting the shortest path if shortest of any path if (!currentWestWallHasBlanks) { for (int y=currentNorthWallY;y<=currentSouthWallY;y++) { if (map[currentWestWallX][y] == 0 ) { int result = pathFind(mx, my, currentWestWallX, y, map,visitCount,currentWestWallX,currentNorthWallY,currentEastWallX,currentSouthWallY); if ((result &0xFFFFFF) <(closestUnvisitedWallCellResult &0xFFFFFF)) { closestUnvisitedWallCellResult = result; } } } } // fail-safe if we are unable to find a path to a wall (i.e. initial game frame or all current boundary walls are known to have blanks and thus // not wall to head for. Simply tries to go north if possible or failing that try to head east, south, west consecutively if (closestUnvisitedWallCellResult == 0xFFFFFF) { for (int i=0;i<4;i++) { if (map[mx+offsets[i][0]][my+offsets[i][1]] == ' ') { direction = i; break; } } } else { direction = closestUnvisitedWallCellResult >> 24; } mx +=offsets[direction][0]; my +=offsets[direction][1]; visitCount[mx][my]+=5; System.out.println(DIRECTION[direction]); //// uncomment to bot's view of maze solving // System.err.println(); // for (int y=currentNorthWallY;y<=currentSouthWallY;y++) // { // for (int x=currentWestWallX;x<=currentEastWallX;x++) // { // if (x==mx && y==my) // { // System.err.print("O"); // } // else // { // System.err.print(map[x][y]); // } // } // System.err.println(); // } line=readLine(System.in); } System.err.println("Exited"); } /** * returns a result that is the combination of movement direction and path length of a path found from the given start position to the target * position for cells within the given bounding box. Only empty cells and unexplored cells are traversable. Sequential cells of unexplored cells * are given increasing magnitude negative score to reduce desirability. */ static int pathFind(int startX, int startY, int targetX,int targetY,char[][] map,int[][] visitCount,int boundMinX,int boundMinY,int boundMaxX,int boundMaxY) { // A* if (!(startX==targetX && startY==targetY)) { int[] tileX = new int[PATH_FINDING_MAX_STEPS]; int[] tileY = new int[PATH_FINDING_MAX_STEPS]; int[] fscore = new int[PATH_FINDING_MAX_STEPS]; int[] gscore = new int[PATH_FINDING_MAX_STEPS]; int[] openList = new int[PATH_FINDING_MAX_STEPS]; int[] tileParent = new int[PATH_FINDING_MAX_STEPS]; int[] unexploredCellRun = new int[PATH_FINDING_MAX_STEPS]; int[][] tileIsClosed = new int[MAP_SIZE][MAP_SIZE]; int currentIndex = -1; int openListSize=1; int tileId=1; tileX[0]=targetX; tileY[0]=targetY; fscore[0]=1; gscore[0]=1; do { int currentBestIndex=-1; int currentBestScore=Integer.MAX_VALUE; // Look for the lowest F cost square on the open list for (int ii=0;ii<openListSize;ii++) { if (fscore[openList[ii]]<currentBestScore) { currentBestScore=fscore[openList[ii]]; currentBestIndex=ii; } } if (currentBestIndex==-1) { break; } currentIndex=openList[currentBestIndex]; int currentTileX=tileX[currentIndex]; int currentTileY=tileY[currentIndex]; // found path if (startX==currentTileX && startY==currentTileY) { break; } // if not in closed list if (tileIsClosed[currentTileX][currentTileY]==0) { // Switch it to the closed list. tileIsClosed[currentTileX][currentTileY]=1; // remove from openlist openList[currentBestIndex]=openList[--openListSize]; // add neigbours to the open list if necessary for (int i=0;i<4;i++) { int surroundingCurrentTileX=currentTileX+offsets[i][0]; int surroundingCurrentTileY=currentTileY+offsets[i][1]; if (surroundingCurrentTileX>=boundMinX-1 && surroundingCurrentTileX<=boundMaxX+1 && surroundingCurrentTileY>=boundMinY-1 && surroundingCurrentTileY<=boundMaxY+1 ) { tileX[tileId]=surroundingCurrentTileX; tileY[tileId]=surroundingCurrentTileY; if (map[surroundingCurrentTileX][surroundingCurrentTileY]==0) { unexploredCellRun[tileId]=0; } else if (map[surroundingCurrentTileX][surroundingCurrentTileY]=='!') { continue; } else { unexploredCellRun[tileId]=unexploredCellRun[currentIndex]+1; } int surroundingCurrentGscore=gscore[currentIndex]+visitCount[surroundingCurrentTileX][surroundingCurrentTileY]+1+((int) (unexploredCellRun[tileId]*10)); gscore[tileId]=surroundingCurrentGscore; fscore[tileId]=surroundingCurrentGscore+Math.abs( surroundingCurrentTileX-startX)+Math.abs( surroundingCurrentTileY-startY); tileParent[tileId]=currentIndex; openList[openListSize++]=tileId++; } } } else { // remove from openlist openList[currentBestIndex]=openList[--openListSize]; } } while(true); if (tileX[tileParent[currentIndex]]-startX<0) return (3 <<24) + currentIndex; else if (tileX[tileParent[currentIndex]]-startX>0) return (1 <<24) + currentIndex; else if (tileY[tileParent[currentIndex]]-startY<0) return (0 <<24) + currentIndex; else if (tileY[tileParent[currentIndex]]-startY>0) return (2 <<24) + currentIndex; } throw new RuntimeException("Path finding failed"); } /** * Reads a line of text from the input stream. Blocks until a new line character is read. * NOTE: This method should be used in favor of BufferedReader.readLine(...) as BufferedReader buffers data before performing * text line tokenization. This means that BufferedReader.readLine() will block until many game frames have been received. * @param in a InputStream, nominally System.in * @return a line of text or null if end of stream. * @throws IOException */ private static String readLine(InputStream in) throws IOException { StringBuilder sb = new StringBuilder(); int readByte = in.read(); while (readByte>-1 && readByte!= '\n') { sb.append((char) readByte); readByte = in.read(); } return readByte==-1?null:sb.toString(); } }

java BoundryFindingBot
 

Alconacravany


Рег
06 Feb, 2014

Тем
59

Постов
226

Баллов
561
Тем
403,760
Комментарии
400,028
Опыт
2,418,908

Интересно