Letter Boxed validator
$begingroup$
The New York Times has a daily online game called Letter Boxed (the link is behind a paywall; the game is also described here), presented on a square as follows:

You are given 4 groups of 3 letters (each group corresponds to one side on the picture); no letter appears twice. The aim of the game is to find words made of those 12 letters (and those letters only) such that:
- Each word is at least 3 letters long;
- Consecutive letters cannot be from the same side;
- The last letter of a word becomes the first letter of the next word;
- All letters are used at least once (letters can be reused).
In this challenge, you are given the letters and a list of words. The goal is to check whether the list of words is a valid Letter Boxed solution.
Input
Input consists of (1) 4 groups of 3 letters and (2) a list of words. It can be in any suitable format.
Output
A truthy value if the list of words is a valid solution to the Letter Boxed challenge for those 4×3 letters, and a falsey value otherwise.
Test cases
Groups of letters={{I,C,O}, {M,R,E}, {G,N,S}, {A,P,L}}.
Truthy values
- PILGRIMAGE, ENCLOSE
- CROPS, SAIL, LEAN, NOPE, ENIGMA
Falsey values
- PILGRIMAGE, ECONOMIES (can't have CO since they are on the same side)
- CROPS, SAIL, LEAN, NOPE (G and M have not been used)
- PILGRIMAGE, ENCLOSURE (U is not one of the 12 letters)
- ENCLOSE, PILGRIMAGE (last letter of 1st word is not first letter of 2nd word)
- SCAMS, SO, ORGANISE, ELOPE (all words must be at least 3 letters long).
Note that in this challenge, we do not care whether the words are valid (part of a dictionary).
Scoring:
This code-golf, lowest score in bytes wins!
code-golf
$endgroup$
add a comment |
$begingroup$
The New York Times has a daily online game called Letter Boxed (the link is behind a paywall; the game is also described here), presented on a square as follows:

You are given 4 groups of 3 letters (each group corresponds to one side on the picture); no letter appears twice. The aim of the game is to find words made of those 12 letters (and those letters only) such that:
- Each word is at least 3 letters long;
- Consecutive letters cannot be from the same side;
- The last letter of a word becomes the first letter of the next word;
- All letters are used at least once (letters can be reused).
In this challenge, you are given the letters and a list of words. The goal is to check whether the list of words is a valid Letter Boxed solution.
Input
Input consists of (1) 4 groups of 3 letters and (2) a list of words. It can be in any suitable format.
Output
A truthy value if the list of words is a valid solution to the Letter Boxed challenge for those 4×3 letters, and a falsey value otherwise.
Test cases
Groups of letters={{I,C,O}, {M,R,E}, {G,N,S}, {A,P,L}}.
Truthy values
- PILGRIMAGE, ENCLOSE
- CROPS, SAIL, LEAN, NOPE, ENIGMA
Falsey values
- PILGRIMAGE, ECONOMIES (can't have CO since they are on the same side)
- CROPS, SAIL, LEAN, NOPE (G and M have not been used)
- PILGRIMAGE, ENCLOSURE (U is not one of the 12 letters)
- ENCLOSE, PILGRIMAGE (last letter of 1st word is not first letter of 2nd word)
- SCAMS, SO, ORGANISE, ELOPE (all words must be at least 3 letters long).
Note that in this challenge, we do not care whether the words are valid (part of a dictionary).
Scoring:
This code-golf, lowest score in bytes wins!
code-golf
$endgroup$
4
$begingroup$
@TFeldno letter appears twice
$endgroup$
– feersum
yesterday
$begingroup$
A truthy value if the list of words is a valid solution to the Letter Boxed challenge for those 4×3 letters, and a falsey value otherwise. For Python (and most other languages, I expect), bothand0are falsey. Can we output either, or must our output be consistent?
$endgroup$
– Artemis Fowl
23 hours ago
$begingroup$
@ArtemisFowl Either is fine.
$endgroup$
– Robin Ryder
15 hours ago
$begingroup$
I thought so, but my question was: can we mix them?
$endgroup$
– Artemis Fowl
7 hours ago
$begingroup$
@ArtemisFowl Yes, you can mix them.
$endgroup$
– Robin Ryder
7 hours ago
add a comment |
$begingroup$
The New York Times has a daily online game called Letter Boxed (the link is behind a paywall; the game is also described here), presented on a square as follows:

You are given 4 groups of 3 letters (each group corresponds to one side on the picture); no letter appears twice. The aim of the game is to find words made of those 12 letters (and those letters only) such that:
- Each word is at least 3 letters long;
- Consecutive letters cannot be from the same side;
- The last letter of a word becomes the first letter of the next word;
- All letters are used at least once (letters can be reused).
In this challenge, you are given the letters and a list of words. The goal is to check whether the list of words is a valid Letter Boxed solution.
Input
Input consists of (1) 4 groups of 3 letters and (2) a list of words. It can be in any suitable format.
Output
A truthy value if the list of words is a valid solution to the Letter Boxed challenge for those 4×3 letters, and a falsey value otherwise.
Test cases
Groups of letters={{I,C,O}, {M,R,E}, {G,N,S}, {A,P,L}}.
Truthy values
- PILGRIMAGE, ENCLOSE
- CROPS, SAIL, LEAN, NOPE, ENIGMA
Falsey values
- PILGRIMAGE, ECONOMIES (can't have CO since they are on the same side)
- CROPS, SAIL, LEAN, NOPE (G and M have not been used)
- PILGRIMAGE, ENCLOSURE (U is not one of the 12 letters)
- ENCLOSE, PILGRIMAGE (last letter of 1st word is not first letter of 2nd word)
- SCAMS, SO, ORGANISE, ELOPE (all words must be at least 3 letters long).
Note that in this challenge, we do not care whether the words are valid (part of a dictionary).
Scoring:
This code-golf, lowest score in bytes wins!
code-golf
$endgroup$
The New York Times has a daily online game called Letter Boxed (the link is behind a paywall; the game is also described here), presented on a square as follows:

You are given 4 groups of 3 letters (each group corresponds to one side on the picture); no letter appears twice. The aim of the game is to find words made of those 12 letters (and those letters only) such that:
- Each word is at least 3 letters long;
- Consecutive letters cannot be from the same side;
- The last letter of a word becomes the first letter of the next word;
- All letters are used at least once (letters can be reused).
In this challenge, you are given the letters and a list of words. The goal is to check whether the list of words is a valid Letter Boxed solution.
Input
Input consists of (1) 4 groups of 3 letters and (2) a list of words. It can be in any suitable format.
Output
A truthy value if the list of words is a valid solution to the Letter Boxed challenge for those 4×3 letters, and a falsey value otherwise.
Test cases
Groups of letters={{I,C,O}, {M,R,E}, {G,N,S}, {A,P,L}}.
Truthy values
- PILGRIMAGE, ENCLOSE
- CROPS, SAIL, LEAN, NOPE, ENIGMA
Falsey values
- PILGRIMAGE, ECONOMIES (can't have CO since they are on the same side)
- CROPS, SAIL, LEAN, NOPE (G and M have not been used)
- PILGRIMAGE, ENCLOSURE (U is not one of the 12 letters)
- ENCLOSE, PILGRIMAGE (last letter of 1st word is not first letter of 2nd word)
- SCAMS, SO, ORGANISE, ELOPE (all words must be at least 3 letters long).
Note that in this challenge, we do not care whether the words are valid (part of a dictionary).
Scoring:
This code-golf, lowest score in bytes wins!
code-golf
code-golf
asked yesterday
Robin RyderRobin Ryder
81611
81611
4
$begingroup$
@TFeldno letter appears twice
$endgroup$
– feersum
yesterday
$begingroup$
A truthy value if the list of words is a valid solution to the Letter Boxed challenge for those 4×3 letters, and a falsey value otherwise. For Python (and most other languages, I expect), bothand0are falsey. Can we output either, or must our output be consistent?
$endgroup$
– Artemis Fowl
23 hours ago
$begingroup$
@ArtemisFowl Either is fine.
$endgroup$
– Robin Ryder
15 hours ago
$begingroup$
I thought so, but my question was: can we mix them?
$endgroup$
– Artemis Fowl
7 hours ago
$begingroup$
@ArtemisFowl Yes, you can mix them.
$endgroup$
– Robin Ryder
7 hours ago
add a comment |
4
$begingroup$
@TFeldno letter appears twice
$endgroup$
– feersum
yesterday
$begingroup$
A truthy value if the list of words is a valid solution to the Letter Boxed challenge for those 4×3 letters, and a falsey value otherwise. For Python (and most other languages, I expect), bothand0are falsey. Can we output either, or must our output be consistent?
$endgroup$
– Artemis Fowl
23 hours ago
$begingroup$
@ArtemisFowl Either is fine.
$endgroup$
– Robin Ryder
15 hours ago
$begingroup$
I thought so, but my question was: can we mix them?
$endgroup$
– Artemis Fowl
7 hours ago
$begingroup$
@ArtemisFowl Yes, you can mix them.
$endgroup$
– Robin Ryder
7 hours ago
4
4
$begingroup$
@TFeld
no letter appears twice$endgroup$
– feersum
yesterday
$begingroup$
@TFeld
no letter appears twice$endgroup$
– feersum
yesterday
$begingroup$
A truthy value if the list of words is a valid solution to the Letter Boxed challenge for those 4×3 letters, and a falsey value otherwise. For Python (and most other languages, I expect), both
and 0 are falsey. Can we output either, or must our output be consistent?$endgroup$
– Artemis Fowl
23 hours ago
$begingroup$
A truthy value if the list of words is a valid solution to the Letter Boxed challenge for those 4×3 letters, and a falsey value otherwise. For Python (and most other languages, I expect), both
and 0 are falsey. Can we output either, or must our output be consistent?$endgroup$
– Artemis Fowl
23 hours ago
$begingroup$
@ArtemisFowl Either is fine.
$endgroup$
– Robin Ryder
15 hours ago
$begingroup$
@ArtemisFowl Either is fine.
$endgroup$
– Robin Ryder
15 hours ago
$begingroup$
I thought so, but my question was: can we mix them?
$endgroup$
– Artemis Fowl
7 hours ago
$begingroup$
I thought so, but my question was: can we mix them?
$endgroup$
– Artemis Fowl
7 hours ago
$begingroup$
@ArtemisFowl Yes, you can mix them.
$endgroup$
– Robin Ryder
7 hours ago
$begingroup$
@ArtemisFowl Yes, you can mix them.
$endgroup$
– Robin Ryder
7 hours ago
add a comment |
11 Answers
11
active
oldest
votes
$begingroup$
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()
$endgroup$
add a comment |
$begingroup$
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!
$endgroup$
add a comment |
$begingroup$
05AB1E, 37 35 33 32 bytes
εSk3÷üÊ}¹ü)ε`нsθQ}²{¹SêQ¹€g3@)˜P
-2 bytes by taking inspiration of the ê approach @Emigna used in his 05AB1E answer.
Takes the string of 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 strings `y` of the (implicit) input-list of words:
S # Convert word `y` to a list of characters
k # Get the index of each character in the (implicit) input-list of letters
3÷ # Integer-divide each index by 3
üÊ # Check for each pair of integers that they are NOT equal
¹ü) # Get all pairs of strings from the input-list of words
ε } # Map over the pair of words:
` # Push both to the stack
н # Leave only the first character of the second word
sθ # And the last character of the first word
Q # And check if they are equal
²{ # Push the input-list of letters, and sort them
¹S # Push the input-list of words, converted to characters and flattened
ê # And then uniquified and sorted as well
Q # And check if both lists of characters are the same
¹€g # Get the length of each string in the input-list of words
3@ # Check for each length if it's >= 3
)˜ # 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)
$endgroup$
add a comment |
$begingroup$
05AB1E, 42 bytes
εg2›}P¹εεUIεXå}ƶO}üÊP}P¹ü‚ε`нsθQ}P¹Jê²JêQP
Try it online!
$endgroup$
$begingroup$
It's not much, but a byte can be saved by removing allPafter the maps, and use)˜Pat the end. 41 bytes Nice approach withêhowever! Saved 2 bytes in my 05AB1E answer.
$endgroup$
– Kevin Cruijssen
yesterday
add a comment |
$begingroup$
Jelly, 34 bytes
Ṫ=¥/ƝḢ€Ạȧ⁸Fe€ⱮZḄ;IẠƊȧF}fƑF{
ẈṂ>2ȧç
A dyadic Link accepting the words on the left and the letter groups on the right which yields 1 if valid and 0 if not.
Try it online! Or see the test-suite.
$endgroup$
add a comment |
$begingroup$
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
$endgroup$
add a comment |
$begingroup$
Jelly, 30 bytes
FQṢ=Ṣ},i@€€’:3Iʋ,Ẉ>2ɗ,Ṫ=Ḣ}ɗƝ{Ȧ
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
Ṫ | Last character of first word
=Ḣ} | Equals first character of second
Ȧ | Flatten all of the above and check there are no false values
$endgroup$
add a comment |
$begingroup$
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)
New contributor
bugs is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
$endgroup$
add a comment |
$begingroup$
Python 2, 168 156 bytes
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)
Try it online!
Returns 1 for truthy, 0 for falsey.
$endgroup$
add a comment |
$begingroup$
Charcoal, 63 bytes
⌊⁺⁺⁺⭆η›Lι²⭆⪫ηω№⪫θωι⭆⪫θω№⪫ηωι⭆η⭆ι⎇μ¬⁼Φθ№νλΦθ№ν§ι⊖μ∨¬κ⁼§ι⁰§§η⊖κ±¹
Try it online! Link is to verbose version of code. Explanation:
⌊⁺⁺⁺
Concatenate the below expressions and output 0 if any of them includes a 0 otherwise 1.
⭆η›Lι²
For each word in the solution output whether its length is at least 3.
⭆⪫ηω№⪫θωι
For each letter in the solution output whether it appears in the puzzle.
⭆⪫θω№⪫ηωι
For each letter in the puzzle output whether it appears in the solution.
⭆η⭆ι⎇μ¬⁼Φθ№νλΦθ№ν§ι⊖μ∨¬κ⁼§ι⁰§§η⊖κ±¹
For each letter in the solution check that the previous letter is not in the same group, unless it is the first letter of a word, in which case check that it is equal to the last letter of the previous word, unless it is the first letter of the solution, in which case just ignore it.
$endgroup$
add a comment |
$begingroup$
Java (JDK), 190 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|=1<<1+(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|=1<<1+(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.
}
$endgroup$
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "200"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodegolf.stackexchange.com%2fquestions%2f183213%2fletter-boxed-validator%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
11 Answers
11
active
oldest
votes
11 Answers
11
active
oldest
votes
active
oldest
votes
active
oldest
votes
$begingroup$
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()
$endgroup$
add a comment |
$begingroup$
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()
$endgroup$
add a comment |
$begingroup$
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()
$endgroup$
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()
edited yesterday
answered yesterday
ArnauldArnauld
81.3k797335
81.3k797335
add a comment |
add a comment |
$begingroup$
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!
$endgroup$
add a comment |
$begingroup$
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!
$endgroup$
add a comment |
$begingroup$
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!
$endgroup$
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!
answered yesterday
TFeldTFeld
16.6k21451
16.6k21451
add a comment |
add a comment |
$begingroup$
05AB1E, 37 35 33 32 bytes
εSk3÷üÊ}¹ü)ε`нsθQ}²{¹SêQ¹€g3@)˜P
-2 bytes by taking inspiration of the ê approach @Emigna used in his 05AB1E answer.
Takes the string of 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 strings `y` of the (implicit) input-list of words:
S # Convert word `y` to a list of characters
k # Get the index of each character in the (implicit) input-list of letters
3÷ # Integer-divide each index by 3
üÊ # Check for each pair of integers that they are NOT equal
¹ü) # Get all pairs of strings from the input-list of words
ε } # Map over the pair of words:
` # Push both to the stack
н # Leave only the first character of the second word
sθ # And the last character of the first word
Q # And check if they are equal
²{ # Push the input-list of letters, and sort them
¹S # Push the input-list of words, converted to characters and flattened
ê # And then uniquified and sorted as well
Q # And check if both lists of characters are the same
¹€g # Get the length of each string in the input-list of words
3@ # Check for each length if it's >= 3
)˜ # 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)
$endgroup$
add a comment |
$begingroup$
05AB1E, 37 35 33 32 bytes
εSk3÷üÊ}¹ü)ε`нsθQ}²{¹SêQ¹€g3@)˜P
-2 bytes by taking inspiration of the ê approach @Emigna used in his 05AB1E answer.
Takes the string of 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 strings `y` of the (implicit) input-list of words:
S # Convert word `y` to a list of characters
k # Get the index of each character in the (implicit) input-list of letters
3÷ # Integer-divide each index by 3
üÊ # Check for each pair of integers that they are NOT equal
¹ü) # Get all pairs of strings from the input-list of words
ε } # Map over the pair of words:
` # Push both to the stack
н # Leave only the first character of the second word
sθ # And the last character of the first word
Q # And check if they are equal
²{ # Push the input-list of letters, and sort them
¹S # Push the input-list of words, converted to characters and flattened
ê # And then uniquified and sorted as well
Q # And check if both lists of characters are the same
¹€g # Get the length of each string in the input-list of words
3@ # Check for each length if it's >= 3
)˜ # 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)
$endgroup$
add a comment |
$begingroup$
05AB1E, 37 35 33 32 bytes
εSk3÷üÊ}¹ü)ε`нsθQ}²{¹SêQ¹€g3@)˜P
-2 bytes by taking inspiration of the ê approach @Emigna used in his 05AB1E answer.
Takes the string of 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 strings `y` of the (implicit) input-list of words:
S # Convert word `y` to a list of characters
k # Get the index of each character in the (implicit) input-list of letters
3÷ # Integer-divide each index by 3
üÊ # Check for each pair of integers that they are NOT equal
¹ü) # Get all pairs of strings from the input-list of words
ε } # Map over the pair of words:
` # Push both to the stack
н # Leave only the first character of the second word
sθ # And the last character of the first word
Q # And check if they are equal
²{ # Push the input-list of letters, and sort them
¹S # Push the input-list of words, converted to characters and flattened
ê # And then uniquified and sorted as well
Q # And check if both lists of characters are the same
¹€g # Get the length of each string in the input-list of words
3@ # Check for each length if it's >= 3
)˜ # 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)
$endgroup$
05AB1E, 37 35 33 32 bytes
εSk3÷üÊ}¹ü)ε`нsθQ}²{¹SêQ¹€g3@)˜P
-2 bytes by taking inspiration of the ê approach @Emigna used in his 05AB1E answer.
Takes the string of 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 strings `y` of the (implicit) input-list of words:
S # Convert word `y` to a list of characters
k # Get the index of each character in the (implicit) input-list of letters
3÷ # Integer-divide each index by 3
üÊ # Check for each pair of integers that they are NOT equal
¹ü) # Get all pairs of strings from the input-list of words
ε } # Map over the pair of words:
` # Push both to the stack
н # Leave only the first character of the second word
sθ # And the last character of the first word
Q # And check if they are equal
²{ # Push the input-list of letters, and sort them
¹S # Push the input-list of words, converted to characters and flattened
ê # And then uniquified and sorted as well
Q # And check if both lists of characters are the same
¹€g # Get the length of each string in the input-list of words
3@ # Check for each length if it's >= 3
)˜ # 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)
edited 9 hours ago
answered yesterday
Kevin CruijssenKevin Cruijssen
42.9k571217
42.9k571217
add a comment |
add a comment |
$begingroup$
05AB1E, 42 bytes
εg2›}P¹εεUIεXå}ƶO}üÊP}P¹ü‚ε`нsθQ}P¹Jê²JêQP
Try it online!
$endgroup$
$begingroup$
It's not much, but a byte can be saved by removing allPafter the maps, and use)˜Pat the end. 41 bytes Nice approach withêhowever! Saved 2 bytes in my 05AB1E answer.
$endgroup$
– Kevin Cruijssen
yesterday
add a comment |
$begingroup$
05AB1E, 42 bytes
εg2›}P¹εεUIεXå}ƶO}üÊP}P¹ü‚ε`нsθQ}P¹Jê²JêQP
Try it online!
$endgroup$
$begingroup$
It's not much, but a byte can be saved by removing allPafter the maps, and use)˜Pat the end. 41 bytes Nice approach withêhowever! Saved 2 bytes in my 05AB1E answer.
$endgroup$
– Kevin Cruijssen
yesterday
add a comment |
$begingroup$
05AB1E, 42 bytes
εg2›}P¹εεUIεXå}ƶO}üÊP}P¹ü‚ε`нsθQ}P¹Jê²JêQP
Try it online!
$endgroup$
05AB1E, 42 bytes
εg2›}P¹εεUIεXå}ƶO}üÊP}P¹ü‚ε`нsθQ}P¹Jê²JêQP
Try it online!
answered yesterday
EmignaEmigna
48.1k434146
48.1k434146
$begingroup$
It's not much, but a byte can be saved by removing allPafter the maps, and use)˜Pat the end. 41 bytes Nice approach withêhowever! Saved 2 bytes in my 05AB1E answer.
$endgroup$
– Kevin Cruijssen
yesterday
add a comment |
$begingroup$
It's not much, but a byte can be saved by removing allPafter the maps, and use)˜Pat the end. 41 bytes Nice approach withêhowever! Saved 2 bytes in my 05AB1E answer.
$endgroup$
– Kevin Cruijssen
yesterday
$begingroup$
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.$endgroup$
– Kevin Cruijssen
yesterday
$begingroup$
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.$endgroup$
– Kevin Cruijssen
yesterday
add a comment |
$begingroup$
Jelly, 34 bytes
Ṫ=¥/ƝḢ€Ạȧ⁸Fe€ⱮZḄ;IẠƊȧF}fƑF{
ẈṂ>2ȧç
A dyadic Link accepting the words on the left and the letter groups on the right which yields 1 if valid and 0 if not.
Try it online! Or see the test-suite.
$endgroup$
add a comment |
$begingroup$
Jelly, 34 bytes
Ṫ=¥/ƝḢ€Ạȧ⁸Fe€ⱮZḄ;IẠƊȧF}fƑF{
ẈṂ>2ȧç
A dyadic Link accepting the words on the left and the letter groups on the right which yields 1 if valid and 0 if not.
Try it online! Or see the test-suite.
$endgroup$
add a comment |
$begingroup$
Jelly, 34 bytes
Ṫ=¥/ƝḢ€Ạȧ⁸Fe€ⱮZḄ;IẠƊȧF}fƑF{
ẈṂ>2ȧç
A dyadic Link accepting the words on the left and the letter groups on the right which yields 1 if valid and 0 if not.
Try it online! Or see the test-suite.
$endgroup$
Jelly, 34 bytes
Ṫ=¥/ƝḢ€Ạȧ⁸Fe€ⱮZḄ;IẠƊȧF}fƑF{
ẈṂ>2ȧç
A dyadic Link accepting the words on the left and the letter groups on the right which yields 1 if valid and 0 if not.
Try it online! Or see the test-suite.
answered yesterday
Jonathan AllanJonathan Allan
54.4k537174
54.4k537174
add a comment |
add a comment |
$begingroup$
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
$endgroup$
add a comment |
$begingroup$
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
$endgroup$
add a comment |
$begingroup$
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
$endgroup$
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
answered yesterday
Paul MutserPaul Mutser
1113
1113
add a comment |
add a comment |
$begingroup$
Jelly, 30 bytes
FQṢ=Ṣ},i@€€’:3Iʋ,Ẉ>2ɗ,Ṫ=Ḣ}ɗƝ{Ȧ
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
Ṫ | Last character of first word
=Ḣ} | Equals first character of second
Ȧ | Flatten all of the above and check there are no false values
$endgroup$
add a comment |
$begingroup$
Jelly, 30 bytes
FQṢ=Ṣ},i@€€’:3Iʋ,Ẉ>2ɗ,Ṫ=Ḣ}ɗƝ{Ȧ
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
Ṫ | Last character of first word
=Ḣ} | Equals first character of second
Ȧ | Flatten all of the above and check there are no false values
$endgroup$
add a comment |
$begingroup$
Jelly, 30 bytes
FQṢ=Ṣ},i@€€’:3Iʋ,Ẉ>2ɗ,Ṫ=Ḣ}ɗƝ{Ȧ
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
Ṫ | Last character of first word
=Ḣ} | Equals first character of second
Ȧ | Flatten all of the above and check there are no false values
$endgroup$
Jelly, 30 bytes
FQṢ=Ṣ},i@€€’:3Iʋ,Ẉ>2ɗ,Ṫ=Ḣ}ɗƝ{Ȧ
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
Ṫ | Last character of first word
=Ḣ} | Equals first character of second
Ȧ | Flatten all of the above and check there are no false values
edited yesterday
answered yesterday
Nick KennedyNick Kennedy
1,68649
1,68649
add a comment |
add a comment |
$begingroup$
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)
New contributor
bugs is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
$endgroup$
add a comment |
$begingroup$
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)
New contributor
bugs is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
$endgroup$
add a comment |
$begingroup$
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)
New contributor
bugs is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
$endgroup$
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)
New contributor
bugs is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
edited 5 hours ago
New contributor
bugs is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
answered yesterday
bugsbugs
1914
1914
New contributor
bugs is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
New contributor
bugs is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
bugs is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
add a comment |
add a comment |
$begingroup$
Python 2, 168 156 bytes
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)
Try it online!
Returns 1 for truthy, 0 for falsey.
$endgroup$
add a comment |
$begingroup$
Python 2, 168 156 bytes
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)
Try it online!
Returns 1 for truthy, 0 for falsey.
$endgroup$
add a comment |
$begingroup$
Python 2, 168 156 bytes
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)
Try it online!
Returns 1 for truthy, 0 for falsey.
$endgroup$
Python 2, 168 156 bytes
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)
Try it online!
Returns 1 for truthy, 0 for falsey.
edited yesterday
answered yesterday
Chas BrownChas Brown
5,2391523
5,2391523
add a comment |
add a comment |
$begingroup$
Charcoal, 63 bytes
⌊⁺⁺⁺⭆η›Lι²⭆⪫ηω№⪫θωι⭆⪫θω№⪫ηωι⭆η⭆ι⎇μ¬⁼Φθ№νλΦθ№ν§ι⊖μ∨¬κ⁼§ι⁰§§η⊖κ±¹
Try it online! Link is to verbose version of code. Explanation:
⌊⁺⁺⁺
Concatenate the below expressions and output 0 if any of them includes a 0 otherwise 1.
⭆η›Lι²
For each word in the solution output whether its length is at least 3.
⭆⪫ηω№⪫θωι
For each letter in the solution output whether it appears in the puzzle.
⭆⪫θω№⪫ηωι
For each letter in the puzzle output whether it appears in the solution.
⭆η⭆ι⎇μ¬⁼Φθ№νλΦθ№ν§ι⊖μ∨¬κ⁼§ι⁰§§η⊖κ±¹
For each letter in the solution check that the previous letter is not in the same group, unless it is the first letter of a word, in which case check that it is equal to the last letter of the previous word, unless it is the first letter of the solution, in which case just ignore it.
$endgroup$
add a comment |
$begingroup$
Charcoal, 63 bytes
⌊⁺⁺⁺⭆η›Lι²⭆⪫ηω№⪫θωι⭆⪫θω№⪫ηωι⭆η⭆ι⎇μ¬⁼Φθ№νλΦθ№ν§ι⊖μ∨¬κ⁼§ι⁰§§η⊖κ±¹
Try it online! Link is to verbose version of code. Explanation:
⌊⁺⁺⁺
Concatenate the below expressions and output 0 if any of them includes a 0 otherwise 1.
⭆η›Lι²
For each word in the solution output whether its length is at least 3.
⭆⪫ηω№⪫θωι
For each letter in the solution output whether it appears in the puzzle.
⭆⪫θω№⪫ηωι
For each letter in the puzzle output whether it appears in the solution.
⭆η⭆ι⎇μ¬⁼Φθ№νλΦθ№ν§ι⊖μ∨¬κ⁼§ι⁰§§η⊖κ±¹
For each letter in the solution check that the previous letter is not in the same group, unless it is the first letter of a word, in which case check that it is equal to the last letter of the previous word, unless it is the first letter of the solution, in which case just ignore it.
$endgroup$
add a comment |
$begingroup$
Charcoal, 63 bytes
⌊⁺⁺⁺⭆η›Lι²⭆⪫ηω№⪫θωι⭆⪫θω№⪫ηωι⭆η⭆ι⎇μ¬⁼Φθ№νλΦθ№ν§ι⊖μ∨¬κ⁼§ι⁰§§η⊖κ±¹
Try it online! Link is to verbose version of code. Explanation:
⌊⁺⁺⁺
Concatenate the below expressions and output 0 if any of them includes a 0 otherwise 1.
⭆η›Lι²
For each word in the solution output whether its length is at least 3.
⭆⪫ηω№⪫θωι
For each letter in the solution output whether it appears in the puzzle.
⭆⪫θω№⪫ηωι
For each letter in the puzzle output whether it appears in the solution.
⭆η⭆ι⎇μ¬⁼Φθ№νλΦθ№ν§ι⊖μ∨¬κ⁼§ι⁰§§η⊖κ±¹
For each letter in the solution check that the previous letter is not in the same group, unless it is the first letter of a word, in which case check that it is equal to the last letter of the previous word, unless it is the first letter of the solution, in which case just ignore it.
$endgroup$
Charcoal, 63 bytes
⌊⁺⁺⁺⭆η›Lι²⭆⪫ηω№⪫θωι⭆⪫θω№⪫ηωι⭆η⭆ι⎇μ¬⁼Φθ№νλΦθ№ν§ι⊖μ∨¬κ⁼§ι⁰§§η⊖κ±¹
Try it online! Link is to verbose version of code. Explanation:
⌊⁺⁺⁺
Concatenate the below expressions and output 0 if any of them includes a 0 otherwise 1.
⭆η›Lι²
For each word in the solution output whether its length is at least 3.
⭆⪫ηω№⪫θωι
For each letter in the solution output whether it appears in the puzzle.
⭆⪫θω№⪫ηωι
For each letter in the puzzle output whether it appears in the solution.
⭆η⭆ι⎇μ¬⁼Φθ№νλΦθ№ν§ι⊖μ∨¬κ⁼§ι⁰§§η⊖κ±¹
For each letter in the solution check that the previous letter is not in the same group, unless it is the first letter of a word, in which case check that it is equal to the last letter of the previous word, unless it is the first letter of the solution, in which case just ignore it.
answered 23 hours ago
NeilNeil
82.9k745179
82.9k745179
add a comment |
add a comment |
$begingroup$
Java (JDK), 190 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|=1<<1+(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|=1<<1+(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.
}
$endgroup$
add a comment |
$begingroup$
Java (JDK), 190 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|=1<<1+(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|=1<<1+(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.
}
$endgroup$
add a comment |
$begingroup$
Java (JDK), 190 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|=1<<1+(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|=1<<1+(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.
}
$endgroup$
Java (JDK), 190 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|=1<<1+(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|=1<<1+(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.
}
edited 12 hours ago
answered 12 hours ago
Olivier GrégoireOlivier Grégoire
9,41511944
9,41511944
add a comment |
add a comment |
If this is an answer to a challenge…
…Be sure to follow the challenge specification. However, please refrain from exploiting obvious loopholes. Answers abusing any of the standard loopholes are considered invalid. If you think a specification is unclear or underspecified, comment on the question instead.
…Try to optimize your score. For instance, answers to code-golf challenges should attempt to be as short as possible. You can always include a readable version of the code in addition to the competitive one.
Explanations of your answer make it more interesting to read and are very much encouraged.…Include a short header which indicates the language(s) of your code and its score, as defined by the challenge.
More generally…
…Please make sure to answer the question and provide sufficient detail.
…Avoid asking for help, clarification or responding to other answers (use comments instead).
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodegolf.stackexchange.com%2fquestions%2f183213%2fletter-boxed-validator%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
4
$begingroup$
@TFeld
no letter appears twice$endgroup$
– feersum
yesterday
$begingroup$
A truthy value if the list of words is a valid solution to the Letter Boxed challenge for those 4×3 letters, and a falsey value otherwise. For Python (and most other languages, I expect), both
and0are falsey. Can we output either, or must our output be consistent?$endgroup$
– Artemis Fowl
23 hours ago
$begingroup$
@ArtemisFowl Either is fine.
$endgroup$
– Robin Ryder
15 hours ago
$begingroup$
I thought so, but my question was: can we mix them?
$endgroup$
– Artemis Fowl
7 hours ago
$begingroup$
@ArtemisFowl Yes, you can mix them.
$endgroup$
– Robin Ryder
7 hours ago