Identify the Eeveelutions

29

2

Gah! It's a shame that Pokémon Sword and Shield won't introduce a new eeveelution. Let's mourn them with a code golf.

The objective is to, when given a type name as the input, output the name of the corresponding eeveelution.

  • When given Water, output Vaporeon.
  • When given Electric, output Jolteon.
  • When given Fire, output Flareon.
  • When given Psychic, output Espeon.
  • When given Dark, output Umbreon.
  • When given Grass, output Leafeon.
  • When given Ice, output Glaceon.
  • When given Fairy, output Sylveon.
  • All other input falls in don't care situation.

No other rules. Enjoy!

Dannyu NDos

Posted 2019-11-07T23:49:54.087

Reputation: 2 087

7Such a shame indeed. So many good types left for the Eeveelutions, like Ghost, Poison, Flying, Dragon, Steel, etc. Instead we get an Eevee the size of a house and a hotdog-sized cat (Meowth).. >.> Btw, I assume both the input and output is case-sensitive (titlecased), but you may want to mention it explicitly just in case. – Kevin Cruijssen – 2019-11-08T08:59:04.597

Answers

4

Pyke, 29 bytes

EF 73 77 59 25 54 25 75 09 60 84 58 22 23 61 82 73 82 72 00 24 52 40 7E 5F 39 39 73 EF

Try it here!, Ungolfed with full tests

