56
\$\begingroup\$

In an earlier challenge I asked code golfers to produce strings which copy each character in a string. For example:

TThhiiss iiss ddoouubbllee ssppeeaakk!! 

This challenge is simply to detect if some text meets the definition of a double speak string.

  • There is an even number of characters.
  • When split into pairs, every pair consists of two of the same character.

The challenge

  • It's code golf, do it in few bytes.
  • Use any language you choose.
  • Please include a link to an online interpreter.
  • The code will accept some text.
  • For simplicity, the input will only consist of printable ASCII characters
  • It will return an indication of whether or not the input is double speak. It could be:
  • A boolean
  • Strings ('true', 'false', 'yes', 'no' etc)
  • Integers 0 or 1

Test Cases:

input -> output aba -> false aab -> false abba -> false aabb -> true aaabb -> false tthhiiss -> true ttthhhiiisss -> false 
\$\endgroup\$
12
  • 9
    \$\begingroup\$ May we error on inputs of length < 2? \$\endgroup\$ Commented Aug 6, 2019 at 16:06
  • 4
    \$\begingroup\$ Suggested test case: abba which should be falsey \$\endgroup\$ Commented Aug 6, 2019 at 16:29
  • 3
    \$\begingroup\$ Suggested test case: aabbbb which should be truthy \$\endgroup\$ Commented Aug 6, 2019 at 17:30
  • 2
    \$\begingroup\$ @val Well, I'm not going to argue with standard I/O \$\endgroup\$ Commented Aug 7, 2019 at 8:27
  • 4
    \$\begingroup\$ What about the empty string? \$\endgroup\$ Commented Aug 7, 2019 at 21:04

102 Answers 102

3
\$\begingroup\$

R, 53 34 bytes

-19 bytes thanks to Giuseppe

function(a)gsub("(.)\\1","",a)=="" 

Try it online!

\$\endgroup\$
4
  • 1
    \$\begingroup\$ I think gsub("(.)\\1","",a)=="" would do the trick as well; many others use the same regex. \$\endgroup\$ Commented Aug 6, 2019 at 18:05
  • \$\begingroup\$ @Giuseppe This whole regex thing is pretty new to me. Thanks. \$\endgroup\$ Commented Aug 6, 2019 at 18:10
  • \$\begingroup\$ R + pryr gets you a 32-byter trivially modified from this answer. \$\endgroup\$ Commented Aug 6, 2019 at 18:19
  • 3
    \$\begingroup\$ If input can be taken as a vector, then function(a)!sum(rle(a)$l%%2) for 28 \$\endgroup\$ Commented Aug 6, 2019 at 19:55
3
\$\begingroup\$

Brain-Flak, 26, 22 bytes

({<({}[{}])>{()<>}{}}) 

Try it online!

Outputs 1 for false and 0 for true.

Readable version:

({ <({}[{}])> { () <> } {} }) 

I originally had this:

{ ({}[{}]) { <>([()])<>{{}} }{} } <>({}()) 

Which is 10 bytes longer.

\$\endgroup\$
4
  • \$\begingroup\$ Does 0/non0 count as a boolean? If so, you can do ({({}[{}]){{}}{}}) \$\endgroup\$ Commented Aug 6, 2019 at 18:15
  • 3
    \$\begingroup\$ lol at the "Readable version" - its so very readable :P \$\endgroup\$ Commented Aug 6, 2019 at 18:32
  • \$\begingroup\$ @riley No that's not valid. However, I found a better trick. \$\endgroup\$ Commented Aug 6, 2019 at 18:42
  • \$\begingroup\$ @quinn Looks readable to me :P \$\endgroup\$ Commented Aug 6, 2019 at 18:42
3
\$\begingroup\$

QuadR, 11 bytes

''≡⍵ (.)\1 

Try it online!

''≡⍵ the result is an empty string when

(.)\1 a character followed by itself

 is replaced by nothing

\$\endgroup\$
3
\$\begingroup\$

JavaScript, 26 23 bytes

s=>/^((.)\2)+$/.test(s) 

