from re import finditer
from collections import defaultdict


class Kolesar:
    def __init__(self, zemljevid: list[str]):
        self.zemljevid = zemljevid
        self.x = 0
        self.y = 0
        self.dist = 0
        self.mrtev = False

    def lokacija(self):
        return self.x, self.y

    def razdalja(self):
        return self.dist

    def pojdi(self, smer: str):
        if self.mrtev:
            return

        x = self.x
        y = self.y
        (x, y) = {
            "<": (x - 1, y),
            ">": (x + 1, y),
            "^": (x, y - 1),
            "v": (x, y + 1),
        }[smer]

        if not (0 <= x < len(self.zemljevid[0]) and 0 <= y < len(self.zemljevid)):
            self.mrtev = True
            return

        self.x = x
        self.y = y
        self.dist += 1

    def prevozi(self, pot: str):
        for match in finditer("([0-9]*)([<>v^])", pot):
            dist, smer = match.groups()
            dist = int(dist) if dist != "" else 1
            for _ in range(dist):
                self.pojdi(smer)


class Zbiralec(Kolesar):
    def __init__(self, x: int, y: int, zemljevid: list[str]):
        super().__init__(zemljevid)
        self.x = x
        self.y = y
        self.pobrane = defaultdict(lambda: 0)

    def znacke(self):
        return self.pobrane.keys()

    def naj_znacke(self):
        return {znacka for znacka, count, in self.pobrane.items() if count == max(self.pobrane.values())}

    def pojdi(self, smer: str):
        super().pojdi(smer)
        znacka = self.zemljevid[self.y][self.x]
        if znacka != ".":
            self.pobrane[znacka] += 1

    def trofeje(self):
        prev = None
        return [(znacka, prev := count) for i, (znacka, count) in
                enumerate(sorted(self.pobrane.items(), key=lambda x: (-x[1], x[0])))
                if prev == count or i <= 2]


class Sledi(dict[tuple[int, int], str]):
    pass


class Drsalec(Zbiralec):
    def __init__(self, x: int, y: int, zemljevid: list[str], sledi: Sledi):
        super().__init__(x, y, zemljevid)
        self.sledi = sledi

    def pojdi(self, smer: str):
        self.sledi[(self.x, self.y)] = smer
        super().pojdi(smer)

        for _ in range(3):
            sled = self.sledi.get((self.x, self.y))
            if sled is None:
                break

            super().pojdi(sled)
