Take the 2-minute tour ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

Input: an integer N between 1 and 151

Output: the Nth Pokemon.

Rules

  • You may use one data file.

  • You may not use any already made data decompression algorithms. This includes libraries and other programs.

  • Your program may not access files other than itself and your data file.

Scoring

Your score is the sum of the length of your code and data file.

Helpful Stuff

Here's a list of the first 151 pokemon to help you generate your data file. Your output should exactly match the Nth line of this file.

Here's an example solution in Python with score 176 + 901 = 1077 (not very good, but at least shorter than the entire list of pokemon which is 1258 characters)

s=open('a','rb').read()
z='\n \'().ABCDEFGHIJKLMNOPRSTVWZabcdefghiklmnopqrstuvwxyz'
i=0
for c in s:i=i*256+ord(c)
s=''
while i>0:s+=z[i%53];i/=53
print s.split('\n')[input()-1]

With this data file called a

Basically all it does is remove unused characters, so there are definitely better compression methods.

Example session:

>echo 12 | python pokemon.py
Butterfree
share|improve this question

5 Answers 5

up vote 6 down vote accepted

J (93 + 787 = 880)

Edit: other capitalisation method that capitalizes 'Mr. Mime' correctly.

Can probably be shortened, I've almost never written J before. It works on a similar principle as the PHP example.

You need the 'p' file in the same directory as you run this, the file can be downloaded from: http://frankenstein.d-n-s.org.uk/p. It is 787 bytes.

