Ruby Quiz

Ruby Quiz - Challenge #8 - Base32 Alphabet - Convert the Super “Sekretoooo” 256-Bit CryptoKitties Genome to Kai Notation - Annipurrsary!

Annipurrsary! Let’s celebrate one year of CryptoKitties - yes, more than one million cute little cartoon cats on the blockchain.

Let’s convert the super “sekretoooo” kitty genome - that is, a 256-bit integer number where every 5-bit block is a gene - into the base32 (2^5=32) kai notation.

Q: What’s base32 kai notation?

Kai notation (named to honor Kai Turner who deciphered the kitties genome) is a base58 variant / subset for decoding the 256-bit integer into 5-bit blocks. Each 5-bit block is a gene with 32 possible traits. The 256-bit genome breaks down into 12 groups of 4 (x 5-bit) genes (that is, 12 x 4 x 5-bit = 240 bits) with the remaining leading 16 bits “unused” and zeroed-out (e.g. 0x0000). Example:

Kai Binary Num Kai Binary Num Kai Binary Num Kai Binary Num
1 00000 0 9 01000 8 h 10000 16 q 11000 24
2 00001 1 a 01001 9 i 10001 17 r 11001 25
3 00010 2 b 01010 10 j 10010 18 s 11010 26
4 00011 3 c 01011 11 k 10011 19 t 11011 27
5 00100 4 d 01100 12 m 10100 20 u 11100 28
6 00101 5 e 01101 13 n 10101 21 v 11101 29
7 00110 6 f 01110 14 o 10110 22 w 11110 30
8 00111 7 g 01111 15 p 10111 23 x 11111 31

Note: The digit-0 and the letter-l are NOT used in kai.

Base58 is a group of binary-to-text encoding schemes used to represent large integers as alphanumeric text. It is similar to Base64 but has been modified to avoid both non-alphanumeric characters and letters which might look ambiguous when printed [e.g. 1 and l, 0 and o]. It is therefore designed for human users who manually enter the data, copying from some visual source, but also allows easy copy and paste because a double-click will usually select the whole string.

– Base58 @ Wikipedia

Let’s get coding, for an example:


# A 256-bit super "sekretoooo" integer genome

# hexadecimal (base 16)
genome = 0x00004a52931ce4085c14bdce014a0318846a0c808c60294a6314a34a1295b9ce
# decimal (base 10)
genome = 512955438081049600613224346938352058409509756310147795204209859701881294
# binary (base 2)
genome = 0b010010100101001010010011000111001110010000001000010111000001010010111101110011100000000101001010000000110001100010000100\
           011010100000110010000000100011000110000000101001010010100110001100010100101000110100101000010010100101011011100111001110

Let’s convert from decimal (base 10) to hexadecimal (base 16 - 2^4) and binary (base 2 that is, 0 and 1):

p genome    # printed as decimal (base 10) by default
# => 512955438081049600613224346938352058409509756310147795204209859701881294

p genome.to_s(16)
# => "4a52931ce4085c14bdce014a0318846a0c808c60294a6314a34a1295b9ce"

p genome.to_s(2)
# => "10010100101001010010011000111001110010000001000010111000001010010111101110011100000000101001010000000110001100010000100\
#     011010100000110010000000100011000110000000101001010010100110001100010100101000110100101000010010100101011011100111001110"

And finally:

kai = kai_encode( genome )   ## number to base32 kai notation
p kai
# => "aaaa788522f2agff16617755e979244166677664a9aacfff"

The challenge: Code a kai_encode method that passes the RubyQuizTest :-).

def kai_encode( num )
  # ...
end

For the starter level 1 turn super “sekretoooo” kitty genome 256-bit integer numbers into base 32 (2^5) kai notation.

For the bonus level 2 pretty print and format the base 32 (2^5) kai notation in groups of four e.g. turn:

"aaaa788522f2agff16617755e979244166677664a9aacfff"

into

"aaaa 7885 22f2 agff 1661 7755 e979 2441 6667 7664 a9aa cfff"
def kai_fmt( kai )
  # ...
end

Start from scratch or, yes, use any library / gem you can find.

To qualify for solving the code challenge / puzzle you must pass the test:

require 'minitest/autorun'

