Pentomino 6x10 normaliseur de solution

19

Comme vous le savez probablement maintenant, il existe 2339 solutions au puzzle pentomino dans une grille 6x10. Il existe différents schémas d'étiquetage pour les 12 pentominos, dont deux sont illustrés sur l'image ci-dessous:

entrez la description de l'image ici

Crédit d'image: Wikipedia

Aux fins de la tâche actuelle, nous dirons qu'une solution de pentomino normalisée est une solution qui utilise le deuxième schéma d'étiquetage (Conway).

Exemple:

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

La pièce à 5 carrés consécutifs est désignée par des lettres O, selon le schéma. La même chose est vraie pour toutes les pièces.

Tâche:

Étant donné une solution au pentomino 6x10 dans lequel les pièces sont étiquetées avec un schéma aléatoire, normalisez-la afin que toutes les pièces soient étiquetées dans le schéma d'étiquetage de Conway. Vous devez reconnaître les pièces et marquer chaque carré d'une pièce particulière avec le symbole de la pièce.

Contribution:

La solution à normaliser, dans n'importe quel format qui vous convient, par exemple:

  • Une chaîne multiligne

  • Une liste de chaînes

  • Une liste de listes de personnages

etc

Production:

La même solution (toutes les positions et orientations des pièces sont conservées), mais chaque pièce est étiquetée selon le schéma d'étiquetage de Conway. Remarque: La sortie DOIT être IMPRIMÉE sous forme d'une grille de 6 x 10 caractères. Les nouvelles lignes et les espaces de début et de fin sont autorisés. Vous pouvez également imprimer un espace entre les caractères (mais pas les lignes vides), comme dans l'exemple ci-dessus.

Cas de test:

1. Entrée:

6623338888
6222344478
66A234BB70
1AAA94B770
11A99BB700
1199555550

Production:

UURTTTQQQQ
URRRTVVVSQ
UUXRTVZZSY
PXXXWVZSSY
PPXWWZZSYY
PPWWOOOOOY

2. Entrée:

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

Production:

OWSSQQQQPP
OWWSSSRQPP
OTWWRRRUUP
OTTTXRZZUV
OTYXXXZUUV
YYYYXZZVVV

Critères gagnants:

La solution la plus courte en octets dans chaque langue l'emporte. Ne vous laissez pas décourager par les langues de golf. Les explications des algorithmes et des implémentations sont les bienvenues.

Galen Ivanov
la source
@KevinCruijssen Merci! (Je n'ai pas vérifié les questions liées aux tétromonos)
Galen Ivanov

Réponses:

12

APL (Dyalog Classic) , 54 53 50 octets

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

Essayez-le en ligne!

Calculez un invariant pour chaque pentomino en entrée: mesurez (∆x, ∆y) de chacun de ses carrés à son centre de gravité, prenez abs (∆x) et abs (∆y), additionnez les composantes x et séparément y et multipliez les deux sommes. Cela donne 12 résultats distincts. Ensuite, trouvez l'indice de chaque invariant de pentomino dans la collection triée de tous les invariants. Remplacez 0 par 'O', 1 par 'X', 2 par 'R', etc.

ngn
la source
Merci pour la réponse rapide et l'explication, +1 de ma part! Je voulais dire que la solution devait être explicitement imprimée sous forme de grille 6x10. J'ai changé la description, veuillez mettre à jour votre solution - je suis désolé pour le dérangement.
Galen Ivanov
@GalenIvanov mais ... c'est une grille . Mes tests donnent "ok" au lieu d'imprimer le résultat - c'est peut-être trop déroutant?
ngn
Oui, j'ai été dérouté par les tests.
Galen Ivanov
3
maintenant ils impriment le résultat avant de le valider
ngn
4

Gelée , 37 octets

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

Un programme complet prenant une liste de chaînes (car nous devons imprimer - sinon supprimez la fin Yet vous avez une monade prenant une liste de listes de nombres ou de caractères qui retourne une liste de listes de caractères).

Essayez-le en ligne!

Comment?

Je crois que cela fonctionne en utilisant la même catégorisation des pentominos que la solution APL de ngn , bien que d'une manière légèrement différente (je ne connais pas non plus l'APL, donc je ne suis pas sûr de la similitude de la méthode au-delà de la catégorisation).

(Notez qu'il “æṂ⁾+’Œ?¤+78Ọne s'agit que d'une sauvegarde d'un octet “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
la source
2

Wolfram Language (Mathematica) , 103 octets

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

Prend la saisie comme une liste de listes de caractères.

Essayez-le en ligne!

L'idée principale ici est que pour chaque caractère dans l'entrée, nous trouvons les coordonnées où il se produit, prenons le kurtosis et additionnons ses coordonnées. Cela nous donne un invariant pour chaque pièce.

(Le kurtosis est un opérateur peu pertinent pour les statistiques - la clé est qu'il est invariant en translation, tandis que la réflexion et la rotation peuvent changer l'ordre des coordonnées au plus. Nous additionnons les coordonnées, donc l'invariant ne change jamais.)

Quoi qu'il en soit, à l'exception de l'invariant bizarre, cette solution est similaire aux autres: nous trions les caractères et les pièces par chaque invariant, puis remplaçons chaque caractère par le caractère correspondant de "UPSWZVRTQXYO": les pièces, triées par somme kurtosis.

Enfin, ""<>Riffle[...,"\n"]est le code d'impression sous forme de grille.

Misha Lavrov
la source
+1 pour avoir connu une opération dont je n'avais jamais entendu parler et l'avoir mise à profit
Black Owl Kai
Ma première tentative de solution avait Sort@Varianceremplacé Tr@Kurtosis, et probablement plus de gens ont entendu parler de variance. Mais Tr@Variancecela ne fonctionne pas car plusieurs pentominos (tels que P et X) ont la même somme de variance x et de variance y. J'ai donc parcouru la documentation de Mathematica pour trouver quelque chose d'amateur.
Misha Lavrov
2

Python 2 , 191 octets

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])

Essayez-le en ligne!

Prend une chaîne de plusieurs lignes avec un retour à la ligne de fin et fait six compréhensions de liste imbriquées.

Version non golfée

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)
Chouette noire Kai
la source