.o                                           -      map(ord, input)
  s                                          -     sum(^)
   wY%T%                                     -    (^ % 57) % 10     // wY is 57
                                   R@        -    v[^]
        u\t`\x84X"#a\x82s\x82r\x00$          -   [96, 600, 34, 35, 97, 371, 370, 0, 36]
                                     ~_99s   -  ^ + 333333 + 99
                                          .o - dictionary_lookup(^)

We start off by converting the input to a list of integers corresponding to the ascii characters and then summing them. This produces the following set of numbers for ["Water", "Electric", "Fire", "Psychic", "Dark", "Grass", "Ice", "Fairy"]: [515, 811, 390, 723, 386, 512, 273, 507]. We then perform a magic operation ((x % 57) % 10) to get the following list of offsets: [2, 3, 8, 9, 4, 6, 5, 1].

The bytes below correspond to the following compressed list: [96, 600, 34, 35, 97, 371, 370, 0, 36], and we index into it based on the offsets we had previously. There's a 0 in there due to my inability to get it not to wrap.

75 09 60 84 58 22 23 61 82 73 82 72 00 24

Try it here!

This list of numbers corresponds to the location in the Pokedex, minus 100. Pyke's dictionary handily contains the Pokedex starting from index 333333 (0 indexed). It also comes with a convenient default variable, ~_, for getting that particular number. We then add 99 to it to take an offset to Pyke's dictionary, and then use .o to look up that particular word.

Blue

Posted 2019-11-07T23:49:54.087

Reputation: 26 661

Even shorter than 05AB1E? What language is this? – Dannyu NDos – 2019-11-10T01:07:55.710

I mostly used it when I was more active a few years ago but I kind of forgot about it (last real commits 2 years ago now). It's got quite a few extremely esoteric functions, and Pokemon finding was one of them^^ Link to some info: https://codegolf.meta.stackexchange.com/a/8627/32686 Mini instructions that are poorly written: https://codegolf.meta.stackexchange.com/a/9636/32686

– Blue – 2019-11-10T01:11:53.103

15

Python 2, 77 76 bytes

lambda s:'VFULJSGEalmeoylspaballaporrftvc'[hash(s)%3695%8::8]+'reon'[s<'V':]

Try it online!

In Python 2, the hash function consistently (across runs and also on different platforms) converts any immutable value into a 64-bit integer. By taking that integer first mod 3695, then mod 8, we get an integer 0<=i<8 (3695 was found by brute force checking all possible values upto 10000).

A common trick is used to encode a list of same-size strings into a single string and then using slicing via [i::8]to extract the strings without using .split or similar strategy. Only two options are not of length 4: Esp and Vapor. The former is handled by making it the last of the 8 strings encoded; and Vapor is handled using the final slicing 'reon'[s<'V':].

Chas Brown

Posted 2019-11-07T23:49:54.087

Reputation: 8 959

How does hash work in this? – EdgyNerd – 2019-11-16T23:28:27.150

@EdgyNerd : I added a little explanation. – Chas Brown – 2019-11-17T01:07:24.553

14

Perl 6, 72 67 65 64 bytes

{<Sylv Esp Glac Jolt Leaf Umbr Flar Vapor>[:36($_)%537%8]~'eon'}

Try it online!

A golf to all unique indexes by parsing the string as base 36 and moduloing it. I've left a version that just uses the sum below so other answer that may not have the same short base converting code that Perl 6/Raku does. There is also base 35 with modulo 51 and 10, but that comes out to the same byte count.

Perl 6, 67 bytes

{<Leaf Esp Umbr Vapor 0 Sylv Flar Jolt Glac>[.ords.sum%64%9]~'eon'}

Try it online!

Differentiates between inputs by the sum of the ordinal values, modulo 64 modulo 9, leaving one extra spot to be filled in. Unfortunately, my brute force script couldn't find any pairs of moduli that led to no empty spaces, and adding a third would cost more than it gained.

Jo King

Posted 2019-11-07T23:49:54.087

Reputation: 38 234

18Ah, everyone's favourite Eeveelution: 0eon :P – caird coinheringaahing – 2019-11-08T09:39:38.443

7Brb, off to catch a Nulleon – Punintended – 2019-11-08T17:41:19.343

7

Ruby -p, 89 67 bytes

Direct port of Jo King's Perl answer. By sheer coincidence, the byte count is even the same. The byte counts are no longer the same as Jo King has switched to using a technique that cannot be tersely replicated in Ruby.

$_=%w"Leaf Esp Umbr Vapor 0 Sylv Flar Jolt Glac"[$_.sum%64%9]+'eon'

Try it online!

Original Version, Ruby -p, 89 bytes

Basic lookup checking the first letter of the input (or first 2 if the second letter is i, which is only present in Fire).

$_=%w"WVapor EJolt PEsp DUmbr GLeaf IGlac FSylv FiFlar".find{|e|e.sub!$_[/.i?/],''}+'eon'

Try it online!

Value Ink

Posted 2019-11-07T23:49:54.087

Reputation: 10 608

4

ink, 111 110 bytes

=e(t)
{
-t?"W":Vapor
-t?"E":Jolt
-t?"P":Esp
-t?"y":Sylv
-t?"D":Umbr
-t?"G":Leaf
-t?"I":Glac
-1:Flar
}<>eon->->

Try it online!

Explanation

=e(t)          // Define a stitch e which takes a parameter t
{              // An if block - finds the first condition that is true and doeses the associated thing
-t?"W":Vapor   // If "W" is a substring of our parameter, we print "Vapor"
-t?"E":Jolt    // otherwise, if "E" is a substring of our parameter, we print "Jolt"
-t?"P":Esp     // "P" is for "Psychic"
-t?"y":Sylv    // We can't check "F" for "Fairy" because that'd also match "Fire", but since we got past "Psychic", "Fairy" is the only option that contains "y"
/* et cetera */
-1:Flar        // If we get here, we check if 1 is truthy (it is) and if so, we print "Flar"
}<>eon->->     // Append "eon" to the last line printed, and return.

Sara J

Posted 2019-11-07T23:49:54.087

Reputation: 2 576

4

05AB1E, 47 40 38 bytes

.•‡ιÏSnÛ@¥I´4óȬ–[и)h‘j"õújв•#ć«™sÇ<Oè

-7 bytes by porting @JoKing's ord-sum % 64 trick.
-2 bytes thanks to @JonathanAllan by using the ord-sum - length on the input-type instead.

Try it online or verify all test cases.

Explanation:

.•‡ιÏSnÛ@¥I´4óȬ–[и)h‘j"õújв•
            "# Push compressed string "eon glac  jolt leaf umbr esp vapor sylv flar"
  #          # Split it on spaces:
             #  ["eon","glac","","jolt","leaf","umbr","esp","vapor","sylv","flar"]
   ć         # Extract head; pop and push remainder-list and the first item
    «        # Concat this first item "eon" to each string in the remainder-list
     ™       # Titlecase each Eeveelution
      sÇ     # Get the input, and convert it to a list of unicode values
        <    # Decrease each value by 1
         O   # Sum these integers
          è  # And use this to (0-based) index into the list (with automatic wrap-around)
             # (after which the result is output implicitly)

See this 05AB1E tip of mine (section How to compress strings not part of the dictionary?) to understand why .•‡ιÏSnÛ@¥I´4óȬ–[и)h‘j"õújв• is "eon glac jolt leaf umbr esp vapor sylv flar".

Kevin Cruijssen

Posted 2019-11-07T23:49:54.087

Reputation: 67 575

1Would doing sum of ordinal-values + length be shorter than modulo 64? (You'd need to change the order of your compressed list to the one in my Jelly answer - rotated to be 0-indexed) – Jonathan Allan – 2019-11-08T19:06:29.387

@JonathanAllan Thanks, that indeed saved 2 bytes (after I noticed it should be ord-values MINUS length instead of plus. ;) You've also made that same typo in your own answer. Took me a bit to notice you're decrementing by 1 instead of incrementing by 1, after I debugged your code to see why my port didn't work, haha). Thanks for the -2, though. – Kevin Cruijssen – 2019-11-08T20:50:24.430

Oops, sorry and thank you! – Jonathan Allan – 2019-11-08T21:38:28.367

3

Charcoal, 50 bytes

§⪪”↶2'⧴mB⁼“↷⁻o⊟HtωhJ№↘Tθ⁼σ4Þχ℅)Zh” ⌕rtFhDscy§S⁴eon

Try it online! Link is to verbose version of code. Explanation:

§⪪”↶2'⧴mB⁼“↷⁻o⊟HtωhJ№↘Tθ⁼σ4Þχ℅)Zh” 

Split the compressed string Vapor Jolt Flar Esp Umbr Leaf Glac Sylv on spaces and index into it using...

⌕rtFhDscy§S⁴

... the index of the fourth character of the input (taken cyclically) in the string rtFhDcsy.

eon

Output the shared suffix.

Neil

Posted 2019-11-07T23:49:54.087

Reputation: 95 035

By "fourth" you mean zero-indexed fourth? – Dannyu NDos – 2019-11-08T01:18:05.650

@DannyuNDos Yes, Charcoal uses zero-indexing. – Neil – 2019-11-08T01:19:27.127

3

Java 8, 84 bytes

t->"Leaf Esp Umbr Vapor  Sylv Flar Jolt Glac".split(" ")[t.chars().sum()%64%9]+"eon"

Port of @JoKing's Perl answer.

Try it online.

Kevin Cruijssen

Posted 2019-11-07T23:49:54.087

Reputation: 67 575

2

Jelly, 43 bytes

“ȦF³ḢẎŻṣ>[ɲ$Ɱ'⁻⁹ḋm¿:ṪœeḂɲẆy$\»Ḳ;€“°9»ŻɓO’Sị

Try it online! Or see the test-suite.

How?

First makes the list ['Jolt', 'Leaf', 'Umbr', 'Esp', 'Vapor', 'Sylv', 'Flar', 'Glac'], adds 'eon' to each, and prepends a zero to the list. Then gets the ASCII code-points of the characters in the input list, subtracts one from each, sums those up and indexes into the created list (using 1-based, modular indexing - i.e. gets the value at index i%9).

Jonathan Allan

Posted 2019-11-07T23:49:54.087

Reputation: 67 804

1

Julia 1.0, 85 83 75 bytes

f(s)=strip("VUEJGSFLamsolylepbplalaaor tcvrfr"[6hash(s)%47%8+1:8:33])*"eon"

Try it online!

Glen O

Posted 2019-11-07T23:49:54.087

Reputation: 2 548

1

Perl 5 -p -MList::Util=pairfirst, 84 bytes

$_=(pairfirst{/$a/}D,Umbr,E,Jolt,Fa,Sylv,Fi,Flar,G,Leaf,I,Glac,P,Esp,W,Vapor)[1].eon

Try it online!

Xcali

Posted 2019-11-07T23:49:54.087

Reputation: 7 671

Misdealt with Fairy. – Dannyu NDos – 2019-11-08T20:47:21.783

Thanks. Accidentally left that case out. Got it now. – Xcali – 2019-11-08T20:55:52.790

1

C (gcc), 103 bytes

I hash the first four bytes of the string to determine the index into the array (the hash function is not optimal, but works well enough: there's probably a more efficient one, but it would likely be bigger!) After the index is computed, I then print the four (or five) characters of the prefix and end with "eon". It's more compact than a string array, and by keeping the five-character string at the end I simplify the indexing.

I used some quirks in the language and implementation to save some length:

  • Due to operator precedence, I use 4|j>7 to give me 4 or 5, as bitwise operators have a lower precedence than relational ones.
  • Strings have to have int-appropriate alignment and int has to be a 32-bit, little-endian value so I can use type punning on the input string; fortunately this is the case for the test environment.
j;f(int*i){(j=(*i-2)%12%10)&&j--;printf("%.*seon",4|j>7,"SylvEsp\0JoltFlarLeafUmbrGlac    Vapor"+4*j);}

Try it online!

ErikF

Posted 2019-11-07T23:49:54.087

Reputation: 2 149