20
\$\begingroup\$

Suppose a codegolf challenge doesn't count whitespace in the length of your program. Cheat this system by encoding your script into whitespace, and golf a script which decodes and executes embedded whitespace.

Example

My solution to JBernardo's Meta Golf Challenge was to encode Sage (or Python) code into whitespace, and golf the decoder.

s = ' '
for c in '<lots of whitespace>'.split(s):
    s+=chr(len(c))
exec s

The encoding is to take a script, prepend a newline, and for each character c in the script, output ord(c) tabs followed by a space. Prepending a newline is necessary since I'm using Python and I start the script s with a space.

Scoring

A complete solution contains a description of the encoding you use (if it's complicated, provide a script), and a 'decode-and-execute' script. Your score is the number of non-whitespace characters in the decode-and-execute script.

Whitespace (the language) is forbidden

Moreover, any language which has a complete set of operators which only use whitespace characters is not allowed: I'll accept the lowest nonzero score.

\$\endgroup\$

10 Answers 10

8
\$\begingroup\$

Golfscript, 12 chars

String delimited by ' goes before these 10 chars:

n/{,}%''+~

Each line is decoded into one character, whose ASCII (probably Unicode, in fact) value is the length of the line.

Unfortunately if I try pasting my Hello World example, Markdown removes the extra spaces, even in a <pre> block.

\$\endgroup\$
  • 2
    \$\begingroup\$ Since whitespace at the beginning of a program is always non-functional, .n/{,}%+~ would work as well. \$\endgroup\$ – Dennis Oct 8 '15 at 15:56
9
\$\begingroup\$

CPAN, 16

use Acme::Bleach;

CPAN has it all. Or at least, just the right module.

\$\endgroup\$
  • \$\begingroup\$ I call cheat on this, that is a complete set of operators that is nothing but whitespace \$\endgroup\$ – ratchet freak Sep 1 '11 at 19:34
  • 5
    \$\begingroup\$ This is not a cheat. It's cheap, but acceptable. \$\endgroup\$ – boothby Sep 1 '11 at 21:59
  • 1
    \$\begingroup\$ This program does nothing. None of the WS is there. BOOOOOO!!!! Please repost this with a program that does something useful here. Keep the Acme::Bleach use, but take advantage of it. \$\endgroup\$ – Thomas Eding Sep 5 '11 at 22:30
  • 1
    \$\begingroup\$ @trinithis: as do none of the other programs presented here. Why pick specifically on this one? \$\endgroup\$ – J B Sep 6 '11 at 7:39
  • \$\begingroup\$ I noticed it and it stands out as a what does this do, it only looks like it imports. \$\endgroup\$ – Thomas Eding Sep 6 '11 at 15:37
3
\$\begingroup\$

Perl, 29

$_="";s/     */chr length $&/ge;eval

Inside that s/// are a tab then a space. The encoding is an ultra-basic encode with spaces, precede with tabs.

Try this one on the command line:

$ tr ST ' \t' <<< '$_="TSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS"; s/TS*/chr length $&/ge; eval' | perl

Edit: well, lol, I can't find a proper way to copy-paste the tab/space mix. Believe me, it works at home :) Update: there, there, encoded with tr

\$\endgroup\$
  • \$\begingroup\$ you can put tabs in with \t and we'll believe it works with whitespace... \$\endgroup\$ – boothby Sep 5 '11 at 7:14
  • \$\begingroup\$ @boothby: oh, better than that, I can have the \t interpreted by the shell and actually have the damn thing work demonstrably. Doing that in a few hours. \$\endgroup\$ – J B Sep 5 '11 at 9:04
3
\$\begingroup\$

JavaScript

Replace \t with a tab to get the posted character count.

Standard (64 characters)

eval(eval("'<code here>'".replace(/\t */g,function(s){return"\\"+s.length})))

Arrow function (49 characters)

eval(eval("'<code here>'".replace(/\t */g,(s)=>"\\"+s.length)))

Encoder program for both

for(var i = 0, si = prompt("Enter the code."), so = ""; i < si.length; ++i) so += '\t' + Array(+si.charCodeAt(i).toString(8)).join(' '); prompt("Here is the result.", so);
\$\endgroup\$
  • \$\begingroup\$ Replace (s)=>... in the arrow function to s=>... to save two bytes \$\endgroup\$ – andrewarchi Jun 15 '17 at 5:06
  • \$\begingroup\$ Keep spaces between any two char and at worst use jsfuck to make it work(and better use " t " [ 1 ] to mean "t") \$\endgroup\$ – l4m2 Dec 11 '18 at 11:40
  • \$\begingroup\$ 44B eval("".replace(/ +/g,s=>' []+!()'[s.length])) \$\endgroup\$ – l4m2 Dec 11 '18 at 11:42
2
\$\begingroup\$

Yabasic (88 characters)

a$ = "<code here>"
for a = 1 to len(a$)
    if mid$(a$, a) < " " then b = b + 1
    else b$ = b$ + chr$(b) : b = 0
    endif
next
compile(b$)
a()

Use the same encoder program as for my C solution, but do not remove the first character. Your original code must be in the form of a subroutine a(), for example:

sub a():?"hello, world":end sub
\$\endgroup\$
2
\$\begingroup\$

C (99 characters)

main(c, p)
{
    char *s = "<code here>";
    for (p = popen("cc -xc -oa -", "w"); *s;)
        *s++ - 9 ? c -= putc(c, p) : ++c;
    execl("a", pclose(p));
}

Tested only with (and perhaps only works with) GCC.

Corresponding encoder program (manually remove the first character from its output):

#include <stdio.h>

int main()
{
    int c;
    while ((c = getchar()) != EOF) {
        while (c--) putchar(9);
        putchar(32);
    }
    return 0;
}
\$\endgroup\$
1
\$\begingroup\$

D (101 chars)

import std.algorithm;mixin((){char[]r;foreach(c;splitter("<lots of whitspace>"," "))r~=cast(char)c.length;return r;}());

same encoding as in the question (no need for the newline)

\$\endgroup\$
  • 2
    \$\begingroup\$ The point of this is that whitespace is free. I count 98 characters. Feel free to write readable code! \$\endgroup\$ – boothby Sep 16 '11 at 16:25
1
\$\begingroup\$

Bash (builtins only, 44 characters)

IFS=
eval `while read a
do printf '\'${#a}
done<<a
<code here>
a`

Corresponding encoder script:

od -b | cut -b9- | tr ' ' '\n' | while read a
do
    for (( b = 0; b < $((10#$a)); ++b ))
    do
        echo -n ' '
    done
    echo
done
\$\endgroup\$
  • \$\begingroup\$ Very nice. I consider myself a bit of a Bash hacker, and I had to man up a bit to grok this. \$\endgroup\$ – boothby Sep 7 '11 at 17:55
1
\$\begingroup\$

K5, 12 bytes

.`c$-':&9=" "

Execute (.) the string formed from the ascii values (`c$) given by the difference between each pair (-':) of the indices where (&) the input is a tab (9=" ").

Input is a string of tab- and non-tab characters, and the character values are encoded in the number of non-tabs (spaces or newlines) between each tab. An example encoder:

" ",/{(x#" "),"\t"}'-1+

Perform a running join beginning with a space over (" ",/) x spaces (x#" ") joined with a tab (,"\t") where X is each of ({...}') one minus the character values of the input string (-1+).

In action:

  enc: " ",/{(x#" "),"\t"}'-1+
  dec: .`c$-':&9=

  enc "2+3"
"                                                  \t                                          \t                                                  \t"
  dec enc "2+3"
5
\$\endgroup\$
0
\$\begingroup\$

Ruby, 43

Very straightforward, encoding is putting x spaces per line, where x is the ascii value of the char, decoding is reverse.

The following script is just a unary to ASCII converter and works even when things other than spaces are free:

eval("".split("\n").map{|x|x.length.chr}.join)

Just replace the empty string with the program that pleases you.

The thing in a more reusable format:

from_space = lambda {|text| text.split("\n").map{|x| x.length.chr}.join}
to_space = lambda {|text| text.chars.map{|x| " " * x.ord}.join("\n")}

p from_space [ to_space [ "abc" ] ] #=> "abc"
\$\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.