Validatore di lettere


28

Il New York Times ha un gioco online quotidiano chiamato Letter Boxed (il link è dietro un paywall; il gioco è anche descritto qui ), presentato in un quadrato come segue:

Esempio di scatola con lettere del New York Times

Ti vengono dati 4 gruppi di 3 lettere (ogni gruppo corrisponde a un lato dell'immagine); nessuna lettera appare due volte. Lo scopo del gioco è trovare parole composte da quelle 12 lettere (e solo quelle lettere) in modo tale che:

  • Ogni parola è lunga almeno 3 lettere;
  • Le lettere consecutive non possono essere dalla stessa parte;
  • L'ultima lettera di una parola diventa la prima lettera della parola successiva;
  • Tutte le lettere vengono utilizzate almeno una volta (le lettere possono essere riutilizzate).

In questa sfida, ti vengono date le lettere e un elenco di parole. L'obiettivo è verificare se l'elenco di parole è una soluzione Letter Box valida.

Ingresso

L'input è composto da (1) 4 gruppi di 3 lettere e (2) un elenco di parole. Può essere in qualsiasi formato adatto.

Produzione

Un valore veritiero se l'elenco di parole è una soluzione valida alla sfida Letter Boxed per quelle lettere 4 × 3 e un valore falso in caso contrario.

Casi test

Gruppi di lettere = {{I,C,O}, {M,R,E}, {G,N,S}, {A,P,L}}.

Valori sinceri

  • PELLEGRINAGGIO, CHIUDERE
  • CROPS, SAIL, LEAN, NOPE, ENIGMA

Valori di Falsey

  • PELLEGRINAGGIO, ECONOMIE (non possono avere CO poiché sono dalla stessa parte)
  • CROPS, SAIL, LEAN, NOPE (G e M non sono stati usati)
  • PELLEGRINAGGIO, RECINZIONE (U non è una delle 12 lettere)
  • CHIUDI, PELLEGRINAGGIO (l'ultima lettera della prima parola non è la prima lettera della seconda parola)
  • SCAMS, SO, ORGANIZE, ELOPE (tutte le parole devono contenere almeno 3 lettere).

Nota che in questa sfida non ci importa se le parole sono valide (parte di un dizionario).

punteggio:

Questo , il punteggio più basso in byte vince!


4
@TFeldno letter appears twice
feersum

Un valore veritiero se l'elenco di parole è una soluzione valida alla sfida Letter Boxed per quelle lettere 4 × 3 e un valore falso in caso contrario. Per Python (e la maggior parte delle altre lingue, mi aspetto), entrambi []e 0sono falsi. Siamo in grado di produrre o deve essere coerente?
Artemis supporta Monica il

@ArtemisFowl O va bene.
Robin Ryder,

Lo pensavo, ma la mia domanda era: possiamo mescolarli ?
Artemis supporta Monica il

@ArtemisFowl Sì, puoi mescolarli.
Robin Ryder,

Risposte:


6

JavaScript (ES6),  130  126 byte

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

Provalo online!

Passo 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()

Passo 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()

6

Gelatina , 30 29 byte

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

Provalo online!

Un collegamento diadico che prende l'elenco di parole come argomento a sinistra e l'elenco schiacciato di lettere nella casella come argomento a destra. Ritorna 1per vero e 0per falso.

Spiegazione

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

6

05AB1E , 37 35 33 32 31 29 28 byte

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

-2 byte prendendo ispirazione del êapproccio @Emigna utilizzato nella sua risposta 05AB1E .
-3 byte grazie a @Grimy .

Prende un elenco di elenco di caratteri per le parole come primo input e l'elenco appiattito di dodici lettere come secondo input.

Provalo online o verifica tutti i casi di test .

Spiegazione:

ε         # 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)

1
@Grimy Ah, quel primo commento è davvero ovvio. L'ho appena cambiato in un array di caratteri, quindi ora funziona davvero dove prima non sarebbe stato quando le parole erano ancora stringhe. Quel secondo approccio di unione, verifica dell'uguaglianza delle coppie, la somma è abbastanza brillante, però! : D Grazie (come sempre).
Kevin Cruijssen,

1
Un altro -1: ¹€g3@-> DO2@dopo il primo controllo ( TIO )
Grimmy,

1
@Grimy Un altro bello, grazie. Ora siamo al di sotto della risposta Jelly del 29. :)
Kevin Cruijssen il

5

05AB1E , 42 byte

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

Provalo online!


Non è molto, ma un byte può essere salvato rimuovendo tutto Pdopo le mappe e utilizzandolo )˜Palla fine. 41 byte Approccio piacevole con êcomunque! Ho salvato 2 byte nella mia risposta 05AB1E.
Kevin Cruijssen,

4

Python 2 , 171 byte

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

Provalo online!



4

Haskell , 231 byte

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

Provalo online!

Non il punteggio migliore. Alcuni guru di Haskell saranno probabilmente in grado di ottenere questo sotto 100 byte.

uso

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

Spiegazione

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

4

Haskell , 231 byte

Una diversa variante di Haskell, esattamente delle stesse dimensioni di @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)

Provalo online!

Ungolfed

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

3

Rubino , 126 byte

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

Provalo online!


Bello, quando ho visto per la prima volta la sfida ho provato a fare qualcosa di simile, ma ho rinunciato con un punteggio da qualche parte in 140-ie. A proposito, salva un byte rilasciando le parentesi dopo grep.
Kirill L.

Questo non funziona quando l'ultima parola è lunga 1 o 2 lettere, ad esempio puts f[l,['PILGRIMAGE','ENCLOSE','EG']]restituisce trueinvece di false.
Robin Ryder,

1
Hai ragione, risolto.
GB

3

Java (JDK) , 188 byte

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;}

Provalo online!

spiegazioni

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.
}

Crediti

  • -2 byte grazie a ceilingcat

2

Carbone , 63 byte

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

Provalo online! Il collegamento è alla versione dettagliata del codice. Spiegazione:

⌊⁺⁺⁺

Concatena le espressioni e l'output seguenti 0se uno di essi include un 0contrario 1.

⭆η›Lι²

Per ogni parola nell'output della soluzione se la sua lunghezza è almeno 3.

⭆⪫ηω№⪫θωι

Per ogni lettera nell'output della soluzione se appare nel puzzle.

⭆⪫θω№⪫ηωι

Per ogni lettera nell'output del puzzle, se appare nella soluzione.

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

Per ogni lettera nella soluzione verifica che la lettera precedente non sia nello stesso gruppo, a meno che non sia la prima lettera di una parola, nel qual caso verifica che sia uguale all'ultima lettera della parola precedente, a meno che non sia la prima lettera della soluzione, nel qual caso basta ignorarla.


0

Python 2 , 168 156 byte

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)

Provalo online!

Ritorna 1per la verità, 0per la falsità.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.