class RubyQuizTest < MiniTest::Test

  ################################
  # test data
  def genomes
   [
[0x00005ad2b318e6724ce4b9290146531884721ad18c63298a5308a55ad6b6b58d,
"ccac 7787 fa7f afaa 1646 7755 f9ee 4444 6766 7366 cccc eede"], ## kitty #1
[0x00004ad083188630c264a1280146021884618c818c6331ca728c425ad6b5b18e,
"ac99 7757 7427 a9a9 1641 5755 d779 4444 7868 6433 cccc cddf"], ## kitty #100
[0x00004a52931ce4085c14bdce014a0318846a0c808c60294a6314a34a1295b9ce,
"aaaa 7885 22f2 agff 1661 7755 e979 2441 6667 7664 a9aa cfff"], ## kitty #1001
[0x000042d28390864842e7b9c900c6321086438c6098ca298c728867425cf6b1ac,
"9ca9 8557 a22f gffa 1444 5557 9f77 277b 6778 6348 9afg eded"], ## kitty #1111
[0x00007918c42de87a96b49c8712d687bc6310cc223d6c081ee6a1ac50d8c3184f,
"g5dd 9cg9 gbcc a858 3cc9 gg44 3473 5gcd 21gf e9ed b4dd 773g"], ## kitty #1000001 
   ]
  end

  #############
  # tests
  def test_kai_encode
    genomes.each do |pair|
      num       = pair[0]
      exp_value = pair[1].gsub(' ','')   # note: remove spaces

      assert_equal exp_value, kai_encode( num )
    end
  end # method test_kai_encode

  def test_kai_fmt
    genomes.each do |pair|
      kai       = pair[1].gsub(' ','') # remove spaces
      exp_value = pair[1]

      assert_equal exp_value, kai_fmt( kai )
    end
  end # method test_kai_fmt

end # class RubyQuizTest

Post your code snippets on the “official” Ruby Quiz Channel, that is, the ruby-talk mailing list.

Happy data wrangling and genome genetics bits & bytes slicing with Ruby.

PS: Using a genes / traits chart you can now decipher the genome:

Fur (0-3) • Pattern (4-7) • Eye Color (8-11) • Eye Shape (12-15) • Base Color (16-19) • Highlight Color (20-23) • Accent Color (24-27) • Wild (28-31) • Mouth (32-35) • Environment (36-39) • Secret Y Gene (40-43) • Purrstige (44-47)

Fur (FU) - Genes 0-3

Kai Code Cattribute Kai Code Cattribute
1 FU00 savannah h FU16 norwegianforest I
2 FU01 selkirk i FU17 mekong I
3 FU02 chantilly j FU18 highlander I
4 FU03 birman k FU19 balinese I
5 FU04 koladiviya m FU20 lynx I
6 FU05 bobtail n FU21 mainecoon I
7 FU06 manul o FU22 laperm I
8 FU07 pixiebob p FU23 persian I
9 FU08 siberian q FU24 fox II
a FU09 cymric r FU25 kurilian II
b FU10 chartreux s FU26 toyger II
c FU11 himalayan t FU27 manx II
d FU12 munchkin u FU28 lykoi III
e FU13 sphynx v FU29 burmilla III
f FU14 ragamuffin w FU30 liger IIII
g FU15 ragdoll x FU31 ?

Pattern (PA) - Genes 4-7

Kai Code Cattribute Kai Code Cattribute
1 PA00 vigilante h PA16 splat I
2 PA01 tiger i PA17 thunderstruck I
3 PA02 rascal j PA18 dippedcone I
4 PA03 ganado k PA19 highsociety I
5 PA04 leopard m PA20 tigerpunk I
6 PA05 camo n PA21 henna I
7 PA06 rorschach o PA22 arcreactor I
8 PA07 spangled p PA23 totesbasic I
9 PA08 calicool q PA24 scorpius II
a PA09 luckystripe r PA25 razzledazzle II
b PA10 amur s PA26 hotrod II
c PA11 jaguar t PA27 allyouneed II
d PA12 spock u PA28 avatar III
e PA13 mittens v PA29 gyre III
f PA14 totesbasic w PA30 moonrise IIII
g PA15 totesbasic x PA31 ?

Eye Color (EC) - Genes 8-11

