[Question]
  [
Letter dice are common in word games. It can be fun to try to spell funny words with boggle dice, for instance. If you grab a handful of dice, chances are you won't be able to spell certain words. This challenge is a generalization of that idea.
# Challenge
Given a list of dice which each have at least 1 face and a word, your task is to determine if it is possible to spell that word using the given dice (in which case, it should return a truthy result). Only one letter from each die can be used and a die can be used only once. You do not need to use all of the given dice.
# Examples
In a trivial example, with the dice [[A], [C], [T]] and the string CAT, the result is true. BAT would, of course, return false since there are no dice with B on them
If given [[A, E, I, O, U], [A, B, C, T], [N, P, R]] as the set of dice, you would return true for ART, TON, and CUR, but false for CAT, EAT, and PAN because those strings require reusing dice. It should also be fairly obvious that CRAB cannot be spelled with these dice since there are not enough dice.
If given [[A, B, C], [A, E, I], [E, O, U], [L, N, R, S, T]] as the set of dice, you would be able to spell CAT, BEE, BEAN, TEA, BEET, and BAN, but you would not be able to spell LONE, CAB, BAIL, TAIL, BAA, or TON
There may be multiples of the same die. If given [[A, B, C], [A, B, C], [A, B, C]], you would be able to spell CAB, BAA, AAA, etc... but obviously nothing without A, B, or C in it.
# Rules
* No exploiting standard loopholes
* This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), so the shortest code wins.
* You may assume that both words and dice will only be made up of capital letters.
* You may assume that the word will always be at least 1 letter long and that there will always be at least 1 die.
* You may assume that a die will never have more than one of the same letter.
* Input and output may be in any convenient format.
  
