Code:
from dataclasses import dataclass

BEARINGS = ["N", "E", "S", "W"]


@dataclass
class Boat:
    x: int  # nombres entiers relatifs
    y: int  # idem
    bearing: str  # "N", "E", "S" ou "W"

    def forward(self, distance: int) -> None:
        if self.bearing == "N":
            self.y += distance
        elif self.bearing == "S":
            self.y -= distance
        elif self.bearing == "E":
            self.x += distance
        elif self.bearing == "W":
            self.x -= distance

    def turn(self, *, clockwise: bool) -> None:
        current_bearing_index = BEARINGS.index(self.bearing)
        if clockwise:
            self.bearing = BEARINGS[(current_bearing_index + 1) % 4]
        else:
            self.bearing = BEARINGS[(current_bearing_index - 1) % 4]

    def __str__(self) -> str:
        return f"Boat(position=({self.x},{self.y}), bearing={repr(self.bearing)})"

    def exec(self, instructions: str) -> None:
        for instruction in instructions:
            if instruction == "F":
                self.forward(1)
            elif instruction == "L":
                self.turn(clockwise=False)
            elif instruction == "R":
                self.turn(clockwise=True)


boat = Boat(0, 0, "N")
boat.forward(2)
boat.turn(clockwise=True)
boat.forward(4)
boat.turn(clockwise=True)
print(boat)

instructions = "FFFRFFFFRFB"

boat = Boat(0, 0, "N")
boat.exec(instructions)
print(boat)


def count(instructions: str) -> dict[str, int]:
    counts: dict[str, int] = {}
    for instruction in instructions:
        if instruction in ["F", "R", "L"]:
            if instruction not in counts:
                counts[instruction] = 0
            counts[instruction] += 1
    return counts


def is_round_trip(instructions: str) -> bool:
    boat = Boat(0, 0, "N")
    boat.exec(instructions)
    return boat.x == 0 and boat.y == 0


def are_path_equivalent(instructions1: str, instructions2: str) -> bool:
    boat1 = Boat(0, 0, "N")
    boat2 = Boat(0, 0, "N")
    boat1.exec(instructions1)
    boat2.exec(instructions2)
    return boat1.x == boat2.x and boat1.y == boat2.y and boat1.bearing == boat2.bearing


def optimize(instructions: str) -> str:
    boat = Boat(0, 0, "N")
    boat.exec(instructions)

    if boat.x == 0 and boat.y == 0:  # origine
        return ""
    if boat.x == 0 and boat.y > 0:  # sur axe Y en haut
        return "F" * boat.y
    if boat.x == 0 and boat.y < 0:  # sur axe Y en bas
        return "RR" + "F" * (-boat.y)
    if boat.x > 0 and boat.y == 0:  # sur axe X à droite
        return "R" + "F" * boat.x
    if boat.x < 0 and boat.y == 0:  # sur axe X à gauche
        return "L" + "F" * (-boat.x)
    if boat.x > 0 and boat.y > 0:  # premier quadrant
        return "F" * boat.y + "R" + "F" * boat.x
    if boat.x < 0 and boat.y > 0:  # deuxième quadrant
        return "F" * boat.y + "L" + "F" * (-boat.x)
    if boat.x < 0 and boat.y < 0:  # troisième quadrant
        return "L" + "F" * (-boat.x) + "L" + "F" * (-boat.y)
    if boat.x > 0 and boat.y < 0:  # quatrième quadrant
        return "R" + "F" * boat.x + "R" + "F" * (-boat.y)

    raise ValueError()


print(instructions)
print(count(instructions))
print(optimize(instructions))
print(optimize("FLFLFLFLLRL"))
print(optimize("RRFFF"))
print(optimize("LLFFF"))
print(are_path_equivalent(instructions, optimize(instructions)
Last modified: Saturday, 11 May 2024, 13:15