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:

input -> output
aba -> false
abba -> false
aabb -> true
aaabb -> false
tthhiiss -> true
ttthhhiiisss -> false
\$\endgroup\$
  • 7
    \$\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

82 Answers 82

57
\$\begingroup\$

Python 3, 24 bytes

lambda s:s[::2]==s[1::2]

Try it online!

| improve this answer | |
\$\endgroup\$
26
\$\begingroup\$

brainfuck, 20 bytes

Saved 1 byte thanks to Jo King.

+>,[>,[-<->]<[<],]<.

Try it online!

Readable output!

Takes input two characters at a time, and moves away from the 1 on the tape if any pair doesn't match. EOF is treated as 0 and thus handled automatically.

Output is a null byte if the string is not double speak, and 0x01 if it is. The readable version outputs these as characters at a cost of 14 bytes.

| improve this answer | |
\$\endgroup\$
17
\$\begingroup\$

MATL, 4 bytes

Heda

Input is a string, enclosed with single qoutes. Output is 0 for double speak, 1 otherwise.

Try it online!

Explanation

Consider input 'TThhiiss iiss ddoouubbllee ssppeeaakk!!' as an example.

H    % Push 2
     % STACK: 2
     % Implicit input (triggered because the next function requires two inputs): string 
     % STACK: 'TThhiiss  iiss  ddoouubbllee  ssppeeaakk!!', 2
e    % Reshape as a 2-column matrix of chars, in column-major order. Pads with char(0)
     % if needed. Note that char(0) cannot be present in the input
     % STACK: ['This is double speak!';
               'This is double speak!']
d    % Difference of each column
     % STACK: [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
a    % Any: gives 0 if and only if all elements are 0
     % STACK: 0
     % Implicit display
| improve this answer | |
\$\endgroup\$
  • 13
    \$\begingroup\$ Um... who is "Heda"? :D \$\endgroup\$ – Erik the Outgolfer Aug 6 '19 at 16:01
  • 11
    \$\begingroup\$ "Heda" is German for "Hey! You!" \$\endgroup\$ – QBrute Aug 9 '19 at 12:47
14
\$\begingroup\$

05AB1E, 6 5 2 bytes

ιË

Input as a list of characters.

-3 bytes by porting @Shaggy's Japt answer, so make sure to upvote him!

Try it online or verify a few more test cases.

Explanation:

ι   # Uninterleave the (implicit) input-list of characters
    #  i.e. ["t","t","t","t","e","e","s","s","t","t","!","!","!"]
    #   → [["t","t","e","s","t","!","!"],["t","t","e","s","t","!"]]
 Ë  # Check if both inner lists are equal
    #  → 0 (falsey)
    # (after which the result is output implicitly)
| improve this answer | |
\$\endgroup\$
11
\$\begingroup\$

Japt, 4 bytes

ó r¶

Try it

ó r¶     :Implicit input of string
ó        :Uniterleave
  r      :Reduce by
   ¶     :  Testing equality

Alternative

ó
¥o

Try it

| improve this answer | |
\$\endgroup\$
10
\$\begingroup\$

Retina, 9 bytes

(.)\1

^$

Try it online.

Explanation:

Remove all pair of the same characters:

(.)\1

Check if there are no characters left:

^$
| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ You can provide a more traditional output by using ^$ as your final stage. \$\endgroup\$ – Neil Aug 6 '19 at 16:38
  • \$\begingroup\$ @Neil Ah of course, thanks! That indeed looks better. I always think it's strange outputting false as truthy and true as falsey (but if it saves a byte and it's allowed, I will still use it). ;) But since this is an equal bytes solution outputting the expected results, this is better. \$\endgroup\$ – Kevin Cruijssen Aug 6 '19 at 16:42
9
\$\begingroup\$

Stax, 5 bytes

■◄┼$Δ

Run and debug it

Procedure:

  • Calculate run-lengths.
  • Get GCD of array.
  • Is even?
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Ahh, you got one that packs. Nice. \$\endgroup\$ – Khuldraeseth na'Barya Aug 6 '19 at 18:20
  • 1
    \$\begingroup\$ i like this algorithm! \$\endgroup\$ – Jonah Aug 6 '19 at 18:51
8
\$\begingroup\$

Jelly, 3 bytes

ŒœE