Kai Code Cattribute Kai Code Cattribute
1 EC00 thundergrey h EC16 pumpkin I
2 EC01 gold i EC17 limegreen I
3 EC02 topaz j EC18 bridesmaid I
4 EC03 mintgreen k EC19 bubblegum I
5 EC04 isotope m EC20 twilightsparkle I
6 EC05 sizzurp n EC21 palejade I
7 EC06 chestnut o EC22 pinefresh I
8 EC07 strawberry p EC23 eclipse I
9 EC08 sapphire q EC24 babypuke II
a EC09 forgetmenot r EC25 downbythebay II
b EC10 dahlia s EC26 autumnmoon II
c EC11 coralsunrise t EC27 oasis II
d EC12 olive u EC28 gemini III
e EC13 doridnudibranch v EC29 dioscuri III
f EC14 parakeet w EC30 kaleidoscope IIII
g EC15 cyan x EC31 ?

Eye Shape (ES) - Genes 12-15

Kai Code Cattribute Kai Code Cattribute
1 ES00 swarley h ES16 chameleon I
2 ES01 wonky i ES17 alien I
3 ES02 serpent j ES18 fabulous I
4 ES03 googly k ES19 raisedbrow I
5 ES04 otaku m ES20 tendertears I
6 ES05 simple n ES21 hacker I
7 ES06 crazy o ES22 sass I
8 ES07 thicccbrowz p ES23 sweetmeloncakes I
9 ES08 caffeine q ES24 oceanid II
a ES09 wowza r ES25 wingtips II
b ES10 baddate s ES26 firedup II
c ES11 asif t ES27 buzzed II
d ES12 chronic u ES28 bornwithit III
e ES13 slyboots v ES29 candyshoppe III
f ES14 wiley w ES30 drama IIII
g ES15 stunned x ES31 ?

Base Color (BC) - Genes 16-19

Kai Code Cattribute Kai Code Cattribute
1 BC00 shadowgrey h BC16 cloudwhite I
2 BC01 salmon i BC17 cornflower I
3 BC02 meowgarine j BC18 oldlace I
4 BC03 orangesoda k BC19 koala I
5 BC04 cottoncandy m BC20 lavender I
6 BC05 mauveover n BC21 glacier I
7 BC06 aquamarine o BC22 redvelvet I
8 BC07 nachocheez p BC23 verdigris I
9 BC08 harbourfog q BC24 icicle II
a BC09 cinderella r BC25 onyx II
b BC10 greymatter s BC26 hyacinth II
c BC11 tundra t BC27 martian II
d BC12 brownies u BC28 hotcocoa III
e BC13 dragonfruit v BC29 shamrock III
f BC14 hintomint w BC30 firstblush IIII
g BC15 bananacream x BC31 ?

Highlight Color (HC) - Genes 20-23

Kai Code Cattribute Kai Code Cattribute
1 HC00 cyborg h HC16 ooze I
2 HC01 springcrocus i HC17 safetyvest I
3 HC02 egyptiankohl j HC18 turtleback I
4 HC03 poisonberry k HC19 rosequartz I
5 HC04 lilac m HC20 wolfgrey I
6 HC05 apricot n HC21 cerulian I
7 HC06 royalpurple o HC22 skyblue I
8 HC07 padparadscha p HC23 garnet I
9 HC08 swampgreen q HC24 peppermint II
a HC09 violet r HC25 universe II
b HC10 scarlet s HC26 royalblue II
c HC11 barkbrown t HC27 mertail II
d HC12 coffee u HC28 inflatablepool III
e HC13 lemonade v HC29 pearl III
f HC14 chocolate w HC30 prairierose IIII
g HC15 butterscotch x HC31 ?

Accent Color (AC) - Genes 24-27

Kai Code Cattribute Kai Code Cattribute
1 AC00 belleblue h AC16 daffodil I
2 AC01 sandalwood i AC17 flamingo I
3 AC02 peach j AC18 buttercup I
4 AC03 icy k AC19 bloodred I
5 AC04 granitegrey m AC20 atlantis I
6 AC05 cashewmilk n AC21 summerbonnet I
7 AC06 kittencream o AC22 periwinkle I
8 AC07 emeraldgreen p AC23 patrickstarfish I
9 AC08 kalahari q AC24 seafoam II
a AC09 shale r AC25 cobalt II
b AC10 purplehaze s AC26 mallowflower II
c AC11 hanauma t AC27 mintmacaron II
d AC12 azaleablush u AC28 sully III
e AC13 missmuffett v AC29 fallspice III
f AC14 morningglory w AC30 dreamboat IIII
g AC15 frosting x AC31 ?

