Буквений валідатор


28

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

Приклад з буквеного письма від New York Times

Вам дано 4 групи по 3 букви (кожна група відповідає одній стороні на малюнку); жоден лист не з’являється двічі. Мета гри - знайти слова, складені з цих 12 літер (і лише цих букв), таких:

  • Кожне слово довжиною не менше 3 букв;
  • Послідовні листи не можуть бути з однієї сторони;
  • Остання буква слова стає першою літерою наступного слова;
  • Усі букви використовуються принаймні один раз (букви можна повторно використовувати).

У цьому виклику вам надаються букви та список слів. Мета - перевірити, чи перелік слів є дійсним рішенням з буквеної скриньки.

Вхідні дані

Введення складається з (1) 4 груп з 3 букв і (2) списку слів. Він може бути у будь-якому відповідному форматі.

Вихідні дані

Достовірне значення, якщо список слів є коректним рішенням виклику «Буква з буквою» для цих 4 × 3 букв, а значення фальси - в іншому випадку.

Тестові справи

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

Ціннісні значення

  • ПІЛГРІМАЖ, РОЗКЛАД
  • КРОПИ, ВЕТРИЛ, ЛІН, НОП, ЕНІГМА

Значення Фальсі

  • МАГАЗИН, ЕКОНОМІКИ (не може мати СО, оскільки вони на одній стороні)
  • CROPS, SAIL, LEAN, NOPE (G і M не використовувались)
  • ПІЛГРІМАЖ, ВКЛЮЧЕННЯ (U - не одна з 12 букв)
  • ВКЛЮЧИТИ, МАЙБУТНІСТЬ (остання літера 1-го слова - це не перша літера другого слова)
  • ШАМИ, ТАК, ОРГАНІЗАЦІЯ, ЕЛОП (всі слова повинні бути не менше 3 літер).

Зауважте, що в цьому виклику нас не хвилює, чи слова є дійсними (частина словника).

Оцінка:

Цей , найнижчий бал у байтах!


4
@TFeldno letter appears twice
feersum

Достовірне значення, якщо список слів є коректним рішенням виклику «Буква з буквою» для цих 4 × 3 букв, а значення фальси - в іншому випадку. Для Python (і в більшості інших мов, я вважаю), як []і 0в falsey. Чи можемо ми випустити або будь-який, чи повинен бути результатом?
Артеміда підтримує Моніку

@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
@Grimy Ще один приємний, дякую. Зараз ми знаходимось нижче відповіді «Желе» на 29. :)
Кевін Круїйсен

5

05AB1E , 42 байти

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

Спробуйте в Інтернеті!


Це не багато, але байт можна зберегти, видаливши всі Pпісля карти, і використовувати )˜Pв кінці. 41 байт Приємний підхід, êоднак! Збережено 2 байти у моїй відповіді 05AB1E.
Кевін Кройсейсен



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)

Спробуйте в Інтернеті!

Безумовно

-- 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-х роках. BTW, збережіть байт, видаливши круглі дужки після grep.
Кирило Л.

Це не працює, коли останнє слово становить 1 або 2 літери, наприклад, puts f[l,['PILGRIMAGE','ENCLOSE','EG']]повертається trueзамість false.
Робін Райдер

1
Ви праві, виправлені.
ГБ

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.