19
\$\begingroup\$

This is part of a Cops and Robbers challenge. Go here for the cops' part.

For the purpose of this challenge, we'll define whitespace as only linefeeds (0x0A) and spaces (0x20). Note that most languages and regex flavours consider many other characters as whitespace as well, both inside and outside the ASCII range so you might not be able to make use of the corresponding built-ins.

The Robbers' Challenge

A cop's answer can be cracked by transforming it into a valid program or function (in the chosen language), which performs the task of removing whitespace from an input string, by inserting whitespace into the code. For example if you received the following input:

H e l l o,
 W o r l  d!

The program should output

Hello,World!

After inserting whitespace, the byte count of the solution must not exceed the byte count stated in the cop's answer. You don't have to find the exact same solution as the cop intended, as long as yours is valid by the above constraints.

If you manage this, post an answer with the solution, linking to the cop's answer, and leave a comment on the cop's answer linking back to yours.

The robber who cracks the most cop answers wins. Ties are broken by the sum of sizes of the cracked cop answers (in favour of the robber who cracks longer submissions).

Each cop answer can only be cracked once, and of course, you're not allowed to crack your own answer. If the cop's answer turns out to be invalid before or after being cracked, it is not counted towards the robber's score.

\$\endgroup\$
0

18 Answers 18

8
\$\begingroup\$

Haskell, 100 bytes, by Laikoni

main=interact$id doid lines id words 
doid oi d o id=do
 iddoid<-do oi id
 oid<-do o iddoid
 do d oid
\$\endgroup\$
7
\$\begingroup\$

><>, 40 bytes, by DanTheMan

v <<
i/\
:=
:
:a?
0/>/
1?o
-=
="
?
;"
>^

Really fun to work out.

Try it on ><>language

\$\endgroup\$
1
  • \$\begingroup\$ Good job! I'm glad you enjoyed cracking it. \$\endgroup\$
    – DanTheMan
    Dec 15, 2016 at 16:45
7
\$\begingroup\$

JavaScript ES6, 199 bytes by Arnauld

s=>eval(atob`ISYgJiAtOkI8Qk97BRBeaxZFShoUZSsiOGkMenNy`.replace(/./g,(c,i)=>String.fromCharCode(c.charCodeAt()^(k+="     S    e c  r   e t     C    o   d  e   ".split(/\w/)[i%11].length)),k=0)).join``

I realized the splitting "SecretCode" meant I was looking for 11 numbers that summed to (I assumed) 33. This is a stars and bars problem where the number of spaces are the stars and the letters in "SecretCode" were the bars. I did the math to see how many combintations there were to try (1,917,334,783 combinations) and decided to just brute force it, took all day.

There's probably a smarter way to have gone about it, for instance noticing that k has to be 33 and 66 for index 10 and 21 respectively, but I'm lazy.

\$\endgroup\$
3
  • \$\begingroup\$ Hey, well done! ;-) \$\endgroup\$
    – Arnauld
    Dec 17, 2016 at 0:44
  • 2
    \$\begingroup\$ $/**/=/[ \n]/;s['sp'+'lit']($)... oh, that's dirty. \$\endgroup\$ Dec 17, 2016 at 0:46
  • \$\begingroup\$ In case anyone was curious about my brute force attempt, it was pastebin.com/aN9Z1jVM \$\endgroup\$ Dec 17, 2016 at 1:02
6
\$\begingroup\$

C, 475 bytes by rexroni

#include<unistd.h>
#define a char
#define b *
#define c write
#define d stdin
#define e stdout
#define f read
#define g (
#define h )
#define i while
#define j if
#define k 0
#define l &
#define m ,
#define n =
#define o ;
#define p 1
#define gpml ml h
#define abo
#define ml d m p
#define jg d o abo
#define lb abo d
#define gf h abo c
#define jgm b e n
#define pml f g
#define gpm lb
int main(){a jg a jgm l jg i g pml k m l gpml h j g d!=' '&&gpm!='\n'gf g p m l gpml o}

I might start using some of these defines :)

After the pre-processor the code looks something like this:

