3
\$\begingroup\$

I'm always forgetting Pokemon type matchups. This is a challenge to print the pokemon type chart!

                                            Attacking Type                              
                No  Fi  Fl  Po  Gr  Ro  Bu  Gh  St  Fr  Wa  Gr  El  Ps  Ic  Dr  Da  Fa
    Normal      1.0 2.0 1.0 1.0 1.0 1.0 1.0 0.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
    Fighting    1.0 1.0 2.0 1.0 1.0 0.5 0.5 1.0 1.0 1.0 1.0 1.0 1.0 2.0 1.0 1.0 0.5 2.0
D   Flying      1.0 0.5 1.0 1.0 0.0 2.0 0.5 1.0 1.0 1.0 1.0 0.5 2.0 1.0 2.0 1.0 1.0 1.0
e   Poison      1.0 0.5 1.0 0.5 2.0 1.0 0.5 1.0 1.0 1.0 1.0 0.5 1.0 2.0 1.0 1.0 1.0 0.5
f   Ground      1.0 1.0 1.0 0.5 1.0 0.5 1.0 1.0 1.0 1.0 2.0 2.0 0.0 1.0 2.0 1.0 1.0 1.0
e   Rock        0.5 2.0 0.5 0.5 2.0 1.0 1.0 1.0 2.0 0.5 2.0 2.0 1.0 1.0 1.0 1.0 1.0 1.0
n   Bug         1.0 0.5 2.0 1.0 0.5 2.0 1.0 1.0 1.0 2.0 1.0 0.5 1.0 1.0 1.0 1.0 1.0 1.0
d   Ghost       0.0 0.0 1.0 0.5 1.0 1.0 0.5 2.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 2.0 1.0
i   Steel       0.5 2.0 0.5 0.0 2.0 0.5 0.5 1.0 0.5 2.0 1.0 0.5 1.0 0.5 0.5 0.5 1.0 0.5
n   Fire        1.0 1.0 1.0 1.0 2.0 2.0 0.5 1.0 0.5 0.5 2.0 0.5 1.0 1.0 0.5 1.0 1.0 0.5
g   Water       1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 2.0 2.0 1.0 0.5 1.0 1.0 1.0
    Grass       1.0 1.0 2.0 2.0 0.5 1.0 2.0 1.0 1.0 2.0 0.5 0.5 0.5 1.0 2.0 1.0 1.0 1.0
T   Electric    1.0 1.0 0.5 1.0 2.0 1.0 1.0 1.0 0.5 1.0 1.0 1.0 0.5 1.0 1.0 1.0 1.0 1.0
y   Psychic     1.0 0.5 1.0 1.0 1.0 1.0 2.0 2.0 1.0 1.0 1.0 1.0 1.0 0.5 1.0 1.0 2.0 1.0
p   Ice         1.0 2.0 1.0 1.0 1.0 2.0 1.0 1.0 2.0 2.0 1.0 1.0 1.0 1.0 0.5 1.0 1.0 1.0
e   Dragon      1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 1.0 2.0 2.0 1.0 2.0
    Dark        1.0 2.0 1.0 1.0 1.0 1.0 2.0 0.5 1.0 1.0 1.0 1.0 1.0 0.0 1.0 1.0 0.5 2.0
    Fairy       1.0 0.5 1.0 2.0 1.0 1.0 0.5 1.0 2.0 1.0 1.0 1.0 1.0 1.0 1.0 0.0 0.5 1.0

It has to take an optional parameter that specifies a single type and then prints the dual type chart for that type, which looks like:

                                                    Attacking Type                                                                  
                        No  Fi  Fl  Po  Gr  Ro  Bu  Gh  St  Fr  Wa  Gr  El  Ps  Ic  Dr  Da  Fa
    Electric/-          1.0 1.0 0.5 1.0 2.0 1.0 1.0 1.0 0.5 1.0 1.0 1.0 0.5 1.0 1.0 1.0 1.0 1.0
    Electric/Normal     1.0 2.0 0.5 1.0 2.0 1.0 1.0 0.0 0.5 1.0 1.0 1.0 0.5 1.0 1.0 1.0 1.0 1.0
