# Is it double speak?

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.
• 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
abba -> false
aabb -> true
aaabb -> false
tthhiiss -> true
ttthhhiiisss -> false
• May we error on inputs of length < 2?
– cole
Aug 6, 2019 at 16:06
• Suggested test case: abba which should be falsey Aug 6, 2019 at 16:29
• Suggested test case: aabbbb which should be truthy Aug 6, 2019 at 17:30
• @val Well, I'm not going to argue with standard I/O Aug 7, 2019 at 8:27
• What about the empty string? Aug 7, 2019 at 21:04

# Stax, 6 5 bytes

╩3╦x╨

Run and debug it at staxlang.xyz!

Outputs integers. Zero for double speak and nonzero (one now!) otherwise, as allowed here. Replace 1I below with |e if you want the opposite behavior, but I think this version looks nicer.

### Unpacked (6 bytes) and explanation

:G|g1I
:G        Array of run lengths
|g      GCD
1I    Is odd? Could use 2% instead

The GCD of run lengths will be even exactly when all run lengths are.

# Pushy, 13 bytes

LL2%}2/:=};P#

Try it online!

L              \ Push len(input)
L2%           \ Take (len(input) + 1) % 2. This will be 1 only if the input had even length.
}          \ Move this to the bottom of the stack for later.
2/:  ;    \ Length of original input, divided by 2, times do:
=      \    Pop top two characters, and check equality. (Pushes 0 or 1)
}     \    Move this to the bottom of the stack for later.
P   \ Push the stack's product. If the input had odd length, or any two characters
\ did not match, then the stack will contain a 0, so the product will be 0.
\ Else, it will be 1.
#  \ Print the product.

# naz, 50 bytes

2a2x1v1x1f1r3x1v2e2x2v1r3x2v1e0m1o0x1x2f0m1a1o0x1f

Works for any input string, provided it's passed as a file terminated with the control character STX (U+0002).

Explanation (with 0x commands removed)

2a2x1v                       # Set variable 1 equal to 2
1x1f1r3x1v2e                 # Function 1
2x2v             # Otherwise, store it in variable 2
# Jump back to the start of function 1 if it equals variable 2
0m1o # Otherwise, output 0
1x2f0m1a1o                   # Function 2
# Output 1
1f                           # Call function 1

# Burlesque, 8 bytes

J2en)J==

Try it online!

[AABBCC]         [ABC]
J   #Duplicate             [AABBCC,AABBCC]  [ABC,ABC]
2en #Every other character [AABBCC,ABC]     [ABC,AC]
)J  #Duplicated            [AABBCC,AABBCC]  [ABC,AACC]
==  #Is the same           [1]              [0]

# Burlesque, 11 bytes