Try it online!

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ Hey I like this! It took me 80mns to do the same lol, I was like "hey let's learn Jelly now" then I learned. I was about to post this but looked if Jelly answers were already there... and then saw this ^^ My steps: ¹©s2L€=2Ạa®s2E€Ạ... ḢƝs2E€Ạ... but I couldn't manage to get what I wanted, and then I saw Œœ lol \$\endgroup\$ – V. Courtois Aug 7 '19 at 14:21
7
\$\begingroup\$

x86 machine code, 9 8 bytes

D1 E9       SHR  CX, 1          ; divide length in half
       L1:
AD          LODSW               ; load next two chars into AH/AL 
3A E0       CMP  AH, AL         ; compare AH and AL 
E1 FB       LOOPE L1            ; if equal, continue loop
C3          RET                 ; return to caller

Callable function. Input string in SI, input string length in CX. Output ZF if is double speak.

Or 14 bytes as a complete PC DOS executable:

B4 01       MOV  AH, 01H        ; DOS read char from STDIN (with echo) 
CD 21       INT  21H            ; read first char into AL
92          XCHG DX, AX         ; put first char into DL
B4 08       MOV  AH, 08H        ; DOS read char from STDIN (no echo) 
CD 21       INT  21H            ; read second char into AL
3A C2       CMP  AL, DL         ; compare first and second char 
74 F3       JE   -13            ; if the same, continue loop 
C3          RET                 ; otherwise exit to DOS 

Input is via STDIN, either pipe or interactive. Will echo the "de-doubled" input until a non-doubled character is detected, at which point will exit (maybe bending I/O rules a little bit, but this is just a bonus answer).

enter image description here

Build and test ISDBL2.COM using xxd -r:

00000000: b401 cd21 92b4 08cd 213a c274 f3c3       ...!....!:.t..

Original 24 bytes complete PC DOS executable:

D1 EE       SHR  SI, 1          ; SI to DOS PSP (080H) 
AD          LODSW               ; load string length into AL 
D0 E8       SHR  AL, 1          ; divide length in half 
8A C8       MOV  CL, AL         ; put string length into BL 
        CLOOP: 
AD          LODSW               ; load next two chars into AH/AL 
3A E0       CMP  AH, AL         ; compare AH and AL 
E1 FB       LOOPE CLOOP         ; if equal, continue loop
        DONE: 
B8 0E59     MOV  AX, 0E59H      ; BIOS tty function in AH, 'Y' in AL 
74 02       JZ   DISP           ; if ZF, result was valid double 
B0 4E       MOV  AL, 'N'        ; if not, change output char to N 
        DISP: 
B4 0E       MOV  AH, 0EH 
CD 10       INT  10H 
C3          RET                 ; return to DOS

Input from command line, output to screen 'Y' if double, 'N' if not.

enter image description here

Build and test ISDBL.COM using xxd -r:

00000000: d1ee add0 e88a c8ad 3ae0 e1fb b859 0e74  ........:....Y.t
00000010: 02b0 4eb4 0ecd 10c3                      ..N.....

Credits:

  • -2 bytes thx to @ErikF!
| improve this answer | |
\$\endgroup\$
  • 2
    \$\begingroup\$ Suggest using LOOPE instead of JNZ/LOOP to save 2 bytes. \$\endgroup\$ – ErikF Aug 7 '19 at 16:11
  • \$\begingroup\$ @ErikF, brilliant! Completely forgot about that! \$\endgroup\$ – 640KB Aug 7 '19 at 16:17
6
\$\begingroup\$

PHP, 58 56 bytes

function f($s){return!$s?:$s[0]==$s[1]&f(substr($s,2));}

Try it online!

As a recursive function.

PHP, 61 56 52 bytes

while(''<$l=$argn[$i++])$r|=$l!=$argn[$i++];echo!$r;

Try it online!

Or standalone program. Input string via STDIN, output is truthy (1) if it is double speak, and falsey (0) if it is not double speak.

-4 bytes thx to @Night2!

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ This appears to output 1 for a non-double speak string, as well as a double speak string. \$\endgroup\$ – AJFaraday Aug 6 '19 at 16:01
  • \$\begingroup\$ @AJFaraday try now - is double speak, is not double speak \$\endgroup\$ – 640KB Aug 6 '19 at 16:07
6
\$\begingroup\$

Lua, 67 66 63 59 33 32 bytes

-25 bytes thanks to Giuseppe
-1 byte thanks to val

