244 lines
7.4 KiB
Python
244 lines
7.4 KiB
Python
|
|
from meshlib import mrmeshpy
|
|
from meshlib import mrmeshnumpy
|
|
import numpy as np
|
|
|
|
def check_x(path):
|
|
points = np.ndarray(shape=(len(path),2), dtype=np.float32, buffer=np.array(path))
|
|
polyline = mrmeshnumpy.polyline2FromPoints(points)
|
|
selfIntersections = mrmeshpy.findSelfCollidingEdges(polyline)
|
|
if selfIntersections.size() > 0:
|
|
return False
|
|
return True
|
|
|
|
def level1():
|
|
output=[]
|
|
map = []
|
|
with open("level1_5.in") as f:
|
|
n=int(f.readline())
|
|
for i in range(n):
|
|
map.append(list(f.readline()))
|
|
printMap(map)
|
|
n_nr = int(f.readline())
|
|
for i in range(n_nr):
|
|
x,y = f.readline().split(',')
|
|
x=int(x)
|
|
y=int(y)
|
|
s=map[y][x]
|
|
output.append(s)
|
|
return output
|
|
|
|
def printMap(map):
|
|
for i in range(len(map)):
|
|
for j in range(len(map[i])):
|
|
print(map[i][j], end=' ')
|
|
print()
|
|
|
|
def readMap():
|
|
map = []
|
|
with open("level1.in") as f:
|
|
n=int(f.readline())
|
|
for i in range(n):
|
|
map.append(f.readline().split())
|
|
|
|
return (n,map)
|
|
|
|
#implement the disktra for the map given 2 points find if they are connected return true or false, they are connected only on
|
|
def disktra(map, x1, y1, x2, y2):
|
|
priority_queue = [(x1,y1)]
|
|
visited = []
|
|
while priority_queue:
|
|
current_node = priority_queue.pop(0)
|
|
visited.append(current_node)
|
|
x1 = current_node[0]
|
|
y1 = current_node[1]
|
|
if current_node[0] == x2 and current_node[1] == y2:
|
|
return True
|
|
if x1 > 0 and map[x1-1][y1] == '1' and (x1-1,y1) not in visited and (x1-1,y1) not in priority_queue:
|
|
priority_queue.append((x1-1,y1))
|
|
if x1 < len(map) and map[x1+1][y1] == '1' and (x1+1,y1) not in visited and (x1+1,y1) not in priority_queue:
|
|
priority_queue.append((x1+1,y1))
|
|
if y1 > 0 and map[x1][y1-1] == '1' and (x1,y1-1) not in visited and (x1,y1-1) not in priority_queue:
|
|
priority_queue.append((x1,y1-1))
|
|
if y1 < len(map[0]) and map[x1][y1+1] == '1' and (x1,y1+1) not in visited and (x1,y1+1) not in priority_queue:
|
|
priority_queue.append((x1,y1+1))
|
|
|
|
return False
|
|
|
|
# Pseudo-code to find and return a cycle in a 2D matrix graph using DFS
|
|
|
|
def findCycle(graph):
|
|
# Create a 2D matrix to store visited vertices
|
|
visited = [[False for _ in range(len(graph[0]))] for _ in range(len(graph))]
|
|
|
|
# Define possible directions (up, down, left, right)
|
|
directions = [(0, 1), (0, -1), (1, 0), (-1, 0)]
|
|
|
|
# Iterate through all vertices and start a DFS from unvisited vertices
|
|
for i in range(len(graph)):
|
|
for j in range(len(graph[0])):
|
|
if not visited[i][j]:
|
|
path = [] # Store the path during DFS
|
|
if dfsFindCycle(graph, visited, i, j, -1, -1, directions, path):
|
|
return path # Cycle found
|
|
|
|
return None # No cycle found
|
|
|
|
def dfsFindCycle(graph, visited, x, y, parent_x, parent_y, directions, path):
|
|
visited[x][y] = True
|
|
path.append((x, y)) # Add the current vertex to the path
|
|
|
|
for dx, dy in directions:
|
|
new_x, new_y = x + dx, y + dy
|
|
if isInsideGrid(new_x, new_y, graph) and not visited[new_x][new_y] and graph[new_x][new_y] == 1:
|
|
if (new_x, new_y) in path:
|
|
# Cycle found, return the path
|
|
return True
|
|
if dfsFindCycle(graph, visited, new_x, new_y, x, y, directions, path):
|
|
return True
|
|
|
|
path.pop() # Remove the current vertex from the path if no cycle is found
|
|
return False
|
|
|
|
def isInsideGrid(x, y, graph):
|
|
return 0 <= x < len(graph) and 0 <= y < len(graph[0])
|
|
|
|
|
|
def level2():
|
|
output=[]
|
|
map = []
|
|
with open("level2_.in") as f:
|
|
n=int(f.readline())
|
|
for i in range(n):
|
|
map.append(list(f.readline()))
|
|
map=transpose(map)
|
|
n_nr = int(f.readline())
|
|
for i in range(n_nr):
|
|
c1,c2 = f.readline().split(' ')
|
|
x1,y1 = c1.split(',')
|
|
x1=int(x1)
|
|
y1=int(y1)
|
|
x2,y2 = c2.split(',')
|
|
x2=int(x2)
|
|
y2=int(y2)
|
|
s=disktra(map,x1,y1,x2,y2)
|
|
if s:
|
|
output.append('SAME')
|
|
else:
|
|
output.append('DIFFERENT')
|
|
return output
|
|
|
|
def transpose(map):
|
|
new_map = []
|
|
for i in range(len(map[0])):
|
|
new_map.append([])
|
|
for j in range(len(map)):
|
|
new_map[i].append(map[j][i])
|
|
return new_map
|
|
|
|
|
|
|
|
def level_3():
|
|
output=[]
|
|
map = []
|
|
with open("level3_1.in") as f:
|
|
n=int(f.readline())
|
|
for i in range(n):
|
|
map.append(list(f.readline()))
|
|
printMap(map)
|
|
n_nr = int(f.readline())
|
|
for i in range(n_nr):
|
|
path = f.readline().split(' ')
|
|
for j in range(len(path)):
|
|
path[j] = path[j].split(',')
|
|
path[j][0] = int(path[j][0])
|
|
path[j][1] = int(path[j][1])
|
|
path[j] = tuple(path[j])
|
|
s=check_x(path)
|
|
if s:
|
|
output.append('VALID')
|
|
else:
|
|
output.append('INVALID')
|
|
return output
|
|
|
|
def check_path(path):
|
|
for index, c in enumerate(path):
|
|
print(index)
|
|
print(c)
|
|
x = c[0]
|
|
y = c[1]
|
|
if path.count((x,y))>1:
|
|
return False
|
|
if index == len(path)-1:
|
|
break
|
|
next = path[index+1]
|
|
if x == next[0]:
|
|
continue
|
|
if y == next[1]:
|
|
continue
|
|
if (x,next[1]) in path :
|
|
index_of_closest = path.index((x,next[1]))+1
|
|
next_close = path[index_of_closest]
|
|
if next_close[1] == next[1]:
|
|
return False
|
|
if next_close[0] == x:
|
|
continue
|
|
if next_close[0]-x and next_close[1] == y:
|
|
return False
|
|
if (next[0],y) in path:
|
|
index_of_closest = path.index((next[0],y))+1
|
|
next_close = path[index_of_closest]
|
|
if next_close[0] == next[0]:
|
|
return False
|
|
if next_close[1] == y:
|
|
continue
|
|
if abs(next_close[1]-y)==1 and next_close[0] == x:
|
|
return False
|
|
return True
|
|
|
|
|
|
def level5():
|
|
output=[]
|
|
map = []
|
|
with open("level5_example.in") as f:
|
|
n=int(f.readline())
|
|
for i in range(n):
|
|
map.append(list(f.readline()))
|
|
n_nr = int(f.readline())
|
|
border=build_border(map)
|
|
return border
|
|
|
|
|
|
|
|
def build_border(map):
|
|
border = [[0 for i in range(len(map[0]))] for j in range(len(map))]
|
|
for x1 in range(len(map)):
|
|
for y1 in range(len(map)):
|
|
if map[x1][y1] == 'L':
|
|
border[x1][y1]=-1
|
|
if x1 > 0 and border[x1-1][y1] != -1:
|
|
border[x1-1][y1]=1
|
|
if x1 < len(map) and border[x1+1][y1] != -1:
|
|
border[x1+1][y1]=1
|
|
if y1 > 0 and border[x1][y1-1] != -1:
|
|
border[x1][y1-1]=1
|
|
if y1 < len(map[0]) and border[x1][y1+1] != -1:
|
|
border[x1][y1+1]=1
|
|
|
|
|
|
return border
|
|
|
|
|
|
|
|
def main():
|
|
output=level5()
|
|
s=findCycle(output)
|
|
print(s)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|
|
|
|
|
|
# code that given a list of connected coordinates checks if an X is form in a 2x2 square
|