Validator Kotak Surat

28

The New York Times memiliki game online harian yang disebut Letter Boxed (tautannya ada di belakang paywall; game ini juga dijelaskan di sini ), disajikan di kotak sebagai berikut:

Contoh Kotak Surat dari New York Times

Anda diberi 4 grup yang terdiri dari 3 huruf (masing-masing grup sesuai dengan satu sisi pada gambar); tidak ada huruf yang muncul dua kali. Tujuan permainan ini adalah untuk menemukan kata-kata yang terbuat dari 12 huruf (dan hanya huruf-huruf itu) sehingga:

  • Setiap kata setidaknya 3 huruf;
  • Surat berturut-turut tidak boleh dari sisi yang sama;
  • Huruf terakhir dari sebuah kata menjadi huruf pertama dari kata berikutnya;
  • Semua huruf digunakan setidaknya satu kali (huruf dapat digunakan kembali).

Dalam tantangan ini, Anda diberikan surat dan daftar kata. Tujuannya adalah untuk memeriksa apakah daftar kata-kata merupakan solusi Kotak Surat yang valid.

Memasukkan

Input terdiri dari (1) 4 grup yang terdiri dari 3 huruf dan (2) daftar kata. Itu bisa dalam format yang sesuai.

Keluaran

Nilai kebenaran jika daftar kata-kata adalah solusi yang valid untuk tantangan Letter Boxed untuk 4 × 3 huruf tersebut, dan nilai falsey sebaliknya.

Uji kasus

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

Nilai-nilai yang sebenarnya

  • PILGRIMAGE, ENCLOSE
  • TANAMAN, SAIL, LEAN, NOPE, ENIGMA

Nilai-nilai Falsey

  • PILGRIMAGE, EKONOMI (tidak dapat memiliki CO karena berada di sisi yang sama)
  • TANAMAN, SAIL, LEAN, NOPE (G dan M belum pernah digunakan)
  • PILGRIMAGE, ENCLOSURE (U bukan salah satu dari 12 huruf)
  • ENCLOSE, PILGRIMAGE (huruf terakhir dari kata pertama bukan huruf pertama dari kata kedua)
  • SCAM, SO, ORGANIZE, ELOPE (semua kata harus terdiri dari minimal 3 huruf).

Perhatikan bahwa dalam tantangan ini, kami tidak peduli apakah kata-kata itu valid (bagian dari kamus).

Mencetak:

Golf ini , skor terendah dalam byte menang!

Robin Ryder
sumber
4
@TFeldno letter appears twice
feersum
Nilai kebenaran jika daftar kata-kata adalah solusi yang valid untuk tantangan Letter Boxed untuk 4 × 3 huruf tersebut, dan nilai falsey sebaliknya. Untuk Python (dan sebagian besar bahasa lain, saya harapkan), keduanya []dan 0adalah falsey. Bisakah kita output, atau haruskah output kita konsisten?
Artemis mendukung Monica
@ArtemisFowl Baik baik-baik saja.
Robin Ryder
Saya pikir begitu, tetapi pertanyaan saya adalah: bisakah kita mencampurnya ?
Artemis mendukung Monica
@ ArtemisFowl Ya, Anda bisa mencampurnya.
Robin Ryder

Jawaban:

6

JavaScript (ES6),  130  126 byte

Mengambil input sebagai (letters)(words). Mengembalikan 0 atau 1 .

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

Cobalah online!

Langkah 1

Kami pertama iterate lebih L. untuk membangun pipa-string dipisahkan s terdiri dari semua pasangan tidak sah surat. Saat melakukannya, kami juga memastikan bahwa setiap huruf muncul setidaknya satu kali dalam beberapa kata.

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

Langkah 2

Kami sekarang beralih ke W untuk menguji setiap kata.

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
sumber
6

Jelly , 30 29 byte

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

Cobalah online!

Tautan diad yang menggunakan daftar kata sebagai argumen kiri dan daftar huruf rata dalam kotak sebagai argumen yang benar. Ia mengembalikan 1true dan0 salah.

Penjelasan

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
sumber
6

05AB1E , 37 35 33 32 31 29 28 byte

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