Try it online!

Recursive Solution, 30 bytes

Thanks to Arnauld for a fix at the cost of 0 bytes.

f=([x,y,...s])=>x?x==y&f(s):!y 

Try it online!

\$\endgroup\$
3
  • \$\begingroup\$ Fixed recursive version? \$\endgroup\$ Commented Aug 6, 2019 at 18:34
  • \$\begingroup\$ Thanks, @Arnauld :) \$\endgroup\$ Commented Aug 6, 2019 at 18:50
  • \$\begingroup\$ @Oliver, crap; only saw your original solution before posting mine. I'm happy to roll back to 26 if you got to that 23 before me - let me know. \$\endgroup\$ Commented Aug 6, 2019 at 18:51
3
\$\begingroup\$

Red, 36 bytes

func[s][parse s[any[copy t skip t]]] 

Try it online!

Longer alternative:

Red, 40 bytes

func[s][(extract s 2)= extract next s 2] 

Try it online!

\$\endgroup\$
3
\$\begingroup\$

Zsh, 36 bytes

My Zsh answer to the previous challenge can be found here.

Exits truthy (0) if NOT double speak, and falsy (1) if double speak. (As allowed in a comment.)

for a b (${(s::)1})r+=${a#$b} [ $r ] 

for a b (${(s::)1})r+=${a#$b} ${(s::)1} # split $1 characterwise for a b ( ) # take pairs of characters from ${(s::)1}, assign to $a and $b ${a } # first character ${ #$b} # remove second character as prefix r+= # append to $r as string [ $r ] # exit truthy if $r is non-empty 

Try it online!

\$\endgroup\$
3
\$\begingroup\$

Prolog (SWI), 60 45 bytes

thanks to Unrelated String

+[]. +[A,A|T]:- +T. -X:-string_chars(X,Y),+Y. 

Try it online!

Converting it from a string to a list of atoms kind of ruined the score, but well..

\$\endgroup\$
2
  • 1
    \$\begingroup\$ 45 bytes \$\endgroup\$ Commented Aug 7, 2019 at 8:08
  • 1
    \$\begingroup\$ ...it looks like you can also use atom_chars instead of string_chars, even though you're taking a string as input, and not an atom. But that may be irrelevant if you can take a backtick-delimited string--that is, a list of char codes. \$\endgroup\$ Commented Aug 7, 2019 at 8:17
3
\$\begingroup\$

Mathematica, 31 bytes

AllTrue[Length/@Split@#,EvenQ]& 

This works by converting the input (an array of characters, according to @attinat) into a list of characters, splitting this list into sublists of contiguous identical elements, and checking that each sublist has an even number of elements.

\$\endgroup\$
4
  • 1
    \$\begingroup\$ An answer should be a full program or function; this is a snippet that requires s to be defined beforehand. \$\endgroup\$ Commented Aug 7, 2019 at 19:34
  • \$\begingroup\$ @attinat fixed; I was adopting the convention used by other answers (and see with amusement you pointed this out after I asked about your exclusion of Characters@) \$\endgroup\$ Commented Aug 7, 2019 at 19:40
  • \$\begingroup\$ 28 bytes by using GCD instead of AllTrue. See also this n-speak solution. \$\endgroup\$ Commented Aug 13, 2019 at 18:37
  • 1
    \$\begingroup\$ 28 bytes by using And instead of AllTrue. \$\endgroup\$ Commented Aug 13, 2019 at 21:17
3
\$\begingroup\$

Scala, 44 bytes

_.grouped(2).forall(t=>t.size>1&&t(0)==t(1)) 

Try it online!

\$\endgroup\$
3
\$\begingroup\$

Cubix, 18 bytes

;U;;A-!/@/n\nW.\O? 

Try it online! Outputs 1 if True and nothing if False.

I suppose that it is fitting that this is twice the length to my answer to the previous question

 ; U ; ; A - ! / @ / n \ n W . \ O ? . . . . . . 

Watch it run

  • A Put all input onto the stack
  • - subtract the TOS and start of the test loop
  • ! test result for 0
  • @ if not 0, halt (FALSE for double speak)
  • /;U;; if 0, pop subtraction result and top two items from the stack, u-turn sends it in the right direction.
  • !\n/? an ignored "if 0", reflect, negate, reflect and test for EOI (now 1)
  • O\/@ if positive (1) output and reflect a couple of times onto the halt (TRUE for double speak)
  • nW if negative, reverse the negation and shift lane onto the start of the test loop.
\$\endgroup\$
3
\$\begingroup\$

C# (Visual C# Interactive Compiler), 40 bytes

s=>s.Where((c,i)=>c!=$"{s}"[i|1]).Any() 

Try it online!

Each character is tested against it's neighbor for inequality. If any inequalities exist, the result is false.

Since input is limited to printable ASCII characters, a control character is appended to input which is compared to the last character of an odd length string.

Outputs are reversed.

-3 bytes inspired by @Oliver

\$\endgroup\$
3
  • \$\begingroup\$ 35 bytes? \$\endgroup\$ Commented Aug 7, 2019 at 17:24
  • \$\begingroup\$ @Oliver - this throws an exception on inputs like a, aaa, aaaaa, etc. You might be into something though, I'll keep fiddling. \$\endgroup\$ Commented Aug 7, 2019 at 22:31
  • 1
    \$\begingroup\$ I was able to knock off a few bytes at least :) \$\endgroup\$ Commented Aug 8, 2019 at 0:43
3
\$\begingroup\$

Brain-Flak, 36 10 42 30 bytes

(<>)<>{({}[{}]<>){{}{}}{}<>}<> 

Outputs 0 if it is double speak, and nothing if it isn't

-12 bytes thanks to Nitrodon

How it works

(<>) Pushes 0 to the second stack <> Swaps back to the first stack { Begins a loop that will run until the stack is empty ({}[{}]<>) Pops the top two items off of the first stack and pushes their difference to the second stack {{}{}}{} If the difference is zero, it gets popped and nothing happens. If there difference is one, the zero that was put on at the beginning gets popped, so nothing will get outputted at the end <> Swaps back to the first stack } End loop <> Swap to the second stack for output 

Try it Online!

\$\endgroup\$
3
  • \$\begingroup\$ Fixed both of the problems \$\endgroup\$ Commented Aug 7, 2019 at 15:11
  • \$\begingroup\$ ({}<>)<>({}<>)({}[{}]) can be simplified to ({}[{}]<>). \$\endgroup\$ Commented Aug 9, 2019 at 20:57
  • \$\begingroup\$ oh wow, no clue why I decided to pop and swap stacks twice, thanks :) \$\endgroup\$ Commented Aug 9, 2019 at 21:50
3
\$\begingroup\$

Gaia, 3 bytes

2Zy 

Almost as trivial as the solution to the other challenge. Errors with an input size < 2, which was never confirmed to be allowed, so might be invalid.

Try it online!

2Z Unzip input by 2 y All equal? 

Unzipping by 2 basically undoes the result of interleaving 2 strings. So if two equal strings are interleaved, then it is doublespeak.

\$\endgroup\$
3
\$\begingroup\$

Pip, 5 bytes

$QUWa 

The existing solution used a longer iterative comparison. Thankfully, the unweave function exists.

Try it online!

\$\endgroup\$
3
\$\begingroup\$

Labyrinth, 13 bytes

,:, " -@ ""}! 

Try it online!

That's a whole lot of no-ops, but I can't find any easy way to remove them.

Prints -1 if the input is a double speak, nothing otherwise. Allowed by this I/O method.

How it works

,:, Push char input (,), duplicate (:), push another char input - Subtract the top two. It can be nonzero for two reasons: the string has odd length or the last two chars differ. In either case, take a turn and exit, producing no output (@) } Remove the top number from scope and reveal the first char pushed (out of the last two). If it is negative (EOF), turn left, print it as number (-1), and exit (@). """ Otherwise, turn right and go through the no-op path back to the start of the program. 
\$\endgroup\$
3
\$\begingroup\$

Factor, 28 bytes

[ 2 group [ = ] assoc-all? ] 

Try it online!

  • 2 group Split a sequence every 2 elements, e.g. { 1 1 2 2 3 3 } -> { { 1 1 } { 2 2 } { 3 3 } }
  • [ = ] assoc-all? Does every pair in a sequence consist of equal values?

Factor, 26 24 bytes

[ 2 group flip 1 cut = ] 

Try it online!

Thanks to @Bubbler!
-2 bytes from me

  • flip Transpose a matrix. e.g. { { 1 1 } { 2 2 } { 3 3 } } -> { { 1 2 3 } { 1 2 3 } }
  • 1 cut Split the matrix in two between its first and second rows. If there isn't a second row, outputs { }. e.g. { { 1 2 3 } { 1 2 3 } } -> { { 1 2 3 } } { { 1 2 3 } }
  • = Are they equal?
\$\endgroup\$
3
  • 2
    \$\begingroup\$ Alternative 26 bytes. \$\endgroup\$ Commented May 6, 2021 at 7:08
  • \$\begingroup\$ @Bubbler that's really nice. I tried the flip approach at first but forgot about conditional first2. \$\endgroup\$ Commented May 6, 2021 at 7:15
  • \$\begingroup\$ @ Bubbler we can save 2 more bytes with 1 cut instead of ?first2. \$\endgroup\$ Commented May 6, 2021 at 7:49
3
\$\begingroup\$

Desmos, 225 bytes

f\left(i\right)=\left\{\operatorname{total}\left(\left[\left\{i\left[a\cdot2+1\right]=i\left[a\cdot2+2\right]\right\}\operatorname{for}a=\left[0...\frac{\operatorname{length}\left(i\right)}{2}-1\right]\right]\right)>0\right\} 

Input is taken as a list of ASCII character codes, I don't know much about Desmos, so I'd love to know if there's a better way!

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ Damn, that's amazing. \$\endgroup\$ Commented Mar 11, 2022 at 15:44
3
\$\begingroup\$

Lexurgy, 22 bytes

Essentially the inverse of my "DDoouubbllee ssppeeaakk!!" answer.

Capture any character twice, and delete it.

If it's double speak, the result is empty string, and a non-empty string otherwise.

a: {[]$1 $1,$$ $$}=>* 
\$\endgroup\$
3
\$\begingroup\$

Thunno 2, 2 bytes

zạ 

Attempt This Online!

Explanation

zạ # Implicit input -> s z # Uninterleave the input -> [s[0::2], s[1::2]] ạ # Check if they are both equal -> s[0::2] == s[1::2] # Implicit output 
\$\endgroup\$
3
\$\begingroup\$

Nekomata + -e, 2 bytes

ĭ= 

Attempt This Online!

ĭ Deinterleave = Check equality 

Since Nekomata doesn't have the concept of booleans or truthiness, the flag -e is required for every challenge.

\$\endgroup\$
3
\$\begingroup\$

Uiua, 11 bytes

≅⊃'▽¬▽◿2⇡⧻. 

Try it!

≅⊃'▽¬▽◿2⇡⧻. . # duplicate ⧻ # length ⇡ # range ◿2 # modulo two ⊃'▽¬▽ # get the elements at even and odd indices ≅ # do they match? 
\$\endgroup\$
2
  • \$\begingroup\$ fails for "aaa". \$\endgroup\$ Commented Oct 12, 2023 at 17:27
  • \$\begingroup\$ @DominicvanEssen Thanks. Fixed for +1. \$\endgroup\$ Commented Oct 12, 2023 at 17:53
2
\$\begingroup\$

PowerShell, 27 24 bytes

-3 bytes thanks to mazzy

!($args-creplace"(.)\1") 

Try it online!

Uses the regex method going around. If the string is emptied out, it will return true, otherwise false.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ you can omit ,'' Try it online! \$\endgroup\$ Commented Aug 6, 2019 at 16:37
  • 1
    \$\begingroup\$ @mazzy Ha ha, I'm smrt. Thanks \$\endgroup\$ Commented Aug 6, 2019 at 16:40
2
\$\begingroup\$

Charcoal, 10 bytes

⬤⪪S²⁼ι⮌…ι² 

Try it online! Link is to verbose version of code. Outputs Charcoal's default boolean format, which is - for true and nothing for false. Explanation:

 S Input string ⪪ ² Split into substrings of length up to 2 ⬤ All substrings ι Current substring … ² Extended to length 2 ⮌ Reversed ⁼ Equals ι Current substring Implicitly print 
\$\endgroup\$
2
\$\begingroup\$

Whitespace, 73 bytes

[N S S N _Create_Label_LOOP][S S S N _Push_0][S N S _Duplicate_0][T N T S _Read_input_as_character][T T T _Retrieve][S N S _Duplicate_input][S S S T S T S N _Push_10][T S S T _Subtract][N T S S N _If_0_Jump_to_Label_EXIT][S S S N _Push_0][S N S _Duplicate_0][T N T S _Read_input_as_character][T T T _Retrieve][T S S T _Subtract][N T S N _If_0_Jump_to_Label_LOOP][S S S N _Push_0][T N S T _Print_as_integer][N S S S N _Create_Label_EXIT] 

Letters S (space), T (tab), and N (new-line) added as highlighting only.
[..._some_action] added as explanation only.

Since Whitespace inputs one character at a time, the input should contain a trailing newline so it knows when to stop reading characters and the input is done.

Outputs 0 for falsey, or nothing for truthy.

Try it online (with raw spaces, tabs and new-lines only).

Explanation in pseudo-code:

Start LOOP: Character c = STDIN as character If(c == '\n'): Stop program Character d = STDIN as character If(c == d): Go to next iteration of LOOP Print 0 
\$\endgroup\$
2
\$\begingroup\$

Befunge-98 (PyFunge), 11 bytes

~#@~# -_#q1 

Try it online!

Returns 1 if double speak, 0 if not.

10 byte solution which returns 0 for double speak and non-0 otherwise:

~#q~#1-_#q 

Try it online!

\$\endgroup\$
2
\$\begingroup\$

SNOBOL4 (CSNOBOL4), 63 bytes

	I =INPUT R	I LEN(1) . X 	I X X =	:S(R) 	OUTPUT =IDENT(I) 1 END 

Try it online!

Matches the first character LEN(1) and saves it . to X. If I matches X concatenated with itself, it replaces that substring and repeats. If the remaining string is empty, IDENT(I,<implicit empty string>), then 1 is output, else nothing is output.

\$\endgroup\$
2
\$\begingroup\$

Python 3, 75 bytes

lambda s:all[([s[2*i]==s[2*i+1]for i in range(int(len(s)/2))]),0][len(s)%2] 

Try it online!

\$\endgroup\$
2
\$\begingroup\$

K (oK), 12 bytes

Solution:

&/1==/'0N 2# 

Try it online!

Explanation:

&/1==/'0N 2# / the solution 0N 2# / reshape into Nx2 grid =/' / equals (=) over (/) each (') 1= / equal to 1 (ie a match) &/ / take the minimum 

Extra:

  • (~).+0N 2# works(ish) for 10 bytes, but not if the only difference is a character on the end of one of the strings :(
\$\endgroup\$
2
  • \$\begingroup\$ Wouldn't just &/=/'0N 2# work? \$\endgroup\$ Commented Aug 13, 2019 at 16:27
  • 1
    \$\begingroup\$ Not for odd-length input :( \$\endgroup\$ Commented Aug 13, 2019 at 16:39
2
\$\begingroup\$

APL+WIN, 20 15 bytes

5 bytes saved thanks to Adam.

Prompts for input of string:

n≡(2×2|⍳⍴n)/n←⎕ 

Try it online! Courtesy of Dyalog Classic

\$\endgroup\$
0
2
\$\begingroup\$

dzaima/APL, 14 11 bytes

⊢≡⊢⌿⍨2 0⍴⍨≢ 

Try it online!

-3 thanks to Adám!

\$\endgroup\$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.