Partie A : symétrie horizontale

type PartialChessboard = list[int | None]
def hsymmetry(q: PartialChessboard) -> PartialChessboard:
    '''
    >>> hsymmetry([0, 1, 2, 3])
    [3, 2, 1, 0]
    >>> hsymmetry([0, None, 2, 3])
    [3, None, 1, 0]
    >>> hsymmetry([0, 1, 1, 0])
    [3, 2, 2, 3]
    >>> hsymmetry([0, 1, 2, 3, 4])
    [4, 3, 2, 1, 0]
    >>> hsymmetry([0, 1, 2, 1, 0])
    [4, 3, 2, 3, 4]
    >>> hsymmetry([0])
    [0]
    '''
    n = len(q)
    return [((n - row_no - 1) if row_no is not None else None) for row_no in q]

if __name__ == '__main__':
    import doctest
    doctest.testmod()

2.B : symétrie verticale

<aside> ℹ️

Attention à ne pas utiliser q.reverse() qui effectuerait une modification “in place” de la liste passée en paramètre : on veut bien retourner une copie !!!

</aside>

type PartialChessboard = list[int | None]

def vsymmetry(q: PartialChessboard) -> PartialChessboard:
    '''
    >>> vsymmetry([0, 1, 2, 3])
    [3, 2, 1, 0]
    >>> vsymmetry([0, 1, 2, None])
    [None, 2, 1, 0]
    '''
    return list(reversed(q))

if __name__ == '__main__':
    import doctest
    doctest.testmod()

2.C : Symétrie par rapport à la diagonale

<aside> ℹ️

</aside>

type PartialChessboard = list[int | None]

def dsymmetry(q: PartialChessboard) -> PartialChessboard:
    '''
    >>> dsymmetry([1, None, None, None])
    [None, 0, None, None]
    >>> dsymmetry([1, None, 3, None])
    [None, 0, None, 2]
    >>> dsymmetry([1, 3, 0, None])
    [2, 0, None, 1]
    >>> dsymmetry([1, 3, 0, 2])
    [2, 0, 3, 1]
    >>> dsymmetry(dsymmetry([1, 3, 0, 2]))
    [1, 3, 0, 2]
    >>> dsymmetry([0])
    [0]
    >>>
    '''
    n = len(q)
    new_board: PartialChessboard = [None] * n
    for i in range(n):
        if q[i] is not None:
            new_board[q[i]] = i

    return new_board

if __name__ == '__main__':
    import doctest
    doctest.testmod()