int main(){
    char stdin;
    char *stdout = &stdin;
    while(read(0, &stdin, 1))
        if(stdin !='' && stdin!='\n')
            write(1, &stdin, 1);
}   
\$\endgroup\$
3
  • \$\begingroup\$ Wow! Good work. I was even having trouble reading it by the end, and I wrote it. \$\endgroup\$
    – rexroni
    Dec 15, 2016 at 18:38
  • \$\begingroup\$ @rexroni #defineabo threw me off for a while. At first I thought it had to be #define ab o which would just add some extra ;s, but that didn't work near the end. \$\endgroup\$
    – Riley
    Dec 15, 2016 at 18:42
  • \$\begingroup\$ yes, that was specifically chosen to make it harder :) \$\endgroup\$
    – rexroni
    Dec 15, 2016 at 18:46
5
\$\begingroup\$

Ruby, 86 bytes + 1 flag = 87 by histocrat

eval"( T $ }{(! // ; : 67 8 ? 32. && )".gsub(/ |(.)/){$1&&$&.ord.^($'.count(' ')).chr}

This was really fun, each character in the string passed to eval is replaced with the character code (ord) XORed ^(...) against the number of remaining spaces in the string. The resultant code is:

$_.tr!(''<<32<<10,'')
\$\endgroup\$
0
4
\$\begingroup\$

RprogN, by Ataco

This appears to do the trick

' ' ` R
"
" ` R
\$\endgroup\$
5
  • \$\begingroup\$ I accidentally golfed it while cracking haha, down to 14 bytes \$\endgroup\$ Dec 14, 2016 at 22:33
  • \$\begingroup\$ I'm really curious how you golfed it. \$\endgroup\$
    – ATaco
    Dec 14, 2016 at 22:54
  • \$\begingroup\$ @ATaco the program is just 14 bytes. Did you count a trailing linefeed or something? \$\endgroup\$ Dec 14, 2016 at 23:08
  • \$\begingroup\$ Looks like 15 bytes to me \$\endgroup\$
    – ATaco
    Dec 14, 2016 at 23:23
  • \$\begingroup\$ @ATaco I was wrong, I couldn't test newlines on the compiler online, which in turn caused me to think it was working but I had removed the lf literal \$\endgroup\$ Dec 15, 2016 at 10:43
4
\$\begingroup\$

V, 37 bytes, by DJMcMayhem

O     VrS200@"kIi|D@"A üî|D@"

Unprintables:

O     <esc>Vr<C-a>S200<esc>@"kIi<C-v><C-v><esc>|D@"<esc>A üî<esc>|D@"

TryItOnline

The ü really threw me for a loop, I kept expecting both it and î to be commands.

O                 # Insert 5 spaces above this line
Vr<C-a>           # Change them all to <C-a>
S200<esc>         # Replace the line with 200
@"                # Play back the 5 <C-a>'s, 200 -> 205
k                 # ????
Ii<C-v><C-v><esc> # insert "i<C-v>" so our line is now "i<C-v>205"
|D@"<esc>         # Delete the line and then run it, which inserts "Í" (ASCII 205)
A üî<esc>         # Append " üî" so our line is "Í üî"
|D@"              # Delete the line and run it

Í üî in V translates to :%s/ \|\n//g in vim, which globally removes all whitespace. The Í command is on the wiki, and the ü and î are | and n respectively with their high bit set

\$\endgroup\$
1
  • \$\begingroup\$ Good job! That's the exact solution I had. :) \$\endgroup\$
    – DJMcMayhem
    Dec 15, 2016 at 15:43
3
\$\begingroup\$

C, 140 bytes by betseg

#include<stdio.h>
int main(){int a=getchar();while(a!=EOF){//\a=getchar();
if(a!=10&&a!=32)//\\putchar(a^10^32);
putchar(a);a=getchar();}}

(I also hope I'm doing this right.)

\$\endgroup\$
2
  • \$\begingroup\$ Ninja'd me by one minute! \$\endgroup\$
    – user41805
    Dec 14, 2016 at 20:16
  • \$\begingroup\$ @KritixiLithos Same, was just about to submit when this anwer popped up ^^ \$\endgroup\$
    – Denker
    Dec 14, 2016 at 20:17
3
\$\begingroup\$

MATL, 22 bytes by Luis Mendo

Though I can't be sure why, this seems to work

t' @ * 'dm1e5%M
dw%Y
(

I'll have to see if I can work out what it's doing. I figured that the comments had to have line feeds after them and then it was just a matter of getting the spaces in the correct spots.

\$\endgroup\$
3
  • \$\begingroup\$ Nice, +1 I added a partial explanation in my answer :) \$\endgroup\$ Dec 16, 2016 at 19:27
  • 1
    \$\begingroup\$ @StewieGriffin, thanks for the explanation. I was trying to work why it worked, but it was going slowly. Very comprehensive docs Luis:) \$\endgroup\$
    – MickyT
    Dec 16, 2016 at 19:31
  • 1
    \$\begingroup\$ @MickyT You mean verbose like Java :-P Nice cracking work! \$\endgroup\$
    – Luis Mendo
    Dec 16, 2016 at 19:47
3
\$\begingroup\$

MATL, 22 21 bytes by Luis Mendo.

Finally... MickyT cracked it while I was writing an explanation, so his answer is the "valid" one. I posted this anyway, in accordance with this meta post.


M and Y are unnecessary and are commented out. It's enough to add 4 whitespace characters, not 5.

t' @ *'dm1e5%M
dw%Y
(

This is equivalent to the more compact:

t' @ *'dm7dw(

Partial explanation:

         % Implicit input
t        % Duplicate input
' @ *'   % String with ASCII-values [32   64   32   42]
d        % diff, giving [32  -32   10], 32 is space, 10 is newline
m        % ismember, checking if the character is 32 or 10
1e5      % 10000, but could just as well be 7
d        % Taking the diff of the scalar 1e5, returning an empty matrix []
w        % Swap stack in order to use ( below
(        % Equivalent to x(y)=[], where x is the input string, and y is the logical
         % vector found using ismember (m)
         % Implicit output
\$\endgroup\$
3
  • \$\begingroup\$ Nice cracking work! \$\endgroup\$
    – Luis Mendo
    Dec 16, 2016 at 19:47
  • 2
    \$\begingroup\$ Thanks :) I knew nothing about MATL before I started... I guess my explanation is not entirely correct (but should be fairly close?). It took me a long time, since the 1e5 either printed 100000, or 1e was a call to reshape, but then what was 5? (I see now that the % is in the end of the line, so it would be 5M, not a five and an M. Also, I thought I had to have Y( on one line. All in all, a very nice MATL tutorial :) \$\endgroup\$ Dec 17, 2016 at 22:10
  • \$\begingroup\$ The explanation is totally correct :-) Yes, it's a good (if only a little hard) way to start with a language \$\endgroup\$
    – Luis Mendo
    Dec 18, 2016 at 1:07
3
\$\begingroup\$

Whitespace, 68 bytes, by Ephphatha

  • 68 bytes, 21 tabs: LSSLSSTLSLSTLTSTTTSSSTSTSLTSSTSLSLTSLSSSTSTTSLTSSTLTSLSSLTTTTLSSLSLL
  • 71 bytes, 21 tabs: LSSLSSLTLTSSSLTTTSSSTSTSLTSSTLTSLSSLTTTSSSTSSSSSLTSSTLTSLSSLTTTTLSSLSLL
  • 72 bytes, 21 tabs: LSSLSSSTTTTTTLSLSTLTSTTTSLSSSSTSTSLTSSTLTSLSLSSSSTSSSSSLTSSTLTSLTLSSLSLL
  • 65 bytes, 15 tabs (too short): LSSLSSLSLSTLTSTTTSLSSSSTSTSLTSSTLTSLSLSSSSTSSSSSLTSSTLTSLTLSSLSLL

Since Whitespace only consists of space, tab, and LF characters (here annotated as S, T, and L), the entire program needs to be reconstructed, with the only constraint being that it have exactly 21 tabs to match the cops submission.

I start with a working program, but it's too short and needs 6 more tabs. It beats the target by 9 bytes, so I could have submitted this as another cop program, but I don't think it's interesting enough to warrant a second Whitespace answer.

# 65 bytes, 15 tabs
loop:                        # LSSL
    0 dup readc retrieve     # SSL SLS TLTS TTT
    dup 10 - jz loop         # SLS SSSTSTSL TSST LTSL
    dup 32 - jz loop         # SLS SSSTSSSSSL TSST LTSL
    printc                   # TLSS
    jmp loop                 # LSLL

The simplest way to add more tabs would be to use 63 (STTTTTT) as the address for reading characters instead of 0 (empty).

# 72 bytes, 21 tabs
loop:                        # LSSL
    63 dup readc retrieve    # SSSTTTTTTL SLS TLTS TTT
    …

That only adds bytes, though. If we retrieve before every usage, we can eliminate three dups, which have no tabs (SLS). (This is also the only of these versions without a stack memory leak.)

# 71 bytes, 21 tabs
loop:                        # LSSL
    0 readc                  # SSL TLTS
    0 retrieve 10 - jz loop  # SSL TTT SSSTSTSL TSST LTSL
    0 retrieve 32 - jz loop  # SSL TTT SSSTSSSSSL TSST LTSL
    0 retrieve printc        # SSL TTT TLSS
    jmp loop                 # LSLL

We can do better. If we compound the subtractions, 32 (STSSSSS) can be replaced with 22 (STSTTS), which gains 2 tabs and saves 1 byte. Then, the second branch doesn't dup and the print would obtain an unmodified value with 0 retrieve, which gains 3 tabs and adds 3 bytes. For the last tab, a negative sign is added to one of the zeros.

# 68 bytes, 21 tabs
loop:                        # LSSL
    -0 dup readc retrieve    # SSTL SLS TLTS TTT
    10 - dup jz loop         # SSSTSTSL TSST SLS LTSL
    22 - jz loop             # SSSTSTTSL TSST LTSL
    0 retrieve printc        # SSL TTT TLSS
    jmp loop                 # LSLL

These programs require an implementation, that allows the sign to be omitted for zero, so will not work with the reference interpreter, which TIO uses.

For this solution and others in Whitespace, see ws-challenges.

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

Befunge-98, 65 bytes by ninjalj

~v       >#@
 >::':'0--\'[';--!8v1+!
*1+j  !j,v         >#@

Try it online!

This was a lot of fun. I deduced that since there are few direction-changing commands and no ^<[]?x or similar, it has to use wrapping. I then wrote a Python script to help with getting the spacing right for the j's.

The code works by taking input (~) and duplicating it twice (::). It then subtracts 10 (':'0 or ord(':') - ord('0')) and 32 ('['; or ord('[') - ord(';')). Then, the second result is logically negated (1 if was space, 0 otherwise) and an 8 is pushed.

Now comes the part that needed figuring out what to skip. The 1+! is skipped by continuing to the next line. # skips the @. The logically negated result (0 or 1) is multiplied by the 8, and 1 is added.

The code then jumps that many (i.e. 1 or 9) spaces plus one extra as the IP moves. If the character wasn't a space it ends up at the !. The character code minus 10 is logically negated (1 if was newline, 0 otherwise). j then skips nothing, and the print (,) is called and the loop resumes by wrapping vertically.

If the character was a space, the bottom line loops again with 32, 22 as the bottom of stack. The first j jumps 705 spaces. Then the line loops a third time. If there are more than two 10's left on the stack (the code only leaves those), the first j jumps 100 spaces and the loop repeats. Otherwise, the first j jumps to the !, a zero is negated, the second j jumps over the print and the program continues.

I managed to golf it down to 59 bytes.

\$\endgroup\$
1
  • \$\begingroup\$ Listing the number of the cop in your header is fine (since the tiebreaker rewards larger sizes anyway). \$\endgroup\$ Dec 15, 2016 at 13:48
2
\$\begingroup\$

C#6, 201 bytes, by milk

using System.Linq;
_=>string./**/
#if trueJoin
(/*"*//*/""/**//*/"*/",
#else
Concat(//*/,
#endif
from m in" "let p=$@"{@" 
"[1]}"from i in(_.Replace(p,@""))where!new[]{p[0]^32^10}.Contains(i)select@i);

repl.it demo

trueJoin is not defined, so only string.Concat() remains.
p is "\n". p[0]^32^10 is space. It would have been (a bit) more difficult if it's p[0]^42 or other similar constants.

\$\endgroup\$
1
  • \$\begingroup\$ As commented on milks answer this needs C# 6+, if they change it can you too? \$\endgroup\$ Dec 15, 2016 at 15:34
2
\$\begingroup\$

reticular, 43 bytes, by Conor O'Brien

ISBqv<>>$$4j
E :d/v$v?
c+91d/ v?E
;!?l$/o $

Try it online!

This was more difficult for me than it should have been because I was too stupid to find the documentation and ended up having to guess how some of the commands worked. So some of this explanation may not be entirely accurate, but this was my basic understanding of the code.

I               Push all the input on to the stack as a string
 S              Convert it into a character array.
  B             Turns that array into individual characters on the stack.
   q            Reverse the stack so the first letter is on top.
    v           Move down... 
    /           ...and turn left.
E :d            Duplicate the value and test if equal to space.

       v?       If it is a space we move down until we wrap to the top.
       >$$      Drop the test result and the space.
          4j    Jump over the next 4 commands (having wrapped to the start).
    v           Bringing us back to the first down arrow, ready to test the next char.

     v$         If it wasn't a space, drop the test result and move down.
c+91d/          Turn left and push a newline (char 10) on to the stack.
       v?E      If equal, we go down, following the same path as with the space.

     /          If not equal, turn down.
   l$/          Then turn left, drop the test result, and push the stack size.
;!?             If zero (the stack is empty) we terminate.
        o$      Otherwise wrap around, drop the stack size, and output the char. 
     /          Then turn down wrapping around to the top of the program.
    v<          Then turn left and down to start the process from the beginning again.
\$\endgroup\$
2
  • \$\begingroup\$ There's docs on the github wiki. \$\endgroup\$ Dec 18, 2016 at 5:43
  • \$\begingroup\$ good idea! And impressive that you did this without the wiki :D \$\endgroup\$ Dec 18, 2016 at 15:18
2
\$\begingroup\$

Vyxal, 18 bytes cracks emanresu

#ȧ
‛  (#
FṘ₴#
Ṙ‛
 

Try it Online!

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

Vyxal 3, 12 bytes cracks Alan Breadel

#?“" "₉r""₉r

Try it Online! Alan didn’t say how much white space was needed, so I took a wild guess and added one to the string literal and it worked

\$\endgroup\$
2
  • \$\begingroup\$ Yes, I was quite surprised that you didn't need to add in a newline as well. \$\endgroup\$ Feb 13 at 1:54
  • \$\begingroup\$ @LarryBagel Late reply but - in Vyxal 3 comments start with ## , not just a single #. \$\endgroup\$
    – noodle man
    Mar 26 at 12:21
1
\$\begingroup\$

C#, 159 bytes by LethalCoder

using System.Linq;s=>string.Join("",string.Join("",s.Split(@" 
".Replace(new string((char)0x0D,1),"").ToCharArray())).Select(c=>c+""!=""?c+"":"").ToArray());

repl.it

The string at the end of line 1 is " \n" (space+newline).

/*Func<string, string> Lambda =*/ s =>
    string.Join("",                                                           // No-op
    string.Join("",                                                           // Join (without whitespace)
        s.Split(@" \n".Replace(new string((char)0x0D,1),"").ToCharArray())    // Split on whitespace
    ).Select(c=>c+""!=""?c+"":"").ToArray());                                 // No-op
\$\endgroup\$
1
\$\begingroup\$

Minkolang v0.15, 88 bytes by Kritixi Lithos

$oI[dd" "=$r'10'=1J,? 1R]r$O3.14
$$$
Cdollars             >
$$$
Ceverywhere           >x

Explanation

                               # Layer 1
$o                             # input chars onto stack
  I                            # stack length pushed to stack
   [                    ]      # loop popped TOS times (length of string)
    dd                         # duplicate, duplicate
      " "                      # push space to stack
         =                     # equality check
          $r                   # swap
            '10'               # number 10 to stack (LF char)
                =              # equality
                 1J            # or
                   ,           # not
                    ?          # if true jump next
                               # drop to layer 2
                      1R       # rotates the stack 1 time
                         r     # reverse the stack
                          $O   # output the stack
                             . # stop
$$$                            # Layer 2
                     >         # shift right and then drop to layer 3
$$$                            # Layer 3
                      >x       # shift right, pop char off stack and drop to Layer 1 (end loop)
\$\endgroup\$
2
  • \$\begingroup\$ Well done in cracking it! I was hoping the Comments would be confusing, but nice job nevertheless! \$\endgroup\$
    – user41805
    Dec 18, 2016 at 21:53
  • \$\begingroup\$ @KritixiLithos to be honest once I split the layers and realised that most of the work was done in the top layer, it became easier. I learnt a bit about the language doing this, so thanks :) \$\endgroup\$
    – MickyT
    Dec 19, 2016 at 1:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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