input:
OOOOO
XOOXO
OOOOO
OOOOO
OOOOX
output:
1 :
RRRRD
XDLXD
DLULL
DRDRO
RURUX
...
12 :
RDRRD
XDUXD
DLULD
DRDUO
RURUX
7개의 풀이가 있습니다.
RLUD 대신 화살표(?)로 해 봤습니다.
def find_path(x, y, move_cnt):
global map_, X, Y, MAX_MOVE
if move_cnt >= MAX_MOVE:
for row in map_:
print(''.join(row))
print()
else:
for dx, dy, dir_ch in [(0, -1, '<'), (0, 1, '>'), (1, 0, 'v'), (-1, 0, '^')]:
x2, y2 = x + dx, y + dy
if 0 <= x2 < X and 0 <= y2 < Y and map_[x2][y2] is 'O':
map_[x][y] = dir_ch
find_path(x2, y2, move_cnt + 1)
map_[x][y] = 'O'
map_ = [list(row) for row in input_str.split('\n')]
X, Y= len(map_), len(map_[0])
MAX_MOVE = X * Y - input_str.count('X') - 1
find_path(0, 0, 0)
def _find_start_point():
for i,j in enumerate(board):
if 'O' in j: return i, j.index('O')
print('시작점을 찾을 수 없음')
def print_board():
for i in board: print(''.join(i))
print()
def fillgame():
dr = ((0,1,'R'), (1,0,'D'), (0,-1,'L'), (-1,0,'U'))
stc = [[_find_start_point(), -1]]
while stc:
stc[-1][1] += 1
if stc[-1][1] < 4:
dx, dy, s, x, y = *dr[stc[-1][1]], *stc[-1][0]
if 0<= x+dx <len(board) and 0<= y+dy <len(board[0]) and board[x+dx][y+dy] == 'O':
board[x][y] = s
stc.append([(x+dx, y+dy), -1])
if str(board).count('O') == 1:
yield
stc.pop()
board[x][y] = 'O'
else:
x, y = stc[-1][0]
board[x][y] = 'O'
stc.pop()
test = '''\
OOOOO
XOOXO
OOOOO
OOOOO
OOOOX'''
board = [list(i) for i in test.splitlines()]
for i,j in enumerate(fillgame()):
print(i+1,':')
print_board()
Ruby
trav = ->r,c,maze do
return [maze] if maze.join.count("O") == 1
[["D", r+1,c], ["U", r-1,c], ["L", r,c-1], ["R", r,c+1]].
select {|_,*pos| pos.none?(&:negative?) && maze[pos[0]] && maze[pos[0]][pos[1]] == "O"}.
map {|log,*pos| pos << maze.map(&:dup).tap {|e| e[r][c] = log}}.flat_map {|e| trav[*e]}
end
find_trails = ->maze { puts trav[0, 0, maze.split].map.with_index(1) {|t,i| ["#{i} :", t, ""]}}
Test
input = <<-eos
OOOOO
XOOXO
OOOOO
OOOOO
OOOOX
eos
end_of_result = <<-eos
12 :
RRRRD
XDLXD
DLULL
DRDRO
RURUX
eos
# output(.. ending_with..).to_stdout은 rspec test framework의 matcher들 입니다.
expect { find_trails[input] }.to output(a_string_ending_with(end_of_result)).to_stdout
from copy import deepcopy
map_ ='''OOOOO
XOOXO
OOOOO
OOOOO
OOOOX'''
map_list_1 = [list(i) for i in map_.split('\n')]
def check(data) : # 완료 여부 확인
count = 0
for line in data[:-1] :
if 'O' in line : count += line.count('O')
if count <= 1 : return True
else : return False
def search_(li) :
queue, count = [li+[[0, 0]]], 0
while len(queue) != 0 :
head = queue.pop(0)
if check(head) == True : # 성공적으로 탐색을 완료한 경우 그 결과를 출력
count += 1
print('\n\n'+str(count)+':')
for RL in head[:-1] :
print(''.join(RL))
head = 0
continue
for cond in [(-1, 0, 'L', head[-1][0]), (1, 0, 'R', len(head[0])-1-head[-1][0]), (0, -1, 'U', head[-1][1]), (0, 1, 'D', len(head)-2-head[-1][1])] : # 순서대로 dx, dy, 방향, 좌표가 데이터 범위 내 있을 조건
head_1 = deepcopy(head)
if cond[3] > 0 and head_1[head_1[-1][1]+cond[1]][head_1[-1][0]+cond[0]] == 'O' : # 좌표가 데이터 범위 내에 있으면서 탐색 가능한 경우
head_1[head_1[-1][1]][head_1[-1][0]] = cond[2] #'O'값 방향으로 대체
head_1[-1][0], head_1[-1][1] = head_1[-1][0]+cond[0], head_1[-1][1]+cond[1] #좌표 갱신
queue.append(head_1) # queue의 마지막에 추가
search_(map_list_1)
queue를 활용하였습니다. mutable한 객체에 대한 개념이 없었는데 이 문제 덕분에 아주 좋은 것을 배웠습니다.
결과중 처음 것만 아래에 작성하겠습니다.
1:
RRRRD
XDLXD
DLULL
DRDRO
RURUX
inp="""OOOOO
XOOXO
OOOOO
OOOOO
OOOOX"""
lst=[list(ln) for ln in inp.split("\n")]
maxX,maxY=len(lst[0]),len(lst) #x축의 길이, y축의 길이
notry,nom=0,0 #시행 차수, 움직인 횟수
maxmove=maxX*maxY-inp.count("X")-1 #최대로 움직일 수 있는 횟수=x축 길이*y축 길이-격자의 X 개수-마지막 O 1개
def solve(y,x):
global maxX,maxY,notry,maxmove,nom
if nom==maxmove: #움직인 횟수가 최대 움직일 수 있는 횟수와 같으면 시행 차수를 +1하고 출력
notry+=1
print(notry)
for ln in lst:
for cmp in ln:
print("%1s"%cmp, end="")
print()
else:
for dx,dy,dr in [(1,0,"R"),(-1,0,"L"),(0,1,"D"),(0,-1,"U")]:
nx,ny=x+dx,y+dy
if 0<=nx<maxX and 0<=ny<maxY and lst[ny][nx]=="O":
lst[y][x],nom=dr,nom+1
solve(ny,nx)
lst[y][x],nom="O",nom-1
solve(0,0)
// Rust
// 어쨌든 결과는 나오네요...
fn lattice_fill() {
let lattice = "OOOOO
XOOXO
OOOOO
OOOOO
OOOOX";
let mut arr = vec![];
for line in lattice.lines() {
arr.push(line.trim().chars().collect::<Vec<_>>());
}
if let Some(_) = step(arr, (0,0)) {
}
}
fn step(arr_:Vec
let mut arr = arr_.clone();
let l = arr.len();
let mut action = vec![];
if i==0 {
if arr[i+1][j] == 'O' {action.push('D');}}
else if i==l-1 {
if arr[i-1][j] == 'O' {action.push('U');}}
else {
if arr[i+1][j] == 'O' {action.push('D');}
if arr[i-1][j] == 'O' {action.push('U');}}
if j==0 {
if arr[i][j+1] == 'O' {action.push('R');}}
else if j==l-1 {
if arr[i][j-1] == 'O' {action.push('L');}}
else {
if arr[i][j-1] == 'O' {action.push('L');}
if arr[i][j+1] == 'O' {action.push('R');}}
if action.is_empty() {
let mut cnt=0;
for line in &arr { cnt += line.iter().filter(|&c| *c=='O').count();}
if cnt <= 1 {
println!("{:?}", (i,j));
print_vec(&arr);
return Some(arr.clone());} //ok
else { return None;} //fail
}
for a in action {
arr[i][j] = a;
if a=='U' {
if let Some(_) = step(arr.clone(), (i-1, j)) {}}
else if a=='D' {
if let Some(_) = step(arr.clone(), (i+1, j)) {}}
else if a=='L' {
if let Some(_) = step(arr.clone(), (i, j-1)) {}}
else {
if let Some(_) = step(arr.clone(), (i, j+1)) {}}
}
None
}
fn print_vec(vec: &Vec
for line in vec {
let mut result = String::new();
result.extend(line);
println!("{}", result);
}
}
using System;
namespace solution
{
class Program
{
public static int maxRow;
public static int maxCol;
public static int maxCnt;
public static int N;
static void Main(string[] args)
{
char[,] input = { {'O','O','O','O','O'}, {'X','O','O','X','O'},
{'O','O','O','O','O' }, {'O','O','O','O','O' }, {'O','O','O','O','X' } };
maxRow = 5;
maxCol = 5;
maxCnt = maxRow * maxCol;
for (int r = 0; r < maxRow; r++)
{
for (int c = 0; c < maxCol; c++)
if (input[r, c] == 'X')
maxCnt--;
}
N = 1;
findPath(0, 0, 1, input);
}
private static void findPath(int r, int c, int cnt, char[,] input)
{
if(cnt >= maxCnt)
{
printInput(input);
return;
}
int[] dr = { -1, 0, 1, 0 };
int[] dc = { 0, 1, 0, -1 };
char[] dir = { 'U', 'R', 'D', 'L' };
for (int i = 0; i < 4; i++)
{
int R = r + dr[i];
int C = c + dc[i];
if(0<=R && R<maxRow && 0<=C && C<maxCol && input[R, C] == 'O')
{
input[r, c] = dir[i];
findPath(R, C, cnt + 1, input);
input[r, c] = 'O';
}
}
}
private static void printInput(char[,] input)
{
Console.WriteLine("\n {0} :", N++);
for (int r = 0; r < maxRow; r++)
{
for (int c = 0; c < maxCol; c++)
{
Console.Write(" {0}", input[r,c]);
}
Console.WriteLine();
}
}
}
}