8
\$\begingroup\$

For cops' post, Cheapo Enigma machine (Cops)

A robber's submission consists of a program/function that accepts the output of a cop's code and returns the input for all the outputs provided by that cop's code. (In other words, you must write the inverse function)

You cannot use built-ins that have the sole purpose of hashing or encryption.

Input/Output format

8 bits (0 or 1), or a base-10 integer in range 1-256, 0-255 or -128 to 127. Can use standard I/O or file I/O. Function can also return a value as output. Input and output must belong to the same range (as in, binary, 1-256, 0-255 or -128 to 127), which must also be the same range as that used by the cop.

Scoring

Ratio of the cop's byte count to your byte count. Highest score wins.

You can submit a robber attempt against your own cop code for reference. (Of course this code isn't eligible for winning)

Notification

Please edit the corresponding cop's answer to include your new byte count and the corresponding ratio.

\$\endgroup\$
  • 2
    \$\begingroup\$ At first I was wondering how you were going to make Emigna into a machine. Then I realized you weren't talking about the user. \$\endgroup\$ – Magic Octopus Urn Apr 24 '17 at 18:39
  • \$\begingroup\$ OK, sorry for bothering you again, but I want to make sure I got it right this time. If the brainfuck answer reads and prints bytes (code points 0 to 255) and my Jelly answer takes an integer between 0 and 255 and returns an integer in the same range, is that acceptable? \$\endgroup\$ – Dennis Apr 28 '17 at 15:32
  • \$\begingroup\$ @Dennis No, it isn't. Maybe you (or someone else) could suggest an alternate wording that makes this clearer. \$\endgroup\$ – ghosts_in_the_code Apr 28 '17 at 16:12
  • \$\begingroup\$ @carusocomputing Emigna is a machine, right? He has every single 05AB1E program loaded up in his memory system, yeah? \$\endgroup\$ – caird coinheringaahing Jun 18 '17 at 23:17

17 Answers 17

3
\$\begingroup\$

JavaScript by Christoph, 8/25

f=(y,x=0)=>y?f(y/2,x^y):x

(range 0-255)

Sadly, f=(y,x)=>y?f(y/2,x^y):x works for all values except 0.

Technical note

We use y/2 rather than y>>1 to save a byte. This is abusing the fact that any value of y will eventually be rounded to 0 because of arithmetic underflow.

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

JavaScript by fəˈnɛtɪk, 13/19

x=>((514>>x%2)-x)/2

(range 1-256)

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

C, by Dave, 64/95 92 85

b,i,e,t[256];r(x){for(;!b;++i,b=e==x)for(srand(i&&e);t[e=rand()%256]++;);return i-1;}

Try it here!

C, shorter version, 64/89 71

i,e,t[256];r(x){for(srand(1);t[e=rand()%256]++||++i,e!=x;);return i-1;}

This one is more implementation specific, but works on TIO. Same length as the PHP solution, I wasn't able to get it any shorter than this.

Try it here!

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Ok I will take it up with the cops submission then. Thanks for informing me. \$\endgroup\$ – Ad Hoc Garf Hunter Apr 28 '17 at 5:05
1
\$\begingroup\$

JavaScript by fəˈnɛtɪk, 13 / 12

x=>x*128%257

Another multiplicative inverse.

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

JavaScript, 11/13

x=>a.sort().indexOf(x)
for(a=[],i=0;i<256;)a[i]=i++;

Try it online!

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

Jelly, 22/3 = 7 1/3

⁹ḶDÞḊi

Try it online!

The cop submission by fəˈnɛtɪk was to return the nth (0-indexed) lexicographically sorted decimal number using the domain [0,255].

I first literally reversed the operation described, ⁹ḶDÞi⁸‘ - takes the lowered range of 256, ⁹Ḷ, and Þ instructs to sort it by a key function of conversion to a decimal list, D; then finds the index of, i, the input, , and subtracts 1, (Jelly lists are 1-indexed).

Then I golfed it by dequeuing the sorted list with . When an item is not found i returns 0 as required for the removed first element (0), while everything else is found one index earlier, allowing the removal of the decrement, , which in turn gives i implicit input on its right from the left (only) input to the monadic link.

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

Javascript by Magenta, 32 / 23

x=>x%16*16+(x/16+13)%16

Code basically switches the lower and the upper 4 bits and does a modulo addition on one part.

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

Javascript by histocrat, 27 / 29

x=>x-65?x-126?x*127%258:131:6

Sadly two hard codings are needed in order to break it. Note that the orginal function doesn't map any value to 130 but maps a value to 256.

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ Having 256 in the range is legal according to the rules ("8 bits (0 or 1), or a base-10 integer in range 1-256"). This is still a valid Robber on that range, though! \$\endgroup\$ – histocrat Apr 25 '17 at 13:05
1
\$\begingroup\$

PHP, Score 64/71

for(srand(0);$a<256;)$b[$c=rand()%256]++||$d[$c]=$a++;echo$d[$argn]|0;

Luckily PHP's rand just forwards to the stdlib like C. So this works as long as we're using the same stdlib. This means it works on TIO but not on e.g. sandbox.onlinephpfunctions.com. The current version of Dave's code just iterates over a pseudorandom sequence and returns the nth unique value so I guess there might be much shorter answers if a golfing languages also uses the stdlib.

Here's an implementation of Dave's code that does not dependent on the stdlib. That might also help.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ +1 for finding a way to switch language on this one! Any idea why this doesn't need to srand(1)? Also here's a Try it online! \$\endgroup\$ – Dave Apr 28 '17 at 12:10
  • \$\begingroup\$ @Dave srand(x&&f(x-1)) this stops only if x==0 therefore it gets seeded with 0 on the first round. Not sure why the next calls don't change it. \$\endgroup\$ – Christoph Apr 28 '17 at 12:47
  • \$\begingroup\$ @Dave it seems srand(0) breaks rand (see here). I guess srand(0) automatically gets promoted to srand(1). I guess if you could use a different seed each time it would get a lot harder to break it. \$\endgroup\$ – Christoph Apr 28 '17 at 12:55
  • \$\begingroup\$ Interesting that this works. Seems to be specific to the stdlib version used on TIO, the behaviour in C on there is apparently the same, while on my local machine with clang it requires to re-invoke srand with 0 resp. 1 on each iteration, instead of just invoking it once with 0. \$\endgroup\$ – Appleshell Apr 28 '17 at 18:02
  • 1
    \$\begingroup\$ @Appleshell seems Christoph's suspicions are correct: glibc has a special check. See here: stackoverflow.com/a/8049852/1180785 (since you mention clang, I'm guessing your local is OSX, so no glibc) \$\endgroup\$ – Dave Apr 28 '17 at 18:09