Wild (WE) - Genes 28-31

Kai Code Cattribute Kai Code Cattribute
1 WE00 ? h WE16 littlefoot I
2 WE01 ? i WE17 elk I
3 WE02 ? j WE18 ducky I
4 WE03 ? k WE19 trioculus I
5 WE04 ? m WE20 daemonwings I
6 WE05 ? n WE21 featherbrain I
7 WE06 ? o WE22 flapflap I
8 WE07 ? p WE23 daemonhorns I
9 WE08 ? q WE24 dragontail II
a WE09 ? r WE25 aflutter II
b WE10 ? s WE26 foghornpawhorn II
c WE11 ? t WE27 unicorn II
d WE12 ? u WE28 dragonwings III
e WE13 ? v WE29 alicorn III
f WE14 ? w WE30 wyrm IIII
g WE15 ? x WE31 ?

Mouth (MO) - Genes 32-35

Kai Code Cattribute Kai Code Cattribute
1 MO00 whixtensions h MO16 cheeky I
2 MO01 wasntme i MO17 starstruck I
3 MO02 wuvme j MO18 samwise I
4 MO03 gerbil k MO19 ruhroh I
5 MO04 confuzzled m MO20 dali I
6 MO05 impish n MO21 grimace I
7 MO06 belch o MO22 majestic I
8 MO07 rollercoaster p MO23 tongue I
9 MO08 beard q MO24 yokel II
a MO09 pouty r MO25 topoftheworld II
b MO10 saycheese s MO26 neckbeard II
c MO11 grim t MO27 satiated II
d MO12 fangtastic u MO28 walrus III
e MO13 moue v MO29 struck III
f MO14 happygokitty w MO30 delite IIII
g MO15 soserious x MO31 ?

Environment (EN) - Genes 36-39

Kai Code Cattribute Kai Code Cattribute
1 EN00 ? h EN16 salty I
2 EN01 ? i EN17 dune I
3 EN02 ? j EN18 juju I
4 EN03 ? k EN19 tinybox I
5 EN04 ? m EN20 myparade I
6 EN05 ? n EN21 finalfrontier I
7 EN06 ? o EN22 metime I
8 EN07 ? p EN23 drift I
9 EN08 ? q EN24 secretgarden II
a EN09 ? r EN25 frozen II
b EN10 ? s EN26 roadtogold II
c EN11 ? t EN27 jacked II
d EN12 ? u EN28 floorislava III
e EN13 ? v EN29 prism III
f EN14 ? w EN30 junglebook IIII
g EN15 ? x EN31 ?

Secret Y Gene (SE) - Genes 40-43

Kai Code Cattribute Kai Code Cattribute
1 SE00 ? h SE16 ?
2 SE01 ? i SE17 ?
3 SE02 ? j SE18 ?
4 SE03 ? k SE19 ?
5 SE04 ? m SE20 ?
6 SE05 ? n SE21 ?
7 SE06 ? o SE22 ?
8 SE07 ? p SE23 ?
9 SE08 ? q SE24 ?
a SE09 ? r SE25 ?
b SE10 ? s SE26 ?
c SE11 ? t SE27 ?
d SE12 ? u SE28 ?
e SE13 ? v SE29 ?
f SE14 ? w SE30 ?
g SE15 ? x SE31 ?

Purrstige (PU) - Genes 44-47

Kai Code Cattribute Kai Code Cattribute
1 PU00 ? h PU16 ?
2 PU01 ? i PU17 ?
3 PU02 ? j PU18 ?
4 PU03 ? k PU19 ?
5 PU04 ? m PU20 ?
6 PU05 ? n PU21 ?
7 PU06 ? o PU22 ?
8 PU07 ? p PU23 ?
9 PU08 ? q PU24 ?
a PU09 ? r PU25 ?
b PU10 ? s PU26 ?
c PU11 ? t PU27 ?
d PU12 ? u PU28 ?
e PU13 ? v PU29 ?
f PU14 ? w PU30 ?
g PU15 ? x PU31 ?