47
\$\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:

  • aba - false
  • abba - false
  • aabb - true
  • aaabb - false
  • tthhiiss - true
  • ttthhhiiisss - false
\$\endgroup\$
  • 6
    \$\begingroup\$ May we error on inputs of length < 2? \$\endgroup\$ – cole Aug 6 '19 at 16:06
  • 3
    \$\begingroup\$ Suggested test case: abba which should be falsey \$\endgroup\$ – Giuseppe Aug 6 '19 at 16:29
  • 2
    \$\begingroup\$ Suggested test case: aabbbb which should be truthy \$\endgroup\$ – Khuldraeseth na'Barya Aug 6 '19 at 17:30
  • 2
    \$\begingroup\$ @val Well, I'm not going to argue with standard I/O \$\endgroup\$ – AJFaraday Aug 7 '19 at 8:27
  • 2
    \$\begingroup\$ Suggested test case: 0 which should be falsey. \$\endgroup\$ – 640KB Aug 7 '19 at 16:06

77 Answers 77

1 2 3
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
    \$\begingroup\$ Save 3 bytes by {it.chunked(2).all{it.length>1&&it[0]==it[1]}} ;) \$\endgroup\$ – cubic lettuce Aug 7 '19 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\$
  • \$\begingroup\$ *s==*++s, how is this not UB when *s points to the end of the string? \$\endgroup\$ – Taemyr Aug 7 '19 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 '19 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 '19 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\$ – Unrelated String Aug 7 '19 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 '19 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\$
  • \$\begingroup\$ @ceilingcat cool, I didn't now you can be that concise \$\endgroup\$ – Przemysław Czechowski Aug 9 '19 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\$ – Przemysław Czechowski Aug 9 '19 at 8:26
  • \$\begingroup\$ Ah sorry, I thought the lack of output meant it wasn't working. 43 bytes \$\endgroup\$ – Jo King Aug 9 '19 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\$
  • \$\begingroup\$ Not sure if I can use grep exit codes and return output there? Instead of this &&echo 0||echo1 \$\endgroup\$ – Grzegorz Oledzki Aug 9 '19 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 '19 at 9:34
  • \$\begingroup\$ @manatwork You're right. This solution is buggy in that sense. \$\endgroup\$ – Grzegorz Oledzki Aug 9 '19 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\$
  • \$\begingroup\$ Welcome to the site! C++ is pretty lenient about whitespace so you can save bytes by removing a bunch of it. \$\endgroup\$ – Post Rock Garf Hunter Aug 11 '19 at 11:58
  • \$\begingroup\$ @SriotchilismO'Zaic Thank you! \$\endgroup\$ – Ver Nick says Reinstate Monica Aug 11 '19 at 17:12
1
\$\begingroup\$

Wolfram Language (Mathematica), 27 26 24 bytes

2==GCD@@Length/@Split@#&

Try it online!

        Length/@Split@#&    (*for the lengths of runs of characters*)
2==GCD@@                    (*check that they are all even*)
\$\endgroup\$
  • \$\begingroup\$ You've excluded the necessary code to convert the string input into a list which can be fed to Split (i.e. the 11 bytes of Characters@) \$\endgroup\$ – Anti Earth Aug 7 '19 at 17:14
  • \$\begingroup\$ @AntiEarth What's a string? \$\endgroup\$ – attinat Aug 7 '19 at 19:30
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 2 3

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.