0
\$\begingroup\$

Octave, 16/18

@(x)mod(x*171,256)

Try it online!

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

Jelly, 2/5 (non-competing)

^H$7¡

Try it online to see the whole table.

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

Jelly, 8/5

^H$7¡

Try it online to see the whole table.

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

Jelly, 16/6

×171%⁹

Try it online to see the whole table.

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

Jelly, 11/8

*205%257

Try it online to see the whole table.

In case robber submissions in a different languages are disallowed in the future, I call dibs on the following solution.

g=(x,y=0)=>x-++y**5%257?g(x,y):y
| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

Jelly, 35/7

⁹Ṗ+\%⁹i

Try it online to see the whole table.

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

C (gcc) by Bijan, 32 / 30

g(x){x=x?g(--x)*205+51&255:0;}

Had a fun time golfing it, thanks ! x= allows to skip return with gcc and tcc (you might want to change your answer to include it). g(--x)*205+51&255 is the inverse.

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

Jelly, 37/11

O_77×191%⁹Ọ

Uses the same I/O format as the cop. Not sure if that is required.

Try it online to see the whole table.

How it works

For input n, the cop answer computes f(n) := ((((n + 5) % 256 × 2) % 256 + 2) % 256 × 9) % 256. Since % is a linear operator, this is equivalent to f(n) = (((n + 5) × 7 + 2) × 9) % 256. Expanding the right term, we get f(n) = (63n + 333) % 256 = (63n + 77) % 256.

Reversing this is rather straightforward. To undo the addition, we simply have to subtract 77. Also, since 191 × 63 % 256 = 12033 % 256 = 1, it follows that 191 is 63's inverse modulo 256, so multiplying by 191 undoes multiplying by 63. This way, g(n) = (n - 77) × 191 % 256 defines the inverse of f.

| 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.