-2 byte dengan mengambil inspirasi dari êpendekatan @Emigna yang digunakan dalam jawaban 05AB1E-nya .
-3 byte terima kasih kepada @Grimy .

Mengambil daftar daftar karakter untuk kata-kata sebagai input pertama, dan daftar rata dua belas huruf sebagai input kedua.

Cobalah secara online atau verifikasi semua kasus uji .

Penjelasan:

ε         # 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
sumber
1
@ Grimy Ah, komentar pertama itu memang jelas. Saya baru saja mengubahnya menjadi array karakter, jadi sekarang itu memang berfungsi di mana tidak akan terjadi sebelumnya ketika kata-kata masih string. Pendekatan penggabungan kedua , periksa kesetaraan pasangan, jumlah cukup brilian, meskipun! : D Terima kasih (seperti biasa).
Kevin Cruijssen
1
Lain -1: ¹€g3@-> DO2@setelah cek pertama ( TIO )
Grimmy
1
@Grimy Satu lagi yang bagus, terima kasih. Kami sekarang di bawah jawaban Jelly dari 29. :)
Kevin Cruijssen
5

05AB1E , 42 byte

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

Cobalah online!

Emigna
sumber
Tidak banyak, tetapi satu byte dapat disimpan dengan menghapus semua Psetelah peta, dan menggunakannya )˜Pdi akhir. 41 byte Pendekatan yang bagus dengan ênamun! Disimpan 2 byte dalam jawaban 05AB1E saya.
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

Cobalah online!

TFeld
sumber
4

Jelly , 34 byte

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

Tautan diadik yang menerima kata-kata di sebelah kiri dan grup surat di sebelah kanan yang menghasilkan 1jika valid dan 0jika tidak.

Cobalah online! Atau lihat test-suite .

Jonathan Allan
sumber
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

Cobalah online!

Bukan skor terbaik. Beberapa guru Haskell mungkin bisa mendapatkan ini di bawah 100 byte.

Pemakaian

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

Penjelasan

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
sumber
4

Haskell , 231 byte

Variasi Haskell berbeda, ukurannya persis sama dengan @Paul Mutser's :)

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)

Cobalah online!

Tidak disatukan

-- 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)
bug
sumber
3

Ruby , 126 byte

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

Cobalah online!

GB
sumber
Bagus, ketika saya pertama kali melihat tantangan saya mencoba melakukan sesuatu yang serupa, tetapi menyerah dengan skor di suatu tempat di 140-an. BTW, simpan byte dengan menjatuhkan tanda kurung setelah grep.
Kirill L.
Ini tidak berfungsi ketika kata terakhir panjangnya 1 atau 2 huruf, misalnya puts f[l,['PILGRIMAGE','ENCLOSE','EG']]mengembalikan truebukan false.
Robin Ryder
1
Anda benar, tetap.
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;}

Cobalah online!

Penjelasan

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

Kredit

  • -2 bytes berkat ceilingcat
Olivier Grégoire
sumber
2

Arang , 63 byte

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

Cobalah online! Tautan adalah untuk mengucapkan versi kode. Penjelasan:

⌊⁺⁺⁺

Gabungkan ekspresi dan output di bawah ini 0jika ada di antaranya yang termasuk 0sebaliknya 1.

⭆η›Lι²

Untuk setiap kata dalam solusi, hasilkan apakah panjangnya setidaknya 3.

⭆⪫ηω№⪫θωι

Untuk setiap huruf dalam solusi, hasilkan apakah itu muncul dalam puzzle.

⭆⪫θω№⪫ηωι

Untuk setiap huruf dalam output puzzle apakah itu muncul dalam solusi.

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

Untuk setiap huruf dalam solusi, periksa apakah huruf sebelumnya tidak berada dalam kelompok yang sama, kecuali jika itu adalah huruf pertama dari sebuah kata, dalam hal ini periksa apakah itu sama dengan huruf terakhir dari kata sebelumnya, kecuali itu adalah yang pertama surat solusinya, dalam hal ini abaikan saja.

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

Cobalah online!

Kembali 1untuk kebenaran, 0untuk kebohongan.

Chas Brown
sumber