| Bytes | Lang | Time | Link |
|---|---|---|---|
| 068 | AWK | 241104T165029Z | xrs |
| 016 | 05AB1E | 220908T082115Z | Kevin Cr |
| 020 | Regex POSIX ERE / RE2 or better | 220908T011928Z | Deadcode |
| 026 | Retina 0.8.2 | 230825T190713Z | mbomb007 |
| 086 | C gcc | 220908T231328Z | Noodle9 |
| 019 | Nekomata + e | 230704T034432Z | alephalp |
| 058 | C gcc | 230703T080007Z | l4m2 |
| 057 | JavaScript Node.js | 230703T113503Z | l4m2 |
| 068 | jq | 230223T204721Z | GammaFun |
| 016 | Japt | 220921T105846Z | Shaggy |
| 013 | Vyxal | 220908T010356Z | naffetS |
| 101 | Rust | 220909T154552Z | Lamdba |
| 039 | sed | 220908T153809Z | Jonah |
| 017 | Husk | 220909T111354Z | Dominic |
| 023 | Husk | 220908T230031Z | Calga |
| 070 | Prolog SWI | 220908T062834Z | Razetime |
| 054 | Zsh | 220908T004440Z | GammaFun |
| 020 | Brachylog | 220908T212108Z | DLosc |
| 050 | Python | 220908T171623Z | loopy wa |
| 016 | Jelly | 220908T170340Z | Jonathan |
| 058 | JavaScript ES6 | 220908T130101Z | Arnauld |
| 061 | Python3 | 220908T003552Z | Ajax1234 |
| 024 | MathGolf | 220908T090230Z | Kevin Cr |
| 021 | Charcoal | 220908T084515Z | Neil |
| 036 | Factor | 220908T072641Z | chunes |
| 039 | JavaScript V8 | 220908T021255Z | thejonym |
| 021 | APL Dyalog Classic | 220908T004137Z | att |
| 042 | Raku | 220908T013712Z | Jo King |
| 042 | Curry PAKCS | 220908T013406Z | alephalp |
AWK, 68 bytes
{while(sub(/[Tt][Uu][Tt]-[Tt][Uu][Tt]/,"TUTTUT"));$0=$0!~/[a-z\-]/}1
This is another one that doesn't seem to work on TIO. With some inspiration from the sed answer. Couldn't figure out a better way to regex with AWK.
05AB1E, 17 16 bytes
ºìü13"tut-"ûδåßΘ
Port of @GammaFunction's Zsh answer, so make sure to upvote that answer as well!
-2 bytes porting @JonathanAllan's Jelly answer
Could be -1 byte without the trailing Θ if default truthy/falsey output was allowed, instead of two distinct outputs.. :/
Try it online or verify all test cases.
Explanation:
º # Mirror the (implicit) input-string
# (e.g. "abc" to "abccba")
ì # Prepend it to the (implicit) input-string
# (e.g. "abccba" to "abcabccba")
ü13 # Pop and create overlapping parts of size 13
"tut-"û # Push string "tut-" and palindromize it to "tut-tut"
δ # Map over each overlapping part using "tut-tut" as argument:
å # Check if the part contains "tut-tut" as substring
ß # Minimum to check all are truthy and it's not empty
Θ # (Explicit ==1 check to convert the empty strings to 0s..)
# (after which the result is output implicitly)
Regex (POSIX ERE / RE2 or better), 23 21 20 bytes
^\b((t?\But)?-tut)+$
Based on regexes by thejonymyster and Bubbler.
Try it on regex101! - RE2
Try it online! - GNU ERE (Bash + egrep)
Try it online! - ECMAScript
Try it online! - Perl
Try it online! - Raku:P5
Try it online! - PCRE
Try it online! - Java
Try it online! – Try It Online") - Boost
Try it online! - Python
Try it online! - Ruby
Try it online! - .NET
^ # Anchor to start of string.
\b # Assert there is a word boundary here. Given the context, this is
# equivalent to asserting that the first character isn't "-".
(
(
t? # Optionally match and consume "t".
\B # Assert that this is not a word boundary. Given the context, this
# is equivalent to asserting that the string does not start here.
ut # Match and consume "ut".
)? # Optionally match the above.
-tut # Match and consume "-tut".
)+ # Iterate the above as many times as possible, minimum one.
$ # Assert we've reached the end of the string.
Alternative 20 bytes:
^(tut-(tu\Bt?)?)+\b$
Try it on regex101! - RE2
Try it online! - ECMAScript
Try it online! - PCRE
This version doesn't work properly in GNU ERE; it matches tut-tuttut-tu. This appears to be a bug in GNU ERE, and is still present in the latest version. Note that ^(a\Bb?){2}$ incorrectly matches aba:
Try it online! - GNU ERE (bug) / Attempt This Online! (bug)
Try it online! - PCRE (no bug)
But ^a\Bb?a\Bb?$ correctly doesn't match aba:
Try it online! - GNU ERE / Attempt This Online!
21 bytes without word-boundary assertions (GNU ERE or better):
^(tut-(tut?|))+tut$\2
21 bytes without word-boundary assertions or backreferences (ECMAScript or better):
^(?=t)((t?ut)?-tut)*$
Regex (ECMAScript or better), 22 bytes
^((?=tut-tut).{1,7})*$
Try it online! - ECMAScript
Try it online! - Perl
Try it online! - Raku:P5
Try it online! - PCRE
Try it online! - Java
Try it online! - Boost
Try it online! - Python
Try it online! - Ruby
Try it online! - .NET
^ # Anchor to start of string
(
(?=tut-tut) # Assert that the following 7 characters match "tut-tut",
# without consuming them.
.{1,7} # Skip anywhere from 1 to 7 characters
)* # Iterate the above as many times as possible
$ # Assert we've reached end of string
Alternative 22 bytes:
^(t(?=ut-tut).{0,6})*$
Regex (Perl v5.34+ / PCRE2 v10.43+ / Python / Ruby), 21 bytes
^((?=tut-tut).{,7})*$
Attempt This Online! - Perl v5.40+
Attempt This Online! - PCRE2 v10.44+
Try it online! - Python
Try it online! - Ruby
Python and Ruby support the quantifier shorthand of {,N} to mean {0,N}. So too do the latest versions of Perl and PCRE.
Alternative 21 bytes:
^(t(?=ut-tut).{,6})*$
Attempt This Online! - Perl v5.40+
Attempt This Online! - PCRE2 v10.44+
Try it online! - Python
Try it online! - Ruby
Regex (Raku), 25 21 bytesSBCS
^tut»((t?ut)?\-tut)+$
Ported from a previous (21 byte) version of the "POSIX ERE / RE2 or better" regex.
Porting the 21 byte lookahead-using version comes to 28 bytes:
^<?before t>((t?ut)?\-tut)*$
\$\large\textit{Anonymous functions}\$
Raku, 29 25 bytesSBCS
{/^tut»((t?ut)?\-tut)+$/}
Ruby, 29 28 30 bytes
->s{s=~/^\b((t?\But)?-tut)+$/}
Julia v1.5+, 32 bytes
endswith(r"^\b((t?\But)?-tut)+")
-5 bytes compared to v1.2+, thanks to MarcMush
Julia v1.2+, 39 38 37 bytes
s->endswith(s,r"^\b((t?\But)?-tut)+")
JavaScript, 35 34 33 bytes
s=>/^\b((t?\But)?-tut)+$/.test(s)
PowerShell, 35 34 bytes
$args-match'^\b((t?\But)?-tut)+$'
Java, 36 bytes
s->s.matches("((?=tut-tut).{1,7})*")
s->s.matches("tut\\b((t?ut)?-tut)+")
s->s.matches("\\b((t?\\But)?-tut)+")
R, 40 bytes
\(L)grepl('^((?=tut-tut).{1,7})*$',L,,1)
\(L)grepl('^tut\\b((t?ut)?-tut)+$',L,,1)
\(L)grepl('^\\b((t?\\But)?-tut)+$',L,,1)
PHP, 47 bytes
fn($s)=>preg_match('/^\b((t?\But)?-tut)+$/',$s)
Python, 54 53 bytes
lambda s:re.match(r'\b((t?\But)?-tut)+$',s);import re
\$\large\textit{Full programs}\$
Retina, 21 20 bytes
^\b((t?\But)?-tut)+$
Pip, 25 24 21 bytes
+`(t?\But|\b)-tut`~=a
Thanks to DLosc for demonstrating this syntax. This is apparently shorthand for ^((t?\But|\b)-tut)+$. This regex is slightly less inefficient speed-wise, but by moving all distinctive operations inside the loop, it allows this shortcut to be used.
Ruby -n, 25 24 bytes
p~/^\b((t?\But)?-tut)+$/
Prints nil for false and 0 for true, which are respectively falsey and truthy in Ruby. If printing 0 or 1 is desired, replace p~ with p !! (+2 bytes).
Perl -p, 27 26 25 bytes
$_=/^\b((t?\But)?-tut)+$/
MATL, 25 bytes
'^\<((t?\But)?-tut)+$'XXn
MATL appears to have \< and \> as its word boundary assertions, and apparently doesn't support \b, yet somehow still supports \B. I can't currently explain this; I thought it used PCRE.
Zsh, 35 34 bytes
[[ $1 =~ '^\<((t?\But)?-tut)+$' ]]
Zsh uses GNU ERE as its regex engine, so while \b would work, \< should be slightly more efficient due to only checking for the type of word boundary that can occur at that location.
PHP -F, 48 47 46 bytes
<?=preg_match('/^\b((t?\But)?-tut)+$/',$argn);
Try it online! - bare-bones test harness
Try it online! - fancier test harness
Retina 0.8.2, 26 bytes
I know it's not as short as some other answers, but here's my solution.
^(tut(-tut))(\1|(ut)?\2)*$
C (gcc), 94 86 bytes
d;b;f(char*s){for(b=~0;b&&s[3]|b+4;s-=b=d&b|d==1?0:~3)s+=d=strstr(s,"tut-tut")-s;b=b;}
Saved 8 bytes thanks to c--
Inputs a pointer to a string.
Returns ~3 if the input is constructed of overlapping or concatenated instances of the string "tut-tut" or 0 otherwise.
Nekomata + -e, 19 bytes
ʷ{;"tut-tut"=ip,}ᵗN
A port of my Curry answer. See also @DLosc's Brachylog answer.
ʷ{;"tut-tut"=ip,}ᵗN
ʷ{ } Loop until failure
; Split the input into two parts
"tut-tut"= Check if the second part is "tut-tut"
ip Take a proper prefix of the second part
, Append it to the first part
ᵗN Check if the result is empty
C (gcc), 58 bytes
Assumes non-empty input
f(char*s){s=bcmp(s,"tut-tut",7)?!*s:f(s+4)|f(s+6)|f(s+7);}
C (gcc), 62 bytes
f(char*s){s=bcmp(s,"tut-tut",7)?0:!s[7]|f(s+4)|f(s+6)|f(s+7);}
-7 bytes from xnor's comment to another answer and 2 from ceilingcat
JavaScript (Node.js), 57 bytes
x=>x.split`-tut`.every(i=>+{ut:1,tut:1,'':x[3]+1}[j=i])>j
Regless
See another regless solution here
jq, 78 68 bytes
[range(length) as $i|"xxxxxx\(.)"[$i:13+$i]|contains("tut-tut")]|all
Port of my Zsh answer. The EDIT: Turns out, it was optimizable!<> as $<> feels optimizable, but I couldn't figure it out.
Japt, 16 bytes
pÔiU ãD eø`t©-t©
pÔiU ãD eø`t©-t© :Implicit input of string U
p :Append
Ô : Reverse
iU :Prepend input
ã :Substrings of length
D : 13
e :All
ø : Contain
`t©-t© : Compressed string "tut-tut"
Vyxal, 16 14 13 bytes
mp13l‛≠₈‹∞vcg
Try it Online! | 12 bytes with g flag
Returns 1 for true, or falsy for false (0 or an empty list).
mp13l‛≠₈‹∞vcg
m # Mirror the input - append its reverse
p # Append the input to that
13l # Get all overlapping strings of length 13
‛≠₈‹∞vc # For each, does it contain "tut-tut"?
g # Minimum. Returns an empty list for an empty list (no idea why)
-3 from porting Jonathan Allan's Jelly answer!
-1 thanks to emanresu A.
Previously:
Vyxal, 16 bytes
6Iø.13l`≠₈-`∞vcA
Uses the same idea as @GammaFunction's Zsh answer.
6Iø.13l`≠₈-`∞vcA
6Iø. # Surround the input with 6 spaces on both sides
13l # Get all overlapping strings of length 13
`≠₈-`∞vcA # Do all of them contain "tut-tut"?
Rust, 101 bytes
|s:&str|(0..s.len()).scan(0,|r,i|{if s[i..].starts_with("tut-tut"){*r=7}*r-=1;Some(*r)}).all(|i|i>=0)
Returns a boolean with the obvious meaning.
sed, 39 bytes
:a
s/tut-tut/TUTTUT/i
ta
s/[^TU]//
T
cN
Truthy test cases -- outputs nothing
Falsy test cases -- outputs one N for each line
The idea here is quite simple:
- Continuously replace
tut-tutwithTUTTUT, using case-insensitive matching, until the input stops changing. - Check if there are any lowercase characters or
-left. - If so, output an
Nfor failure. Otherwise, output nothing for success.
sed, 29 bytes, straight regex, thanks to Deadcode
s/^((t?\But)?\b-tut)+$//
t
cN
Thanks to Deadcode for this alternate approach which forgoes looping and solves it with a single application of a true regex.
Husk, 22 18 17 bytes
Edit: saved 4 5 bytes based on Jonathan Allan's idea
▼M€X13‼S+↔⁰¨μζ-μζ
‼ ⁰ # apply twice to the input:
S+↔ # join to itself reversed
X13 # and split this into strings of 13 characters;
M # now map over these
€ # do they contain
¨μζ-μζ¨ # the compressed string "tut-tut"?
▼ # and return the minimum result
Husk, 24 23 bytes
Edit: saved 1 byte based on Dominic van Essen's comment.
±Λ≤7Ẋ-J¥¨μζ-μζ¨X7¹e_6→L
Explanation
±Λ≤7Ẋ-J¥¨μζ-μζ¨X7¹e_6→L
±Λ≤7 check if all differences are ≤7
Ẋ- take the difference of all adjacent elements in list
J put indices list the into the middle of [-6,1+len(input)]
¥ create indices list of all occurrences of "tut-tut" in substring list
¨μζ-μζ¨ "tut-tut"
X7¹ create list of substrings of input with length 7
e_6→L list [-6,1+len(input)]
Prolog (SWI), 70 bytes
b-->"tut-tut".
n-->(b;"ut-tut";"-tut"),(n;"").
t-->b;b,n.
+X:-t(X,[]).
-4 from jo king.
Zsh, 66 54 bytes
-6 bytes thanks to Neil, -6 bytes by switching to -e thanks to pxeger.
s=xxxxxx$1
repeat $#1 [[ ${s:$[i++]:13} = *tut-tut* ]]
The problem stated is equivalent to: Every sliding 13-character window of xxxxxx[string]xxxxxx contains tut-tut. In Bash and Zsh, the ${var:${idx}:13} is valid even if the string isn't long enough, so the trailing xxxxxx are unneeded.
We loop over each window, and exit out if any single test fails thanks to errexit.
Brachylog, 20 bytes
Ẹ|a₀"tut-tut"sl;?b₍↰
Explanation
This is a pretty straight-at-the-problem approach; possibly something more subtle would be shorter.
Ẹ|a₀"tut-tut"sl;?b₍↰
Ẹ Either the input is the empty string
| Or
a₀ A prefix of the input
"tut-tut" is "tut-tut"
s Take a nonempty substring of "tut-tut"
l Get its length
;?b₍ Remove that many characters from the start of the input string
↰ Recurse
Python, 50 bytes
def f(s):s[:7]=="tut-tut"and f(s[~ord(s[7])%5|4:])
Signals by exit code: errors out if the input is "tut-tut"-decomposible.
How?
Recursively checks that input starts with "tut-tut". Based on the next character directly computes where the next "tut-tut" has to start.
0 1 2 3 4 5 6 7 8 9 ...
---
t u t - t u t | - |
| |
==> t u t | - | t u t
---
---
t u t - t u t | u |
| |
==> t | u | t - t u t
---
---
t u t - t u t | t |
| |
==> | t | u t - t u t
---
The figure shows offsets inferred from char at position 7:
"-"--> 4"u"--> 6"t"--> 7
The magic formula ~x%5|4 implements this map. x is the code point of input character.
Importantly, any input is mapped to 4,5,6,7, so the algorithm can neither get stuck nor skip any characters.
Now, if we can cover the input with "tut-tut"s we will eventually reach the end and error out as soon as we try to access out-of-bounds characters. Otherwise the algorithm will simply stop at the first place that cannot be covered.
Thanks to eagle-eyed @Jonathan Allan for spotting a problem with my first attempt.
Wrong Python, 54 bytes
def f(s):s[:7]=="tut-tut"and f(s[~ord(s[7])%31%12%8:])
Jelly, 16 bytes
m0;w13Ƥ“"ṁĿ4ṘṘ»Ṃ
A monadic Link that accepts a list of characters and yields 1 if constructible or 0 if not.
How?
The input must (a) start with tut-tut, (b) end with tut-tut, and (c) have tut-tut as a contiguous substring of all of its length \$13\$ slices. We can, however, just test that (c) holds for the input concatenated with its reverse concatenated with the input (e.g. abc -> abccbaabc). This works since tut-tut is palindromic and any bad starts or bad ends in the input will now nest between any tut-tuts.
m0;w13Ƥ“"ṁĿ4ṘṘ»Ṃ - Link: list of characters, S e.g. "abc"
m0 - reflect -> "abccba"
; - concatenate -> "abccbaabc"
Ƥ - for infixes...
13 - ...of length 13:
w “"ṁĿ4ṘṘ» - first 1-indexed index of "tut-tut" or 0 if not found
Ṃ - minimum (an empty list yields 0)
Bit of a shame it takes half the code to make "tut-tut"!
JavaScript (ES6), 58 bytes
A non-regex solution.
f=([c,...a],i)=>i>6?!c:c=="tut-"[i&3]&&f(a,-~i)|3%~-i&f(a)
How?
We use a pointer \$i\$ into the string \$s=\$ "tut-tut". At each iteration, we make sure that the current character from the input string matches \$s[i]\$, then we either increment \$i\$ or restart with \$i=0\$ if we are allowed to do so. The parsing is successful if we end up with \$i=7\$ exactly when the end of the input string is reached.
The table below summarizes after which positions it's possible to restart with \$i=0\$ and how this can be computed with the expression 3 % ~-i & 1.
| i = position | character | restart after? | 3 % ~-i | 3 % ~-i & 1 |
|---|---|---|---|---|
| 0 | t | No | 0 | 0 |
| 1 | u | No | NaN | 0 |
| 2 | t | No | 0 | 0 |
| 3 | - | Yes | 1 | 1 |
| 4 | t | No | 0 | 0 |
| 5 | u | Yes | 3 | 1 |
| 6 | t | Yes | 3 | 1 |
MathGolf, 24 bytes
☼▌☼▐l£{_C<ÿtut-ñ╧\╞};]ε*
Port of @GammaFunction's Zsh answer, so make sure to upvote him/her as well!
Explanation:
☼▌ # Prepend a leading "100000" in front of the (implicit) input-string
☼▐ # Append "100000" as well
l£ # Push the input-string, pop and push its length
{ } # Loop that many times:
_ # Duplicate the current string
C< # Pop the copy, and keep its first 13 characters
ÿtut-ñ # Push string "tut-", and palindromize it to "tut-tut"
╧ # Check if the string contains this "tut-tut" as substring
\ # Swap so the string we've duplicated is at the top of the stack again
╞ # Remove its leading character
; # After the loop, discard the remaining string from the stack
] # Wrap everything else on the stack into a list
ε* # Product (reduce by multiplication) to verify whether all checks were
# truthy
# (after which the entire stack is output implicitly as result)
Charcoal, 21 bytes
⬤θ№✂⁺×⁶ψθκ⁺¹³κ¹…tut-⁷
Try it online! Link is to verbose version of code. Outputs a Charcoal boolean, i.e. - for a valid string, nothing if not. Explanation: A port of my golf to @GammaFunction's zsh answer.
θ Input string
⬤ All indices satisfy
⁶ Literal integer `6`
× Repetitions of
ψ Null byte
⁺ Plus
θ Input string
✂ ¹ Sliced from
κ Current index to
¹³ Literal integer `13`
⁺ Plus
κ Current index
№ Contains
tut- Literal string `tut-`
… Extended to length
⁷ Literal integer `7`
Factor, 36 bytes
[ R/ tut\b((t?ut)?-tut)+/ matches? ]
Port of Deadcode's (Bubbler's/thejonymyster's) regex answer.
Factor + math.unicode, 63 bytes
[ "xxxxxx"dup surround 13 clump [ "tut-tut"swap subseq? ] ∀ ]
Port of GammaFunction's Zsh answer.
JavaScript (V8), 39 bytes
x=>x.replace(/(?=tu)((t?ut)?-tut)*/,"")
Returns a falsy string if the string is correctly composed of tut-tuts, and a truthy string otherwise.
Mostly the same logic as my (slightly broken) regex solution, except instead of having the "this regex matches the entire string or else it fails" logic be in the regex, its in the fact that we only delete one occurrence of the pattern. If the entire string is not composed of the pattern, there will be string remaining after the replacement, and in js, any nonempty string is truthy, with the empty string being the only falsy string :-)
(in case you wonder why this doesn't fail for cases where two valid strings are concatenated: regex is greedy, and will grab the largest match it can grab)
Breakdown:
x=>x.replace(/(?=tu)((t?ut)?-tut)*/,"") // full function
x=>x.replace(/ /,"") // return the string with exactly one
// match of the following regex removed
(?=tu) // string starting with "tu"
( )* // which contains at least 0 of
// the following pattern
// (actually at least 1, since otherwise,
// the pattern would be empty and
// thus would fail the "tu" check)
(t?ut)?-tut // any of "-tut"
// (will never be at the start due to the
// "tu" check, but can appear in cases
// where the entire "tut" overlaps),
// "ut-tut"
// (in cases where just the "t" is overlapping,
// also can never be at the start)
// or "tut-tut"
// (this one always comes first
// due to the "tu" check)
BTW this regex saves a byte over the straightforward regex /tut-tut((t?ut)?-tut)*/ because we don't actually have to use the entire "tut-tut"; the first group ((t?ut)?-tut) is forced to complete to tut-tut once it's forced to start with tu, if that makes sense... :-)
APL (Dyalog Classic), 21 bytes
∧/7∨/'tut-tut'⍷6∘↓⍣¯1
6∘↓⍣¯1 pad with leading spaces
'tut-tut'⍷ find occurrences of tut-tut
∧/7∨/ present in every group of 7 consecutive positions
Raku, 42 bytes
{^.comb⊆m:ex/tut\-tut/>>.&{.from..^.to}}
An anonymous function that takes a string and returns a true/false value for if it is composed of overlapping 'tut-tut's.
Explanation
{ } # Anonymous function block
^.comb # The range 0 to length of input
⊆ # is a subset or equal to
m:ex/tut\-tut/ # Match all instances of 'tut-tut'
>>.&{ } # And map them to
.from..^.to # The range of covered indexes
This basically finds the indexes covered by each 'tut-tut' and makes sure that they cover the entire string. Note that you could easily generalise this function to any string.
Curry (PAKCS), 42 bytes
f""=1
f(a@(_:_++b)++c)|a=="tut-tut"=f$b++c
Returns 1 for truth, and nothing otherwise.