u:p-32*96<p*|.!.1[32=p=.(}.p#~(".1!:1[1)=+/\31=p=.#._5>\,#:a.i.1!:1<'p'){(97+i.26),a.i.'.()'' '

The file is encoded in a five-bit format, as follows:

0-25: A-Z
26: .
27: (
28: )
29: '
30: <space>
31: separator

The file also starts with a separator, to make the list 1-based.

The J code works as follows:

  • (97+i.26),a.i.'.()'' ': a string where the index N is the ASCII character
  • {: select from this list the values generated by the expression below
  • 1!:1<'p': read the 'p' file
  • ,#:a.i.: get the file as bits
  • _5>\: group the bits in groups of five
  • p=.#.: transform each group of bits into a number and assign to p
  • +/\31=p: a list of the size of p where each value N means the value at that position in p belongs to the N-th pokemon.
  • (".1!:1[1)=: read a number from the keyboard and see where in p the characters for that pokemon are.
  • }.p#~: look them up in p, and remove the first item (which is the separator).
  • p-32*96<p*_1|.(!.1)32=p=.: Assign the output to p again, and subtract 32 from p where p is bigger than 96 and to the right of a space. Which is cumbersome. According to the J documentation there should be a capitalize function but it's not there on my system.
  • u:: look them up as unicode.
share|improve this answer
    
I'm getting Ulbasaur for the first pokemon. Am I running it correctly? I've never used J before. Also, Mr. Mime should be capitalized. –  cardboard_box Dec 4 '12 at 20:28
    
@cardboard_box: I've changed the capitalisation method so that Mr. Mime works (at the cost of 9 characters). The Ulbasaur was a typo in the data file, that has also been fixed. –  marinus Dec 4 '12 at 21:46

Bash 1182 chars

read n;echo {Bulba,Ivy,Venu}saur Char{mander,meleon,izard} {Squi,Warto}rtle Blastoise Caterpie Metapod Butterfree Weedle Kakuna Beedrill Pidge{y,otto,ot} Rat{tata,icate} {Sp,F}earow Ekans Arbok {Pika,Rai}chu Sands{hrew,lash} Nido{ran%\(f\),rina,queen,ran%\(m\),rino,king} Clefa{iry,ble} Vulpix Ninetales {Jigglyp,Wigglyt}uff {Zu,Gol}bat Oddish Gloom Vileplume Paras{,ect} Veno{nat,moth} Diglett Dugtrio Meowth Persian {Psy,Gol}duck Mankey Primeape Growlith Arcanine Poliw{ag,hirl,rath} {A,Kada}bra Alakazam Mach{op,oke,amp} Bellsprout {Weepin,Victree}bell Tentac{ool,ruel} Geodude Graveler Golem Ponyta Rapidash Slow{poke,bro} Magne{mite,ton} Farfetch\'d Dod{uo,rio} Seel Dewgong Grimer Muk {Shelld,Cloyst}er Gastly Haunter Gengar Onix Drowsee Hypno Krabby Kingler Voltorb Electrode Exeggut{e,or} Cubone Marowak Hitmon{lee,chan} Lickitung {Koff,Weez}ing Rhy{horn,don} Chansey Tangela Kangaskhan Horsea Seadra Goldeen Seaking Star{yu,mie} Mr.%Mime Scyther Jynx Electabuzz Magmar Pinsir Tauros Magikarp Gyarados Lapras Ditto Eevee {Vapore,Jolte,Flare,Poryg}on Oma{nyte,star} Kabuto{,ps} Aerodactyl Snorlax Articuno Zapdos Moltres Dra{tini,gon{air,ite}} Mew{two,}|tr %\  \ \\n|sed $n!d
share|improve this answer
2  
That is a really cool idea. –  MrZander Nov 21 '12 at 18:32

PHP 919 (925) bytes

As with Peter Taylor's answer, I also cannot post my solution directly, so instead i'll post a program that generates it:

<?php
$data = <<<EOD
PD9mb3IoJG89J5SWUHYPaY6dSs/pjsJBMS1pRDc1yZ3AUcQkNcnZsYIkJDXtpa4UB4mOMNH8zbDbcDhcKD
VYu89cFyjRlBm8GSjMiFSxCNHitpn8Kdi43B+XUkX2gVjN8LQEmEkF5D2zE9gbTD3z6djUJQAVFXwlXV/o
kVwnsV1rW5J9zpssN3JXdW5LjAS3DYTcBtV/YUdtoAfGC+ztsoc1LxQamD5lmQMaes37flJcGvg7CdkS+s
1bhZLjAQQtmL5tS3rN+2eS7LeROnX9nOCRRWhRQhFkBDSN0igwMUwem4BNYVrkxZuAzUEiRDG+KFODVqV0
KDAvpLM747wC0AwYUVkELsVsBA5vyThUQQtiKFRBK6EYnBC7oMiAkJtYbXOZk9scdPF3hTJEh7hhZ4yDEG
FHzJ1vSfxkDVkd8fz+u6ConHVH7Y3SHFtgq20M22ALpO40xMC9vmictX6lf+2VfqV1EBctRRwZ38RceT3E
G2l5PcTVTFahWEdGGYhjKSwy5lBYAn944VmhWNQRkvXDw5SAkpV/URm0SZPBOPweZUGwDlODERHEwt0VfK
X9WG+kp9tbe+d8oLvu1uw9+6ExyFwZe6LogoTF7oG3RCiUm0GTcJsmcyxJmdRR68Oi7P4NmQ6ZlwxE8djR
DtfANTjRZBOvWE281RLRDtPJY05E4k10BkvfCRwNLKssXh4GHB+SgBFEwsDbHsSxMdhmCBExsfvZKLzEEY
uZ26SXfutBOR1rezc8/XmT6HkcHciTBwTSxD1cJ+XBcmyjis2S7ClZLZJMTG2bngTs7VtCN3VSaQUAcuPQ
VR9yY0+ntSTcnhcdZ4n4JtzDwPHZJEl9pZJsONV96ad1jpV5eVhpldF8r7WcMeRd8hSxMXjVEcZEPZsdLg
SSd+4kNY7L7Bkbdy10VDVuJdtfGOyG7yydwJux2SFcAiz7QSIEa8BxAoQIFUFCRJt+G6KkoZ3d8fzBPZhO
xG2eaIwfvrGb54zZ7mgfGPA0Qp6I5NSund9SSw5MUD8M0wAmzywmSF2N/CZbw8V1JEZF42LIXJmLeIM5uU
wnOzc4OD4kbjspJGY9c3BsaXQonywkeC49Y2hyKDMxJiR2PSsrJGklOCUzPzgqJHZeb3JkKCRvWyRuKytd
KTokdj4+NSleiyk7ZWNob35zdHJ0cigkZlsrZmdldHMoU1RESU4pXXygLICEgYOCLNfY1tHfKTsNCg==
EOD;
print base64_decode($data);
?>

Sample I/O:

$ php generator.php > out.php

$ echo 12 | php out.php
Butterfree

$ echo 32 | php out.php
Nidoran (m)

$ echo 83 | php out.php
Farfetch'd

$ echo 122 | php out.php
Mr. mime

$ echo 151 | php out.php
Mew

How it works (spoiler):

This code operates on the observation that there are only 32 unique characters, including a separator - if you're not counting capitals. This immediately implies a 5:8 encoding; only 5 bits are needed to represent each byte.

I accomplish this in the following manner:

++$i%8%3

When this value is non-zero, a new byte is read, and when zero, the next byte is generated from the previously read bytes. The 3rd, 6th, and 8th byte are generated in this manner, and then the process repeats.

The bit distribution follows accordingly. If for example you wanted to produce the string:

abcdefgh

The bits for each are distributed among the 5 source bytes in the following fashion:

hccaaaaa|cccbbbbb|hffddddd|fffeeeee|hhhggggg

After generating c, only the top most bit of h remains, after generating f, the top two bits of h remain, and after reading g, h remains in its entirety (I save a few shift operations by using xored values instead, for example the value I load for the second byte is the value I want xor a<<3, but that's the gist of it).

This produces characters on the range of [0,31]. By xoring by any character on the range [96,127], all characters will be mapped to that range (I chose 116, because it resulted in the least amount of escape sequences). After that, it's a simple matter of translating the 5 characters that don't belong there with their appropriate replacements, and capitalizing the first letter. This code requires three bytes to do so: oring the (previously generated as such) bit inverted string with char 160, and then bit inverting back. A small caveat: the second m in 'Mr. mime' is not capitalized by this method. This could be repaired by replacing the method described above with the ucwords() function, at the cost of 6 bytes, resulting in a code length of 925, instead of 919.

share|improve this answer

GolfScript (1040 bytes)

Unfortunately I can't directly post the program, so I'll provide a link and the base64-encoded text:

fignACc1Nix7XFsxJF0nJysvXCdCdWxiNzYKSXZ5czY0dXM2CjJtMWQvMm0tZSsyaXozZCpxdSZ0
bCVXMyRydGwlQmw3JGlzJUMjMHBpImUhcB8KQnV0dDBmcmUlHmRsJUtha3VuYQpCZWVkHWxsG3kb
b3QkG290GiN0I2EaI2ljIyVTcGUzGQpGZTMZCkVrMXMYcmJvaxxpa2EXdRphaRd1KjFkc2hyZXcq
MWRzbDdoFWYpFnIUYRZxdWU1FW0pFnIUbxZrExEmeRFibCVWdWxwaXgKThRlIRJzCkoQcHVmZgpX
EHR1ZmYKWnViIw8OYiMKT2RkaXNoD2xvb20KVmkScGx1bSVQMzccMzdlY3Q0LCM0b21vdGgNaWcS
dHQNdWd0HW8MZRl0aBwwc2kxHHN5ZHVjaw8OZHVjawwxa2V5HB1tZQslR3IZbAloGHJjMRQlUAhh
ZxwIaCZsHAgHdGgYYgcGYWRhYgcYbGFrYXphbQUXb3AFF29rImEXYW1wCkItbHNwcm91dAoecBRi
LWwKVmljdHJlZWItbARvDgRydS0PZR91ZCVHB3YtL0cOZW0cLHkhGgtpZDdoKmwZcG9rJVNsGWJy
bwVnbmVtCSJhZ25ldCtGM2ZldBdcJ2QNH3VvDR8dbyplLQ1ld2csZw8dbS9NdWsqaC1sZC9DbG95
c3QvRzd0bHkKSGF1bnQvRzVnMwpPbml4DXIZc2UlSHlwbm8GB2JieQYTbC9WDiRyYgpFEmN0ch8D
dAMkcgpDdWIsIjMZYWsKSAltLBIlSAltLBcxCkxpY2sJdW5nBm9mZhMKHnoTGmh5aAJuGmh5ZCtD
aDFzZXkKVDFnLWEGMWc3a2gxCkgCc2VhKmVhZAcPDmRlNSplYWsTKnQzeXUqdDNtaSJyLiBNaW0l
U2N5dGgvSnlueApFEmMhYnV6egVnbTMcFHMmClQ2b3MFZ2lrM3APeTNhZG9zCkwLB3MNCSQKRWV2
ZSVWCwJlK0oOdGUrRmwzZSwcAnlnK09tMXl0JU9tN3QzAQFwcxgwH2FjdHlsKm4CbGF4GHJ0aWN1
bm8KWgtkb3MMDnRyZXMNB3QUaQ0HZyxhJg0HZywJImV3dHdvDGV3AAZhYnUkAG9yACVFeGVnZ3UA
ClQ1IWMADGEACksAcmEADml3AGl0AAoAYXAACk0ACkQAb2wACkcAaWdnbHkACkMSZmEAbGUAFGcA
aW4AFnIxICgACk5pZG8AY2gACkEAb3cAClIAHGlkZ2UAClAAcmkAV2VlAG9kACAAdGEAJU0AYXQA
dG8AZQoAaXIAXCcAKAApAApTACwKAG9uAGVsAC4AMAoAZXIAYW4AQ2gzAGFyAApWNQBlbgBhdXIA
YXMnJwAnLz0qfS9uLz0=

It uses a grammar-based approach with rules separated by NUL characters and a simple expansion approach, followed by splitting on newlines and selecting the desired line. Input is via stdin. No external file is used.

In more detail

I have written a Java program which applies several grammar-generating strategies and two grammar-to-GolfScript generation strategies and outputs a lot of GS programs to reconstruct a string. In this particular case the winning combination was a greedy grammar builder with a threshold of 2, and the remap engine. The greedy grammar builder starts with a grammar

<0> ::= "Bulbasaur\nIvysaur\nVenusaur\n..."

and repeatedly looks for the repeated sequence of terminals and non-terminals in the right hand sides which, when pulled out into a rule defining a new non-terminal, produces the greatest decrease in the total number of terminals and non-terminals in the grammar. The threshold is the cutoff point at which the decrease is considered no longer worth it.

The non-terminals are topologically sorted and then numbered from 0 up. If they overlap any character values which are also terminals, the remap engine creates a new rule mapping to that terminal. (E.g. if there are rules 0 to 37 and the space character occurs, it will map 38 to the space character and then update the RHS of all rules to use 38 instead of 32). The right hand sides of the rules are then concatenated, separated by NULs, and a small piece of hand-written GolfScript to expand the grammar is appended.

share|improve this answer
2  
+1 Would you say a bit more about your approach? –  David Carraher Nov 21 '12 at 23:55

k (750+24 = 774)

Doesn't use any built-in decompression however it does use a system call to acquire the data.

{@[."\\gzip -dc x";x-1]}

The data file is 750 bytes and is just the gzipped raw list, named x. There are 24 characters in the above function.

share|improve this answer
2  
-1 for not only being an unfun rules lawyer but not even doing it properly. (I can get 732+15 using this cheat in bash). –  Peter Taylor Nov 20 '12 at 22:56
    
Updated the rules to not allow pre-made decompression algorithms, regardless of whether or not they are built-in. –  cardboard_box Nov 21 '12 at 0:36

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.