Письмо в штучной упаковке валидатор


28

В New York Times есть ежедневная онлайн-игра под названием Letter Boxed (ссылка находится за платным доступом; игра также описана здесь ), представленная на квадрате следующим образом:

Пример письма в штучной упаковке от New York Times

Вам дается 4 группы по 3 буквы (каждая группа соответствует одной стороне на картинке); ни одна буква не появляется дважды. Цель игры - найти слова, состоящие из этих 12 букв (и только из этих букв), которые бы:

  • Каждое слово длиной не менее 3 букв;
  • Последовательные письма не могут быть с одной и той же стороны;
  • Последняя буква слова становится первой буквой следующего слова;
  • Все буквы используются как минимум один раз (буквы можно использовать повторно).

В этом задании вам даны буквы и список слов. Цель состоит в том, чтобы проверить, является ли список слов действительным решением в штучной упаковке.

вход

Ввод состоит из (1) 4 групп по 3 буквы и (2) списка слов. Это может быть в любом подходящем формате.

Выход

Истинное значение, если список слов является допустимым решением проблемы Letter Boxed для этих букв 4 × 3, а в противном случае - ложное значение.

Контрольные примеры

Группы букв = {{I,C,O}, {M,R,E}, {G,N,S}, {A,P,L}}.

Истинные ценности

  • ПОДГОТОВКА, ЗАКРЫТЬ
  • УРОЖАЙ, ПАРУС, ЛИН, НОП, ЭНИГМА

Ложные ценности

  • КРАСНАЯ СИСТЕМА, ЭКОНОМИКА (не может иметь CO, так как они на одной стороне)
  • CROPS, SAIL, LEAN, NOPE (G и M не использовались)
  • ПОДГОТОВКА, ЗАКРЫТИЕ (U не одна из 12 букв)
  • ENCLOSE, PILGRIMAGE (последняя буква первого слова не является первой буквой второго слова)
  • Мошенничество, SO, ОРГАНИЗАЦИЯ, ELOPE (все слова должны быть не менее 3 букв).

Обратите внимание, что в этой задаче нам не важно, правильны ли слова (часть словаря).

Подсчет очков:

Этот , выигрывает самая низкая оценка в байтах!


4
@TFeldno letter appears twice
feersum

Истинное значение, если список слов является допустимым решением проблемы Letter Boxed для этих букв 4 × 3, а в противном случае - ложное значение. Для Python (и большинства других языков, я ожидаю) оба []и 0ложные. Можем ли мы выводить либо, либо наш вывод должен быть последовательным?
Артемида поддерживает Монику

@ArtemisFowl Либо в порядке.
Робин Райдер

Я так и думал, но мой вопрос был: можем ли мы их смешать ?
Артемида поддерживает Монику

@ArtemisFowl Да, вы можете смешивать их.
Робин Райдер

Ответы:


6

JavaScript (ES6),  130  126 байтов

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

Попробуйте онлайн!

Шаг 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()

Шаг 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

Желе , 30 29 байт

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

Попробуйте онлайн!

Диадическая ссылка, которая принимает список слов в качестве левого аргумента и плоский список букв в поле в качестве правого аргумента. Он возвращает 1для истинного и 0ложного.

объяснение

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 байт

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

-2 байта, вдохновляя êподход @Emigna, использованный в его ответе 05AB1E .
-3 байта благодаря @Grimy .

Принимает список символов для слов в качестве первого ввода и плоский список из двенадцати букв в качестве второго ввода.

Попробуйте онлайн или проверьте все контрольные примеры .

Объяснение:

ε         # 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 Ах, этот первый комментарий действительно очевиден. Я только что изменил его на массив символов, так что теперь он действительно работает там, где раньше не было, когда слова были еще строками. Этот второй подход слияния, проверка парного равенства, сумма довольно блестящая, хотя! : D Спасибо (как всегда).
Кевин Круйссен

1
Еще -1: ¹€g3@-> DO2@после первой проверки ( TIO )
Grimmy

1
@ Грими Еще один хороший, спасибо. Мы теперь ниже Желе ответ 29.
Кевин Круйссен




4

Haskell , 231 байт

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

Попробуйте онлайн!

Не лучший результат. Некоторые гуру Haskell, вероятно, смогут получить это менее 100 байтов.

использование

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

объяснение

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 байт

Другой вариант Haskell, точно такого же размера, как у @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)

Попробуйте онлайн!

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

Рубин , 126 байт

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

Попробуйте онлайн!


Приятно, когда я впервые увидел вызов, я попытался сделать что-то похожее, но сдался со счетом где-то в 140-х годах. Кстати, сохраните байт, убрав скобки после grep.
Кирилл Л.

Это не работает, когда последнее слово имеет длину 1 или 2 буквы, например, puts f[l,['PILGRIMAGE','ENCLOSE','EG']]возвращает trueвместо false.
Робин Райдер

1
Вы правы, исправлены.
GB

3

Java (JDK) , 188 байт

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

Попробуйте онлайн!

Пояснения

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

кредиты

  • -2 байта благодаря потолку

2

Древесный уголь , 63 байта

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

Попробуйте онлайн! Ссылка на подробную версию кода. Объяснение:

⌊⁺⁺⁺

Объедините приведенные ниже выражения и выведите их, 0если любое из них содержит 0другое 1.

⭆η›Lι²

Для каждого слова в решении выведите, будет ли его длина не менее 3.

⭆⪫ηω№⪫θωι

Для каждой буквы в решении выведите, появляется ли она в головоломке.

⭆⪫θω№⪫ηωι

Для каждой буквы в загадке выведите, появляется ли она в решении.

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

Для каждой буквы в решении проверьте, что предыдущая буква не входит в ту же группу, если только она не является первой буквой слова, и в этом случае убедитесь, что она равна последней букве предыдущего слова, если только она не является первой буква решения, в этом случае просто игнорировать его.


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.