D   Electric/Fighting   1.0 1.0 1.0 1.0 2.0 0.5 0.5 1.0 0.5 1.0 1.0 1.0 0.5 2.0 1.0 1.0 0.5 2.0
e   Electric/Flying     1.0 0.5 0.5 1.0 0.0 2.0 0.5 1.0 0.5 1.0 1.0 0.5 1.0 1.0 2.0 1.0 1.0 1.0
f   Electric/Poison     1.0 0.5 0.5 0.5 4.0 1.0 0.5 1.0 0.5 1.0 1.0 0.5 0.5 2.0 1.0 1.0 1.0 0.5
e   Electric/Ground     1.0 1.0 0.5 0.5 2.0 0.5 1.0 1.0 0.5 1.0 2.0 2.0 0.0 1.0 2.0 1.0 1.0 1.0
n   Electric/Rock       0.5 2.0 0.3 0.5 4.0 1.0 1.0 1.0 1.0 0.5 2.0 2.0 0.5 1.0 1.0 1.0 1.0 1.0
d   Electric/Bug        1.0 0.5 1.0 1.0 1.0 2.0 1.0 1.0 0.5 2.0 1.0 0.5 0.5 1.0 1.0 1.0 1.0 1.0
i   Electric/Ghost      0.0 0.0 0.5 0.5 2.0 1.0 0.5 2.0 0.5 1.0 1.0 1.0 0.5 1.0 1.0 1.0 2.0 1.0
n   Electric/Steel      0.5 2.0 0.3 0.0 4.0 0.5 0.5 1.0 0.3 2.0 1.0 0.5 0.5 0.5 0.5 0.5 1.0 0.5
g   Electric/Fire       1.0 1.0 0.5 1.0 4.0 2.0 0.5 1.0 0.3 0.5 2.0 0.5 0.5 1.0 0.5 1.0 1.0 0.5
    Electric/Water      1.0 1.0 0.5 1.0 2.0 1.0 1.0 1.0 0.3 0.5 0.5 2.0 1.0 1.0 0.5 1.0 1.0 1.0
T   Electric/Grass      1.0 1.0 1.0 2.0 1.0 1.0 2.0 1.0 0.5 2.0 0.5 0.5 0.3 1.0 2.0 1.0 1.0 1.0
y   Electric/Psychic    1.0 0.5 0.5 1.0 2.0 1.0 2.0 2.0 0.5 1.0 1.0 1.0 0.5 0.5 1.0 1.0 2.0 1.0
p   Electric/Ice        1.0 2.0 0.5 1.0 2.0 2.0 1.0 1.0 1.0 2.0 1.0 1.0 0.5 1.0 0.5 1.0 1.0 1.0
e   Electric/Dragon     1.0 1.0 0.5 1.0 2.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.3 1.0 2.0 2.0 1.0 2.0
    Electric/Dark       1.0 2.0 0.5 1.0 2.0 1.0 2.0 0.5 0.5 1.0 1.0 1.0 0.5 0.0 1.0 1.0 0.5 2.0
    Electric/Fairy      1.0 0.5 0.5 2.0 2.0 1.0 0.5 1.0 1.0 1.0 1.0 1.0 0.5 1.0 1.0 0.0 0.5 1.0

The best dual type charts I've found is here, don't forget to list even the non-existent combinations, by clicking 'Show all types'. Types combine by multiplication, except for the same time (eg. electric/electric which is actually electric/-). White space in the output is only important between columns and rows (to remain legibility).

This is code golf so shortest bytes wins.

