레터 박스 검사기


28

New York Times에는 Letter Boxed 라는 온라인 게임이 매일 있습니다 (링크는 페이 월 뒤에 있으며 게임도 여기에 설명 되어 있음). 다음과 같이 사각형에 표시됩니다.

Letter Boxed example from the New York Times

당신은 3 글자로 된 4 개의 그룹을받습니다 (각 그룹은 그림의 한쪽에 해당합니다). 글자가 두 번 나타나지 않습니다. 이 게임의 목표는 다음과 같은 12 글자로 된 단어를 찾는 것입니다.

  • 각 단어의 길이는 3 자 이상입니다.
  • 연속 문자는 같은 쪽에서 나올 수 없습니다.
  • 단어의 마지막 글자는 다음 단어의 첫 글자가됩니다.
  • 모든 문자는 한 번 이상 사용됩니다 (문자는 재사용 가능).

이 도전에서, 당신은 글자와 단어의 목록이 제공됩니다. 목표는 단어 목록이 유효한 레터 박스 솔루션인지 확인하는 것입니다.

입력

입력은 (1) 3 개의 문자로 구성된 4 개의 그룹과 (2) 단어 목록으로 구성됩니다. 적합한 형식 일 수 있습니다.

산출

단어 목록이 4x3 글자에 대한 레터 박스 챌린지에 대한 유효한 솔루션 인 경우 진실 값, 그렇지 않으면 거짓 값.

테스트 사례

글자 그룹 ={{I,C,O}, {M,R,E}, {G,N,S}, {A,P,L}} .

진실한 가치

  • 순례, 동봉
  • 농작물, SAIL, LEAN, NOPE, ENIGMA

팔시 값

  • 순례, 경제 (동일한쪽에 있으므로 CO를 가질 수 없음)
  • 작물, SAIL, LEAN, NOPE (G 및 M은 사용되지 않음)
  • 순례, 엔클로저 (U는 12 자 중 하나가 아님)
  • ENCLOSE, PILGRIMAGE (첫 번째 단어의 마지막 글자가 두 번째 단어의 첫 글자가 아님)
  • SCAMS, SO, ORGANISE, ELOPE (모든 단어는 3 자 이상이어야합니다).

이 과제에서는 단어가 유효한지 (사전의 일부) 상관하지 않습니다.

채점 :

, 바이트 단위의 최저 점수가 승리합니다!


4
@TFeldno letter appears twice
feersum

단어 목록이 4x3 글자에 대한 레터 박스 챌린지에 대한 유효한 솔루션 인 경우 진실 값, 그렇지 않으면 거짓 값. 파이썬의 경우 (대부분의 다른 언어, 나는 기대), 모두 []0falsey 있습니다. 출력을 할 수 있습니까, 아니면 출력이 일정해야합니까?
Artemis는

@ArtemisFowl 어느 쪽이든 괜찮습니다.
로빈 라이더

나는 그렇게 생각했지만 내 질문은 : 우리는 그것들 을 섞을 수 있습니까?
Artemis는 Monica

@ArtemisFowl 네, 섞을 수 있습니다.
로빈 라이더

답변:


6

JavaScript (ES6),  130  126 bytes

Takes input as (letters)(words). Returns 0 or 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)))

Try it online!

Step 1

We first iterate over L to build a pipe-separated string s consisting of all invalid pairs of letters. While doing so, we also make sure that each letter appears at least once in some word.

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

Step 2

We now iterate over W to test each word.

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

Jelly, 30 29 bytes

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

Try it online!

A dyadic link that takes the list of words as left argument and the flattened list of letters in the box as the right argument. It returns 1 for true and 0 for false.

Explanation

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 bytes

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

-2 bytes by taking inspiration of the ê approach @Emigna used in his 05AB1E answer.
-3 bytes thanks to @Grimy.

Takes a list of list of characters for the words as first input, and the flattened list of twelve letters as second input.

Try it online or verify all test cases.

Explanation:

ε         # 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, that first comment is indeed an obvious one. I've just changed it to a character array, so now that indeed works where it wouldn't before when the words were still strings. That second approach of merge, check pair equality, sum is quite brilliant, though! :D Thanks (as always).
Kevin Cruijssen

1
Another -1: ¹€g3@ -> DO2@ after the first check (TIO)
Grimmy

1
@Grimy Another nice one, thanks. We're now below the Jelly answer of 29. :)
Kevin Cruijssen

5

05AB1E, 42 bytes

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

Try it online!


It's not much, but a byte can be saved by removing all P after the maps, and use )˜P at the end. 41 bytes Nice approach with ê however! Saved 2 bytes in my 05AB1E answer.
Kevin Cruijssen

4

Python 2, 171 bytes

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

Try it online!



4

Haskell, 231 bytes

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

Try it online!

Not the best score. Some Haskell guru will probably be able to get this under 100 bytes.

Usage

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

Explanation

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 bytes

A different Haskell variation, exactly the same size as @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)

Try it 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

Ruby, 126 bytes

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

Try it online!


Nice, when I first saw the challenge I tried to do something similar, but gave up with a score somewhere in 140-ies. BTW, save a byte by dropping parentheses after grep.
Kirill L.

This doesn't work when the last word is 1 or 2 letters long, e.g. puts f[l,['PILGRIMAGE','ENCLOSE','EG']] returns true instead of false.
Robin Ryder

1
You are right, fixed.
G B

3

Java (JDK), 188 bytes

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

Try it online!

Explanations

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

Credits

  • -2 bytes thanks to ceilingcat

2

Charcoal, 63 bytes

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

온라인으로 사용해보십시오! 링크는 자세한 버전의 코드입니다. 설명:

⌊⁺⁺⁺

아래 표현식을 연결하고 다른 표현식이 0포함 된 0경우 출력1 .

⭆η›Lι²

솔루션의 각 단어에 대해 길이가 3 이상인지 여부를 출력합니다.

⭆⪫ηω№⪫θωι

솔루션의 각 문자에 대해 퍼즐에 표시되는지 여부를 출력합니다.

⭆⪫θω№⪫ηωι

퍼즐 출력의 각 문자에 대해 솔루션에 표시되는지 여부입니다.

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

솔루션의 각 문자에 대해 이전 문자가 단어의 첫 번째 문자가 아닌 한 동일한 그룹에 있지 않은지 확인하십시오.이 경우 첫 번째 문자가 아닌 한 이전 단어의 마지막 문자와 같은지 확인하십시오. 솔루션의 편지,이 경우 그냥 무시하십시오.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.