| Bytes | Lang | Time | Link |
|---|---|---|---|
| 280 | Python3 | 250518T024750Z | Ajax1234 |
| 123 | JavaScript Node.js | 231020T191521Z | l4m2 |
| 019 | Jelly | 231020T200418Z | Jonathan |
| 077 | R | 231021T135401Z | Nick Ken |
| 074 | JavaScript ES6 | 231020T190405Z | Arnauld |
| nan | J | 231020T205915Z | Jonah |
| 032 | Charcoal | 231020T214309Z | Neil |
| 041 | Retina 0.8.2 | 231020T205349Z | Neil |
| 095 | Ruby | 231020T185726Z | Value In |
Python3, 280 bytes
def f(c,w):
a,*U,b=c.split()
if w in a or w in b:return
for i in range(1,len(w)):
if(K:=''.join(U))==w[i:len(K)+i]:
W=w[i+len(K):]
if a[:-i]and b[len(W):]and a[-i:]==w[:i]and b[:len(W)]==W:return 1
W=a+''.join(U)+b
if W[:i]==w[:i]and W[-(len(w)-i):]==w[i:]:return 1
JavaScript (Node.js), 123 bytes
x=>y=>(z=x.split` `.join``,g=i=>z[i]==y[i]?g(i+1):y[i]&&i*z.endsWith(y.slice(i))||eval(`/.${y}./`).test(z))(0)&&!x.match(y)
-1B from noodle man
Jelly, 19 bytes
Uses some of Unrelated String's answer to Is it a circumfix? saving bytes over using the "outfix quick", ÐƤ.
ḲFŒṖḢ;ṪƊ€;ṖḊẆƊƲḟẆ{i
A dyadic Link that accepts the clue on the left and the answer on the right and yields a positive integer (truthy) if valid or zero (falsey) otherwise.
Try it online! (Some tests have been shortened in the middle since the algorithm is inefficient.)
How?
ḲFŒṖḢ;ṪƊ€;ṖḊẆƊƲḟẆ{i - Link: Clue, Answer
Ḳ - split {Clue} on space characters
F - flatten -> Squished
Ʋ - last four links as a monad - f(Squished):
ŒṖ - all partitions (no empty parts)
Ɗ€ - for each: last three links as a monad - f(Partition):
Ḣ - head (remove first part and yield it)
Ṫ - tail (remove last part of that and yield it ...
...or integer zero* if nothing left)
; - concatenate
-> Bookends (plus an invalid one with a trailing zero*)
Ɗ - last three links as a monad - f(Squished):
Ṗ - pop (remove the tail character)
Ḋ - dequeue (remove the head character)
Ẇ - all sublists
-> Hiddens
; - {Bookends} concatenate {Hiddens} -> Potential Answers
Ẇ{ - sublists of {Clue}
ḟ - {Potential Answers} filter discard {Clue sublists}
-> Valid Answers (plus an invalid bookend with a trailing zero*)
i - 1-indexed index of {Answer} in* {Valid Answers} ...
...or zero if not found
* Integer zero wont match a zero character
R, 77 bytes
\(x,y,`/`=grepl)"^((.+)(.+)) (\\2.*\\3$|.+\\1.)"/paste(y,gsub(" ","",x))&!y/x
A function taking two character arguments and returning a logical value. Inspired by @Neil’s Retina answer so be sure to upvote that one too! The regular expression here is slightly different because of R’s requirement to escape backslashes.
JavaScript (ES6), 74 bytes
A significantly shorter version suggested by Nick Kennedy and using Neil's regular expression.
Expects (clue)(word). Returns a Boolean value.
c=>w=>c.match(w)</^(.+)(.+),(\1.*\2$|.+\1\2.)/.test([w,c.split` `.join``])
JavaScript (ES6), 86 bytes
Expects (clue)(word). Returns a Boolean value.
The "bookend" test is based on the method used by Deadcode in this answer.
c=>w=>c.match(w)</^(.+)(.+),\1.*\2$/.test([w,s=c.split` `.join``])+!!s.match(`.${w}.`)
Commented
c => // outer function taking c = clue
w => // inner function taking w = hidden word
c.match(w) // look for w in c; the comparison will succeed
< // if this is null and the right side is > 0
/^(.+)(.+),\1.*\2$/ // regular expression for the "bookend" test
.test([ // applied to this array coerced to a string:
w, // the word, followed by a comma
s = c.split` ` // followed by s,
.join`` // which is c without spaces
]) + // end of test()
!!s.match(`.${w}.`) // for word breaks, we look for w in s with at
// least one char. before and one char. after
J, 52 51 45 bytes
-.@rxin*[e.((]#~#@[>:#\@](-.|."{[),&#)-.&' ')
This approach allows us to avoid treating the two cases of bookends and word breaks as separate:
-.@rxin*Not in the unaltered string*And...-.&' 'Remove spaces from haystack#\@]Create the integers 1..n (where n is length of haystack),&#Create the integers n and m, the lengths of needle and the haystack. I'll explain why below.-.Remove n and m from 1..n (again, why below). Call this our "rotation list".|."{[Do every rotation of 1..n in our rotation list. The rotations we are leaving out are precisely the ones where our haystack abuts the left or right side, which are the illegal ones. We now have a matrix, with each row representing a legal rotation.#@[>:In every row, change the numbers 1..m (where m is length of needle) to 1 and the rest to 0, so now we have a matrix of the legal rotations of, eg,1 1 1 0 0 0 0 0(if the needle had length 3).]#~Now use the rows of legal 0-1 masks to filter the no-spaces input. These represent all possible bookends and word breaks.[e.Is the needle in any of those?
J, 52 bytes
-.@rxin*[((rxin g)+.[e.-~&#(g=.}:@}.)@(]\.)])' '-.~]
Another nice candidate for J's outfix adverb. Reading through other answers I was reminded that this approach is similar to my answer on Is it a cirumfix as well.
-.@rxinDoes not appear in unaltered string*and...(rxin g)Does appear in the no-spaces' '-.~]string, after that string has its first and last elements removedg=.}:@}.+.or...-~&#(g=.}:@}.)@(]\.)Matches one of the outfixes (of appropriate length-~&#) after the set of all such outfixes has its first and last elements removed}:@}..
Charcoal, 32 bytes
‹№θη∨№⁻θ η⊙η∧κ¬∨⌕⁻θ …ηκ⌕⮌⁻θ ⮌✂ηκ
Try it online! Link is to verbose version of code. Outputs a Charcoal boolean, i.e. - for a valid clue, nothing if not. Explanation:
№ Count of
η Input word in
θ Input clue
‹ Is less than
№ Count of
η Input word in
θ Input clue
⁻ With spaces removed
∨ Logical Or
η Input clue
⊙ Any index satisfies
κ Current index
∧ Logical And
θ Input clue
⁻ With spaces removed
⌕ Does not start with
η Input word
… Truncated to length
κ Current index
∨ Logical Or
θ Input clue
⁻ With spaces removed
⮌ Reversed
⌕ Does not start with
η Input word
✂ Sliced from
κ Current index
⮌ Reversed
¬ Logical Not
Retina 0.8.2, 41 bytes
|^(.+)¶.*\1
^(.+)(.+)¶(\1.*\2$|.+\1\2.)
Try it online! Takes input as the word and clue on separate lines but link is to test suite that splits on comma and exchanges the word and clue. Explanation:
|^(.+)¶.*\1
Delete spaces in the clue, but delete the word if is is a contiguous substring of the clue, which prevents the following match from succeeding.
^(.+)(.+)¶(\1.*\2$|.+\1\2.)
Check that the word either bookends or is now contained in the clue.
Ruby, 95 bytes
Bookends code is a slight tweak of my old answer to Is it a circumfix?
->s,w{t=s.tr' ','';(t=~/.#{w}./||(1...~-z=w.size).any?{w==t[0,_1]+t[_1-z..]}&&z<t.size)&&!s[w]}