Short Deadfish Numbers
ES6 JavaScript 2126 + 311 = 2437 score
m=Math;s=n=>[b=m.min(m.sqrt(n)+.5|0,15),n-b*b];f=n=>(n<0?'d':'i').repeat(m.abs(n));g=(n,t)=>n<4?f(n):g((t=s(n))[0])+'s'+f(t[1]);q=n=>((x=g(n)).length>(z=[...n+''].map((k,i,a)=>i?(a[i-1]==a[i]?'':(y=f((l=s(k))[0]-a[i-1])+(l[0]?'s':'')+f(l[1])).length>m.abs(Q=a[i]-a[i-1])?f(Q):y):g(k)).join('o')).length?z:x)+'o'
Semi-commented:
m = Math; // Keep a reference to math
// This function returns the closest perfect square and the distance from that square to the number
// E.g. s(10) --> [3, 1] because 3^2 + 1 = 10
s = n => [b = m.min(m.sqrt(n) + .5 | 0, 15), n - b * b];
// This creates a bunch of "d"s or "i"s
// E.g. f(3) --> "iii" or f(-2) --> "dd"
f = n => Array(m.abs(n) + 1).join(n < 0 ? 'd' : 'i');
// This constructs the number as a number rather than by digit
g = (n, t) => n < 4 ?
// If n is less than 4, then we can just increment in normally (base case)
f(n) :
// Otherwise, build the square root recursively and shift
g((t = s(n))[0]) + 's' + f(t[1]);
// This maps based on digits (constructs the number by digit)
// This has now been removed and replaced inline because it is only used once
d = n => (a = [...(n + '')]).map((k, i) => i ? (a[i - 1] == a[i] ? '' : f((l = s(k))[0] - a[i - 1]) + (l[0] ? 's' : '') + f(l[1])) : g(k)).join('o');
// For the official function, compare the digit-method and nondigit-method and return the best one
q = n => ((x = g(n)).length > (z = d(n)).length ? z : x) + 'o'
This takes advantage of the fact that in deadfish, you can print more than one character.
Example: 10
compiles to iodo
which is "print one, decrement, print zero."
Usage:
q(10) // --> iodo
q(16) // --> iisso
Here's json data of output:
{
"0": "o",
"1": "io",
"2": "iio",
"3": "iiio",
"4": "iiso",
"5": "iisio",
"6": "iisiio",
"7": "iiisddo",
"8": "iiisdo",
"9": "iiiso",
"10": "iodo",
"11": "ioo",
"12": "ioio",
"13": "ioiio",
"14": "ioiso",
"15": "iissdo",
"16": "iisso",
"17": "iissio",
"18": "iissiio",
"19": "ioiiso",
"20": "iioddo",
"21": "iiodo",
"22": "iioo",
"23": "iioio",
"24": "iioso",
"25": "iisiso",
"26": "iisisio",
"27": "iisisiio",
"28": "iioisdo",
"29": "iioiso",
"30": "iiiodddo",
"31": "iiioddo",
"32": "iiiodo",
"33": "iiioo",
"34": "iiioio",
"35": "iiioiio",
"36": "iisiiso",
"37": "iisiisio",
"38": "iiiosdo",
"39": "iiioso",
"40": "iisoddddo",
"41": "iisodddo",
"42": "iisoddo",
"43": "iisodo",
"44": "iisoo",
"45": "iisoio",
"46": "iisoiio",
"47": "iisoiiio",
"48": "iisodsdo",
"49": "iisodso",
"50": "iiisddsio",
"51": "iiisddsiio",
"52": "iisiodddo",
"53": "iisioddo",
"54": "iisiodo",
"55": "iisioo",
"56": "iisioio",
"57": "iisioiio",
"58": "iisioiiio",
"59": "iisioddso",
"60": "iiisdsddddo",
"61": "iiisdsdddo",
"62": "iiisdsddo",
"63": "iiisdsdo",
"64": "iiisdso",
"65": "iiisdsio",
"66": "iisiioo",
"67": "iisiioio",
"68": "iisiioiio",
"69": "iisiioiiio",
"70": "iiisdsiiiiiio",
"71": "iiisdsiiiiiiio",
"72": "iiisddodddddo",
"73": "iiisddoddddo",
"74": "iiisddodddo",
"75": "iiisddoddo",
"76": "iiisddodo",
"77": "iiisddoo",
"78": "iiissdddo",
"79": "iiissddo",
"80": "iiissdo",
"81": "iiisso",
"82": "iiissio",
"83": "iiissiio",
"84": "iiissiiio",
"85": "iiissiiiio",
"86": "iiisdoddo",
"87": "iiisdodo",
"88": "iiisdoo",
"89": "iiisdoio",
"90": "iiissiiiiiiiiio",
"91": "iiisoddddddddo",
"92": "iiisodddddddo",
"93": "iiisoddddddo",
"94": "iiisodddddo",
"95": "iiisoddddo",
"96": "iiisodddo",
"97": "iiisoddo",
"98": "iiisodo",
"99": "iiisoo",
"100": "iodoo",
"101": "iodoio",
"102": "iodoiio",
"103": "iodoiiio",
"104": "iodoiiso",
"105": "iodoiisio",
"106": "iodoiisiio",
"107": "iodoiiisddo",
"108": "iodoiiisdo",
"109": "iodoiiiso",
"110": "ioodo",
"111": "iooo",
"112": "iooio",
"113": "iooiio",
"114": "iooiso",
"115": "iooisio",
"116": "iooisiio",
"117": "iooiisddo",
"118": "iooiisdo",
"119": "iooiiso",
"120": "ioioddo",
"121": "ioiodo",
"122": "ioioo",
"123": "ioioio",
"124": "ioioso",
"125": "ioiosio",
"126": "ioiosiio",
"127": "ioioisddo",
"128": "ioioisdo",
"129": "ioioiso",
"130": "ioiiodddo",
"131": "ioiioddo",
"132": "ioiiodo",
"133": "ioiioo",
"134": "ioiioio",
"135": "ioiioiio",
"136": "ioiioiiio",
"137": "ioiiosddo",
"138": "ioiiosdo",
"139": "ioiioso",
"140": "ioisoddddo",
"141": "ioisodddo",
"142": "ioisoddo",
"143": "ioisodo",
"144": "ioisoo",
"145": "ioisoio",
"146": "ioisoiio",
"147": "ioisoiiio",
"148": "ioisodsdo",
"149": "ioisodso",
"150": "ioisiodddddo",
"151": "ioisioddddo",
"152": "ioisiodddo",
"153": "ioisioddo",
"154": "ioisiodo",
"155": "ioisioo",
"156": "ioisioio",
"157": "ioisioiio",
"158": "ioisioiiio",
"159": "ioisioddso",
"160": "ioisiioddddddo",
"161": "ioisiiodddddo",
"162": "ioisiioddddo",
"163": "ioisiiodddo",
"164": "ioisiioddo",
"165": "ioisiiodo",
"166": "ioisiioo",
"167": "ioisiioio",
"168": "iissdddsdo",
"169": "iissdddso",
"170": "iissdddsio",
"171": "iissdddsiio",
"172": "iissdddsiiio",
"173": "iissdddsiiiio",
"174": "ioiisddodddo",
"175": "ioiisddoddo",
"176": "ioiisddodo",
"177": "ioiisddoo",
"178": "ioiisddoio",
"179": "ioiisddoiio",
"180": "ioiisdoddddddddo",
"181": "ioiisdodddddddo",
"182": "ioiisdoddddddo",
"183": "ioiisdodddddo",
"184": "ioiisdoddddo",
"185": "ioiisdodddo",
"186": "ioiisdoddo",
"187": "ioiisdodo",
"188": "ioiisdoo",
"189": "ioiisdoio",
"190": "iissddsddddddo",
"191": "iissddsdddddo",
"192": "iissddsddddo",
"193": "iissddsdddo",
"194": "iissddsddo",
"195": "iissddsdo",
"196": "iissddso",
"197": "iissddsio",
"198": "ioiisodo",
"199": "ioiisoo",
"200": "iioddoo",
"201": "iioddoio",
"202": "iioddoiio",
"203": "iioddoiiio",
"204": "iioddoiiso",
"205": "iioddoiisio",
"206": "iioddoiisiio",
"207": "iioddoiiisddo",
"208": "iioddoiiisdo",
"209": "iioddoiiiso",
"210": "iiododo",
"211": "iiodoo",
"212": "iiodoio",
"213": "iiodoiio",
"214": "iiodoiso",
"215": "iiodoisio",
"216": "iiodoisiio",
"217": "iiodoiisddo",
"218": "iiodoiisdo",
"219": "iiodoiiso",
"220": "iiooddo",
"221": "iioodo",
"222": "iiooo",
"223": "iiooio",
"224": "iiooso",
"225": "iissdso",
"226": "iissdsio",
"227": "iissdsiio",
"228": "iiooisdo",
"229": "iiooiso",
"230": "iioiodddo",
"231": "iioioddo",
"232": "iioiodo",
"233": "iioioo",
"234": "iioioio",
"235": "iioioiio",
"236": "iioioiiio",
"237": "iioiosddo",
"238": "iioiosdo",
"239": "iioioso",
"240": "iiosoddddo",
"241": "iiosodddo",
"242": "iiosoddo",
"243": "iiosodo",
"244": "iiosoo",
"245": "iiosoio",
"246": "iiosoiio",
"247": "iiosoiiio",
"248": "iiosodsdo",
"249": "iiosodso",
"250": "iiosiodddddo",
"251": "iiosioddddo",
"252": "iiosiodddo",
"253": "iiosioddo",
"254": "iiosiodo",
"255": "iiosioo"
}
That was generated by this code:
var c = {}, result = 0;
for (var i = 0; i <= 255; ++i) result += (c[i] = q(i)).length;
which prints result = (the result)
and c =
the thing above.
This gets a remarkably high score despite being pretty simple. It searches for the nearest perfect square, calculates the square root of that perfect square, adds 's', and increments/decrements appropriately.
Old version which didn't use the fact that "10" = "print one, print zero"
m=Math;s=n=>[b=m.sqrt(n)+.5|0,n-b*b];f=(n)=>Array(m.abs(n)+1).join('id'[+(n<0)]);g=(n,t)=>n<4?f(n):g((t=s(n))[0])+'s'+f(t[1]);q=n=>g(n)+'o'
Mathematica, 254 165 characters + 3455 = 3620
f@n_:=n;g@0="";l={f@0=0};h=If[f@#>f@i&&#<256&&#>0,f@#=f@i+1;g@#=g@i<>#2;l~AppendTo~#]&;While[l!={},i=#&@@l;l=Rest@l;h[i+1,"i"];h[i-1,"d"];h[i*i,"s"];];g@Input[]<>"o"
Less golf:
f@n_ := n;
g@0 = "";
l = {f@0 = 0};
h = If[f@# > f@i && # < 256 && # > 0,
f@# = f@i + 1;
g@# = g@i <> #2;
l~AppendTo~#] &;
While[l != {},
i = # & @@ l;
l = Rest@l;
h[i + 1, "i"];
h[i - 1, "d"];
h[i*i, "s"];
];
g@Input[] <> "o"
I believe the resulting numbers are optimal. This is doing a breadth-first search over all 256 numbers, keeping track of the shortest way it has found to represent each number. The search is building a sort of lookup table in the function g
which is then applied to the input.
For reference, here are all 255 results:
io
iio
iiio
iiso
iisio
iisiio
iisiiio
iiisdo
iiiso
iiisio
iiisiio
iiisiiio
iissdddo
iissddo
iissdo
iisso
iissio
iissiio
iissiiio
iissiiiio
iissiiiiio
iisisdddo
iisisddo
iisisdo
iisiso
iisisio
iisisiio
iisisiiio
iisisiiiio
iisisiiiiio
iisisiiiiiio
iisiisddddo
iisiisdddo
iisiisddo
iisiisdo
iisiiso
iisiisio
iisiisiio
iisiisiiio
iisiisiiiio
iisiisiiiiio
iisiisiiiiiio
iisiisiiiiiiio
iisiiisdddddo
iisiiisddddo
iisiiisdddo
iisiiisddo
iisiiisdo
iisiiiso
iisiiisio
iisiiisiio
iisiiisiiio
iisiiisiiiio
iisiiisiiiiio
iisiiisiiiiiio
iisiiisiiiiiiio
iiisdsdddddddo
iiisdsddddddo
iiisdsdddddo
iiisdsddddo
iiisdsdddo
iiisdsddo
iiisdsdo
iiisdso
iiisdsio
iiisdsiio
iiisdsiiio
iiisdsiiiio
iiisdsiiiiio
iiisdsiiiiiio
iiisdsiiiiiiio
iiissdddddddddo
iiissddddddddo
iiissdddddddo
iiissddddddo
iiissdddddo
iiissddddo
iiissdddo
iiissddo
iiissdo
iiisso
iiissio
iiissiio
iiissiiio
iiissiiiio
iiissiiiiio
iiissiiiiiio
iiissiiiiiiio
iiissiiiiiiiio
iiissiiiiiiiiio
iiissiiiiiiiiiio
iiisisddddddddo
iiisisdddddddo
iiisisddddddo
iiisisdddddo
iiisisddddo
iiisisdddo
iiisisddo
iiisisdo
iiisiso
iiisisio
iiisisiio
iiisisiiio
iiisisiiiio
iiisisiiiiio
iiisisiiiiiio
iiisisiiiiiiio
iiisisiiiiiiiio
iiisisiiiiiiiiio
iiisisiiiiiiiiiio
iiisisiiiiiiiiiiio
iiisiisdddddddddo
iiisiisddddddddo
iiisiisdddddddo
iiisiisddddddo
iiisiisdddddo
iiisiisddddo
iiisiisdddo
iiisiisddo
iiisiisdo
iiisiiso
iiisiisio
iiisiisiio
iiisiisiiio
iiisiisiiiio
iiisiisiiiiio
iiisiisiiiiiio
iiisiisiiiiiiio
iiisiisiiiiiiiio
iiisiisiiiiiiiiio
iiisiisiiiiiiiiiio
iiisiisiiiiiiiiiiio
iiisiisiiiiiiiiiiiio
iiisiiisddddddddddo
iiisiiisdddddddddo
iiisiiisddddddddo
iiisiiisdddddddo
iiisiiisddddddo
iiisiiisdddddo
iiisiiisddddo
iiisiiisdddo
iiisiiisddo
iiisiiisdo
iiisiiiso
iiisiiisio
iiisiiisiio
iiisiiisiiio
iiisiiisiiiio
iiisiiisiiiiio
iiisiiisiiiiiio
iiisiiisiiiiiiio
iiisiiisiiiiiiiio
iiisiiisiiiiiiiiio
iiisiiisiiiiiiiiiio
iiisiiisiiiiiiiiiiio
iiisiiisiiiiiiiiiiiio
iissdddsddddddddddddo
iissdddsdddddddddddo
iissdddsddddddddddo
iissdddsdddddddddo
iissdddsddddddddo
iissdddsdddddddo
iissdddsddddddo
iissdddsdddddo
iissdddsddddo
iissdddsdddo
iissdddsddo
iissdddsdo
iissdddso
iissdddsio
iissdddsiio
iissdddsiiio
iissdddsiiiio
iissdddsiiiiio
iissdddsiiiiiio
iissdddsiiiiiiio
iissdddsiiiiiiiio
iissdddsiiiiiiiiio
iissdddsiiiiiiiiiio
iissdddsiiiiiiiiiiio
iissdddsiiiiiiiiiiiio
iissddsddddddddddddddo
iissddsdddddddddddddo
iissddsddddddddddddo
iissddsdddddddddddo
iissddsddddddddddo
iissddsdddddddddo
iissddsddddddddo
iissddsdddddddo
iissddsddddddo
iissddsdddddo
iissddsddddo
iissddsdddo
iissddsddo
iissddsdo
iissddso
iissddsio
iissddsiio
iissddsiiio
iissddsiiiio
iissddsiiiiio
iissddsiiiiiio
iissddsiiiiiiio
iissddsiiiiiiiio
iissddsiiiiiiiiio
iissddsiiiiiiiiiio
iissddsiiiiiiiiiiio
iissddsiiiiiiiiiiiio
iissddsiiiiiiiiiiiiio
iissdsdddddddddddddddo
iissdsddddddddddddddo
iissdsdddddddddddddo
iissdsddddddddddddo
iissdsdddddddddddo
iissdsddddddddddo
iissdsdddddddddo
iissdsddddddddo
iissdsdddddddo
iissdsddddddo
iissdsdddddo
iissdsddddo
iissdsdddo
iissdsddo
iissdsdo
iissdso
iissdsio
iissdsiio
iissdsiiio
iissdsiiiio
iissdsiiiiio
iissdsiiiiiio
iissdsiiiiiiio
iissdsiiiiiiiio
iissdsiiiiiiiiio
iissdsiiiiiiiiiio
iissdsiiiiiiiiiiio
iissdsiiiiiiiiiiiio
iissdsiiiiiiiiiiiiio
iissdsiiiiiiiiiiiiiio
iissdsiiiiiiiiiiiiiiio
iissdsiiiiiiiiiiiiiiiio
iissdsiiiiiiiiiiiiiiiiio
iissdsiiiiiiiiiiiiiiiiiio
iissdsiiiiiiiiiiiiiiiiiiio
iissdsiiiiiiiiiiiiiiiiiiiio
iissdsiiiiiiiiiiiiiiiiiiiiio
iissdsiiiiiiiiiiiiiiiiiiiiiio
iissdsiiiiiiiiiiiiiiiiiiiiiiio
iissdsiiiiiiiiiiiiiiiiiiiiiiiio
iissdsiiiiiiiiiiiiiiiiiiiiiiiiio
iissdsiiiiiiiiiiiiiiiiiiiiiiiiiio
iissdsiiiiiiiiiiiiiiiiiiiiiiiiiiio
iissdsiiiiiiiiiiiiiiiiiiiiiiiiiiiio
iissdsiiiiiiiiiiiiiiiiiiiiiiiiiiiiio
iissdsiiiiiiiiiiiiiiiiiiiiiiiiiiiiiio
C, 433 code + 3455 output = 3888
C++, 430 code + 3455 output = 3885
And now for something completely different.
I used the output from Martin's Mathematica answer (updated on October 23rd as it was wrong for 240+ before). My output is the same 3455 characters. I analyzed patterns in the output and discovered that [0,255] can be represented by this sequence:
- 0-3
i
s - 0-2
s
s - 0-3
i
s ord
s - 0-1
s
s - 0-14
i
or 0-16d
s - 1
o
The next step was to carefully construct these five columns (c
through g
in the code below). I used negative numbers to indicate d
instead of i
in columns e
and g
. Then, it turns out that the results work mostly like a counter in the g
column, since each row u
usually removes one d
or adds one i
relative to the previous row (v
). There are 15 exceptions, which are stored in x
(the indexes) and b
(the five columns, packed into an integer which only requires 14 bits to store the maximum 10832
).
For example, the first "exception" is the very first row, where we want zero characters apart from the terminating o
. So x[0]
is 0
, and b[0]
is 544
, which when unpacked is ("little endian" style, since g
is the counting column) { 32, 0, 4, 0, 0 }
. We always subtract 32 from g
and 4 from e
to make the unsigned bit-fields work (i.e. those two columns represent negative numbers conceptually when d
is required instead of i
, but in the implementation the values are offset to avoid actual negative numbers).
Here's a table showing how the first ten numbers work (blanks are zeros):
n text c d e f g
0 o
1 io 1
2 iio 2
3 iiio 3
4 iiso 2 1
5 iisio 2 1 1
6 iisiio 2 1 2
7 iisiiio 2 1 3
8 iiisdo 3 1 -1
9 iiiso 3 1
You can see that g
mostly just increments by one for each new row, but some rows (0, 4, 8, ..., which I briefly hoped to find in OEIS) "reset" the sequence, meaning g
takes on some new value and at least one other column is modified as well.
The code character count excludes whitespace except the mandatory newline before each #
and space after unsigned
and int
. You can save 3 characters by compiling as C++ instead of C, replacing <stdio.h>
with <cstdio>
, and *(int*)&u
with (int&)u
.
#include <stdio.h>
struct { unsigned g:6, f:1, e:3, d:2, c:2; } u;
int
x[] = { 0,4,8,13,22,32,44,57,72,92,112,134,157,182,210,256 },
b[] = { 544,9760,13855,9821,9949,10076,10203,13785,13911,14040,14167,14294,10452,10578,10705,10832 };
int main()
{
int n,i=0,q=0;
scanf("%d", &n);
while(i++ <= n) {
++u.g;
if (i > x[q])
*(int*)&u = b[q++];
}
#define m(p, q) while (p) putchar(#q[0]);
m(u.c--, i)
m(u.d--, s)
m(u.e++ < 4, d)
m(--u.e > 4, i)
m(u.f--, s)
m(u.g++ < 32, d)
m(--u.g > 32, i)
puts("o");
}
A fun fact about this code: an earlier version used an array of 256 unions instead of just u
and v
. That version caused GCC 4.7.2 to generate an internal compiler error! GCC 4.9 fixed it, however, and the above code works with either version.