Validateur de boîte aux lettres

28

Le New York Times a un jeu en ligne quotidien appelé Letter Boxed (le lien est derrière un mur payant; le jeu est également décrit ici ), présenté sur un carré comme suit:

Exemple de boîte aux lettres du New York Times

On vous donne 4 groupes de 3 lettres (chaque groupe correspond à un côté sur l'image); aucune lettre n'apparaît deux fois. Le but du jeu est de trouver des mots composés de ces 12 lettres (et de ces lettres uniquement) de telle sorte que:

  • Chaque mot comporte au moins 3 lettres;
  • Les lettres consécutives ne peuvent pas être du même côté;
  • La dernière lettre d'un mot devient la première lettre du mot suivant;
  • Toutes les lettres sont utilisées au moins une fois (les lettres peuvent être réutilisées).

Dans ce défi, vous recevez les lettres et une liste de mots. Le but est de vérifier si la liste de mots est une solution valide de boîte aux lettres.

Contribution

La saisie consiste en (1) 4 groupes de 3 lettres et (2) une liste de mots. Il peut être dans n'importe quel format approprié.

Sortie

Une valeur vraie si la liste de mots est une solution valide au défi Boîte aux lettres pour ces 4 × 3 lettres, et une valeur de falsey sinon.

Cas de test

Groupes de lettres = {{I,C,O}, {M,R,E}, {G,N,S}, {A,P,L}}.

Des valeurs véridiques

  • PÈLERINAGE, CLÔTURE
  • CULTURES, VOILE, LEAN, NOPE, ENIGMA

Valeurs de Falsey

  • PÈLERINAGE, ÉCONOMIES (ne peut pas avoir de CO car ils sont du même côté)
  • CROPS, SAIL, LEAN, NOPE (G et M n'ont pas été utilisés)
  • PÈLERINAGE, ENCEINTE (U n'est pas l'une des 12 lettres)
  • ENCLOSE, PELGRIMAGE (la dernière lettre du 1er mot n'est pas la première lettre du 2e mot)
  • SCAMS, SO, ORGANIZE, ELOPE (tous les mots doivent contenir au moins 3 lettres).

Notez que dans ce défi, nous ne nous soucions pas de la validité des mots (partie d'un dictionnaire).

Notation:

Ce , le score le plus bas en octets gagne!

Robin Ryder
la source
4
@TFeldno letter appears twice
feersum
Une valeur vraie si la liste de mots est une solution valide au défi Boîte aux lettres pour ces 4 × 3 lettres, et une valeur de falsey sinon. Pour Python (et la plupart des autres langues, je pense), les deux []et 0sont falsey. Pouvons-nous produire l'un ou l'autre, ou devons-nous être cohérents?
Artemis soutient Monica le
@ArtemisFowl Soit c'est bien.
Robin Ryder
Je le pensais, mais ma question était: pouvons-nous les mélanger ?
Artemis prend en charge Monica le
@ArtemisFowl Oui, vous pouvez les mélanger.
Robin Ryder

Réponses:

6

JavaScript (ES6),  130  126 octets

(letters)(words)01

L=>W=>L.every(a=>a.every(x=>(W+'').match(x,a.map(y=>s+='|'+x+y))),p=s=1)&W.every(w=>w[2]&&p|w[0]==p&!w.match(s,p=w.slice(-1)))

Essayez-le en ligne!

Étape 1

Ls

L.every(a =>              // for each group of letter a[] in L[]:
  a.every(x =>            //   for each letter x in a[]:
    (W + '')              //     coerce W[] to a string
    .match(               //     and test whether ...
      x,                  //       ... x can be found in it
      a.map(y =>          //       for each letter y in a[]:
        s += '|' + x + y  //         append '|' + x + y to s
      )                   //       end of map()
    )                     //     end of match()
  ),                      //   end of inner every()
  p = s = 1               //   start with p = s = 1
)                         // end of outer every()

Étape 2

W

W.every(w =>              // for each word w in W[]:
  w[2] &&                 //   is this word at least 3 characters long?
  p |                     //   is it the first word? (p = 1)
  w[0] == p &             //   or does it start with the last letter of the previous word?
  !w.match(               //   and finally make sure that ...
    s,                    //     ... it doesn't contain any invalid pair of letters
    p = w.slice(-1)       //     and update p to the last letter of w
  )                       //   end of match()
)                         // end of every()
Arnauld
la source
6

Gelée , 30 29 octets

FQṢ=Ṣ},i@€€’:3Iʋ,Ẉ>2ɗ,U=ḢɗƝ{Ȧ

Essayez-le en ligne!

Un lien dyadique qui prend la liste de mots comme argument de gauche et la liste aplatie de lettres dans la boîte comme argument de droite. Il revient 1pour vrai et 0pour faux.

Explication

F                               | Flatten the word list
 Q                              | Unique
  Ṣ                             | Sort
   =                            | Is equal to
    Ṣ}                          |   The sorted letterbox letters
      ,        ʋ                | Pair this with the following:
       i@€€                     |   The index of each letter of each word in the letterbox            
           ’                    |   Decrease by 1
            :3                  |   Integer divide by 3
              I                 |   Differences between consecutive ones (will be zero if any two consecutive letters in a word from same side of box)
                ,   ɗ           | Pair everything so far with the following:
                 Ẉ>2            |   Whether length of each input word is greater than 2
                     ,   ɗƝ{    | Pair everything so far with the following, applied to each neighbouring pair of the input word list
                      U         |   Upend (reverse) first word
                       =        | Compare characters to second
                        Ḣ       |   Take first (i.e. last character of first word equals first character of second)
                            Ȧ   | Flatten all of the above and check there are no false values
Nick Kennedy
la source
6

05AB1E , 37 35 33 32 31 29 28 octets

εk3÷üÊ}DO2@¹ü«εüQO}²{¹˜êQ)˜P

-2 octets en s'inspirant de l' êapproche @Emigna utilisée dans sa réponse 05AB1E .
-3 octets grâce à @Grimy .

Prend une liste de liste de caractères pour les mots comme première entrée et la liste aplatie de douze lettres comme deuxième entrée.

Essayez-le en ligne ou vérifiez tous les cas de test .

Explication:

ε         # Map over the character-lists `y` of the (implicit) input-list of words:
 k        #  Get the index of each character in the (implicit) input-list of letters
  3÷      #  Integer-divide each index by 3
    üÊ    #  Check for each overlapping pair of integers that they are NOT equal
}D        # After the map: duplicate the resulting list
  O       #  Get the sum of each inner list of truthy/falsey values
   2@     #  And check that each is larger than 2 (so all words had at least 3 letters)
¹ü        # Get all overlapping pairs of character-lists from the input-list of words:
  «       #  And merge them together to a flattened list of characters
   ε   }  # Map over those merged character lists:
    üQ    #  Check for each overlapping pair of characters in the list that they are equal
      O   #  And take the sum of this (where we'd expect 1/truthy if the last character of
          #  the first word and the first character of the second word are equal)
          #  (NOTE: This could fail for inputs with identical adjacent characters,
          #   but the earlier check of `εk3÷üÊ}` already covers for this)
