Pokemon Type chart (and dual type chart)

4

1

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.

Pureferret

Posted 2017-01-02T12:56:03.737

Reputation: 960

related and related – Rod – 2017-01-02T13:15:05.343

What about the ordering of the types? – busukxuan – 2017-01-02T13:25:16.063

4Normally, instead of 0.3, it is actually 0.25 then you have to identify STAB bonuses... – Anthony Pham – 2017-01-02T13:58:57.383

1@PythonMaster I mean the order in which they appear in the table, should they be exactly as listed by OP? – busukxuan – 2017-01-02T13:59:38.377

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. – ericw31415 – 2017-01-02T15:23:59.287

@PythonMaster Not sure how 0.3 crept in there, I'd remove it but I presume the answers would be trivially different so I'll leave it in there – Pureferret – 2017-01-03T09:19:27.877

@busukxuan the ordering of rows is not important – Pureferret – 2017-01-03T09:20:21.427

@Pureferret my guess is you rounded your calculations to one decimal place, which would round 0.25 to 0.3 – Patrick Roberts – 2017-01-04T07:47:55.627

@PatrickRoberts indeed, it was more how did I not notice it? – Pureferret – 2017-01-04T18:17:05.507

In the dual type chart, does the double type need to be first? – FlipTack – 2017-12-10T09:34:36.290

@fliptack first only – Pureferret – 2017-12-10T13:09:42.317

Answers

4

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.

Neil

Posted 2017-01-02T12:56:03.737

Reputation: 95 035

How do you receive input for the the second table? – Anthony Pham – 2017-01-03T15:50:29.913

1@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. – Neil – 2017-01-03T19:30:41.983

3

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!

Anthony Pham

Posted 2017-01-02T12:56:03.737

Reputation: 1 911

1Typo: Pyschic should be Psychic. – Neil – 2017-01-02T21:31:07.187

@Neil Nice catch – Anthony Pham – 2017-01-02T21:32:31.973

Did you even try and golf that massive list? – FlipTack – 2017-01-03T00:11:46.323

@FlipTack Yes I did – Anthony Pham – 2017-01-03T00:43:25.390

I do love a python answer! – Pureferret – 2017-01-03T09:21:10.033

you can assign \t to an variable and use x*6+ instead \t\t\t\t\t\t in every use. Also the types abbreviated are duplicated too, put that on variable too, even better extract from the e list ' '.join(a[:2] for a in e) – Rod – 2017-01-03T13:53:46.770

@Rod I'll try to implement that – Anthony Pham – 2017-01-03T13:54:11.087

for the effective list, you can assign .5 to a variable, and use the variable instead (~60 occurences cut by half), you can also you eval() to chop bytes like s=eval('[2aa],[1a,2]'.replace('a',',1')) to generate s=eval('[2,1,1],[1,1,2]') – Rod – 2017-01-03T14:00:11.503

1or just use gzip ¯\(ツ) – Rod – 2017-01-03T14:04:00.083

Also, can't that long line be condensed down to an array, then be joined by two spaces for each element? It would save bytes, I'm sure. TBH, this one doesn't seem like it's properly golfed at all. – clismique – 2017-01-03T14:47:17.713

@Qwerp-Derp I'm quite new to golfing and I am still editing... – Anthony Pham – 2017-01-03T14:53:43.073

int(raw_input()) can be reduced to input() as well, since you're using Python 2. In the second for loop, you should be able to save e[s.index(c)] as a variable inside the loop, since you're not altering it in any way. Also, you should be able to do z=[[round(float(a*b),1)for a,b in zip(c,s[i])],c][c!=s[i]] for the if/else thing. Sorry for the harsh message before, I didn't know you were new. It's just that I've seen a lot of golfs in Python over here. – clismique – 2017-01-03T14:53:45.033

@PythonMaster bro just do t=' '.join(a[:2] for a in e) – Rod – 2017-01-03T14:56:05.450

it was to big to post as comment, so here is a gzip demo

– Rod – 2017-01-03T14:57:50.620

Thanks ya'll... these tips should be implemented in a few hours since I have a school life :) – Anthony Pham – 2017-01-03T15:00:52.200

I count 1,390 bytes. – clismique – 2017-01-04T08:46:11.280

Did you delete the two print lines at the start on purpose? Also, the top row isn't positioned properly - there needs to be extra spaces. – clismique – 2017-01-04T09:14:30.847