Input: an integer N between 1 and 151

Output: the Nth Pokemon.


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


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 separated by semicolons to help you generate your data file. Your output should exactly match the Nth entry of this line:

Bulbasaur;Ivysaur;Venusaur;Charmander;Charmeleon;Charizard;Squirtle;Wartortle;Blastoise;Caterpie;Metapod;Butterfree;Weedle;Kakuna;Beedrill;Pidgey;Pidgeotto;Pidgeot;Rattata;Raticate;Spearow;Fearow;Ekans;Arbok;Pikachu;Raichu;Sandshrew;Sandslash;Nidoran (f);Nidorina;Nidoqueen;Nidoran (m);Nidorino;Nidoking;Clefairy;Clefable;Vulpix;Ninetales;Jigglypuff;Wigglytuff;Zubat;Golbat;Oddish;Gloom;Vileplume;Paras;Parasect;Venonat;Venomoth;Diglett;Dugtrio;Meowth;Persian;Psyduck;Golduck;Mankey;Primeape;Growlith;Arcanine;Poliwag;Poliwhirl;Poliwrath;Abra;Kadabra;Alakazam;Machop;Machoke;Machamp;Bellsprout;Weepinbell;Victreebell;Tentacool;Tentacruel;Geodude;Graveler;Golem;Ponyta;Rapidash;Slowpoke;Slowbro;Magnemite;Magneton;Farfetch'd;Doduo;Dodrio;Seel;Dewgong;Grimer;Muk;Shellder;Cloyster;Gastly;Haunter;Gengar;Onix;Drowsee;Hypno;Krabby;Kingler;Voltorb;Electrode;Exeggute;Exeggutor;Cubone;Marowak;Hitmonlee;Hitmonchan;Lickitung;Koffing;Weezing;Rhyhorn;Rhydon;Chansey;Tangela;Kangaskhan;Horsea;Seadra;Goldeen;Seaking;Staryu;Starmie;Mr. Mime;Scyther;Jynx;Electabuzz;Magmar;Pinsir;Tauros;Magikarp;Gyarados;Lapras;Ditto;Eevee;Vaporeon;Jolteon;Flareon;Porygon;Omanyte;Omastar;Kabuto;Kabutops;Aerodactyl;Snorlax;Articuno;Zapdos;Moltres;Dratini;Dragonair;Dragonite;Mewtwo;Mew
  • \$\begingroup\$ Is Bubblegum allowed? \$\endgroup\$ – PyRulez Oct 28 '17 at 20:41
  • \$\begingroup\$ @PyRulez Yes, so long as you don't use any of its built-in data decompression. So good luck breaking SHA256. \$\endgroup\$ – cardboard_box Oct 29 '17 at 0:26
  • \$\begingroup\$ If our language has a builtin for returning the list of pokemon, can we use it without a byte addition? \$\endgroup\$ – caird coinheringaahing Oct 30 '17 at 19:20
  • \$\begingroup\$ @cairdcoinheringaahing If you're talking about pyke's builtin, I feel that goes against the spirit of the challenge, however I guess it would be non-competing anyway. \$\endgroup\$ – FlipTack Oct 30 '17 at 19:57

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.
  • 1
    \$\begingroup\$ 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. \$\endgroup\$ – cardboard_box Dec 4 '12 at 20:28
  • \$\begingroup\$ @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. \$\endgroup\$ – marinus Dec 4 '12 at 21:46
  • \$\begingroup\$ It looks like the link is dead. \$\endgroup\$ – Erik the Outgolfer May 30 '18 at 14:16

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
  • 2
    \$\begingroup\$ That is a really cool idea. \$\endgroup\$ – 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:

$data = <<<EOD
print base64_decode($data);

Sample I/O:

$ php generator.php > out.php

$ echo 12 | php out.php

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

$ echo 83 | php out.php

$ echo 122 | php out.php
Mr. mime

$ echo 151 | php out.php

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:


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:


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


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.


GolfScript (1040 bytes)

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


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.

  • 2
    \$\begingroup\$ +1 Would you say a bit more about your approach? \$\endgroup\$ – DavidC Nov 21 '12 at 23:55

q/kdb, 789+77 = 866 bytes


/ encoding pokemon.txt into 'q' text file (not added to byte count, not golfed)
`:q 0:enlist "c"$2 sv'8 cut (raze 3_'0b vs'4h$(asc distinct p)?p:lower first read0`:pokemon.txt),000000b

/ checking length of q file (note: file is written with trailing newline \r\n, so could/should be 787 bytes)
hcount `:q

/ decoding q and look-up of value
@[;0;upper](";"vs(" '().;",.Q.a)2 sv'5 cut -6_(,/)0b vs'4h$"\n"sv(0:)`:q)@-1+


q)@[;0;upper](";"vs(" '().;",.Q.a)2 sv'5 cut -6_(,/)0b vs'4h$"\n"sv(0:)`:q)@-1+45
q)@[;0;upper](";"vs(" '().;",.Q.a)2 sv'5 cut -6_(,/)0b vs'4h$"\n"sv(0:)`:q)@-1+151
q)@[;0;upper](";"vs(" '().;",.Q.a)2 sv'5 cut -6_(,/)0b vs'4h$"\n"sv(0:)`:q)@-1+1


The strategy (like other solutions) is to encode each 8 bit character in 5 bits, this is done by creating a smaller alphabet of 32 characters, finding the indices of each letter in the input list (0..31) and then encoding these as 5-bit numbers (which need to be joined and converted to 8-bit chars to be written down in Q).

The decoding is just doing the opposite of this, the alphabet is known to be " '().;abcdefghijklmnopqrstuvwxyz", so split the input into batches of 5 bits and convert back into integers, index into the alphabet. Split this on ; and then index into it with user input (subtract 1 due to 0-indexing), and (re)capitalise the first letter.

@[;0;upper] (";" vs " '().;abcdefghijklmnopqrstuvwxyz"2 sv'5 cut -6_raze 0b vs'4h$ "\n" sv read0 `:q)@-1+ / ungolfed decoder
                                                                                                      -1+ / same as doing 'x-1', subtract 1 from input
                                                                                                     @    / index in to item on the left
            (                                                                                       )     / do all this together
                                                                                           read0 `:q      / read text file 'q'
                                                                                   "\n" sv                / join back newlines (as q breaks text files on newlines)
                                                                               4h$                        / cast char array to bytes
                                                                         0b vs'                           / convert each byte to binary (boolean list)
                                                                    raze                                  / flatten list
                                                                 -6_                                      / drop the 6 padding bits added to align 5/8-bits
                                                           5 cut                                          / chop into lists of 5-bit lengths
                                                      2 sv'                                               / convert each boolean list back to an integer
                    " '().;abcdefghijklmnopqrstuvwxyz"                                                    / index into our lookup table at each index
             ";" vs                                                                                       / break this string up at semicolons
 @[;0;upper]                                                                                              / apply 'upper' to each first character in the result


An extra 13 bytes (879) if we need to capitalise the second M of Mr. Mime:

{@[x;0,1+x ss" ";upper]}(";"vs(" '().;",.Q.a)2 sv'5 cut -6_(,/)0b vs'4h$"\n"sv(0:)`:q)@-1+

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.