Code:
from dataclasses import dataclass
from typing import Dict

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: Wednesday, 14 December 2022, 12:58