如何创建在下面指定的管网中查找连接的接收器的练习所需的代码? [已关闭]

问题描述 投票:0回答:1

管道系统中连接的水槽。

在本练习中,您将编写代码来解决问题。您的代码必须使用 Python(首选)或 JavaScript 编写 - 其他语言的解决方案将不被接受!您可以使用任何您想要的 IDE 编写代码。

问题:

我们有一个由二维矩形单元格表示的管道系统。网格中的单元格中有三种不同类型的对象,每个单元格有 0 个对象或 1 个对象:

来源:系统中有1个来源。它由星号字符“*”表示。

Sinks:系统中有任意数量的Sinks。它们各自由不同的大写字母表示(“A”、“B”、“C”等)。

管道:有10种不同形状的管道,用以下字符表示:'═'、'║'、'╔'、'╗'、'╚'、'╝'、'╠'、'╣'、' ╦', '╩'.

请注意,每个管道在其单元的 2 或 3 侧都有开口。

如果两个相邻单元在其共享边缘都有管道开口,则两个相邻单元被连接。

例如,两个单元“╩╦”通过共享边相互连接。这两个单元格“╩╔”并未通过其共享边相互连接,但它们仍可能通过穿过它们周围其他单元格的路径连接。

将源和汇视为在其所有边缘都有管道开口。例如,两个单元格“A╦”通过其共享边连接,但两个单元格“B╔”不通过其共享边直接连接。

一个接收器可以通过另一个接收器连接到源。例如,在简单的管道系统 '* ╦ X Y ═ Z' 中,所有三个接收器都连接到源。

您的目标是编写一个函数来确定给定管道系统中哪些接收器连接到源。

作为示例,请考虑以下管道系统图示:

* ╣   ╔ ═ A
  ╠ ═ ╝    
  C   ╚ ═ B

在此系统中,源连接到接收器 A 和 C,但未连接到接收器 B。

系统由输入文本文件指定,该文件包含指示网格中对象位置的数据行。每行有三段信息,用空格字符分隔:

代表对象的字符(星号、大写字母或竖线)。

网格中对象的 x 坐标。该值的最小值为 0。

网格中对象的 y 坐标。该值的最小值为 0。

下面是指定上述示例管道系统的输入文件的内容。文件中行的顺序是任意的,因此可以按任何顺序给出行。坐标 (0, 0) 将始终对应于网格的同一个角,如本例所示,因此请确保了解 x 和 y 坐标在哪些方向上增加。

* 0 2
C 1 0
╠ 1 1
╣ 1 2
═ 2 1
╚ 3 0
╝ 3 1
╔ 3 2
═ 4 0
═ 4 2
B 5 0
A 5 2

规格:

您的函数必须用 Python(首选)或 JavaScript 编写。

该函数应接受一个参数,该参数是一个包含输入文本文件的文件路径的字符串。

该函数应返回(而不是打印)您的答案作为一串大写字母,按字母顺序排列,没有其他字符。例如,如果代码确定接收器“P”、“B”、“J”和“T”是连接到源的唯一接收器,则您的代码应返回字符串“BJPT”。

请提交您的函数的完整代码。

我在生成代码时遇到挑战。

javascript python python-3.x
1个回答
0
投票

在解决问题陈述的代码建议下面,您可以使用进一步的示例进行测试,以最终解决任何剩余的问题(如果有)。 查看here提供的代码解释,以及所使用的变量名称的可理解含义对于了解所使用的方法非常有帮助:

from collections import deque