=[{L[2dv}al

Try it online!

=[   # Group consecutive like values
{
L[  # Length of (group)
2dv # Divisible by 2
}al  # All

# Marbelous, 84 bytes

No output for false, output one \u0000 for true using this standard I/O rule

@0@1
0000
]]]]&101
eqal\\&1
@0@1..=0\/
:eqal
@0..@1
}0..}1
--..--
<1&0<1&0
{0@0{1@1

interpretor

# JavaScript (Node.js), 23 bytes

z=>/^((.)\2)+$/.test(z) Uses a regular expression that match two of the same characters one or more times Try it online! # Risky, 5 bytes 0?/20_?:? Try it online! Doesn't work with the empty string; OP hasn't clarified if that's a problem. ## Explanation 0 transpose ? input / split into groups of 2 2 0 reduce _ ? accumulator : = ? item ## PHP4 (45 chars) Given$argv[1] as a command line argument :

echo preg_match('#^((.)\2)*$#',$argv[1])?1:0;

The script will output 0 or 1 to answer.

The $f arrow function will return the answer :$f=fn($s)=>preg_match('#^((.)\2)*$#',$s); ## C gcc (27 chars) Function f today return an indication of whether or not the input is double speak : f(char*s){1[s]-*s||f(s+2);} Usage : #include <stdio.h> int main() { printf("EXPECT %5s ... %-5s .. aba\n","NO", f("aba")?"NO":"YES"); printf("EXPECT %5s ... %-5s .. abba\n","NO", f("abba")?"NO":"YES"); printf("EXPECT %5s ... %-5s .. aabb\n","YES", f("aabb")?"NO":"YES"); printf("EXPECT %5s ... %-5s .. aaabb\n","NO", f("aaabb")?"NO":"YES"); printf("EXPECT %5s ... %-5s .. tthhiiss\n","YES", f("tthhiiss")?"NO":"YES"); printf("EXPECT %5s ... %-5s .. ttthhhiiisss\n","NO", f("ttthhhiiisss")?"NO":"YES"); } Try it Online C Variants : g(char*s){s=*s&&g(s+2)+s[1]-*s;} // 32 chars h(char*s){return*s&&h(s+2)+s[1]-*s;} // 36 chars # 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! # Gema, 17 characters ?$1=
?=0@end
\Z=1

Outputs 1 on double speak and 0 on not.

Sample run:

bash-5.0$echo -n 'TThhiiss iiss ddoouubbllee ssppeeaakk!!' | gema '?$1=;?=0@end;\Z=1'
1

Try it online!

?$1= ?=@fail Terminates with exit code 0 on double speak and 2 on not. Sample run: bash-5.0$ echo -n 'TThhiiss  iiss  ddoouubbllee  ssppeeaakk!!' | gema '?$1=;?=@fail' bash-5.0$ echo $? 0 Try it online! # Kotlin, 59 57 bytes {s->(0..s.length-1 step 2).fold(""){t,c->t+s[c]+s[c]}==s} Try it online! -1 byte thanks to Khuldraeseth na'Barya -1 byte changing it -> s Slightly lazy attempt - basically just took my answer from the doublespeak question, applied it to every second char of the input and see if the result is the input. • Save a byte Aug 6, 2019 at 19:25 • @Khuldraesethna'Barya updated, thanks! did not know that was a thing Aug 6, 2019 at 19:32 # Kotlin, 4649 bytes -3 bytes thanks to @cubic lettuce {it.chunked(2).all{it.length>1&&it[0]==it[1]}} Try it online! {it.length%2==0&&it.chunked(2).all{it[0]==it[1]}} Try it online! • Save 3 bytes by {it.chunked(2).all{it.length>1&&it[0]==it[1]}} ;) Aug 7, 2019 at 20:41 # C (tcc), 5955 50 bytes f(char *s){while(*s==*++s)s++;return!*--s&&s!="";} Try it online! Thanks to Jo King for the 4 bytes and Unrelated String for saving 5 bytes Can it be even shorter? • *s==*++s, how is this not UB when *s points to the end of the string? Aug 7, 2019 at 11:26 • the *s will always point to the last character of the string given in argument which is not last character because string here ends with '\0' so the *++s gets the \0 – Loki Aug 7, 2019 at 11:36 • You increment s by two each time through the loop, so if there is an even number of actuall characters in the string I do not see how you can guarantee that *s never points to the '\0' Aug 7, 2019 at 11:58 • You could golf it considerably by replacing *--s=='\0' with the simple !*--s, but also note that most challenges require submissions to be either functions or full programs, and this is neither. Aug 7, 2019 at 19:37 • Thanks guys for helping shortening it and @Taemyr play with this code TIO I don't need to care if *s gets the \0 character cause then the *++s will get the first character from the string used in printf. – Loki Aug 8, 2019 at 5:07 # Rust, 73 bytes |s:&str|!s.chars().enumerate().any(|(i,c)|s.chars().nth(i|1).unwrap()!=c) Try it online! # T-SQL 2012, 76 bytes Looping using the following logic. Finding the first match on the first character in the rest of the string. If the match is on the second position, the first 2 characters are removed. if the match is on a later position, character 0 to 1 is removed, resulting in null string. If there are no matches, characters 3-4 are removed. Repeating this will eventually result in a null string. The final string will be an empty string or a null string. Empty string is "double speak"(1). Null string is not "double speak"(0). DECLARE @ varchar(max)='ccbbddeeff' WHILE @>''SET @=stuff(@,-3/~charindex(left(@,1),@,2),2,'')PRINT iif(@=0,1,0) Try it online # JavaScript (Node.js), 26 bytes s=>!s.replace(/(.)\1/g,'') Try it online! # C++ (gcc), 484745 43 bytes -2 bytes thanks to @ceilingcat -2 bytes thanks to @JoKing recursive function assuming zero terminated char table int f(char*s){return!*s||*s==s[1]&&f(s+2);} Try it online! • @ceilingcat cool, I didn't now you can be that concise Aug 9, 2019 at 8:02 • @JoKing it works, there's just a warning because I'm using string literals to generate right kind of input - zero-terminated char* - which is not exactly legal in c++ but gcc allows it Aug 9, 2019 at 8:26 • Ah sorry, I thought the lack of output meant it wasn't working. 43 bytes – Jo King Aug 9, 2019 at 8:36 ## EDIT: This solution is totally broken as demonstrated by the aabbbb test case. Thanks to @manatwork for pointing this out. Do not pass Go! Do not collect 200 dollars! ## Bash and Gnu utils, 46 45 bytes fold -1|uniq -c|grep -qv "2 "&&echo 0||echo 1 Try it online! -1 byte by skipping the first space in grep expression • Not sure if I can use grep exit codes and return output there? Instead of this &&echo 0||echo1 Aug 9, 2019 at 9:32 • This works fine on the question's test cases, but as I understand the challenge, it should output 1 on Khuldraeseth na'Barya's suggested test case, “aabbbb”. Aug 9, 2019 at 9:34 • @manatwork You're right. This solution is buggy in that sense. Aug 9, 2019 at 11:23 # Lua, 908786 82 bytes a,e=1,os.exit;(...):gsub('.',load's=...a=a~=1 and(a==s and 1 or e(1))or s')e(a==1) Try it online! Take input as argument, use exit code as output. ## Explanation This is based on abusing few Lua features: • os.exit could accept either number, allowing short code for exit or boolean, making last check possible (true meaning success, false meaning failure). • gsub can be also used to iterate over string in callback-style, not only for doing replacement. • load is shorter than function(...) end. • ... is often shorter than arg[1]. Whole idea hidden behind those tricks: 1. For each character: either remember if nothing is already it or perform check: if current is different from remembered, fail. Otherwise, reset remembered value and continue. 2. When done, make sure that there's nothing pending in the buffer (e(a==1)). This is required to fail on strings with odd length. # C++ (gcc), 156 145 bytes #include <iostream> int f(){ char a[2]; while(std::cin.get(a, 3)) if(a[0] != a[1]) return 0; return 1; } int main() { std::cout << f(); } Try it online! • Welcome to the site! C++ is pretty lenient about whitespace so you can save bytes by removing a bunch of it. Aug 11, 2019 at 11:58 • @SriotchilismO'Zaic Thank you! Aug 11, 2019 at 17:12 # Oracle SQL, 47 bytes select*from t where regexp_like(x,'^((.)\2)+$')

It works with an assumption that input data is stored in a table t(x), e.g.

with t(x) as (select 'hheelllloo' from dual)

Returns either original string or no rows.

# Rust, 6158 39 bytes

|s:&[u8]|s.chunks(2).all(|n|n[0]==n[1])

Try it online!

This is a closure that takes the input as a byte slice (b prefix on a string), e.g.

println!("{}", f(b"aabb"));

# Swift, 109 bytes

func a(b:String){let c=Array(b),l=c.count;var d=0,i=0;while i<l-1{if c[i]==c[i+1]{d+=1};i+=2;};print(d*2==l)}

Try it online!

# C#, 190 bytes

public class P{public static void Main(string[]a){bool d=true;if(a[0].Length%(double)2>0)d=false;else for(int i=0;i<a[0].Length;i+=2){d=a[0][i]==a[0][i+1]?d:false;}System.Console.Write(d);}}

Try Online

# Clojure, 48 bytes

(fn[x](every? #(apply = %)(partition 2 2[\0]x)))

Try it online!

p~/^((.)\2)*$/ Try it online! # GolfScript, 7 bytes 2/zip~= Try it online! # Explanation 2/ # Split input into parts of 2, e.g. tt,ee,ss,tt zip # Read the list horizontally, yielding test, test ~ # Put the two strings onto the stack, yielding test,test = # Check whether they are equal, yielding 1 # False case: # tteesst #->tt,ee,ss,t #->test,tes #->0 $$`$$ # Pip, 5 bytes$QUWa

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

Try it online!

Try it online!

# Rockstar, 108 97 bytes

listen to S
D's1
X's0
while D and S at X
let C be S at X
let D be C is S at X+1
let X be+2

say D

Try it here (Code will need to be pasted in)

• I quite like the output of 'mysterious' if it's false. Sep 24, 2020 at 14:24
• Odd, @AJFaraday, could've sworn I has it outputting 0 for falsey. Must've changed something before posting without realising. Anyway, long's you're OK with that, I'll leave it as-is. Could save some more by looping forever with no output if the result is truthy but that would probably be pushing things! Sep 24, 2020 at 14:29