ThoughtWorks 2019届校招算法、软开迷宫(maze)生成题目

ThoughtWorks 2019届校招算法、软开迷宫(maze)生成题目

1.校招题目

2.代码


1.校招题目

用计算机生成迷宫是一个很有趣的任务。我们可以用道路网格(Road Grid)来表示迷宫的道路,那么3x3的道路网格(图-1左)可以对应一个7x7的渲染网格(Render Grid)——图-1右的方式(迷宫的墙是灰色的,道路是白色的):


                                                                     图-1 3 x 3 的 道路网格 及其 渲染网格
如果我们将迷宫 道路网格 两个相邻的 cell 连通,则可以打通道路。如 图 -2 所示:


                                                                 图-2 3 x 3 连通迷宫的 道路网格 和 渲染网格
连通 道路网格 有如下的约束条件:
● 每一个 cell 只能够直接与相邻正南、正北、正东、正西的 cell 连通。不能够和其他的 cell 连通。
● 两个 cell 之间的连通一定是双向的。即 cell(0,0) 和 cell(1,0) 连通等价于 cell(1,0) 和cell(0,0) 的连通。
要求1:将迷宫渲染为字符串
现在我们希望你书写程序,将给定迷宫的 道路网格 ,渲染为字符串输出。例如,其使用方式如下(伪代码,仅做演示,实际实现时请应用实际语言的编程风格)
Maze maze = MazeFactory.Create(command);
String mazeText = maze.Render();
其中 command 是一个字符串。它的定义如下:
● 第一行是迷宫道路网格的尺寸。例如 3 x 3 的迷宫为3 3 ,而 5 x 4 的迷宫为5 4。
● 第二行是迷宫道路网格的连通性定义。如果cell(0,1)和cell(0,2)是连通的,则表示为:
0,1 0,2 ,多个连通以分号 ; 隔开。
例如,如果给定输入:
3 3
0,1 0,2;0,0 1,0;0,1 1,1;0,2 1,2;1,0 1,1;1,1 1,2;1,1 2,1;1,2 2,2;2,0 2,1
则输出字符串为(如果当前 渲染网格 为墙壁,则输出 [W] 如果为道路则输出 [R]):


要求2:检查输入的有效性
在处理输入的时候需要检查输入的有效性。需要检查的有效性包括如下的几个方面:
● 无效的数字:输入的字符串无法正确的转换为数字。此时,该函数的输出为字符串 ”Invalidnumber format . ”
● 数字超出预定范围:数字超出了允许的范围,例如为负数等。此时,该函数的输出为字符串”Number out of range . ”
● 格式错误:输入命令的格式不符合约定。此时,该函数的输出为字符串 ”Incorrect command format . ”
● 连通性错误:如果两个网格无法连通,则属于这种错误。此时,该函数的输出为字符串 ”Maze format error.”
当多个问题同时出现时,报告其中一个错误即可。

2.代码

题目不难,文档倒是要花功夫写,直接贴代码吧:

'''
===========================================
  @author:  jiaxin
  @time:    2018/8/9 0009   10:00
===========================================
'''

import numpy as np


def draw_maze(row, col, road):
    '''
    :param row: 道路网格的行
    :param col: 道路网格的列
    :param road: cell之间的连通关系
    :return final_maze: 生成的迷宫
    '''

    render_row = 2 * row + 1
    render_col = 2 * col + 1

    final_maze = []
    render_num = np.zeros((2 * row + 1, 2 * col + 1))

    for i in range(1, render_row, 2):
        for j in range(1, render_col, 2):
            render_num[i][j] = 1

    for i in road:
        if i[0] == i[2]:
            render_num[i[0] * 2 + 1, min(i[1], i[3]) * 2 + 1:max(i[1], i[3]) * 2 + 2] = 1
        elif i[1] == i[3]:
            render_num[min(i[0], i[2]) * 2 + 1:max(i[0], i[2]) * 2 + 2, i[1] * 2 + 1] = 1

    render_alpha = [['[W]'] * (2 * col + 1) for _ in range(2 * row + 1)]
    for i, coor_row in enumerate(render_num):
        for j, single_coor in enumerate(coor_row):
            if single_coor:
                render_alpha[i][j] = '[R]'
    for i in render_alpha:
        final_maze.append(' '.join(i))

    return final_maze


def check():
    # 使用try_except语句,若道路网格的尺寸输入错误,如不是数字,不是两个数字,或是由其它符号分隔开的,则返回'Invalid number format.'
    try:
        print('请输入迷宫道路网格的尺寸:')
        row, col = [int(i) for i in input().split()]
    except:
        return 'Invalid number format.'

    try:
        # source_road为用户输入的:迷宫道路网格的连通性定义,如果输入中包含除正确格式以外的格式,如坐标不是数字,则返回'Invalid number format.'
        print('请输入迷宫道路网格的连通性定义:')
        source_road = input()
        str_road = []
        coor = []
        alpha = []
        for i in source_road.split(';'):
            str_road.append(i.split())
            [coor.append(int(kk)) for j in i.split() for kk in j.split(',') if kk.lstrip('-').isdigit()]
            [alpha.append(True) for j in i.split() for kk in j.split(',') if kk.isalpha()]
        if True in alpha:
            return 'Invalid number format.'
    except:
        return 'Invalid number format.'

    # 连通域的每个小部分都是4个坐标,如果有多余的坐标,证明没有输入完全,则返回'Incorrect command format.'
    # 而同时检测coor和str_road,是为了防止像这类有多个分号的情况,如:0,1 0,2;0,0 ;1,0;
    if len(coor) % 4 != 0 or len(coor) // 4 != len(str_road):
        return 'Incorrect command format.'

    # 检测数字的范围,范围为0~1e6,并且连通cell的横纵坐标必须小于道路网格的行列数
    if 0 < row < 1e6 and 0 < col < 1e6 and max(coor) < row and max(coor) < col and 0 <= min(coor) and 0 <= min(
            coor):
        pass
    else:
        return 'Number out of range.'

    road = [coor[4 * i:4 * i + 4] for i in range(len(coor) // 4)]
    # 检测连通是否正确,只能够直接与相邻正南、正北、正东、正西的cell连通,其他的位置都不能连接,即两个cell的横纵坐标至少有一者是相等的
    for i in road:
        if i[0] == i[2] or i[1] == i[3]:
            pass
        else:
            return 'Maze format error.'

    print("是否使用机器人?如果使用请输入指令,不输入则输入回车即可")
    robot = input()
    robot_coor = None
    try:
        robot = robot.split()
        if len(robot) == 1:
            robot_coor = robot[0].split(',')
        else:
            robot_coor = [int(i) for i in robot[0].split(',')]
            robot_coor.append(robot[1])
    except:
        pass

    return (row, col, road, robot_coor)


if __name__ == "__main__":

    user_input = check()

    if isinstance(user_input, tuple):
        row, col, road = user_input
        maze = draw_maze(row, col, road)
        for i in maze:
            print(i)
    else:
        print(user_input)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

任博啥时候能毕业?

有用的话,请博主喝杯咖啡吧!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值