\$\endgroup\$
  • \$\begingroup\$ related and related \$\endgroup\$ – Rod Jan 2 '17 at 13:15
  • \$\begingroup\$ What about the ordering of the types? \$\endgroup\$ – busukxuan Jan 2 '17 at 13:25
  • 4
    \$\begingroup\$ Normally, instead of 0.3, it is actually 0.25 then you have to identify STAB bonuses... \$\endgroup\$ – Anthony Pham Jan 2 '17 at 13:58
  • 1
    \$\begingroup\$ @PythonMaster I mean the order in which they appear in the table, should they be exactly as listed by OP? \$\endgroup\$ – busukxuan Jan 2 '17 at 13:59
  • \$\begingroup\$ You should keep the number of spaces consistent. There are four spaces in between the first Fighting and the numbers. There are only three spaces in between the Electric/Fighting and the numbers. \$\endgroup\$ – ericw31415 Jan 2 '17 at 15:23
4
\$\begingroup\$

JavaScript (ES6), 666 bytes

p=>(a=[18611524949,21853721688,27323097365,27406984278,23191686421,37066245461,26177987925,66127746385,37356070566,22827115926,22906831253,21627185429,23913388373,27196216913,18594420117,22906579204,18608379736,26936956281].map(n=>[...n.toString(4)].map(c=>(4>>c)/2)),t=`Normal,Fighting,Flying,Poison,Ground,Rock,Bug,Ghost,Steel,Fire,Water,Grass,Electric,Psychic,Ice,Dragon,Dark,Fairy`.split`,`,n=t.indexOf(p),w=` `.repeat(l=n<0?16:24),w+` `.repeat(28)+`Attacking Type
`+w+t.map(s=>s[0]+s[1]).join`  `+`
`+t.map((s,i)=>(`  Defending Type  `[i]+`   `+(n<0?s:n-i?p+`/`+s:p+`/--------`)+w).slice(0,l)+a[i].map((e,j)=>(i==n|n<0?e:e*a[n][j]).toFixed(1)).join` `).join`
`)

Explanation:

a=[18611524949,
   21853721688,
   27323097365,
   27406984278,
   23191686421,
   37066245461,
   26177987925,
   66127746385,
   37356070566,
   22827115926,
   22906831253,
   21627185429,
   23913388373,
   27196216913,
   18594420117,
   22906579204,
   18608379736,
   26936956281].map(n=>[...n.toString(4)].map(c=>(4>>c)/2)),

These are base 4 encoded numbers where each base 4 digit represents the effectiveness. The mapping is 0 - super effective, 1 - normally effective, 2 - not very effective, 3 - immune. This mapping is chosen because Normal is not super effective against any type and therefore each number will have 18 digits in base 4, but also allowing the effectiveness to be relatively easy to compute.

t is just an array of types (split from a string to save bytes). n is the index of the passed-in type, this is the easiest way to detect whether a type has been passed in but also saves a byte when checking the current row. l is the indentation of the main array, and w a string of spaces of length l. The first line is therefore just w plus a further 28 spaces plus the phrase "Attacking Type". The second line is w plus the first two characters of each type, with each pair separated by two spaces. Each row of the array is then generated. The header column is calculated using the appropriate character of phrase "Defending type", three spaces, the relevant types, and enough spaces to pad to length l. The columns are then calculated and formatted to 1 decimal place and joined with a single space as required.

There are probably further golfing opportunities but I stopped at 666 bytes because I have spent too much time on this already today.

\$\endgroup\$
  • \$\begingroup\$ How do you receive input for the the second table? \$\endgroup\$ – Anthony Pham Jan 3 '17 at 15:50
  • 1
    \$\begingroup\$ @PythonMaster If the parameter p is exactly one of the types in the array t then you get the second table, otherwise you get the first table. \$\endgroup\$ – Neil Jan 3 '17 at 19:30
3
\$\begingroup\$

Python 2 - 2163, 1648, 1642, 1580, 1560, 1490, 1390 bytes

