from itertools import groupby import operator from os import path from collections import Counter import re def preberi_zemljevid(ime_dat: str): directory = path.dirname(path.abspath(__file__)) file = open(path.join(directory, ime_dat)) return file.read().strip().split("\n") def check(x: int, y: int, c: str, zemljevid: list[str], prepovedani: set = None): if prepovedani is None: prepovedani = set() return ( (x, y) not in prepovedani and 0 <= y < len(zemljevid) and 0 <= x < len(zemljevid[0]) and (c == "" and zemljevid[y][x] != "." or zemljevid[y][x] == c) ) def najblizji_distance(x: int, y: int, c: str, zemljevid: list[str], prepovedani: set = None): d = 1 max_d = len(zemljevid) + len(zemljevid[0]) while d <= max_d: x -= 1 ry = 0 ry_inc = 1 for rx in range(d * 2 + 1): if check(x + rx, y - ry, c, zemljevid, prepovedani): return x + rx, y - ry, d if check(x + rx, y + ry, c, zemljevid, prepovedani): return x + rx, y + ry, d if ry == d: ry_inc = -1 ry += ry_inc d += 1 def najblizji(x: int, y: int, c: str, zemljevid: list[str], prepovedani: set = None): if prepovedani is None: prepovedani = set() res = najblizji_distance(x, y, c, zemljevid, prepovedani) if res is None: return return res[0], res[1] def najpogostejsi(x, y, d, zemljevid): chars = [] for y2, line in enumerate(zemljevid): for x2, val in enumerate(line): if abs(x - x2) + abs(y - y2) <= d and val != ".": chars.append(val) if len(chars) == 0: return None m, _ = max(Counter(sorted(chars)).items(), key=operator.itemgetter(1)) return m def vsi_najpogostejsi(x, y, d, zemljevid): chars = [] for y2, line in enumerate(zemljevid): for x2, val in enumerate(line): if abs(x - x2) + abs(y - y2) <= d and val != ".": chars.append(val) if len(chars) == 0: return set() a = [(k, list(v)) for (k, v) in groupby(sorted(Counter(chars).items(), key=operator.itemgetter(1)), key=operator.itemgetter(1))] _, c = max(sorted(a)) return set(k for (k, v) in c) def angelca(x, y, znamenitosti, zemljevid): prepovedani = set() distance = 0 for znam in znamenitosti: res = najblizji_distance(x, y, znam, zemljevid, prepovedani) if res is None: return distance prepovedani.add((x, y)) x, y, d = res distance += d return distance def johanca(x, y, pot, zemljevid): znamenitosti = [] obiskane = set() for match in re.finditer("([0-9]*)([<>v^])", pot): dist, dir = match.groups() dist = int(dist) if dist != "" else 1 match dir: case "^": y -= dist case "v": y += dist case "<": x -= dist case ">": x += dist if ( (x, y) not in obiskane and 0 <= y < len(zemljevid) and 0 <= x < len(zemljevid[0]) and zemljevid[y][x] != "." ): obiskane.add((x, y)) znamenitosti.append(zemljevid[y][x]) return "".join(znamenitosti) def najboljsa_cetrt(a: int, zemljevid: list[str]): x_len = len(zemljevid[0]) - a + 1 y_len = len(zemljevid) - a + 1 y_len = y_len if y_len > 0 else 1 max_count = 0 max_x = 0 max_y = 0 for x in range(x_len): for y in range(y_len): count = 0 for ry in range(a): for rx in range(a): if zemljevid[y + ry][x + rx] != ".": count += 1 if count > max_count: max_count = count max_x = x max_y = y return max_x, max_y def dosegljive(x, y, max_d, max_n, zemljevid): def dosegljive_r(x, y, n, prepovedani): if zemljevid[y][x] == "*": n = max_n else: prepovedani.add((x, y)) prepovedani = prepovedani.copy() accessible = set() for d in range(1, max_d + 1): x -= 1 ry = 0 ry_inc = 1 for rx in range(d * 2 + 1): xx = x + rx y1 = y - ry y2 = y + ry if check(xx, y1, "", zemljevid, prepovedani) and (zemljevid[y1][xx] != "*" or n < max_n): accessible.add((xx, y1)) if check(xx, y2, "", zemljevid, prepovedani) and (zemljevid[y2][xx] != "*" or n < max_n): accessible.add((xx, y2)) if ry == d: ry_inc = -1 ry += ry_inc if n == 0: if any(zemljevid[y][x] == "*" for x, y in accessible): accessible = {(x, y) for x, y in accessible if zemljevid[y][x] == "*"} else: return set() points = set(accessible) for x, y in accessible: points.update(dosegljive_r(x, y, n - 1, prepovedani)) return points tocke = dosegljive_r(x, y, max_n, set()) return {(x, y) for x, y in tocke if zemljevid[y][x] != "*"}