Walidator w skrzynce pocztowej

28

New York Times ma codzienną grę online o nazwie Letter Boxed (link znajduje się za zaporą; gra jest również opisana tutaj ), przedstawiona na kwadracie w następujący sposób:

Przykład skrzynki na listy z New York Times

Dostajesz 4 grupy po 3 litery (każda grupa odpowiada jednej stronie na zdjęciu); żadna litera nie pojawia się dwukrotnie. Celem gry jest znalezienie słów składających się z tych 12 liter (i tylko tych liter), aby:

  • Każde słowo ma co najmniej 3 litery;
  • Kolejne litery nie mogą być z tej samej strony;
  • Ostatnia litera słowa staje się pierwszą literą następnego słowa;
  • Wszystkie litery są używane co najmniej raz (litery można ponownie wykorzystać).

W tym wyzwaniu otrzymasz litery i listę słów. Celem jest sprawdzenie, czy lista słów jest prawidłowym rozwiązaniem w skrzynce na listy.

Wkład

Dane wejściowe składają się z (1) 4 grup po 3 litery i (2) listy słów. Może być w dowolnym odpowiednim formacie.

Wydajność

Prawdziwa wartość, jeśli lista słów jest prawidłowym rozwiązaniem wyzwania w skrzynce na listy dla tych liter 4 × 3, a w przeciwnym razie wartość falsey.

Przypadki testowe

Grupy liter = {{I,C,O}, {M,R,E}, {G,N,S}, {A,P,L}}.

Prawdziwe wartości

  • PIELGRZYMKA, OBEJMUJ
  • CROPS, SAIL, LEAN, NOPE, ENIGMA

Wartości Falsey

  • PIELGRZYMKA, GOSPODARKA (nie może mieć CO, ponieważ są po tej samej stronie)
  • CROPS, SAIL, LEAN, NOPE (G i M nie były używane)
  • PIELGRZYMKA, OBUDOWA (U nie jest jedną z 12 liter)
  • OBEJMUJ, PIELGRZYMKA (ostatnia litera pierwszego słowa nie jest pierwszą literą drugiego słowa)
  • Oszustwa, SO, ORGANIZACJA, ELOPE (wszystkie słowa muszą mieć co najmniej 3 litery).

Pamiętaj, że w tym wyzwaniu nie dbamy o to, czy słowa są poprawne (część słownika).

Punktacja:

Ten , najniższy wynik w bajtach wygrywa!

Robin Ryder
źródło
4
@TFeldno letter appears twice
feersum
Prawdziwa wartość, jeśli lista słów jest prawidłowym rozwiązaniem wyzwania w skrzynce na listy dla tych liter 4 × 3, a w przeciwnym razie wartość falsey. Dla Pythona (i większości innych języków, spodziewam), oba []i 0są falsey. Czy możemy generować wyniki, czy też nasze wyniki muszą być spójne?
Artemis obsługuje Monikę
@ArtemisFowl Albo jest w porządku.
Robin Ryder
Tak myślałem, ale moje pytanie brzmiało: czy możemy je mieszać ?
Artemis obsługuje Monikę
@ArtemisFowl Tak, możesz je mieszać.
Robin Ryder

Odpowiedzi:

6

JavaScript (ES6),  130  126 bajtów

Pobiera dane wejściowe jako (letters)(words). Zwraca lub .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)))

Wypróbuj online!

Krok 1

Najpierw iteracyjnego do budowy rur oddziela łańcuch składa się z wszystkich nieprawidłowych pary liter. Robiąc to, upewniamy się również, że każda litera pojawia się przynajmniej raz w jednym słowie.L.s

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

Krok 2

Teraz iterujemy nad aby przetestować każde słowo.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
źródło
6

Galaretka , 30 29 bajtów

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

Wypróbuj online!

Dyadyczny link, który przyjmuje listę słów jako lewy argument, a spłaszczoną listę liter w polu jako prawy argument. Zwraca wartość 1prawda i 0fałsz.

Wyjaśnienie

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
źródło
6

05AB1E , 37 35 33 32 31 29 28 bajtów

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

-2 bajty, czerpiąc inspirację z êpodejścia @Emigna zastosowanego w jego odpowiedzi 05AB1E .
-3 bajty dzięki @Grimy .