[Answer]
# [Brachylog](https://github.com/JCumin/Brachylog), 5 bytes
```
∋ᵐ⊇pc
```
[Try it online!](https://tio.run/##SypKTM6ozMlPN/r//1FH98OtEx51tRck//8fHa3kqKSj5ATEzkqxOhCeKxB7gnkglj8Qh4J5PkCWHxAHAXEwEIcoxcb@V3JydfRTAgA "Brachylog – Try It Online")
We use the input variable for the dice and the output variable for the word. It outputs `true.` when it's possible to spell the word and `false.` otherwise.
### Explanation
```
∋ᵐ        Map element: Take one side from each die
  ⊇       Subset
   p      Permute
    c     Concatenate into a string: will only succeed if it results in the output word
```
[Answer]
# [Haskell](https://www.haskell.org/), ~~48~~ 44 bytes
```
import Data.List
(.mapM id).any.(null.).(\\)
```
This is an anonymous function. Bound to some identifier `f` it can be used as `f "ART" ["AEIOU", "ABCT", "NPR"]`, which yields `True`. [Try it online!](https://tio.run/##JY7BDoIwEETvfsWm8dAG7R9gUpCDCQJBOImHRiA0QiG0xPj1lbant5nZ3ZmBq083jsaIaZlXDVeuOU2F0oc@xHTiyx1ESyiXP4rlNo6UUNw0xLTi3UEIT8SSW16jEyAWxZVlVpToddCd0sovOJWVDlWeWcR16eC9xKNg3itZtD@YuJD7vWuAGwXnCyybfug1lXAEBUEAyIrITmqYv4D7Xba9CAEXb/4 "Haskell – Try It Online")
The non-point-free equivalent is
```
f word dice = any(\s -> null $ word\\s) $ mapM id dice
```
`mapM id` over a list of lists uses the `Monad` instance of list and can be seen as [non-deterministic choice](https://en.wikibooks.org/wiki/Haskell/Understanding_monads/List). Thus e.g. `mapM id ["AB","123"]` yields `["A1","A2","A3","B1","B2","B3"]`.
For each of those dice combinations, we check if the list difference [`(\\)`](http://hackage.haskell.org/package/base-4.11.1.0/docs/Data-List.html#v:-92--92-) of the given word and the combination yields an empty list.
[Answer]
## JavaScript (ES6), 68 bytes
```
f=([c,...w],a)=>!c||a.some((d,i)=>d.match(c)&&f(w,a.filter(_=>i--)))
```
```
<div oninput=o.textContent=f(i.value,d.value.split`\n`)>
<textarea id=d rows=9>
ABC
AEI
EOU
LNRST
</textarea>
<br>
<input id=i value=BEAN>
<pre id=o>true
```
[Answer]
# [Python 2](https://docs.python.org/2/), 82 bytes
```
f=lambda d,w:w==''or any(w[0]in x>0<f(d[:i]+d[i+1:],w[1:])for i,x in enumerate(d))
```
[Try it online!](https://tio.run/##HUrBCoMwFLvvK96tLSvD7VjmoEoPglTYulPx4KiyglZxjurXu3aBJC95mbblPbrLvndp3wwv04Chnvk0RWicoXEb9jqprYP1llw7bDSz9dFoezyzmnodlHRhaOkKYdS679DOzdJiQ8geHz7WKOcKMsEjJaj/IUITQllJATnPQihKUFEyzkFVEp0@U28XTNgBAqbZugU6rBHPckQBcVFEE9UzWinvD4VqCp7sPw "Python 2 – Try It Online")
```
f=lambda d,w:w==''                                                                 # Base case: we can spell '' with any dice.
                  or any(                                 for i,x in enumerate(d)) # Otherwise, we check if there is some die x such that...
                         w[0]in x                                                  # the first letter is on this die,
                                 >0<                                               # and
                                    f(d[:i]+d[i+1:],w[1:])                         # we can spell the rest of the word with the rest of the dice.
```
The comparison chain `w[0]in x>0<f(...)` is equivalent to: `w[0]in x` **and** `x>0` **and** `0<f(...)`.
The second of those is always true (`str` > `int`) and the third of those is equivalent to `f(...)`, so that the whole thing is a shorter way to write `w[0]in x and f(...)`
[Answer]
# JavaScript (ES6), 74 bytes
Takes input in currying syntax `(w)(a)`, where **w** is the word we're looking for and **a** is a list of strings describing the dice. Returns **0** or **1**.
```
w=>P=(a,m='')=>w.match(m)==w|a.some((w,i)=>P(a.filter(_=>i--),m+`[${w}]`))
```
[Try it online!](https://tio.run/##nZPRaoMwFIbv@xS9GCRh6htEOJEMBIni0iuRNThdLaYWdQtj27O7dmN0o2U0uTqQ5OM/OV@yVS9qrIZ2P/m7/rGeGzobGmYUK09ThAgNTaDVVG2wJpSadxWMva4xNl572MuwCpq2m@oBP9Cw9X3i6dt1cfNmPso1IXPV78a@q4Ouf8KokMPztHktEVn8Xm8wglwissQFAh6nK@QtEbBIHqvIclSSM0Cmwg6IVrklAD8tsejrOI@PhX/Dicjv5SWMce6GweFC1ph0TePSIY2BuCpt8df6nerGS9JPE75SCbcFMrB8JUkquMNgImBOGiBOXKS7YQzApcnTT/sXmz8B "JavaScript (Node.js) – Try It Online")
### Commented
We turn each subset-permutation of the dice into a regular expression pattern and test them against the target word.
```
w =>                        // w = target word
  P =                       // P = recursive function taking:
    (a,                     //   a[] = list of dice
        m = '') =>          //   m   = search pattern
    w.match(m) == w |       // force a truthy result if w matches m
    a.some((w, i) =>        // for each word w at position i in a[]:
      P(                    //   do a recursive call:
        a.filter(_ => i--), //     using a copy of a[] without the current element
        m + `[${w}]`        //     and adding '[w]' to the search pattern
      )                     //   end of recursive call
    )                       // end of some()
```
[Answer]
# [Husk](https://github.com/barbuz/Husk), 5 bytes
```
~V`¦Π
```
[Try it online!](https://tio.run/##yygtzv7/vy4s4dCycwv@//@v5OTqGqL0P1rJ0clZSUfJ0dUTSLr6hwJJH7@g4BClWAA "Husk – Try It Online")
Returns a non-zero value if it's possible to spell the word, zero otherwise.
### Explanation
```
~V`¦Π  Arguments: word [Char], dice [[Char]]
 V     Checks if any element of a list (2) satisfies a predicate (1)
~      Composes both arguments of the above function
  `¦     (1) Is the word a subset of the element?
    Π    (2) Cartesian product of the dice list
```
[Answer]
# [Perl 5](https://www.perl.org/) `-plF`, ~~48~~ 46 bytes
*@DomHastings saved 2 bytes*
```
$_=grep/@{[sort@F]}/,map"@{[sort/./g]}",glob<>
```
[Try it online!](https://tio.run/##K0gtyjH9/18l3ja9KLVA36E6uji/qMTBLbZWXyc3sUAJKqCvp58eW6ukk56Tn2Rj9/9/ZIALV3WETmRttbOOS221o46TTkDtv/yCksz8vOL/ur6megaGBv91C3LcAA "Perl 5 – Try It Online")
### Input:
```
word               # The word to validate
{A,B,C}{D,E,F}     # Each die is surrounded by braces, commas between the letters
```
### Output:
`0` for a word that is not validated. Any positive integer for a word that is validated
### How?
This explanation looks at the code in the order of execution, effectively right-to-left for this one-liner.
```
-F             # The first line of input is automatically split by the -F command option into the @F array.
glob<>         # Read the rest of the input and enumerate all of the permutations of it
map"@{[sort/./g]}",  # Split the permutation into separate letters, sort them and put them back together
/@{[sort@F]}/, # use the sorted letters of the target to match against
$_=grep        # check all of those permutations to see if the desired word is in them
-p             # Command line option to output the contents of $_ at the end
```
[Answer]
# [JavaScript (Node.js)](https://nodejs.org), 98 bytes
```
f=(s,d,u=[])=>d<1?s.every(t=>u.pop().match(t)):d.some((x,i)=>f(s,e=[...d],[...u,x],e.splice(i,1)))
```
[Try it online!](https://tio.run/##fcuxDoIwEIDh3RfpXXJewmosBo0rEoITYSC0aA1QQoHg09e6G6d/@b9Xvdaumcw47wertPetBEeKFllWKGN1jE6O9aqnN8wyXni0IyD39dw8YUY8KHa21wAbmbC3wWpZMrOq6JuFtoo0u7EzjQZDESL6xg7Odpo7@4AWvptI8kIEIZJrcbsLEsn5UoSkWS4qxN0PkSXpP@H9Bw "JavaScript (Node.js) – Try It Online")
Assuming there's enough dice
# [JavaScript (Node.js)](https://nodejs.org), 100 bytes
```
f=(s,d,u=[''])=>d<1?s.every(t=>u.pop().match(t)):d.some((x,i)=>f(s,e=[...d],[...u,x],e.splice(i,1)))
```
[Try it online!](https://tio.run/##lc5BC4IwGMbxe19k72C94DWasayridghwoO4WQt1w6nYp1/zHkGn/@X5wfOq5srVg7bjtjdSed9wcEyyid8JKSmP5T46OFSzGt4w8nhCayxQ7KqxfsJI6U6iM50CWJgO8yZoxe@IKEu2ZmJLyRQ62@pagWYRpdTXpnemVdiaBzSwzojICxIEEeficiWMiGNShKRZHm7QzReRifRPkYj0dPtlvP8A "JavaScript (Node.js) – Try It Online")
# [JavaScript (Node.js)](https://nodejs.org), 99 bytes
```
s=>f=(d,u=[''])=>d<1?s.every(t=>u.pop().match(t)):d.some((x,i)=>f(e=[...d],[...u,x],e.splice(i,1)))
```
[Try it online!](https://tio.run/##lY1BC4IwGIbv/ZF9g/WB12jGsjyaiB1CPIibZagbTsV@/Vr3CDo98PI8vM9qqWw9tmbaDloqF3NnedhwkGzmBSEl5aHcBweLalHjCyYezmi0AYp9NdUPmCjdSbS6VwAra73egOIFIsqSfTCztWQKrenaWkHLAkqpq/Vgdaew03eI4aMRkeX@DQoizvnlShgRxyj3SNLM73TzJUlF8m8SieR0@xk59wY "JavaScript (Node.js) – Try It Online")
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), ~~10~~ 9 [bytes](https://github.com/DennisMitchell/jelly/wiki/Code-page)
-1 thanks to Erik the Outgolfer (use `w` rather than `ẇ@` >.<)
```
Œ!Œp€Ẏw€Ṁ
```
A dyadic link accepting a list of lists of characters on the left (the dice) and
a list of characters on the right (the word) which returns 1 if possible and 0 if not.
**[Try it online!](https://tio.run/##y0rNyan8///oJMWjkwoeNa15uKuvHEzt@P//f7R6VJS6joK6s7OTp7criBXk7wOmfRyjXINADP/QEPXY/@rO/v4@6gA "Jelly – Try It Online")** Or see the [test-suite](https://tio.run/##y0rNyan8///oJMWjkwoeNa15uKuvHEzt@H94@eEJQCaY@P8/Wt3RyVldR0Hd0dUTRLn6h4IoH7@g4BD12P/R0erOjiEgESdXVwjl6AeiQ1wdoaIQWaBorI5CtLqPvx9YnbOjE0Tc0wesHEo7OYK1hfgDlccCAA "Jelly – Try It Online").
### How?
```
Œ!Œp€Ẏw€Ẹ - Link: list of lists of characters Dice, list of characters Word
Œ!        - all permutations of the dice (i.e. all ways to order the dice)
  Œp€     - Cartesian product of €ach (i.e. all ways to roll each ordering)
     Ẏ    - tighten (i.e. all ordered ways to roll the dice)
       €  - for each:
      w   -   first index (of sublist W) in the result (positive if there, 0 otherwise)
        Ẹ - any truthy? (1 if it is possible to roll the word, 0 otherwise)
```
---
### Faster algorithm (also 9 bytes):
A dyadic link with the same input format which returns positive integer (truthy) when possible and 0 (falsey) otherwise.
```
Œpf€Ṣ€ċṢ} - Link: list of lists of characters Dice, list of characters Word
Œp        - Cartesian product of the dice (all rolls of the dice)
  f€      - filter keep for €ach (keep the rolled letters if they are in the word)
    Ṣ€    - sort €ach result
       Ṣ} - sort Word
      ċ   - count occurrences
```
[Answer]
# [R](https://www.r-project.org/), ~~192 185 135 117 111~~ 109 bytes
```
function(x,...)s(x)%in%apply(expand.grid(lapply(list(...),c,"")),1,s)
s=function(x)paste(sort(x),collapse="")
```
[Try it online!](https://tio.run/##lU7RCoJAEHzvMxaEPdiE3vNBLSOIgrIPEDU5kPPwLri@3lZP6cWXHoaduZnZvX5o9tvh9VallZ1CR2EYCoNOBFIFhdbtB2unC1WFTS8rbP1TK43FMUklAQhBOzJiY6LfHqELY2s0XW9ZUNm1XDV1xOmhQReVCCkQxIwc2MdlpH7EvHUzB8fQgZEtFkHCmJOjc/Q0Y3paKeb/FpP5a9fVYjwVCc5ejvTGeHp5mXoEd8bDHxfDFw "R – Try It Online")
-2 chars thanks to Giuseppe.
[Answer]
# [Vyxal](https://github.com/Vyxal/Vyxal), 8 bytes
```
ṖvÞ*Þf$c
```
[Try it Online!](https://vyxal.pythonanywhere.com/#WyIiLCIiLCLhuZZ2w54qw55mJGMiLCIiLCJbW1wiQVwiLFwiQlwiLFwiQ1wiXSxbXCJBXCIsXCJFXCIsXCJJXCJdLFtcIkVcIixcIk9cIixcIlVcIl0sW1wiTFwiLFwiTlwiLFwiUlwiLFwiU1wiLFwiVFwiXV1cbltcIkNcIixcIk9cIixcIkFcIixcIkxcIl0iXQ==)
Returns 1 for valid, 0 for invalid.
```
Ṗv  Þf   # over all permutations
  Þ*     # Reduce by cartesian product
      $c # Check if the input contains that
```
[Answer]
# [Pyth](https://github.com/isaacg1/pyth), 21 bytes
```
.Em}eQdsm.ps.nd.U*bZh
```
[**Test suite**](https://pyth.herokuapp.com/?code=.Em%7DeQdsm.ps.nd.U%2abZh&test_suite=1&test_suite_input=%5B%22A%22%2C%22C%22%2C%22T%22%5D%2C%22CAT%22%0A%5B%22A%22%2C%22C%22%2C%22T%22%5D%2C%22BAT%22%0A%5B%22AEIOU%22%2C%22ABCT%22%2C%22NPR%22%5D%2C%22ART%22%0A%5B%22AEIOU%22%2C%22ABCT%22%2C%22NPR%22%5D%2C%22EAT%22%0A%5B%22ABC%22%2C%22AEI%22%2C%22EOU%22%2C%22LNRST%22%5D%2C%22BEAT%22%0A%5B%22ABC%22%2C%22AEI%22%2C%22EOU%22%2C%22LNRST%22%5D%2C%22BAIL%22%0A%5B%22ABC%22%2C%22ABC%22%2C%22ABC%22%5D%2C%22AAA%22%0A%5B%22ABC%22%2C%22ABC%22%2C%22ABC%22%5D%2C%22ANA%22&debug=0)
Explanation:
```
.Em}eQdsm.ps.nd.U*bZhQ # Code with implicit variables
.E                     # Print whether any of
       sm.ps  d        # all positive length permutations of each element in
        m   .nd.U*bZhQ # the Cartesian product of the list of dice
  m}eQd                # contain the target word
```
[Answer]
# [Ruby](https://www.ruby-lang.org/), 54 bytes
```
->w,a{a.permutation.any?{/#{w.chars*".*,.*"}/=~_1*?,}}
```
[Attempt This Online!](https://ato.pxeger.com/run?1=m72kqDSpcsEiN9ulpSVpuhY3zXTtynUSqxP1ClKLcktLEksy8_P0EvMq7av1lavL9ZIzEouKtZT0tHT0tJRq9W3r4g217HVqa6G6FxQouEWrOwaFqOsoAGlXT_9QIEvd0ckZJKLuFxCkHhvLBVbk7EiEohBXR4giJ2ewEldPEOUK0eDjFxQcAlfq4-_nSlgtxJ0LFkBoAA)
]