How much Mana do I need?
Python 2, 135 119 115 bytes
b=[int('27169735 2 4567 435262'[int(x,36)%141%83%50%23])for x in input()]
print b[0]+sum(a*-~b[0]/2for a in b[1:])
Try it online!
Input is list of strings from stdin
05AB1E, 83 82 bytes
.•Y<εΔ•¹нk©.•M₄P畲нkÌ.•Jrû •³нkD(i\ë4 3‡4+}.•A1Δ#•I4èkD(i\ë3LJ012‡Ì})ćsv®>y*;(î(+
Try it online!
-1 thanks to Emigna.
SOOOOOOO ungolfed :(
Explanation:
.•Y<εΔ•¹нk©.•M₄P畲нkÌ.•Jrû •³нkD(i\ë4 3‡4+}.•A1Δ#•I4èkD(i\ë3LJ012‡Ì})ćsv®>y*;(î(+ Accepts four runes as separate lines, lowercase. Use Ø for missing runes.
.•Y<εΔ•¹нk© Index first letter of first rune into "aluoepm" ("a" makes 1-indexed)
.•M₄P畲нkÌ Index first letter of second rune into "yvofdz", 2-indexed.
.•Jrû •³нkD(i\ë4 3‡4+} Index first letter of third rune into "vekibg", 0-indexed, if it's not there pop, else, if index is 4 replace with 3, else keep as-is, then increment by 4.
.•A1Δ#•I4èkD(i\ë3LJ012‡Ì} Index fourth letter (modular wrapping) of fourth rune into "kodnra", if it's not there pop, else, if index is one of 1, 2 or 3, replace with 0, 1 or 2 respectively, else keep as-is, then increment by 2.
)ćs Wrap all numbers into a list, keeping the power rune behind.
v For each
®>y*;(î( Apply the formula
+ Add to total sum
JavaScript (ES6), 157 156 116 112 100 99 97 bytes
Takes input as an array of strings.
a=>a.map(c=>t+=(v=+`27169735020045670435262`[parseInt(c,36)%141%83%50%23],+a?a*v+v>>1:a=v),t=0)|t
- Saved a massive 44 bytes by borrowing the indexing trick from ovs' Python solution - if you're upvoting this answer, please upvote that one too.
- Saved 13 bytes thanks to Arnauld pointing out what should have been an obvious opportunity to use a ternary.
Try it Online!
Explanation
Hoo, boy, this is gonna be fun - my explanations to trivial solutions suck at the best of times! Let's give it a go ...
a=>
An anonymous function taking the array as an argument via parameter a
.
a.reduce((t,c)=>,0)
Reduce the elements in the array by passing each through a function; the t
parameter is the running total, the c
parameter is the current string and 0
is the initial value of t
.
parseInt(c,36)
Convert the current element from a base 36 string to a decimal integer.
%141%83%50%23
Perform a few modulo operations on it.
+`27169735 2 4567 435262`[]
Grab the character from the string at that index and convert it to a number.
v=
Assign that number to variable v
.
+a?
Check if variable a
is a number. For the first element a
will be the array of strings, trying to convert that to a number will return NaN
, which is falsey. On each subsequent pass, a
will be a positive integer, which is truthy.
a*v+v>>1
If a
is a number then we multiply it by the value of v
, add the value of v
and shift the bits of the result 1 bit to the right, which gives the same result as dividing by 2 and flooring.
:a=v
If a
is not a number the we assign the value of v
to it, which will also give us a 0
to add to our total on the first pass.
t+
Finally, we add the result from the ternary above to our running total.
Original, 156 bytes
a=>a.reduce((t,c)=>t+(p+1)*g(c)/2|0,p=(g=e=>+`123456234567456779223467`["LoUmOnEePaMoYaViOhFuDeZoVeEwKaIrBrGoKuRoDaNeRaSa".search(e[0]+e[1])/2])(a.shift()))