print(#(...):gsub("(.)%1","")<1)

Try it online!

Removes every doubled character, then checks if the result is empty.

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ why not just i:gsub("(.)%1","") and check if i==""? \$\endgroup\$ – Giuseppe Aug 8 '19 at 16:26
  • 1
    \$\begingroup\$ this is 34 bytes, not totally sure it's valid since I've never written Lua before, but it appears to work. \$\endgroup\$ – Giuseppe Aug 8 '19 at 16:27
  • \$\begingroup\$ welcome to Code Golf Stack Exchange though! \$\endgroup\$ – Giuseppe Aug 8 '19 at 16:28
  • \$\begingroup\$ I assumed that "(.)%1" by itself included collisions, but it didn't occur to me that by replacing it once for all captures would be enough. Should I implement your solution or should you write your own answer? And thanks! \$\endgroup\$ – HugoBDesigner Aug 8 '19 at 17:03
  • 1
    \$\begingroup\$ Nice idea! arg[1] can be replaced with (...) to save one byte. \$\endgroup\$ – val says Reinstate Monica Aug 12 '19 at 10:44
5
\$\begingroup\$

Perl 5, 15 bytes

$_=/^((.)\2)*$/

Try it online!

Outputs 1 for double-speak, nothing for non-double-speak.

| improve this answer | |
\$\endgroup\$
5
\$\begingroup\$

MathGolf, 2 bytes

½=

Try it online!

Basically the same as the 05AB1E answer, ½ splits the string into even and odd characters, then check for equality. Passes for the empty string.

| improve this answer | |
\$\endgroup\$
5
\$\begingroup\$

JavaScript, 28 bytes

s=>s.every((x,y)=>x==s[y|1])

Try it online!


23 bytes using wastl's regex

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

Try it online!

| improve this answer | |
\$\endgroup\$
5
\$\begingroup\$

Haskell, 28 23 bytes

f(x:y:z)|x==y=f z
f[]=1

Try it online!

Very straightforward. Double speak is only empty or a repeated character prepended to double speak.

Less straightforward now. Outputs via presence or absence of an error, per meta consensus; no error means double speak. Pattern matching fails when the first two characters differ or when there are an odd number of characters. Thanks to Laikoni for these savings!

| improve this answer | |
\$\endgroup\$
4
\$\begingroup\$

V (vim), 7 bytes

Óˆ±
ø^$

Try it online! or Verify test cases

Hexdump:

00000000: d388 b10a d85e 24                        .....^$

Just two regexes. Explanation:

Ó   " Remove all occurrences...
 ˆ  "   Any character
  ± "   Followed by itself
    "   This regex is actually just the compressed form of (.)\1
ø   " Count the number of matches
 ^$ "   An empty line
| improve this answer | |
\$\endgroup\$
4
\$\begingroup\$

Brachylog, 5 bytes

ġ₂z₂=

Try it online!

Succeeds or fails.

ġ₂       The at-most-length-2 chunks of the input,
  z₂     which have equal length, zipped together,
    =    are equal.
| improve this answer | |
\$\endgroup\$
4
\$\begingroup\$

PowerShell, 39 38 bytes

!$($args|?{+$p*($p="$_"[$p-eq$_])};$p)

Try it online!

where $p contains a previous char.

No recursion, no regex :). Takes input as a char-array via a splatting string (see TIO link).


PowerShell, 48 bytes

for(;$b-eq$a-and$args){$a,$b,$args=$args}$b-eq$a

Try it online!

No recursion, no regex and no pipe :D. It also takes input as a char-array via a splatting string. It uses $b-eq$a instead $a-eq$b for a case when a last char has #0 code.

| improve this answer | |
\$\endgroup\$
4
\$\begingroup\$

PowerShell, 64 59 bytes

filter f($n){$a,$b,$r=$n;$a-eq$b-and$(if($r){f $r}else{1})}

Try it online!

Recursive function, no regex. Takes input as a char-array (see TIO link). Peels off the first two elements into $a and $b, stores the remaining into $r. If we still have elements remaining, recurse along with $a -eq $b. Otherwise just check whether $a -eq $b. Output is implicit.

-5 bytes thanks to mazzy

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ de-duplicate Try it online! \$\endgroup\$ – mazzy Aug 7 '19 at 4:19
  • 1
    \$\begingroup\$ @mazzy Thanks! I was missing the $ before the statement block and couldn't figure out why it wasn't working. \$\endgroup\$ – AdmBorkBork Aug 7 '19 at 12:37
4
\$\begingroup\$

Julia 1.0, 25 bytes

s->s[1:2:end]==s[2:2:end]

Try it online!

