9
\$\begingroup\$

In golf, a knowledgable caddie helps an already good golfer to be even better. In this challenge, you build a "caddie" to help you code golf. In particular, your caddie will compress golfed code in such a way that another program can uncompress and then run the code. A good caddie will compress golfed code to be much smaller than the original golfed code. In fact, in caddie-assisted Python (say), you might be able to golf on par with a Jelly golfer!

Formally, a caddie for a language L is a pair (E,D) of programs. The program E takes as input any code c in L and outputs a string s. The program D takes s as input along with any input x of c and returns the output of c(x). We do not require E and D to be written in L. You could say that E is a transpiler that converts c into a version s that runs in the language D. We are interested in transpilers E for which E(c) tends to be smaller than c, even when c is already golfed.

Write a caddie (E,D) for any language L of your choosing. When you first post a caddie here, its score is infinity. Use the following method to update your score:

  • Let C denote the challenge in with at least 10 points that was posted first after your submission.
  • Let c denote the shortest posted solution to C that is written in L.
  • Your score is infinity unless C and c both exist, at which point your score is size(E(c))/size(c).

Recompute your score whenever either C or c changes. Lowest score wins.

\$\endgroup\$
7
  • 1
    \$\begingroup\$ This is a very nice question imho. \$\endgroup\$
    – user9207
    Commented Jan 4, 2020 at 13:45
  • \$\begingroup\$ I am a bit confused about "The program D takes s as input along with any input x of c and returns the output of c(x)." Does this just mean that D is the inverse of E? Or does D have to work for any caddy? \$\endgroup\$
    – sugarfi
    Commented Jan 9, 2020 at 1:08
  • \$\begingroup\$ @sugarfi - D is designed with E, for E. One possibility is that D uncompresses s to obtain c and then evaluates c on input x. Yes, this conversion from s to c can be thought of as the inverse of E. \$\endgroup\$ Commented Jan 9, 2020 at 1:13
  • \$\begingroup\$ Is Japt a valid caddie for JavaScript? \$\endgroup\$
    – user85052
    Commented Jan 11, 2020 at 14:46
  • \$\begingroup\$ @a'_' - If there's a program E that converts from JavaScript to Japt, then it's valid, yes. \$\endgroup\$ Commented Jan 11, 2020 at 23:11

1 Answer 1

2
\$\begingroup\$

Python 3 Caddy, interprets BrainF***

Score: \$\frac{38}{224}\approx0.17\$ (with newlines removed)

Program E

from textwrap import wrap

x = input('Code: ')
i = ['<', '>', '+', '-', '[', ']', '.', ',']
o = ''
for c in x:
    if c in i:
        o += str(i.index(c) + 1)
if o:
    d = wrap(o, 6)
    d = [int(x) for x in d]
    o = ''
    for c in d:
        o += chr(int(c) + 128)
print('Compressed: ', o)

The way this works is by converting every instruction in the input to a digit, then concatenating those digits to a number. Then it splits that number into 6-digit groups and converts each to a Unicode character. (A number higher than 6 could be used, by that would cause errors for large programs). Then it outputs it.

Program D

x = input('Compressed: ')
p = input('Input: ')
p = list(p)
d = ''
for c in x:
    c = ord(c) - 128
    d += str(c)
d = d.replace('-', '')
i = ['<', '>', '+', '-', '[', ']', '.', ',']
o = ''
for n in d:
    n = int(n) - 1
    o += i[n]
tape = [0] * 30000
head = 0
m = {}
m2 = {}
stack = []
for i in range(len(o)):
    char = o[i]
    if char == '[':
        stack.append(i)
    elif char == ']':
        begin = stack.pop()
        m[begin] = i + 1
        m2[i] = begin
i = 0
while i < len(o):
    char = o[i]
    if char == '<':
        head -= 1
        i += 1
    elif char == '>':
        head += 1
        i += 1
    elif char == '+':
        tape[head] += 1
        i += 1
    elif char == '-':
        tape[head] -= 1
        i += 1
    elif char == '[':
        if tape[head] == 0:
            i = m[i]
        else:
            i += 1
    elif char == ']':
        if tape[head] != 0:
            i = m2[i]
        else:
            i += 1
    elif char == '.':
        print(chr(tape[head]), end='')
        i += 1
    elif char == ',':
        try:
            tape[head] = ord(p.pop(0))
        except:
            tape[head] = 0
        i += 1

This is pretty simple, it just reverses the compression algorithm and evaluates the result.

\$\endgroup\$
7
  • \$\begingroup\$ FYI - Here is a link to what is currently challenge C for your post, but I don't see a solution coded in BrainF*** yet: codegolf.stackexchange.com/questions/197879/… \$\endgroup\$ Commented Jan 11, 2020 at 0:36
  • \$\begingroup\$ @DustinG.Mixon - yeah, I checked the new challenges, but none had a solution in BrainF*** \$\endgroup\$
    – sugarfi
    Commented Jan 11, 2020 at 0:50
  • \$\begingroup\$ Also, you are allowed to post a BrainF*** solution to that challenge and then compress it here. \$\endgroup\$ Commented Jan 11, 2020 at 23:08
  • \$\begingroup\$ @DustinG.Mixon - ok, I will do that soon \$\endgroup\$
    – sugarfi
    Commented Jan 11, 2020 at 23:54
  • \$\begingroup\$ @DustinG.Mixon - Finally found a BrainF answer! Updating my score now. \$\endgroup\$
    – sugarfi
    Commented Jan 16, 2020 at 21:39

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.