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.
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)
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 | ? |
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 | ? |
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 | ? |
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 | ? |
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 | ? |
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 | ? |
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 | ? |
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 | ? |
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 | ? |
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 | ? |
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 | ? |
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 | ? |