def find_connected_sinks(file_path, printGrid=False):
    def print_grid(grid, max_x, max_y):
        for y in range(max_y + 1):
            row = ""
            for x in range(max_x + 1):
                row += grid.get((x, y), ' ') + " "
            print(row)
    
    # Read and parse the input file
    with open(file_path, 'r') as file:
        lines = file.readlines()
    
    # Determine the maximum x and y coordinates
    x_coords = [int(line.strip().split()[1]) for line in lines]
    y_coords = [int(line.strip().split()[2]) for line in lines]
    max_x = max(x_coords)
    max_y = max(y_coords)

    # Initialize the grid and objects dictionary
    grid = {}
    sinks = set()
    source = None
    
    # Parse each line to fill the grid, reversing the y-coordinates
    for line in lines:
        parts = line.strip().split()
        obj = parts[0]
        x, y = int(parts[1]), int(parts[2])
        reversed_y = max_y - y  # Reverse the y-coordinate
        grid[(x, reversed_y)] = obj
        if obj == '*':
            source = (x, reversed_y)
        elif obj.isupper():
            sinks.add((x, reversed_y))
    
    # Optionally print the grid
    if printGrid:
        print_grid(grid, max_x, max_y)
    
    # Directions for moving in the grid (right, left, down, up)
    directions = [(0, 1), (0, -1), (1, 0), (-1, 0)]
    dictDirections={"right":(0, 1), "left":(0, -1), "down":(1, 0), "up":(-1, 0)}
    
    # Pipe connections
    pipe_connections = {
        '═': [(1, 0), (-1, 0)],
        '║': [(0, 1), (0, -1)],
        '╔': [(1, 0), (0, 1)],
        '╗': [(-1, 0), (0, 1)],
        '╚': [(-1, 0), (0, 1)],
        '╝': [(-1, 0), (0, -1)],
        '╠': [(0, -1), (0, 1), (1, 0)],
        '╣': [(0, -1), (0, 1), (-1, 0)],
        '╦': [(-1, 0), (1, 0), (0, 1)],
        '╩': [(-1, 0), (1, 0), (0, -1)]
    }
    sink_connections = source_connections = directions
        
    def is_connected(from_cell, to_cell, direction):
        if (from_cell == '*' or from_cell.isupper()) and to_cell in pipe_connections:
            return (-direction[0], -direction[1]) in pipe_connections[to_cell]
        if (to_cell == '*' or to_cell.isupper()) and from_cell in pipe_connections:
            return direction in pipe_connections[from_cell]
        if (from_cell == '*' or from_cell.isupper()) and (to_cell == '*' or to_cell.isupper()):
            return True
        if from_cell in pipe_connections and to_cell in pipe_connections:
            return direction in pipe_connections[from_cell] and (-direction[0], -direction[1]) in pipe_connections[to_cell]

        return False
    
    def inverted_direction( direction ):
        return ( -direction[0], -direction[1] )
        
    # BFS to find all connected sinks
    visited = set()
    queue = deque([source])
    connected_sinks = set()
    
    print(f"{sinks=}" )
    print(f"while: {queue=} == {[grid[item] for item in queue]}")    

    while queue:
        current = queue.popleft()
        visited.add(current)
        
        print(f"    still in {queue=},  {current=} {grid[current]=} {visited=} == {[ grid[item] for item in visited]}" )

        if current in sinks:
            connected_sinks.add(current)
        
        for direction in directions:
            next_cell = (current[0] + direction[0], current[1] + direction[1])
            print(f"        {direction=}  {next_cell=}")
            if next_cell in grid and next_cell not in visited:
                current_pipe = grid.get(current)
                next_pipe = grid.get(next_cell)
                
                print(f"            {current_pipe=}  {next_pipe=} {direction=} {is_connected(current_pipe, next_pipe, direction)=}")
                if is_connected(current_pipe, next_pipe, direction):
                    queue.append(next_cell)

        print(f"while: {queue=} == {[grid[item] for item in queue]}")    

    # Extract sink labels and sort them alphabetically
    connected_sink_labels = ''.join(sorted(grid[x, y] for x, y in connected_sinks))
    
    return connected_sink_labels
## -----------------------------------
# Example usage
file_path = 'connectedSinks.txt'  # Replace with the actual path to your input file
connectedSinks = find_connected_sinks(file_path, printGrid=True)
print(" --- ")
print(f"{connectedSinks = }")

代码打印有关自身进度的有价值的信息,这进一步帮助理解代码的作用并为给定的示例得出正确的结果。

© www.soinside.com 2019 - 2024. All rights reserved.