Pentomino Validator

9

En tant que personne qui ne peut pas être gênée de regarder ses pentominos pour voir si elle a une forme rectangulaire, j'ai décidé de vous faire écrire un programme qui le fait.

Ta tâche

Étant donné certaines entrées divisées par des sauts de ligne contenant 12 caractères uniques, décidez si c'est une solution valide.

Une solution valide DOIT

  • Avoir 5 de chaque personnage (sauf les nouvelles lignes)
  • Chaque jeu de caractères doit être entièrement connecté
  • Chaque jeu de caractères doit avoir une forme unique
  • Être dans une forme rectangulaire régulière

S'il s'agit d'une solution valide, affichez une valeur vraie, sinon affichez une valeur fausse.

Votre programme peut être une fonction ou un programme complet mais doit prendre l'entrée de stdin et la sortie vers stdout.

Cas de test

Solutions valides

000111
203331
203431
22 444
2   46
57 666
57769!
58779!
58899!
5889!!

00.@@@ccccF111//=---
0...@@c))FFF1//8===-
00.ttttt)))F1/8888=-

Configurations invalides

invalid (doesn't contain 12 unique characters)

111112222233333444445555566666
77777888889999900000qqqqqwwwww (Each set has the same shape)

1234567890qw
w1234567890q
qw1234567890
0qw123456789
90qw12345678 (None of the characters are connected)

1234567890qw (Not 5 characters in every set)

1111122222333334444455555666666
77777888889999900000qqqqqwwwwww (More than 5 characters in some sets)

00
0                   
00.@@@ccccF111//=---
 ...@@c))FFF1//8===-
  .ttttt)))F1/8888=- (Doesn't form a rectangular shape)
Bleu
la source
1. Le reflet d'un pentomino a-t-il la même forme que l'original? 2. Pouvons-nous supposer que l'entrée sera composée de caractères ASCII imprimables et de nouvelles lignes?
Dennis
@Dennis Oui et Oui
Blue
@DigitalTrauma Ce n'est pas à distance un doublon de cela. BTW qui était une question géniale, c'est dommage que je n'ai pas eu le temps d'y répondre quand elle a été récemment posée.
Level River St
@steveverill vous avez raison - Je n'ai pas lu cette question correctement
Digital Trauma

Réponses:

3

JavaScript (ES6), 237 235 222 octets

f=p=>(m=[],s=[],d=0,l=p.indexOf`
`+1,[...p].map((c,i)=>(i+1)%l&&!m[i]?g=d-2<s.indexOf((t=a=>m[a]|p[a]!=c?r=0:(m[a]=y.push(a),n=a<n?a:n,t(a+1)+t(a-1)+t(a+l)+t(a-l)+1))(n=i,y=[])!=5?g=0:s[d++]=y.map(a=>r+=a-n)|r):0),d==12&g)

2 octets enregistrés grâce à @DankMemes !

Usage

f(`000111
203331
203431
22 444
2   46
57 666
57769!
58779!
58899!
5889!!`);
=> true

Explication

Quelques notes sur cette solution:

  • Il est possible que cette réponse ne soit pas valide. Il ne vérifie pas réellement si les pentominos tournés ont la même forme, mais j'ai essayé mais je n'ai pas pu trouver un rectangle pentomino valide qui réponde aux exigences des règles et comprend deux ou plus de la même forme pivotée. Mais je ne suis pas un expert du pentomino, donc si vous trouvez une combinaison valide avec laquelle cela échoue, faites le moi savoir.
  • Les règles exigent également des réponses à utiliser STDINet STDOUTpour l'entrée et la sortie, mais prompt()sont uniquement conçues pour une entrée sur une seule ligne et mon ordinateur (Windows) place automatiquement des \r\ncaractères à chaque nouvelle ligne lors du collage, donc j'en ai fait une fonction qui accepte une chaîne.
f=p=>(
  m=[],                      // m = map of checked characters
  s=[],                      // s = list of shapes found (stored as integer)
  d=0,                       // d = number shapes found
  l=p.indexOf`
`+1,                         // l = length of each line (including newline character)
  [...p].map((c,i)=>         // iterate through each character of the input
    (i+1)%l&&                // skip newline characters
      !m[i]?                 // skip the character if it has already been mapped
        g=                   // g = pentomino is valid
          d-2<s.indexOf(     // check if shape already existed before just now
            (t=a=>           // t() checks if character is part of the shape then maps it
              m[a]|          // skip if character is already mapped
                p[a]!=c      //    or if the current character is part of the shape
              ?r=0:(
                m[a]=        // mark the character as mapped
                  y.push(a), // y = list of shape character indices
                n=a<n?a:n,   // n = minimum index of all characters in the shape
                t(a+1)+      // check and map adjacent characters
                t(a-1)+
                t(a+l)+
                t(a-l)+
                1
              )
          )(n=i,y=[])
            !=5?g=0:         // make sure there are only 5 characters in the shape
            s[d++]=          // add the shape to the list
              y.map(a=>      // sum of (index of each character in the shape - minimum
                r+=a-n)|r    //     index) = unique integer representing the shape
        ):0
  ),
  d==12&g                    // ensure there is 12 shapes and return the 'is valid' result
)
user81655
la source
1
Vous pouvez abuser des modèles balisés avec l=p.indexOf`<newline here>`pour économiser 2 octets
DankMemes
@DankMemes Merci pour la capture! J'étais vraiment fatigué quand j'ai écrit ça et je n'ai pas encore vérifié. : P
user81655