Python 2, 14508 11700 11088 10164 9486 9746 7860 145 bytes * 36 unique = 5220
I saw the title and thought this was an interesting challenge for the rather wordy Python. These are my notes as I tackled this problem.
My first try reduced the uniques to 31:
print''.join(chr([69,108,105,122,97,98,101,116,104,32,111,98,110,111,120,105,111,117,115,108,121,32,113,117,111,116,101,100,32,40,106,117,115,116,32,116,111,111,32,114,111,119,100,121,32,102,111,114,32,109,121,32,112,101,97,99,101,41,58,32,34,84,72,69,32,81,85,73,67,75,32,66,82,79,87,78,32,70,79,88,32,74,85,77,80,83,32,79,86,69,82,32,84,72,69,32,76,65,90,89,32,68,79,71,44,34,32,103,105,118,105,110,103,32,109,101,32,97,32,108,111,111,107,46][r])for r in range(124))
I thought I could do better. By using map
, uniques came down to 26:
print''.join(map(chr,(69,108,105,122,97,98,101,116,104,32,111,98,110,111,120,105,111,117,115,108,121,32,113,117,111,116,101,100,32,40,106,117,115,116,32,116,111,111,32,114,111,119,100,121,32,102,111,114,32,109,121,32,112,101,97,99,101,41,58,32,34,84,72,69,32,81,85,73,67,75,32,66,82,79,87,78,32,70,79,88,32,74,85,77,80,83,32,79,86,69,82,32,84,72,69,32,76,65,90,89,32,68,79,71,44,34,32,103,105,118,105,110,103,32,109,101,32,97,32,108,111,111,107,46)))
At about this time, I noticed in the question text that the score was uniques * bytes
, not just uniques! That meant my scores for the above were 14508 and 11700. Not very competitive. So I now reduce the bytes by storing the text as a hex string:
# 308*36 = 11088
print''.join(chr(int('456c697a6162657468206f626e6f78696f75736c792071756f74656420286a75737420746f6f20726f77647920666f72206d79207065616365293a202254484520515549434b2042524f574e20464f58204a554d5053204f56455220544845204c415a5920444f472c2220676976696e67206d652061206c6f6f6b2e'[i*2:i*2+2],16)) for i in range(124))
Size was reduced but more unique characters. But if I used a packed 2 digit decimal string with a 32 offset:
# 308*33 = 10164
print''.join(chr(int('37767390656669847200796678798873798583768900818579846968000874858384008479790082798768890070798200778900806965676909260002524037004953413543003450475546003847560042534548510047543750005240370044335857003647391202007173867378710077690065007679797514'[i*2:i*2+2])+32) for i in range(124))
This has the same number of bytes but saves 3 uniques.
I hatch a new plan. If I pack a Python long integer with 7 bit characters, I could extract each one by shifting:
# 306*31 = 9486
h=1073974643401006528619595312441225198653732186368270382545648881135648217524502741093886285232362673460172159947573049818819511630304840724474679255867143965214892747087773876949021986013520804726327302180335979259392708372721217579101211940864406962137554744750
w=''
while h:w=chr(h&127)+w;h>>=7
print w
Well that reduced the score to 9486. An interesting experiment, but nowhere near good enough. Now what if I get rid of the function names and rely on string formatting?
# 443 * 22 = 9746
print('%c'*124)%(69,108,105,122,97,98,101,116,104,32,111,98,110,111,120,105,111,117,115,108,121,32,113,117,111,116,101,100,32,40,106,117,115,116,32,116,111,111,32,114,111,119,100,121,32,102,111,114,32,109,121,32,112,101,97,99,101,41,58,32,34,84,72,69,32,81,85,73,67,75,32,66,82,79,87,78,32,70,79,88,32,74,85,77,80,83,32,79,86,69,82,32,84,72,69,32,76,65,90,89,32,68,79,71,44,34,32,103,105,118,105,110,103,32,109,101,32,97,32,108,111,111,107,46)
I now have only 22 uniques, but the score does not improve.
Ok, What if I took the obvious way and just printed the string:
# 131*60 = 7860
print'Elizabeth obnoxiously quoted (just too rowdy for my peace): "THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG," giving me a look.'
Score of 7860. I should have done this first. But I would not have learned so much.
I guess I could reduce uniques by 26 if I dynamically produced the upper case parts, so:
# 145*36 = 5220
print'Elizabeth obnoxiously quoted (just too rowdy for my peace): '+'"the quick brown fox jumps over the lazy dog,"'.upper()+' giving me a look.'
I think Python will not get much better than 5220. The task of minimising the unique characters in Python sure was instructive though.
Update: mbomb007 has a better Python solution scoring 5005. Nice work.
I'm assuming casing has to be exact? – EnragedTanker – 2015-03-04T16:43:31.537
@crayzeedude yes, that's sort of the point – durron597 – 2015-03-04T16:47:43.647
Alright. Just clarifying. :p – EnragedTanker – 2015-03-04T16:48:10.843
With JSfuck the score is near 200K * 6. I'll try something else – edc65 – 2015-03-05T08:28:39.940
I suspect we would see some very creative solutions from the non-golfing languages if the score was changed to reward small unique counts (such as
sqrt(bytecount)+uniquecount^2
). The golfing languages would still win but some of the techniques I explored in my answer would beat the simple 'print the text' solution. – Logic Knight – 2015-03-06T00:56:15.0371@CarpetPython There was some debate about this in the sandbox, and ultimately I decided there was no way to TRULY level the playing field. Notice that whitespace and insomnia have the highest scores anyway! – durron597 – 2015-03-06T06:14:48.107
2As I wrote somewhere, if we assume that using more bytes to compensate for less unique characters behaves similarly to converting numbers into different bases, then approximately
bytecount~Log(X,unique)
, with X some constant for this problem. Thus unique^bytecount ~ constant. Computing this score (log2) givespython2_mbomb007 728, python2_carpetpython 744, ruby 756, Fish 825, Insomnia 1148, cjam 1277, whitespace 1484, brainfuck 3546
. So except for the brainfuck answer, it is relatively constant... – blutorange – 2015-03-06T11:23:57.297Also, applying zlib::deflate on the string would give a score of Log(95unique ^ 123bytes,2)+1 = 809. – blutorange – 2015-03-06T11:30:28.483
Related: Print a string in as few distinct characters as possible
– sergiol – 2018-04-30T00:26:52.943