s=[[1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
[1,1,2,1,1,.5,.5,1,1,1,1,1,1,2,1,1,.5,2],
[1,.5,1,1,0,2,.5,1,1,1,1,.5,2,1,2,1,1,1],
[1,.5,1,.5,2,1,.5,1,1,1,1,.5,1,2,1,1,1,.5],
[1,1,1,.5,1,.5,1,1,1,1,2,2,0,1,2,1,1,1],
[.5,2,.5,.5,2,1,1,1,2,.5,2,2,1,1,1,1,1,1],
[1,.5,2,1,.5,2,1,1,1,2,1,.5,1,1,1,1,1,1],
[0,0,1,.5,1,1,.5,2,1,1,1,1,1,1,1,1,2,1],
[.5,2,.5,0,2,.5,.5,1,.5,2,1,.5,1,.5,.5,.5,1,.5],
[1,1,1,1,2,2,.5,1,.5,.5,2,.5,1,1,.5,1,1,.5],
[1,1,1,1,1,1,1,1,.5,.5,.5,2,2,1,.5,1,1,1],
[1,1,2,2,.5,1,2,1,1,2,.5,.5,.5,1,2,1,1,1],
[1,1,.5,1,2,1,1,1,.5,1,1,1,.5,1,1,1,1,1],
[1,.5,1,1,1,1,2,2,1,1,1,1,1,.5,1,1,2,1],
[1,2,1,1,1,2,1,1,2,2,1,1,1,1,.5,1,1,1],
[1,1,1,1,1,1,1,1,1,.5,.5,.5,.5,1,2,2,1,2],
[1,2,1,1,1,1,2,.5,1,1,1,1,1,0,1,1,.5,2],
[1,.5,1,2,1,1,.5,1,2,1,1,1,1,1,1,0,.5,1]]
e=["Normal ","Fighting","Flying  ","Poison ","Ground ","Rock   ","Bug    ","Ghost  ","Steel  ","Fire   ","Water  ","Grass  ","Electric","Psychic","Ice    ","Dragon ","Dark   ","Fairy  "]
x="\t"
t="No  Fi  Fl  Po  Gr  Ro  Bu  Gh  St  Fi  Wa  Gr  El  Py  Ic  Dr  Da  Fa"
r=range
for i in r(0,18):
  n=""
  for b in r(0,18):n+=str(float(s[i][b]))+" "
  print e[i],x,n
c=s[input()]
print x*6+"Attacking Types"
print x*3+t
for i in r(0,18):
  a=e[s.index(c)]
  n=a+"/"+e[i]+x
  if e[i]==a:n=a+"/--------"+x
  if c!=s[i]:z=[round(float(a*b),1)for a,b in zip(c,s[i])]
  else:z=c
  for b in r(0,18):n+=str(float(z[b]))+" "
  print n

Try it here!

This program has 765 bytes from hard-coding the data of the effectiveness of each type down in s. Example Output:

The chart with single types (last line is where you type in the input): enter image description here The chart with dual types: enter image description here

Explanation

s holds the effectiveness stats in list per defending element (first is for the effectiveness against Normal, next against Fighting, etc.)

s=[[1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
[1,1,2,1,1,.5,.5,1,1,1,1,1,1,2,1,1,.5,2],
[1,.5,1,1,0,2,.5,1,1,1,1,.5,2,1,2,1,1,1],
[1,.5,1,.5,2,1,.5,1,1,1,1,.5,1,2,1,1,1,.5],
[1,1,1,.5,1,.5,1,1,1,1,2,2,0,1,2,1,1,1],
[.5,2,.5,.5,2,1,1,1,2,.5,2,2,1,1,1,1,1,1],
[1,.5,2,1,.5,2,1,1,1,2,1,.5,1,1,1,1,1,1],
[0,0,1,.5,1,1,.5,2,1,1,1,1,1,1,1,1,2,1],
[.5,2,.5,0,2,.5,.5,1,.5,2,1,.5,1,.5,.5,.5,1,.5],
[1,1,1,1,2,2,.5,1,.5,.5,2,.5,1,1,.5,1,1,.5],
[1,1,1,1,1,1,1,1,.5,.5,.5,2,2,1,.5,1,1,1],
[1,1,2,2,.5,1,2,1,1,2,.5,.5,.5,1,2,1,1,1],
[1,1,.5,1,2,1,1,1,.5,1,1,1,.5,1,1,1,1,1],
[1,.5,1,1,1,1,2,2,1,1,1,1,1,.5,1,1,2,1],
[1,2,1,1,1,2,1,1,2,2,1,1,1,1,.5,1,1,1],
[1,1,1,1,1,1,1,1,1,.5,.5,.5,.5,1,2,2,1,2],
[1,2,1,1,1,1,2,.5,1,1,1,1,1,0,1,1,.5,2],
[1,.5,1,2,1,1,.5,1,2,1,1,1,1,1,1,0,.5,1]] 

e holds the names of the types. There are spaces put in to maximize the usage of \t in later parts of the code.

e=["Normal ","Fighting","Flying  ","Poison ","Ground ","Rock   ","Bug    ","Ghost  ","Steel  ","Fire   ","Water  ","Grass  ","Electric","Psychic","Ice    ","Dragon ","Dark   ","Fairy  "]

This part prints the attacking types (literally too!)

print "\t\t\t\t\tAttacking Types"
print "\t\tNo  Fi  Fl  Po  Gr  Ro  Bu  Gh  St  Fi  Wa  Gr  El  Ps  Ic  Dr  Da  Fa"

This prints out the defending type and its respective stats according to the pre-made table and uses \t for uniform spacing:

for i in range(0, 18):
  n=""
  for b in range(0, 18):
    n+=str(float(s[i][b]))+" "
  print e[i],"\t",n

Take input. The input is an integer from 0 to 17 since there are 18 lists (one for each element). 0 returns s[0] which is the list for Normal type, 1 returns s[1] which is the list for Fighting type, etc. Notice how in the screenshot, 12 is used since s[12] is the list for the Electric type:

c = s[int(raw_input())]

Print out the attacking types (literally as well) again for second table:

print "\t\t\t\t\t\tAttacking Types"
print "\t\t\tNo  Fi  Fl  Po  Gr  Ro  Bu  Gh  St  Fi  Wa  Gr  El  Ps  Ic  Dr  Da  Fa"

This is where the second table starts to take place. To get the dual types' results, we must loop through every single list and prepare the string with the two types used:

for i in range(0, 18):
  n=e[s.index(c)] + "/"+e[i]+"\t"
  if e[i]==e[s.index(c)]:
    n=e[s.index(c)]+"/--------"+"\t"

Then we actually do the math. If the input matches the type the list belongs to, do nothing really. Else, start multiplying:

if c!=s[i]:
  z=[round(float(a*b), 1) for a,b in zip(c, s[i])]
else:
  z=c

Finish the table by printing out the string, n, for each dual type possibilty:

for b in range(0, 18):
  n+=str(float(z[b]))+" "
print n

Thanks @DJMcMayhem for saving 515 bytes! Thanks @Rod for saving 20 bytes! Thanks @Qwerp-Derp for saving 70 bytes!

\$\endgroup\$
  • 1
    \$\begingroup\$ Typo: Pyschic should be Psychic. \$\endgroup\$ – Neil Jan 2 '17 at 21:31
  • \$\begingroup\$ @Neil Nice catch \$\endgroup\$ – Anthony Pham Jan 2 '17 at 21:32
  • \$\begingroup\$ Did you even try and golf that massive list? \$\endgroup\$ – FlipTack Jan 3 '17 at 0:11
  • 1
    \$\begingroup\$ or just use gzip ¯\_(ツ)_/¯ \$\endgroup\$ – Rod Jan 3 '17 at 14:04
  • 1
    \$\begingroup\$ and of course this should be VERY helpfull for a new python golfer :D \$\endgroup\$ – Rod Jan 3 '17 at 14:58

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.