| improve this answer | |
\$\endgroup\$
  • 3
    \$\begingroup\$ It's shorter to use a symbol instead of f, e.g !a=.... Or to use an anonymous function: s->... \$\endgroup\$ – H.PWiz Aug 6 '19 at 15:54
  • \$\begingroup\$ Yes, you're right. I fixed it \$\endgroup\$ – Simeon Schaub Aug 7 '19 at 15:15
4
\$\begingroup\$

J, 13 11 10 bytes

-:2#_2{.\]

Try it online!

-2 bytes thanks to Adám

-1 byte thanks to miles

TLDR explanation: Is the input the same as every other character of the input doubled?

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ -:]#~2 0$~# \$\endgroup\$ – Adám Aug 6 '19 at 19:03
  • \$\begingroup\$ -:2#_2{.\] should save another byte \$\endgroup\$ – miles Aug 7 '19 at 22:51
  • \$\begingroup\$ very nice, thanks @miles \$\endgroup\$ – Jonah Aug 7 '19 at 22:56
4
\$\begingroup\$

Shakespeare Programming Language, 204 156 bytes

-48 bytes thanks to Jo King (mostly by changing the output method)

A.Ajax,.Puck,.Act I:.Scene I:.[Exeunt][Enter Ajax and Puck]Ajax:Open mind.Puck:Open
mind.Is I worse zero?If soSpeak thy.Is you as big as I?If soLet usAct I.

Try it online!

Exits with error if the input is double speak, and with warning if it is not double speak (which is allowed by default).

| improve this answer | |
\$\endgroup\$
4
\$\begingroup\$

Keg, 19 17 characters

?{!1<|=[|0.(_)]}1

Explanation:

?             # read input

{             # while
    !1<       # stack length greater than 1?
|             # end of while condition and beginning of while block
    =         # compare the 2 top values in the stack
    [         # if (the condition is the top of stack)
    |         # end of then block and beginning of else block
        0.    # output 0
        (_)   # clear stack (discard top of stack in for loop stack length times)
    ]         # end if
}             # end while

1             # stack is already empty, push a truthy value

              # implicitly output the stack content if there was no explicit output

Try it online!

| improve this answer | |
\$\endgroup\$
4
+50
\$\begingroup\$

Husk, 6 bytes

Von1Lg

Try it online!

Hooray for all ASCII solutions! Outputs 0 if the input is doublespeak, otherwise a positive integer. if you want 1 for truthy, 0 for falsey, you can prepend =0 to the code.

     g  Group the input into lists of the same adjacent elements
V       Find the index of the first element that matches the predicate
 o      Combination of the next two functions
    L   The length
  n1    Is odd (bitwise AND 1)
| improve this answer | |
\$\endgroup\$
3
\$\begingroup\$

R, 53 34 bytes

-19 bytes thanks to Giuseppe

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

Try it online!

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ I think gsub("(.)\\1","",a)=="" would do the trick as well; many others use the same regex. \$\endgroup\$ – Giuseppe Aug 6 '19 at 18:05
  • \$\begingroup\$ @Giuseppe This whole regex thing is pretty new to me. Thanks. \$\endgroup\$ – Robert S. Aug 6 '19 at 18:10
  • \$\begingroup\$ R + pryr gets you a 32-byter trivially modified from this answer. \$\endgroup\$ – Khuldraeseth na'Barya Aug 6 '19 at 18:19
  • 3
    \$\begingroup\$ If input can be taken as a vector, then function(a)!sum(rle(a)$l%%2) for 28 \$\endgroup\$ – MickyT Aug 6 '19 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.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Does 0/non0 count as a boolean? If so, you can do ({({}[{}]){{}}{}}) \$\endgroup\$ – Riley Aug 6 '19 at 18:15
  • 3
    \$\begingroup\$ lol at the "Readable version" - its so very readable :P \$\endgroup\$ – Quinn Aug 6 '19 at 18:32
  • \$\begingroup\$ @riley No that's not valid. However, I found a better trick. \$\endgroup\$ – James Aug 6 '19 at 18:42
  • \$\begingroup\$ @quinn Looks readable to me :P \$\endgroup\$ – James Aug 6 '19 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

| improve this answer | |
\$\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!

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Fixed recursive version? \$\endgroup\$ – Arnauld Aug 6 '19 at 18:34
  • \$\begingroup\$ Thanks, @Arnauld :) \$\endgroup\$ – Shaggy Aug 6 '19 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\$ – Shaggy Aug 6 '19 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!

| improve this answer | |
\$\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!

| improve this answer | |
\$\endgroup\$

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.