# your code goes here
#0JLQsNGB0LjQu9C10L3QutC+INCQ0YDRgtC10Lwg
import random
import sys
from collections import deque
COLOR_RESET = "\033[0m"
COLOR_RED = "\033[91m"
COLOR_YELLOW = "\033[93m"
COLOR_GREEN = "\033[92m"
COLOR_BLUE = "\033[94m"
COLOR_WHITE = "\033[97m"
ARROWS = ['↑', '→', '↓', '←']
def solve_highway():
N = 20
M = 20
TREE_CHANCE = 0.25
try:
user_input = input("Введіть макс. кількість поворотів (K) [Enter для 10]: ")
K = int(user_input) if user_input.strip() else 10
except ValueError:
print("K має бути числом.")
return
grid = []
for _ in range(N):
row = []
for _ in range(M):
row.append(1 if random.random() < TREE_CHANCE else 0)
grid.append(row)
dr = [-1, 0, 1, 0]
dc = [0, 1, 0, -1]
path_tracker = {}
min_lengths = {}
queue = deque()
for r in range(N):
if grid[r][0] == 0:
state = (r, 0, -1, 0, 1)
queue.append(state)
min_lengths[(r, 0, -1, 0)] = 1
path_tracker[(r, 0, -1, 0)] = None
best_end_state = None
min_found_length = float('inf')
while queue:
r, c, last_dir, turns, length = queue.popleft()
if length >= min_found_length:
continue
if c == M - 1:
if length < min_found_length:
min_found_length = length
best_end_state = (r, c, last_dir, turns)
continue
for next_dir in range(4):
nr, nc = r + dr[next_dir], c + dc[next_dir]
if 0 <= nr < N and 0 <= nc < M and grid[nr][nc] == 0:
new_turns = turns
if last_dir != -1 and last_dir != next_dir:
new_turns += 1
if new_turns > K:
continue
new_length = length + 1
new_state_key = (nr, nc, next_dir, new_turns)
if new_length < min_lengths.get(new_state_key, float('inf')):
min_lengths[new_state_key] = new_length
path_tracker[new_state_key] = (r, c, last_dir, turns)
queue.append((nr, nc, next_dir, new_turns, new_length))
if best_end_state is None:
print(f"\n{COLOR_RED}Неможливо прокласти шосе з {K} поворотами.{COLOR_RESET}")
path_set = set()
else:
print(f"\n{COLOR_GREEN}Шлях знайдено! Довжина: {min_found_length}{COLOR_RESET}")
path_map = {}
curr = best_end_state
while curr is not None:
r, c, d, t = curr
path_map[(r, c)] = d
curr = path_tracker.get(curr)
path_set = set(path_map.keys())
print(" " + "".join([f"{i%10} " for i in range(M)]))
print(" +" + "-" * (M * 2) + "+")
for r in range(N):
line = f"{r%10} |"
for c in range(M):
if (r, c) in path_set:
direction = path_map[(r, c)]
if direction == -1:
symbol = "S"
color = COLOR_RED
elif c == M - 1:
symbol = "F"
color = COLOR_BLUE
else:
symbol = ARROWS[direction]
color = COLOR_YELLOW
line += f"{color}{symbol}{COLOR_RESET} "
elif grid[r][c] == 1:
line += f"{COLOR_GREEN}#{COLOR_RESET} "
else:
line += f"{COLOR_WHITE}.{COLOR_RESET} "
print(line + "|")
print(" +" + "-" * (M * 2) + "+")
if __name__ == "__main__":
solve_highway()
IyB5b3VyIGNvZGUgZ29lcyBoZXJlCiMwSkxRc05HQjBMalF1OUMxMEwzUXV0QytJTkNRMFlEUmd0QzEwTHdnCgppbXBvcnQgcmFuZG9tCmltcG9ydCBzeXMKZnJvbSBjb2xsZWN0aW9ucyBpbXBvcnQgZGVxdWUKCkNPTE9SX1JFU0VUID0gIlwwMzNbMG0iCkNPTE9SX1JFRCA9ICJcMDMzWzkxbSIKQ09MT1JfWUVMTE9XID0gIlwwMzNbOTNtIgpDT0xPUl9HUkVFTiA9ICJcMDMzWzkybSIKQ09MT1JfQkxVRSA9ICJcMDMzWzk0bSIKQ09MT1JfV0hJVEUgPSAiXDAzM1s5N20iCkFSUk9XUyA9IFsn4oaRJywgJ+KGkicsICfihpMnLCAn4oaQJ10KCmRlZiBzb2x2ZV9oaWdod2F5KCk6CiAgICBOID0gMjAKICAgIE0gPSAyMAogICAgVFJFRV9DSEFOQ0UgPSAwLjI1CiAgICAKICAgIHRyeToKICAgICAgICB1c2VyX2lucHV0ID0gaW5wdXQoItCS0LLQtdC00ZbRgtGMINC80LDQutGBLiDQutGW0LvRjNC60ZbRgdGC0Ywg0L/QvtCy0L7RgNC+0YLRltCyIChLKSBbRW50ZXIg0LTQu9GPIDEwXTogIikKICAgICAgICBLID0gaW50KHVzZXJfaW5wdXQpIGlmIHVzZXJfaW5wdXQuc3RyaXAoKSBlbHNlIDEwCiAgICBleGNlcHQgVmFsdWVFcnJvcjoKICAgICAgICBwcmludCgiSyDQvNCw0ZQg0LHRg9GC0Lgg0YfQuNGB0LvQvtC8LiIpCiAgICAgICAgcmV0dXJuCgogICAgZ3JpZCA9IFtdCiAgICBmb3IgXyBpbiByYW5nZShOKToKICAgICAgICByb3cgPSBbXQogICAgICAgIGZvciBfIGluIHJhbmdlKE0pOgogICAgICAgICAgICByb3cuYXBwZW5kKDEgaWYgcmFuZG9tLnJhbmRvbSgpIDwgVFJFRV9DSEFOQ0UgZWxzZSAwKQogICAgICAgIGdyaWQuYXBwZW5kKHJvdykKCiAgICBkciA9IFstMSwgMCwgMSwgMF0gCiAgICBkYyA9IFswLCAxLCAwLCAtMV0KICAgIAogICAgcGF0aF90cmFja2VyID0ge30KICAgIG1pbl9sZW5ndGhzID0ge30KICAgIHF1ZXVlID0gZGVxdWUoKQoKICAgIGZvciByIGluIHJhbmdlKE4pOgogICAgICAgIGlmIGdyaWRbcl1bMF0gPT0gMDoKICAgICAgICAgICAgc3RhdGUgPSAociwgMCwgLTEsIDAsIDEpCiAgICAgICAgICAgIHF1ZXVlLmFwcGVuZChzdGF0ZSkKICAgICAgICAgICAgbWluX2xlbmd0aHNbKHIsIDAsIC0xLCAwKV0gPSAxCiAgICAgICAgICAgIHBhdGhfdHJhY2tlclsociwgMCwgLTEsIDApXSA9IE5vbmUKCiAgICBiZXN0X2VuZF9zdGF0ZSA9IE5vbmUKICAgIG1pbl9mb3VuZF9sZW5ndGggPSBmbG9hdCgnaW5mJykKCiAgICB3aGlsZSBxdWV1ZToKICAgICAgICByLCBjLCBsYXN0X2RpciwgdHVybnMsIGxlbmd0aCA9IHF1ZXVlLnBvcGxlZnQoKQoKICAgICAgICBpZiBsZW5ndGggPj0gbWluX2ZvdW5kX2xlbmd0aDoKICAgICAgICAgICAgY29udGludWUKCiAgICAgICAgaWYgYyA9PSBNIC0gMToKICAgICAgICAgICAgaWYgbGVuZ3RoIDwgbWluX2ZvdW5kX2xlbmd0aDoKICAgICAgICAgICAgICAgIG1pbl9mb3VuZF9sZW5ndGggPSBsZW5ndGgKICAgICAgICAgICAgICAgIGJlc3RfZW5kX3N0YXRlID0gKHIsIGMsIGxhc3RfZGlyLCB0dXJucykKICAgICAgICAgICAgY29udGludWUKCiAgICAgICAgZm9yIG5leHRfZGlyIGluIHJhbmdlKDQpOgogICAgICAgICAgICBuciwgbmMgPSByICsgZHJbbmV4dF9kaXJdLCBjICsgZGNbbmV4dF9kaXJdCgogICAgICAgICAgICBpZiAwIDw9IG5yIDwgTiBhbmQgMCA8PSBuYyA8IE0gYW5kIGdyaWRbbnJdW25jXSA9PSAwOgogICAgICAgICAgICAgICAgbmV3X3R1cm5zID0gdHVybnMKICAgICAgICAgICAgICAgIGlmIGxhc3RfZGlyICE9IC0xIGFuZCBsYXN0X2RpciAhPSBuZXh0X2RpcjoKICAgICAgICAgICAgICAgICAgICBuZXdfdHVybnMgKz0gMQogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICBpZiBuZXdfdHVybnMgPiBLOgogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlCgogICAgICAgICAgICAgICAgbmV3X2xlbmd0aCA9IGxlbmd0aCArIDEKICAgICAgICAgICAgICAgIG5ld19zdGF0ZV9rZXkgPSAobnIsIG5jLCBuZXh0X2RpciwgbmV3X3R1cm5zKQoKICAgICAgICAgICAgICAgIGlmIG5ld19sZW5ndGggPCBtaW5fbGVuZ3Rocy5nZXQobmV3X3N0YXRlX2tleSwgZmxvYXQoJ2luZicpKToKICAgICAgICAgICAgICAgICAgICBtaW5fbGVuZ3Roc1tuZXdfc3RhdGVfa2V5XSA9IG5ld19sZW5ndGgKICAgICAgICAgICAgICAgICAgICBwYXRoX3RyYWNrZXJbbmV3X3N0YXRlX2tleV0gPSAociwgYywgbGFzdF9kaXIsIHR1cm5zKQogICAgICAgICAgICAgICAgICAgIHF1ZXVlLmFwcGVuZCgobnIsIG5jLCBuZXh0X2RpciwgbmV3X3R1cm5zLCBuZXdfbGVuZ3RoKSkKCiAgICBpZiBiZXN0X2VuZF9zdGF0ZSBpcyBOb25lOgogICAgICAgIHByaW50KGYiXG57Q09MT1JfUkVEfdCd0LXQvNC+0LbQu9C40LLQviDQv9GA0L7QutC70LDRgdGC0Lgg0YjQvtGB0LUg0Lcge0t9INC/0L7QstC+0YDQvtGC0LDQvNC4LntDT0xPUl9SRVNFVH0iKQogICAgICAgIHBhdGhfc2V0ID0gc2V0KCkKICAgIGVsc2U6CiAgICAgICAgcHJpbnQoZiJcbntDT0xPUl9HUkVFTn3QqNC70Y/RhSDQt9C90LDQudC00LXQvdC+ISDQlNC+0LLQttC40L3QsDoge21pbl9mb3VuZF9sZW5ndGh9e0NPTE9SX1JFU0VUfSIpCiAgICAgICAgCiAgICAgICAgcGF0aF9tYXAgPSB7fQogICAgICAgIGN1cnIgPSBiZXN0X2VuZF9zdGF0ZQogICAgICAgIHdoaWxlIGN1cnIgaXMgbm90IE5vbmU6CiAgICAgICAgICAgIHIsIGMsIGQsIHQgPSBjdXJyCiAgICAgICAgICAgIHBhdGhfbWFwWyhyLCBjKV0gPSBkCiAgICAgICAgICAgIGN1cnIgPSBwYXRoX3RyYWNrZXIuZ2V0KGN1cnIpCiAgICAgICAgcGF0aF9zZXQgPSBzZXQocGF0aF9tYXAua2V5cygpKQoKICAgIAogICAgcHJpbnQoIiAgICIgKyAiIi5qb2luKFtmIntpJTEwfSAiIGZvciBpIGluIHJhbmdlKE0pXSkpIAogICAgcHJpbnQoIiAgKyIgKyAiLSIgKiAoTSAqIDIpICsgIisiKSAKICAgIAogICAgZm9yIHIgaW4gcmFuZ2UoTik6CiAgICAgICAgbGluZSA9IGYie3IlMTB9IHwiCiAgICAgICAgZm9yIGMgaW4gcmFuZ2UoTSk6CiAgICAgICAgICAgIGlmIChyLCBjKSBpbiBwYXRoX3NldDoKICAgICAgICAgICAgICAgIGRpcmVjdGlvbiA9IHBhdGhfbWFwWyhyLCBjKV0KICAgICAgICAgICAgICAgIGlmIGRpcmVjdGlvbiA9PSAtMToKICAgICAgICAgICAgICAgICAgICBzeW1ib2wgPSAiUyIKICAgICAgICAgICAgICAgICAgICBjb2xvciA9IENPTE9SX1JFRAogICAgICAgICAgICAgICAgZWxpZiBjID09IE0gLSAxOgogICAgICAgICAgICAgICAgICAgIHN5bWJvbCA9ICJGIgogICAgICAgICAgICAgICAgICAgIGNvbG9yID0gQ09MT1JfQkxVRQogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBzeW1ib2wgPSBBUlJPV1NbZGlyZWN0aW9uXQogICAgICAgICAgICAgICAgICAgIGNvbG9yID0gQ09MT1JfWUVMTE9XCiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIGxpbmUgKz0gZiJ7Y29sb3J9e3N5bWJvbH17Q09MT1JfUkVTRVR9ICIKICAgICAgICAgICAgZWxpZiBncmlkW3JdW2NdID09IDE6CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIGxpbmUgKz0gZiJ7Q09MT1JfR1JFRU59I3tDT0xPUl9SRVNFVH0gIgogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgbGluZSArPSBmIntDT0xPUl9XSElURX0ue0NPTE9SX1JFU0VUfSAiCiAgICAgICAgcHJpbnQobGluZSArICJ8IikKICAgIHByaW50KCIgICsiICsgIi0iICogKE0gKiAyKSArICIrIikKCmlmIF9fbmFtZV9fID09ICJfX21haW5fXyI6CiAgICBzb2x2ZV9oaWdod2F5KCkK