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

94 Answers 94

2
\$\begingroup\$

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.

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

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.  
\$\endgroup\$
2
\$\begingroup\$

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
                             # Read a byte and jump to function 2 if it equals variable 1
            2x2v             # Otherwise, store it in variable 2
                1r3x2v1e     # Read another byte
                             # 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
\$\endgroup\$
2
\$\begingroup\$

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
\$\endgroup\$
2
\$\begingroup\$

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

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

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!

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

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
\$\endgroup\$
2
\$\begingroup\$

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.

PHP7.4 (41 chars)

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
\$\endgroup\$
1
\$\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\$
1
\$\begingroup\$

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!

Gema, 12 characters

?$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!

\$\endgroup\$
1
\$\begingroup\$

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.

\$\endgroup\$
2
  • \$\begingroup\$ Save a byte \$\endgroup\$ Aug 6, 2019 at 19:25
  • \$\begingroup\$ @Khuldraesethna'Barya updated, thanks! did not know that was a thing \$\endgroup\$
    – Quinn
    Aug 6, 2019 at 19:32
1
\$\begingroup\$

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!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Save 3 bytes by {it.chunked(2).all{it.length>1&&it[0]==it[1]}} ;) \$\endgroup\$ Aug 7, 2019 at 20:41
1
\$\begingroup\$

C (tcc), 59 55 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?

\$\endgroup\$
8
  • \$\begingroup\$ *s==*++s, how is this not UB when *s points to the end of the string? \$\endgroup\$
    – Taemyr
    Aug 7, 2019 at 11:26
  • \$\begingroup\$ 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 \$\endgroup\$
    – Loki
    Aug 7, 2019 at 11:36
  • 1
    \$\begingroup\$ 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' \$\endgroup\$
    – Taemyr
    Aug 7, 2019 at 11:58
  • \$\begingroup\$ 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. \$\endgroup\$ Aug 7, 2019 at 19:37
  • \$\begingroup\$ 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. \$\endgroup\$
    – Loki
    Aug 8, 2019 at 5:07
1
\$\begingroup\$

Rust, 73 bytes

|s:&str|!s.chars().enumerate().any(|(i,c)|s.chars().nth(i|1).unwrap()!=c)

Try it online!

\$\endgroup\$
1
\$\begingroup\$

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

\$\endgroup\$
1
\$\begingroup\$

JavaScript (Node.js), 26 bytes

s=>!s.replace(/(.)\1/g,'')

Try it online!

\$\endgroup\$
1
\$\begingroup\$

C++ (gcc), 48 47 45 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!

\$\endgroup\$
3
  • \$\begingroup\$ @ceilingcat cool, I didn't now you can be that concise \$\endgroup\$ Aug 9, 2019 at 8:02
  • \$\begingroup\$ @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 \$\endgroup\$ Aug 9, 2019 at 8:26
  • \$\begingroup\$ Ah sorry, I thought the lack of output meant it wasn't working. 43 bytes \$\endgroup\$
    – Jo King
    Aug 9, 2019 at 8:36
1
\$\begingroup\$

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

\$\endgroup\$
3
  • \$\begingroup\$ Not sure if I can use grep exit codes and return output there? Instead of this &&echo 0||echo1 \$\endgroup\$ Aug 9, 2019 at 9:32
  • 1
    \$\begingroup\$ 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”. \$\endgroup\$
    – manatwork
    Aug 9, 2019 at 9:34
  • \$\begingroup\$ @manatwork You're right. This solution is buggy in that sense. \$\endgroup\$ Aug 9, 2019 at 11:23
1
\$\begingroup\$

Lua, 90 87 86 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.
\$\endgroup\$
1
\$\begingroup\$

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!

\$\endgroup\$
2
  • \$\begingroup\$ Welcome to the site! C++ is pretty lenient about whitespace so you can save bytes by removing a bunch of it. \$\endgroup\$
    – Wheat Wizard
    Aug 11, 2019 at 11:58
  • \$\begingroup\$ @SriotchilismO'Zaic Thank you! \$\endgroup\$
    – Ver Nick
    Aug 11, 2019 at 17:12
1
\$\begingroup\$

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.

\$\endgroup\$
1
\$\begingroup\$

Rust, 61 58 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"));
\$\endgroup\$
1
\$\begingroup\$

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!

\$\endgroup\$
1
\$\begingroup\$

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

\$\endgroup\$
1
\$\begingroup\$

Clojure, 48 bytes

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

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Ruby -n, 21 14+1 = 15 bytes

p~/^((.)\2)*$/

Try it online!

\$\endgroup\$
1
\$\begingroup\$

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
```
\$\endgroup\$
1
\$\begingroup\$

Pip, 5 bytes

$QUWa

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

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Perl 5 + -pF/^((.)\2)+$/, 7 bytes

Outputs 0 for falsy and 2 for truthy.

$_=@F^1

Try it online!

\$\endgroup\$
1
\$\begingroup\$

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)

\$\endgroup\$
2
  • \$\begingroup\$ I quite like the output of 'mysterious' if it's false. \$\endgroup\$
    – AJFaraday
    Sep 24, 2020 at 14:24
  • \$\begingroup\$ 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! \$\endgroup\$
    – Shaggy
    Sep 24, 2020 at 14:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.