Pobiera listę znaków dla słów jako pierwsze wejście, a spłaszczoną listę dwunastu liter jako drugie wejście.

Wypróbuj online lub sprawdź wszystkie przypadki testowe .

Wyjaśnienie:

ε         # 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
źródło
1
@Grimy Ah, ten pierwszy komentarz jest rzeczywiście oczywisty. Właśnie zmieniłem go na tablicę znaków, więc teraz działa naprawdę tam, gdzie wcześniej nie byłoby, gdy słowa były ciągami. To drugie podejście łączenia, sprawdzania równości par, suma jest jednak genialne! : D Dzięki (jak zawsze).
Kevin Cruijssen
1
Kolejne -1: ¹€g3@-> DO2@po pierwszej kontroli ( TIO )
Grimmy
1
@Grimy Kolejny miły, dzięki. Jesteśmy teraz poniżej odpowiedzi
żelki
5

05AB1E , 42 bajty

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

Wypróbuj online!

Emigna
źródło
To niewiele, ale bajt można zapisać, usuwając wszystko Ppo mapach i używając )˜Pna końcu. 41 bajtów. Przyjemne podejście ê! Zapisałem 2 bajty w mojej odpowiedzi 05AB1E.
Kevin Cruijssen
4

Python 2 , 171 bajtów

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

Wypróbuj online!

TFeld
źródło
4

Galaretka , 34 bajty

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

Dyadyczny link akceptujący słowa po lewej stronie i grupy liter po prawej, które dają, 1jeśli są prawidłowe, a 0jeśli nie.

Wypróbuj online! Lub zobacz zestaw testowy .

Jonathan Allan
źródło
4

Haskell , 231 bajtów

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

Wypróbuj online!

Nie najlepszy wynik. Niektórzy guru z Haskell prawdopodobnie będą w stanie uzyskać to poniżej 100 bajtów.

Stosowanie

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

Wyjaśnienie

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
źródło
4

Haskell , 231 bajtów

Inna odmiana Haskell, dokładnie taka sama jak @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)

Wypróbuj online!

Nie golfił

-- 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)
robaki
źródło
3

Rubin , 126 bajtów

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

Wypróbuj online!

GB
źródło
Fajnie, kiedy po raz pierwszy zobaczyłem wyzwanie, próbowałem zrobić coś podobnego, ale poddałem się z wynikiem gdzieś w latach 140-tych. BTW, zapisz bajt, upuszczając po nim nawiasy grep.
Kirill L.
To nie działa, gdy ostatnie słowo ma 1 lub 2 litery, np. puts f[l,['PILGRIMAGE','ENCLOSE','EG']]Zwraca truezamiast false.
Robin Ryder
1
Masz rację, naprawiony.
GB
3

Java (JDK) , 188 bajtów

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

Wypróbuj online!

Objaśnienia

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

Kredyty

  • -2 bajty dzięki pułapkowi cat
Olivier Grégoire
źródło
2

Węgiel drzewny , 63 bajty

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

Wypróbuj online! Link jest do pełnej wersji kodu. Wyjaśnienie:

⌊⁺⁺⁺

Połącz poniższe wyrażenia i wyślij, 0jeśli którekolwiek z nich zawiera 0inaczej 1.

⭆η›Lι²

Dla każdego słowa w rozwiązaniu wypisz, czy jego długość wynosi co najmniej 3.

⭆⪫ηω№⪫θωι

Dla każdej litery w rozwiązaniu wypisz, czy pojawia się ona w układance.

⭆⪫θω№⪫ηωι

Dla każdej litery w wyjściu układanki, czy pojawia się w rozwiązaniu.

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

Dla każdej litery w rozwiązaniu sprawdź, czy poprzednia litera nie należy do tej samej grupy, chyba że jest to pierwsza litera słowa, w takim przypadku sprawdź, czy jest ona równa ostatniej literze poprzedniego słowa, chyba że jest to pierwsza litera rozwiązania, w którym to przypadku po prostu go zignoruj.

Neil
źródło
0

Python 2 , 168 156 bajtów

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)

Wypróbuj online!

Zwraca 1za prawdę, 0za falsey.

Chas Brown
źródło