我正在尝试使用python解决A child's play上的编码挑战Codingame。 使用我的程序,我可以通过前两个测试用例,但是当测试需要大量循环时,我的程序将超时。我可以改善什么?
要完全理解问题,需要提供挑战的详细信息,但由于不确定是否允许,我不想在此处复制和粘贴挑战。
我试图用我的话来解释这个问题。鉴于此输入:
12 6
987
...#........
...........#
............
............
..#O........
..........#.
O
是字符的起点。#
是您无法踩到的墙.
是角色可以踩到的地方在此示例中,w = 12(矩阵的宽度)和h = 6(矩阵的高度)。 n = 987是角色必须采取的步骤数。
必需的输出:
在这种情况下,7 1
在给定移动次数之后字符的位置
规则:
当我用那个测试用例运行程序时,我得到正确的结果。
改为使用以下测试用例:
14 10
123456789
..#...........
....#..#......
.#O.....#.....
..............
..............
.......##...#.
............#.
.#........###.
.#.#..........
..............
我得到:
失败 进程已超时。这可能意味着您的解决方案不够优化,无法处理某些情况。
这是我设法编写的代码:
import math
import sys
def find_initial_position(maze, w, h):
for i in range(0, h):
for j in range(0,w):
if maze[i][j] == "O":
return [i, j]
return -1
def can_move(maze, direction, x, y):
if direction == "U":
if maze[ x -1 ][ y ] == "#":
return False
elif direction == "R":
if maze[ x ][ y + 1 ] == "#":
return False
elif direction == "D":
if maze[ x +1 ][ y ] == "#":
return False
elif direction == "L":
if maze[ x ][ y-1 ] == "#":
return False
return True
def turn_clockwise(direction):
directions = ["U", "R", "D", "L"]
return directions[ (directions.index(direction) + 1) % 4 ]
def move(direction, coordinates):
if direction == "U":
coordinates[0] -=1
elif direction == "R":
coordinates[1] +=1
elif direction == "D":
coordinates[0] +=1
elif direction == "L":
coordinates[1] -=1
def main():
w, h = [int(i) for i in input().split()]
n = int(input())
maze = []
direction = "U"
position = [0, 0]
for i in range(h):
line = input()
maze.append(line)
position = find_initial_position(maze, w, h)
for i in range(0, n):
while not can_move(maze, direction, position[0], position[1]):
direction = turn_clockwise(direction)
move(direction, position)
print( "%(x)d %(y)d" %{"x": position[1], "y": position[0]} )
main()
答案 0 :(得分:0)
我通过以下方式简化了代码,使代码更具可读性:
str.index()
查找初始位置。 以下结果... 但是,确实,这没有说明重点。
如果您在所有测试用例中都看到“迷宫”,则说明是“机器人”以矩形模式(也可能是更复杂的模式)在四个#
障碍物之间循环弹跳。因此,使用您的方法,您正在计算和重新计算相同的短步动作,数百万亿次。即使最长的循环不可能有比小迷宫中的平方数(数量级)更多的移动。
您应该尝试做的是连续记录到目前为止已完成的所有移动(位置,方向)。而且,如果(或者更确切地说,是何时)您最终到达了以前所处的位置(方向),那么您已经完成了一个完整的周期。无需计算更多的移动。假设您的循环序列的长度为 L ,并且规定的移动总数为 n ,那么最终位置将为序列元素编号 L { {3}} n (或类似的东西,尽管出现了一个错误)。
import sys
import numpy as np
def is_obstacle(maze, position):
return maze[position[0]][position[1]] == '#'
def main():
w, h = [int(i) for i in input().split()]
n = int(input())
# Load maze
maze = []
for i in range(h):
line = input()
maze.append(line)
if 'O' in line:
# Found initial position
position = np.array([i, line.index('O')])
# Initial direction
direction = np.array([-1,0])
# Define actions
turn_clockwise = np.array([[0,-1],[1,0]])
# Walk maze
for i in range(n):
while is_obstacle(maze, position + direction):
direction = direction @ turn_clockwise
position = position + direction
print( "%(x)d %(y)d" %{"x": position[1], "y": position[0]} )
main()