Normalizador Pentomino 6x10

19

Como você provavelmente agora, existem 2339 soluções para o quebra-cabeça pentomino em uma grade 6x10. Existem diferentes esquemas de rotulagem para os 12 pentominós, dois deles são mostrados na imagem abaixo:

insira a descrição da imagem aqui

Crédito de imagem: Wikipedia

Para os propósitos da tarefa atual, diremos que uma solução pentomino normalizada é uma solução que utiliza o segundo esquema de rotulagem (de Conway).

Exemplo:

O O O O O S S S Z Z
P P R R S S W W Z V
P P P R R W W Z Z V
U U X R T W Y V V V
U X X X T Y Y Y Y Q
U U X T T T Q Q Q Q

A peça com 5 quadrados seguidos é indicada por letras O, de acordo com o esquema. O mesmo vale para todas as peças.

Tarefa:

Dada uma solução para o pentomino 6x10 no qual as peças são rotuladas com um sheme aleatório, normalize-a para que todas as peças sejam rotuladas no esquema de rotulagem de Conway. Você precisa reconhecer as peças e marcar cada quadrado de uma peça em particular com o símbolo da peça.

Entrada:

A solução a ser normalizada, em qualquer formato que seja conveniente para você, por exemplo:

  • Uma sequência multilinha

  • Uma lista de strings

  • Uma lista de listas de caracteres

e assim por diante

Resultado:

A mesma solução (todas as posições e orientação das peças preservadas), mas cada peça é rotulada de acordo com o esquema de rotulagem de Conway. Nota: A saída DEVE SER IMPRESSA como uma grade 6x10 de caracteres. Novas linhas e espaços à esquerda e à direita são permitidos. Você também pode imprimir um espaço entre os caracteres (mas não as linhas vazias), como no exemplo acima.

Casos de teste:

1. Entrada:

6623338888
6222344478
66A234BB70
1AAA94B770
11A99BB700
1199555550

Resultado:

UURTTTQQQQ
URRRTVVVSQ
UUXRTVZZSY
PXXXWVZSSY
PPXWWZZSYY
PPWWOOOOOY

2. Entrada:

45ookkkk00
455ooogk00
4a55gggdd0
4aaa3gnnd.
4am333ndd.
mmmm3nn...

Resultado:

OWSSQQQQPP
OWWSSSRQPP
OTWWRRRUUP
OTTTXRZZUV
OTYXXXZUUV
YYYYXZZVVV

Critérios de vitória:

A solução mais curta em bytes em cada idioma vence. Não desanime pelas línguas do golfe. Explicações sobre algoritmos e implementações são bem-vindas.

Galen Ivanov
fonte
@KevinCruijssen Thank you! (Eu não verificar se há questões relacionadas com tetromonoes)
Galen Ivanov

Respostas:

12

APL (Dyalog Classic) , 54 53 50 bytes

⍴⍴{'OXRYTPZQUWSV'[⌊5÷⍨⍋⍋,{×/+⌿↑|(⊢-+/÷≢)⍸⍵}¨⍵=⊂⍵]}

Experimente online!

Calcule uma invariante para cada pentomino na entrada: meça (∆x, ∆y) de cada um dos seus quadrados até o centro de gravidade, tire abs (∆x) e abs (∆y), some os componentes x e separadamente y componentes e multiplique as duas somas. Isso fornece 12 resultados distintos. Em seguida, encontre o índice da invariante de cada pentomino na coleção classificada de todos os invariantes. Substitua 0 por 'O', 1 por 'X', 2 por 'R', etc.

ngn
fonte
Obrigado pela resposta rápida e pela explicação, +1 de mim! Eu quis dizer que a solução seria impressa explicitamente como uma grade 6x10. Alterei a descrição, atualize sua solução. Sinto muito pelo inconveniente.
Galen Ivanov #
@GalenIvanov mas ... é uma grade . Meus testes emitem "ok" em vez de imprimir o resultado - talvez seja muito confuso?
NGN
Sim, fiquei confuso com os testes.
Galen Ivanov
3
agora eles imprimir o resultado antes de validar isso
NGN
4

Geléia , 37 bytes

ŒĠZÆmạƊ€ḅı§AỤỤị“æṂ⁾+’Œ?¤+78Ọ,@FQṢƊyⱮY

Um programa completo com uma lista de strings (porque precisamos imprimir - caso contrário, remova o Y e você tem uma mônada fazendo uma lista de listas de números ou caracteres que retorna uma lista de listas de caracteres).

Experimente online!

Quão?

Eu acredito que isso funciona usando a mesma categorização de pentominos que a solução APL da ngn , embora de uma maneira um pouco diferente (eu também não conheço a APL, portanto, não tenho certeza de quão semelhante o método está além da categorização).

(Observe que “æṂ⁾+’Œ?¤+78Ọé apenas um salvamento de um byte “XRPTZWUYSVQO”!)