²{        # Push the input-list of letters, and sort them
  ¹˜      # Push the input-list of list of word-letters, flattened,
    ê     # and then uniquified and sorted as well
     Q    # And check if both lists of characters are the same
        # Then wrap everything on the stack into a list, and deep flatten it
  P       # And check if everything is truthy by taking the product
          # (which is output implicitly as result)
Kevin Cruijssen
la source
1
@Grimy Ah, ce premier commentaire est en effet évident. Je viens de le changer en un tableau de caractères, donc maintenant cela fonctionne effectivement là où il ne le faisait pas auparavant quand les mots étaient encore des chaînes. Cette deuxième approche de fusion, vérifiez l'égalité des paires, la somme est assez brillante, cependant! : D Merci (comme toujours).
Kevin Cruijssen
1
Un autre -1: ¹€g3@-> DO2@après le premier contrôle ( TIO )
Grimmy
1
@Grimy Encore une bonne idée, merci. Nous sommes maintenant en dessous de la réponse Jelly de 29. :)
Kevin Cruijssen
5

05AB1E , 42 octets

εg2›}P¹εεUIεXå}ƶO}üÊP}P¹ü‚ε`нsθQ}P¹Jê²JêQP

Essayez-le en ligne!

Emigna
la source
Ce n'est pas grand-chose, mais un octet peut être enregistré en supprimant tout Paprès les cartes et à utiliser )˜Pà la fin. 41 octets Belle approche avec êcependant! Enregistré 2 octets dans ma réponse 05AB1E.
Kevin Cruijssen
4

Python 2 , 171 octets

lambda l,w:(set(sum(l,[]))==set(''.join(w)))*all(a[-1]==b[0]for a,b in zip(w,w[1:]))*all((a in g)+(b in g)<2for x in w for a,b in zip(x,x[1:])for g in l)*min(map(len,w))>2

Essayez-le en ligne!

TFeld
la source
4

Gelée , 34 octets

Ṫ=¥/ƝḢ€Ạȧ⁸Fe€ⱮZḄ;IẠƊȧF}fƑF{
ẈṂ>2ȧç

Un lien dyadique acceptant les mots à gauche et les groupes de lettres à droite qui donne 1si valide et 0sinon.

Essayez-le en ligne! Ou consultez la suite de tests .

Jonathan Allan
la source
4

Haskell , 231 octets

import Data.List
l&w=all((>2).length)w&&c w&&all(l!)w&&(h l)%(h w)
h=concat
l%w=null[x|x<-l,x`notElem`w]
l!(a:b:c)=a#l?(b#l)&&l!(b:c)
l!_=1>0
Just a?Just b=a/=b
_?_=1<0
c#l=findIndex(elem c)l
c(a:b:t)=last a==head b&&c(b:t)
c _=1>0

Essayez-le en ligne!

Pas le meilleur score. Certains gourous de Haskell seront probablement en mesure d'obtenir cela sous 100 octets.

Usage

["ICO","MRE","GNS","APL"]&["CROPS", "SAIL", "LEAN", "NOPE", "ENIGMA"]

Explication

import Data.List
l&w = all((>2).length)w &&      -- Every word has length > 2
      c w &&                    -- Every word ends with the same letter as the next one starts with
      all(l!)w &&               -- For every word: Consecutive letters are on different sides (and must exist on a side)
      (h l)%(h w)               -- All letters are used

h=concat                        -- Just a shorthand

l%w=null[x|x<-l,x`notElem`w]    -- The letters of l, with all letters of w removed, is empty

l!(a:b:c)=a#l?(b#l)&&l!(b:c)    -- Sides of the first two letters are different, recurse from second letter
l!_=1>0                         -- Until fewer than 2 letters remain

Just a?Just b=a/=b              -- Both sides must be different
_?_=1<0                         -- And must exist

c#l=findIndex(elem c)l          -- Find the side of letter c

c(a:b:t)=last a==head b&&c(b:t) -- Last letter of the first word must be same as first letter of second word, recurse starting from second word
c _=1>0                         -- Until there are fewer than 2 words
Paul Mutser
la source
4

Haskell , 231 octets

Une variation Haskell différente, exactement de la même taille que @Paul Mutser :)

import Data.List
f x=filter(\a->length a>1)$concatMap subsequences x
g=nub.concat.f
p l(x:y)=foldl(\(m,n)c->(c,n&&length c>2&&(not$any(`isInfixOf`c)(f l))&&last m==head c))(x,True)y
z l w=null(g l\\g w)&&null(g w\\g l)&&(snd$p l w)

Essayez-le en ligne!

Non golfé

-- generate all invalid substrings
f :: [String] -> [String] 
f xs = filter (\x -> length x > 1) $ concatMap subsequences xs

-- utility function to flatten and remove duplicates
g :: [String] -> String
g  = nub $ concat $ f

-- verify that all conditions are satisfied along the list
p :: [String] -> [String] -> (String, Bool)
p l (x:xs) = foldl (\(m,n) c -> (c , n && length c > 2 && (not $ any (`isInfixOf` c)(f l)) && last m == head c)) (x, True) xs

-- put all the pieces together and consume input
z :: [String] -> [String] -> Bool
z l w = null (g l \\ g w) && null (g w \\ g l) && (snd $ p l w)
bogues
la source
3

Rubis , 126 octets

->l,w{(/(_|^)..(_|$)/!~s=w*?_)&&!!s.chars.uniq[12]&&/__|^_|_$|(_.*)\1/!~s.gsub(/(.)_\1/,'\1').chars.map{|x|l.grep(/#{x}/)}*?_}

Essayez-le en ligne!

GB
la source
Bien, quand j'ai vu le défi pour la première fois, j'ai essayé de faire quelque chose de similaire, mais j'ai abandonné avec un score quelque part dans 140-s. BTW, enregistrez un octet en supprimant les parenthèses après grep.
Kirill L.
Cela ne fonctionne pas lorsque le dernier mot contient 1 ou 2 lettres, par exemple puts f[l,['PILGRIMAGE','ENCLOSE','EG']]retourne trueau lieu de false.
Robin Ryder
1
Vous avez raison, fixe.
GB
3

Java (JDK) , 188 octets

g->w->{var v=0<1;int x=0,l,i=0,j,p,z,y=w[0][0];for(;i<w.length;i++)for(l=w[i].length,v&=y==w[i][0]&l>2,j=0,p=-9;j<l;v&=z>=0&z/3!=p/3,x|=2<<(p=z))z=g.indexOf(y=w[i][j++]);return v&x==8190;}

Essayez-le en ligne!

Explications

g->w->{     // Lambda accepting letter groups as a string and a list of words, in the form of an array of char arrays.
 var v=0<1;     // Validity variable
 int x=0,       // The letter coverage (rule 4)
     l,         // The length of w[i]
     i=0,       // The w iterator
     j,         // The w[i] iterator
     p,         // The previous group
     z,         // The current group
     y=w[0][0]; // The previous character
 for(;i<w.length;i++) // For each word...
  for(
     l=w[i].length,     // make a shortcut for the length
     v&=y==w[i][0]&l>2, // check if the last character of the previous word is the same as the first of the current.
                        // Also, check if the length is at least 3
     j=0,               // Reset the iteration
     p=-9               // Set p to an impossible value.
    ;
     j<l                // 
    ;
     v&=z>=0&z/3!=p/3,  // Check that each letter of the word is in the letter pool,
                        //  and that the current letter group isn't the same as the previous one.
     x|=2<<(p=z)      // After the checks, assign z to p,
                        //  and mark the letter of the pool as used.
   )
   z=g.indexOf(y=w[i][j++]); // Assign the current letter to y so that it contains the last at the end of the loop.
                             //  and fetch the position of the letter in the pool.
 return v&x==8190; // Return true if all matched
                   //  and if the rule 4 is enforced.
}

Crédits

  • -2 octets grâce au plafond
Olivier Grégoire
la source
2

Fusain , 63 octets

⌊⁺⁺⁺⭆η›Lι²⭆⪫ηω№⪫θωι⭆⪫θω№⪫ηωι⭆η⭆ι⎇μ¬⁼Φθ№νλΦθ№ν§ι⊖μ∨¬κ⁼§ι⁰§§η⊖κ±¹

Essayez-le en ligne! Le lien est vers la version détaillée du code. Explication:

⌊⁺⁺⁺

Concaténez les expressions ci-dessous et affichez-les 0si l'une d'entre elles inclut un 0sinon 1.

⭆η›Lι²

Pour chaque mot de la solution, indiquez si sa longueur est d'au moins 3.

⭆⪫ηω№⪫θωι

Pour chaque lettre de la solution, indiquez si elle apparaît dans le puzzle.

⭆⪫θω№⪫ηωι

Pour chaque lettre du puzzle, indiquez si elle apparaît dans la solution.

⭆η⭆ι⎇μ¬⁼Φθ№νλΦθ№ν§ι⊖μ∨¬κ⁼§ι⁰§§η⊖κ±¹

Pour chaque lettre de la solution, vérifiez que la lettre précédente n'est pas dans le même groupe, sauf s'il s'agit de la première lettre d'un mot, auquel cas vérifiez qu'elle est égale à la dernière lettre du mot précédent, sauf si elle est la première lettre de la solution, auquel cas il suffit de l'ignorer.

Neil
la source
0

Python 2 , 168 156 octets

lambda l,w,J=''.join:(set(J(w))==set(J(l)))*all((v<1or u[-1]==v[0])*u[2:]*(2>(x in p)+(y in p))for u,v in zip(w,w[1:]+[0])for x,y in zip(u,u[1:])for p in l)

Essayez-le en ligne!

Retourne 1pour vrai, 0pour falsey.

Chas Brown
la source