ŒĠZÆmạƊ€ḅı§AỤỤị“æṂ⁾+’Œ?¤+78Ọ,@FQṢƊyⱮY - Main Link: list of lists of characters L
ŒĠ                                    - group multidimensional indices by value
      Ɗ€                              - last three links as a monad for €ach i.e. f(x):
  Z                                   -   transpose x
   Æm                                 -   mean (vectorises) (i.e. the average of the coordinates)
     ạ                                -   absolute difference with x (vectorises) (i.e. [dx, dy])
         ı                            - square root of -1 (i)
        ḅ                             - convert from base (vectorises) (i.e a list of (i*dx+dy)s)
          §                           - sum each
           A                          - absolute value (i.e. norm of the complex number)
            Ụ                         - grade up (sort indices by value)
             Ụ                        - grade up (...getting the order from the result of A back,
                                      -              but now with one through to 12)
                       ¤              - nilad followed by links as a nilad:
               “æṂ⁾+’                 -   base 250 literal = 370660794
                     Œ?               -   permutation@lex-index = [10,4,2,6,12,9,7,11,5,8,3,1]
              ị                       - index into
                        +78           - add seventy-eight
                           Ọ          - cast to characters (character(1+78)='O', etc...)
                                 Ɗ    - last three links as a monad (i.e. f(L)):
                              F       -   flatten
                               Q      -   de-duplicate
                                Ṣ     -    sort
                            ,@        - pair (with sw@pped @rguments) (giving a list of 2 lists)
                                   Ɱ  - Ɱap across L with:
                                  y   -   translate i.e. swap the letters as per the the pair)
                                    Y - join with new lines
                                      - implicit print
Jonathan Allan
fonte
2

Wolfram Language (Mathematica) , 103 bytes

""<>Riffle[(t=#)/.Thread[SortBy[Union@@t,Tr@Kurtosis@Position[t,#]&]->Characters@"UPSWZVRTQXYO"],"\n"]&

Recebe a entrada como uma lista de listas de caracteres.

Experimente online!

A idéia principal aqui é que, para cada caractere da entrada, localizemos as coordenadas onde ocorrem, pegamos a curtose e somamos suas coordenadas. Isso nos dá um invariante para cada peça.

(A curtose é um operador quase irrelevante das estatísticas - a chave é que ela é invariante na tradução, enquanto reflexão e rotação podem mudar a ordem das coordenadas no máximo. Somamos as coordenadas, para que a invariante nunca mude.)

De qualquer forma, além da invariante estranha, essa solução é semelhante às outras: classificamos os personagens e as peças por cada invariante e substituímos cada caractere pelo caractere correspondente de "UPSWZVRTQXYO" : as peças, classificadas pela soma da curtose.

Por fim, ""<>Riffle[...,"\n"]é o código de impressão como grade.

Misha Lavrov
fonte
+1 para conhecer uma operação que eu nunca sequer ouviu falar e colocá-lo em bom uso
Preto Kai Owl
Minha primeira tentativa de solução foi Sort@Variancesubstituída Tr@Kurtosise provavelmente mais pessoas já ouviram falar de variação. Mas Tr@Variancenão funciona porque vários pentominós (como P e X) têm a mesma soma de variância x e variância y. Então eu procurei na documentação do Mathematica por algo mais sofisticado.
Misha Lavrov
2

Python 2 , 191 bytes

def y(o):print"".join(['XPRTWZUYSVQO\n'[[w for v,w in sorted([sum(abs(u-sum(t)/5)for t in[[complex(r%11,r/11)for r,q in enumerate(o)if q==p]]for u in t),p]for p in o)].index(x)/5]for x in o])

Experimente online!

Pega uma sequência de várias linhas com uma nova linha à direita e faz seis compreensões de lista aninhadas.

Versão Ungolfed

def pentomino_normalizer(input_string):
    # input_string is a multi-line string with a trailing newline

    results = []  # For saving the results of the for loop
    for current_char in input_string:
        # current_char = p in the golfed version

        # The python data type complex stores a real and a imaginary value and
        # is used for storing the x and y coordinates.
        # In the end, the positions list contains a complex number for every
        # occurence of current_char in the string
        # positions_list = t in the golfed version
        positions_list = [complex(i % 11, i / 11) for i, c
                          in enumerate(input_string) if c == current_char]
        # average_pos is the midpoint of all occurences of current_char, 
        # to get rid of translations
        average_pos = sum(positions_list)/5
        # Calculates a value for each tile that is invariant under 
        # translations and rotations,
        # simply the sum of all the distances between the midpoint
        # and the positions
        invariant = sum(abs(pos - average_pos) for pos in positions_list)

        # Saves the invariant value to a list
        results.append(invariant, current_char)

    # This new list contains the characters occuring in the string, sorted
    # by the invariant value. Because this was done with each char in the 
    # input string, this lists contains every value five times and also 
    # contains six newlines
    # at the end of the list
    sorted_results = [w for v, w in sorted(results)]

    # This code snippet maps each char from the input string to its according
    # output and prints to stdout
    chars = ['XPRTWZUYSVQO\n'[sorted_results.index(c)/5] for c in input_string]
    print "".join(chars)
Black Owl Kai
fonte