33
\$\begingroup\$

Dungeon Master was one of the first ever real-time role-playing games, originally released in 1987 on the Atari ST. Among other exciting things for the time, it offered a rather sophisticated spell system based on runes.

Your task today is to write a program or function that evaluates the number of Mana points required to cast a given spell in Dungeon Master.

Dungeon Master screenshot

The 'spell cast' system is the top right cyan box in the above picture.

Spells, runes and Mana

Dungeon Master spells are composed of 2 to 4 runes, picked among the following categories, in this exact order:

  1. Power (mandatory)
  2. Elemental Influence (mandatory)
  3. Form (optional)
  4. Class / Alignment (optional)

It means that valid spells are either:

  • Power + Elemental Influence
  • Power + Elemental Influence + Form
  • Power + Elemental Influence + Form + Class / Alignment

Each category contains 6 runes, and each rune has an associated base Mana cost:

=============================================================================
| Power               | Rune      |   Lo |   Um |   On |   Ee |  Pal |  Mon |
|                     +-----------+------+------+------+------+------+------+
|                     | Base cost |    1 |    2 |    3 |    4 |    5 |    6 |
=============================================================================
| Elemental Influence | Rune      |   Ya |   Vi |   Oh |  Ful |  Des |   Zo |
|                     +-----------+------+------+------+------+------+------+
|                     | Base cost |    2 |    3 |    4 |    5 |    6 |    7 |
=============================================================================
| Form                | Rune      |  Ven |   Ew | Kath |   Ir |  Bro |  Gor |
|                     +-----------+------+------+------+------+------+------+
|                     | Base cost |    4 |    5 |    6 |    7 |    7 |    9 |
=============================================================================
| Class / Alignment   | Rune      |   Ku |  Ros | Dain | Neta |   Ra |  Sar |
|                     +-----------+------+------+------+------+------+------+
|                     | Base cost |    2 |    2 |    3 |    4 |    6 |    7 |
=============================================================================

Evaluating the Mana cost

The Mana cost of the spell is the sum of the Mana cost of all runes:

  • The cost of the Power rune always equals its base cost (from 1 to 6).

  • For the other runes, the following formula applies:

    cost = floor( (power + 1) * base_cost / 2 )

    where power is the base cost of the Power rune.

Examples

Spell: Lo Ful
Cost : 1 + floor((1 + 1) * 5 / 2) = 1 + 5 = 6

Spell: Um Ful
Cost : 2 + floor((2 + 1) * 5 / 2) = 2 + 7 = 9

Spell: Pal Vi Bro
Cost : 5 + floor((5 + 1) * 3 / 2) + floor((5 + 1) * 7 / 2) = 5 + 9 + 21 = 35

Clarifications and rules

  • Your input will consist of 2 to 4 strings designating the runes of the spell. You can take them in any reasonable format, such as 4 distinct parameters, an array of strings (e.g. ['Lo', 'Ful']), or just one string with a single-character separator of your choice (e.g. 'Lo Ful'). Please specify the selected input format in your answer.
  • The runes are guaranteed to be valid.
  • The order of the categories must be respected. Unused categories may be either missing or replaced with some falsy value.
  • You can accept the runes in any of these formats: 1. A capital letter followed by lower case ('Ful') 2. All lower case ('ful') 3. All upper case ('FUL'). But you can't mix different formats.
  • Quite obviously, we do not care to know whether the spell actually has some effect in the game (for the curious, useful spells are listed here.)
  • This is , so the shortest code in bytes wins.
  • And remember: Lord Chaos is watching you!

Test cases

Spell          | Output
---------------+-------
Lo Ful         | 6
Um Ful         | 9
On Ya          | 7
Lo Zo Ven      | 12
Pal Vi Bro     | 35
Ee Ya Bro Ros  | 31
On Ful Bro Ku  | 31
Lo Zo Kath Ra  | 20
On Oh Ew Sar   | 35
Ee Oh Gor Dain | 43
Mon Zo Ir Neta | 68
Mon Des Ir Sar | 75
\$\endgroup\$
  • 1
    \$\begingroup\$ Tangential - but for people that like this system, The Magical Land of Wozz is a Japanese SNES game (English translation available) that implements nearly the same system - where any string of letters becomes a spell. google.co.jp/webhp?ie=UTF-8#q=magical+land+of+wozz \$\endgroup\$ – Coty Johnathan Saxman Jun 30 '17 at 7:10
  • \$\begingroup\$ I have a vague memory of watching someone play Dungeon Master (I don't think it was on the ST). They had equipped one of their fighters with a magic necklace, and every so often they would check whether it had recharged and if so cast another rune of what I think was a light producing spell of some sort, so that the fighter was able to cast this spell every ten minutes or so, and eventually gained a level in wizardry. \$\endgroup\$ – Neil Jun 30 '17 at 8:39
  • \$\begingroup\$ @Neil This necklace was probably either the Moonstone (+3 Mana) or the Pendant Feral (+1 Wizard Skill). All items are listed here. \$\endgroup\$ – Arnauld Jun 30 '17 at 8:55
  • \$\begingroup\$ this script should output all possible input combinations \$\endgroup\$ – NieDzejkob Jul 1 '17 at 12:43

15 Answers 15

6
\$\begingroup\$

SOGL V0.12, 110 78 bytes

θKKι"LUOEPM”;W:A≤{B"⁶Μ↓§QΕņj“L─"¶Ζq«╝γDyΜ2¶S◄Μ$‘č¹I6nēwι{_Cb:ƧRA=┌*ΚKι=?aIc*»+

Try it Here!

Could probably golf a byte or two from redoing everything

Explanation:

θ            split on spaces
 K           pop the 1st item
  K          pop from the string the 1st character
   ι         remove the original string from stack
    "”;W     get the chars index in "LUOEPM"
        :A   save a copy to variable A
          ≤  put the power (used as the mana) on the bottom of the stack (with the thing above being the input array)

{            for the leftover items in the input do
 B             save the current name on B
  "..“         push 456779223467234567
      L─       base-10 decode it (yes, silly, but it converts it to an array of digits)
        ".‘    push "VEKIBGKRDN-SYVOFDZ"

      č        chop to characters
       ¹       create an array of those two
        I      rotate clockwise
         6n    group to an array with sub-arrays of length 6 (so each array in the array contains 3 items, corresponding to the categories, each with 6 arrays with the runes 1st letter (or "-" in the case of Ra) and base cost)
           ē   push variable e (default = user input number, which errors and defaults to 0) and after that increase it (aka `e++`)
            w  get that item in the array (the array is 1-indexed and the variable is not, so the array was created shifted (which somehow saves 0.9 ≈ 1 byte in the compression))

 ι             remove the original array
  {            for each in that (current category) array
   _             dump all contents on stack (so pushing the runes name and then base cost)
    C            save pop (base cost) on variable B
     b:          duplicate the name
       ƧRA=      push if pop = "RA"
           ┌*    get that many (so 0 or 1) dashes
             Κ   prepend the "" or "-" to the name
              K  pop the 1st letter of the name
               ι remove the modified name, leaving the 1st letter on the stack

         =?      if top 2 are equal (one of the dumped items and the 1st letter of the current inputs)
           a       push variable A (the power)
            I      increase it
             c     push variable C (the current base cost)
              *    multiply
               »   floor-divide by 2
                +  add that to the power
\$\endgroup\$
  • 2
    \$\begingroup\$ that's what make it even more interesting \$\endgroup\$ – Walfrat Jun 29 '17 at 14:11
  • \$\begingroup\$ Can you add an explanation? \$\endgroup\$ – CalculatorFeline Jun 30 '17 at 15:01
  • \$\begingroup\$ @CalculatorFeline Kinda forgot about this answer. Will probably golf & then add an explanation \$\endgroup\$ – dzaima Jun 30 '17 at 15:02
17
\$\begingroup\$

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

\$\endgroup\$
  • \$\begingroup\$ Outgolfed... >.< \$\endgroup\$ – Mr. Xcoder Jun 29 '17 at 13:16
  • \$\begingroup\$ I have copied your TIO input method to my answer as well, hope you don't mind. \$\endgroup\$ – Mr. Xcoder Jun 29 '17 at 13:28
  • \$\begingroup\$ @Mr.Xcoder I have now included all test cases. You can copy them if you want to \$\endgroup\$ – ovs Jun 29 '17 at 13:38
  • \$\begingroup\$ Oo, nicely done on the indexing - mind if I borrow it for my JS solution? \$\endgroup\$ – Shaggy Jun 29 '17 at 15:01
11
\$\begingroup\$

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
\$\endgroup\$
  • \$\begingroup\$ One small golf would be that if you index into .•Y<εΔ• at the beginning, you don't need to increment the index. \$\endgroup\$ – Emigna Jun 29 '17 at 14:27
  • \$\begingroup\$ @Emigna Ooh didn't have time to try that yet... \$\endgroup\$ – Erik the Outgolfer Jun 29 '17 at 14:28
11
\$\begingroup\$

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()))
\$\endgroup\$
  • \$\begingroup\$ You can save one more byte by reusing a: a=>a.reduce((t,c)=>t+(v=+'27169735020045670435262'[parseInt(c,36)%141%83%50%23],+a?a*v+v>>1:a=v),0) (EDIT: removed an irrelevant comment about integers passed in the input -- it seems like I didn't understand my own challenge very well ^^) \$\endgroup\$ – Arnauld Jun 30 '17 at 14:38
  • \$\begingroup\$ Neat trick, thanks, @Arnauld. Trying to come up with a calculation that would give me the number we're indexing in less bytes at the moment but not having much luck. \$\endgroup\$ – Shaggy Jun 30 '17 at 15:07
6
\$\begingroup\$

JavaScript, 212 210 207 206 bytes

Straight-forward searching algorithm, the search strings are just contributing to the total bytes.

Code

s=>eval('p=q=+(e=s.map(r=>"1 2 3 4 5  6  2 3 4 5  6  7 4  5 6   7 7  9  2 2  3   4   6 7"["LoUmOnEePalMonYaViOhFulDesZoVenEwKathIrBroGorKuRosDainNetaRaSar".search(r)])).shift();e.map(c=>p+=((q+1)*c)>>1);p')

Input Format

String array, each item is a first-letter-capitalized string. Example: ["Mon", "Zo", "Ir", "Neta"]

Explanation

e=s.map(r=>"1 2 3 4 5  6  2 3 4 5  6  7 4  5 6   7 7  9  2 2  3   4   6 7"["LoUmOnEePalMonYaViOhFulDesZoVenEwKathIrBroGorKuRosDainNetaRaSar".search(r)])

This queries for the basic costs.

p=q=+(/*blah*/).shift() 

Initializes 2 variables with the first item from the array result above, and remove that item. Must be cast to number first, otherwise it will be considered as string concatenation in the next part.

e.map(c=>p+=((q+1)*c)>>1);

Adds the costs of the non-power runes to the base power. Shifting is used instead of floor(blah)/2.

eval(/*blah*/;p)

Evaluate the last result. (Credit: Step Hen)

Test Cases

Lo Ful | 6
Um Ful | 9
On Ya | 7
Lo Zo Ven | 12
Pal Vi Bro | 35
Ee Ya Bro Ros | 31
On Ful Bro Ku | 31
Lo Zo Kath Ra | 20
On Oh Ew Sar | 35
Ee Oh Gor Dain | 43
Mon Zo Ir Neta | 68
Mon Des Ir Sar | 75

Edit 1: 212 > 210 - Removed a pair of braces

Edit 2: 210 > 207 - Thanks Step Hen for reminder on JS rules and some hint on using eval() function. Since AS3 forbids the use of eval() I haven't use that for long time

Edit 3: 207 > 206 - Thanks Shaggy for the idea replacing indexOf() with search()

\$\endgroup\$
  • 1
    \$\begingroup\$ Unless you call g inside of g, we allow JS answers to remove the g=. Also, you can save a couple bytes by switching it to an eval and removing the return: Fiddle \$\endgroup\$ – Stephen Jun 29 '17 at 12:50
  • \$\begingroup\$ @StepHen Thanks for the eval() idea and the JS rules, since AS3 forbade the eval() I thought I can't use that anymore \$\endgroup\$ – Shieru Asakoto Jun 29 '17 at 13:15
  • \$\begingroup\$ Well, it still works, and we define the language by the implementation :P \$\endgroup\$ – Stephen Jun 29 '17 at 13:21
  • 1
    \$\begingroup\$ search will save you a bytes over indexOf. \$\endgroup\$ – Shaggy Jun 29 '17 at 14:06
  • \$\begingroup\$ @Shaggy It worked, thanks for the search idea ;) \$\endgroup\$ – Shieru Asakoto Jun 29 '17 at 14:29
3
\$\begingroup\$

Haskell, 159 156 148 133 130 127 bytes

k(p:y)=sum$floor<$>c p:map(\x->c x*(c p+1)/2)y
c s=read["3764529516342767"!!(foldl(\c n->c*94+fromEnum n-9)0s%7086%17)]
(%)=mod

Try it online!

\$\endgroup\$
3
\$\begingroup\$

Python 2, 320 318 314 311 307 bytes

Input Format - List of Strings. Full program:

i=input()
t=[x.split()for x in"Lo Um On Ee Pal Mon|Ya Vi Oh Ful Des Zo|Ven Ew Kath Ir Bro Gor|Ku Ros Dain Neta Ra Sar".split('|')]
c=t[0].index(i[0])+1;r=c+1;s=c+r*(t[1].index(i[1])+2)/2
if len(i)>2:s+=r*(t[2].index(i[2])+4-(i[2]=='Bro'))/2
if len(i)>3:s+=r*(t[3].index(i[3])+1+(i[3]in'KuRaSar'))/2
print(s)

Try it online!

\$\endgroup\$
  • 1
    \$\begingroup\$ I kind of gave up golfing this, so anyone who has golfing ideas is welcome to edit in themselves. \$\endgroup\$ – Mr. Xcoder Jun 29 '17 at 13:44
3
\$\begingroup\$

Excel, 339 bytes

Inputs entered in A1 through D1. Formula in any other cell.

=CHOOSE(MOD(CODE(A1),12),2,,,1,6,,3,5,4)+INT((CHOOSE(MOD(CODE(A1),12),2,,,1,6,,3,5,4)+1)*CHOOSE(MOD(CODE(B1),12),,3,,,2,7,4,6,,5)/2)+INT((CHOOSE(MOD(CODE(A1),12),2,,,1,6,,3,5,4)+1)*CHOOSE(MOD(CODE(C1),12),7,4,6,,,7,,,5,,9)/2)+INT((CHOOSE(MOD(CODE(A1),12),2,,,1,6,,3,5,4)+1)*CHOOSE(MOD(CODE(SUBSTITUTE(D1,"Ra","E")),11),4,3,6,,2,7,,,2,0)/2)

Alternatively, importing as CSV:

Excel & CSV, 228 bytes

,,,
=CHOOSE(MOD(CODE(A1),12),2,,,1,6,,3,5,4)+1
=A2-1+INT(A2*CHOOSE(MOD(CODE(B1),12),,3,,,2,7,4,6,,5)/2)+INT(A2*CHOOSE(MOD(CODE(C1),12),7,4,6,,,7,,,5,,9)/2)+INT(A2*CHOOSE(MOD(CODE(SUBSTITUTE(D1,"Ra","E")),11),4,3,6,,2,7,,,2,0)/2)

Input entered in first row, SPACE for nulls. Result displayed in A3.

\$\endgroup\$
2
\$\begingroup\$

SCALA, 1106 chars, 1106 bytes

This is quite long, probably optimizable, but it was fun to do :)

Input format : space-separated runes in a string. If there is only 2 inputs (like "Lo Ful") my code completes it with while(k.length<4)k:+="" (so I can save 24 bytes by changing the parameters, if I require it to be "A B C D").

def n(i:Int,p:String):Int={Math.floor(i*((""+p(0)).toInt+1)/2).toInt}
def m(s:String):Int={var k=s.split(' ')

while(k.length<4)k:+=""

k match{case Array(p,i,f,a)=>{p match{case "Lo"=>1+m(1+"/ "+i+" "+f+" "+a)
case "Um"=>2+m(2+"/ "+i+" "+f+" "+a)
case "On"=>3+m(3+"/ "+i+" "+f+" "+a)
case "Ee"=>4+m(4+"/ "+i+" "+f+" "+a)
case "Pal"=>5+m(5+"/ "+i+" "+f+" "+a)
case "Mon"=>6+m(6+"/ "+i+" "+f+" "+a)
case _ if p.contains("/")=>i match{case "Ya"=>n(2,p)+m(p+" / "+f+" "+a)
case "Vi"=>n(3,p)+m(p+" / "+f+" "+a)
case "Oh"=>n(4,p)+m(p+" / "+f+" "+a)
case "Ful"=>n(5,p)+m(p+" / "+f+" "+a)
case "Des"=>n(6,p)+m(p+" / "+f+" "+a)
case "Zo"=>n(7,p)+m(p+" / "+f+" "+a)
case _ if p.contains("/")=>f match{case "Ven"=>n(4,p)+m(p+" / "+"/ "+a)
case "Ew"=>n(5,p)+m(p+" / "+"/ "+a)
case "Kath"=>n(6,p)+m(p+" / "+"/ "+a)
case "Ir"=>n(7,p)+m(p+" / "+"/ "+a)
case "Bro"=>n(7,p)+m(p+" / "+"/ "+a)
case "Gor"=>n(9,p)+m(p+" / "+"/ "+a)
case _ if p.contains("/")=>a match{case "Ku"=>n(2,p)
case "Ros"=>n(2,p)
case "Dain"=>n(3,p)
case "Neta"=>n(4,p)
case "Ra"=>n(6,p)
case "Sar"=>n(7,p)
case _=>0}
case _=>0}
case _=>0}
case _=>0}}}}

Thanks for this superb challenge. Try it online!

\$\endgroup\$
  • \$\begingroup\$ @Arnauld I just noticed something about my code : it doesn't really check if the thing exists! I mean, if I input "Lo Whoo Gor" it outputs 5! Is it okay? Or should I fix this? \$\endgroup\$ – V. Courtois Jun 29 '17 at 14:42
  • \$\begingroup\$ That's fine because the "the runes are guaranteed to be valid" (2nd rule). \$\endgroup\$ – Arnauld Jun 29 '17 at 14:44
  • \$\begingroup\$ Oh true :) I did it without thinking so I forgot this rule. Thanks again. \$\endgroup\$ – V. Courtois Jun 29 '17 at 14:45
2
\$\begingroup\$

Shakespeare Programming Language, 4420 bytes

,.Ajax,.Ford,.Page,.Puck,.Romeo,.Act I:.Scene I:.[Enter Romeo and Page]Page:You big big big big big big cat.[Exit Romeo][Enter Ajax]Page:Open thy mind!Ajax:Open thy mind!Open thy mind!You is the sum of Romeo and the sum of a big big cat and a cat.Am I as big as you?If not,let us return to Scene V.Page:You is the sum of a big big cat and a cat.Let us return to Act V.Scene V:.Ajax:You is the sum of you and the sum of a big big big cat and a pig.Am I as big as you?If not,let us return to Scene X.Page:You big cat.Let us return to Act V.Scene X:.Ajax:You is the sum of you and the sum of a big cat and a cat.Am I as big as you?If not,let us return to Scene L.Page:You big big cat.Let us return to Act V.Scene L:.Ajax:You is the sum of you and the sum of a big big cat and a big cat.Am I as big as you?If not,let us return to Scene C.Page:You is the sum of a big cat and a cat.Let us return to Act V.Scene C:.Ajax:Am I as big as the sum of you and a big big big pig?Page:You is the sum of a big big cat and a big cat.If so,you is the sum of you and a cat.Ajax:Open thy mind!Act V:.Scene I:.[Exit Ajax][Enter Ford]Page:Open thy mind!Ford:Open thy mind!Open thy mind!You is the sum of Romeo and the sum of a big big big big cat and a pig.Am I as big as you?If not,let us return to Scene V.Page:You big big cat.Let us return to Act X.Scene V:.Ford:You is the sum of you and the sum of a big big big cat and a pig.Am I as big as you?If not,let us return to Scene X.Page:You is the sum of a big cat and a cat.Let us return to Act X.Scene X:.Ford:You is the sum of you and a big big cat.Am I as big as you?If not,let us return to Scene L.Page:You is the sum of a big big big cat and a pig.Let us return to Act X.Scene L:.Ford:Am I as big as the sum of you and a pig?If not,let us return to Scene C.Page:You big cat.Let us return to Act X.Scene C:.Ford:Am I as big as the sum of Romeo and a big big cat?Page:You is the sum of a big big cat and a cat.If so,you is the sum of you and a cat.Ford:Open thy mind!Act X:.Scene I:.[Exit Page][Enter Puck]Ford:You is the sum of the sum of Ajax and a pig and the quotient between the product of Ajax and I and a big cat.Puck:Open thy mind!Is you as big as a pig?If so,let us return to Act D.[Exit Puck][Enter Page]Ford:Open thy mind!Open thy mind!You is the sum of Romeo and the sum of a big big cat and a cat.Am I as big as you?If not,let us return to Scene V.Page:You is the sum of a big big cat and a cat.Let us return to Act L.Scene V:.Ford:Am I as big as the sum of you and a big big cat?If not,let us return to Scene X.Page:You is the sum of a big big big cat and a pig.Let us return to Act L.Scene X:.Ford:Open thy mind!Am I as big as the sum of Romeo and a big cat?If not,let us return to Scene L.Page:You is the sum of a big big big cat and a pig.Let us return to Act L.Scene L:.Ford:You is the sum of Romeo and the sum of a big big big cat and a pig.Am I as big as you?If not,let us return to Scene C.Page:You is the sum of a big big big cat and a cat.Let us return to Act L.Scene C:.Ford:Am I as big as the sum of you and a big big cat?If so,let us return to Scene D.Page:You big big cat.Let us return to Act L.Scene D:.Page:Open thy mind!You is the sum of a big big cat and a big cat.Act L:.Scene I:.[Exit Page][Enter Puck]Ford:You is the sum of you and the quotient between the product of Ajax and I and a big cat.Puck:Open thy mind!Is you as big as a pig?If so,let us return to Act D.[Exit Puck][Enter Page]Ford:You is the sum of Romeo and a big big cat.Am I as big as you?If not,let us return to Scene V.Page:You is the sum of a big cat and a cat.Let us return to Act C.Scene V:.Ford:You is the sum of you and the sum of a big big big cat and a pig.Am I as big as you?If not,let us return to Scene X.Page:You big cat.Let us return to Act C.Scene X:.Ford:Am I as big as the sum of you and the sum of a big cat and a cat?If not,let us return to Scene L.Page:You big big cat.Let us return to Act C.Scene L:.Ford:Am I as big as the sum of you and a big big big cat?If not,let us return to Scene C.Page:You is the sum of a big big big cat and a pig.Let us return to Act C.Scene C:.Page:Open thy mind!Is you as big as the sum of Romeo and a cat?You big cat.If so,you is the sum of you and a big big cat.Act C:.Scene I:.[Exit Page][Enter Puck]Ford:You is the sum of you and the quotient between the product of Ajax and I and a big cat.Act D:.Scene I:.Ford:Open thy heart![Exeunt]

Takes the input as an uppercase string.

Explanation coming soon... For now, Fun fact: Microsoft is a negative noun in SPL. All other accepted words appeared in the works of Shakespeare.

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Java (OpenJDK 8), 252 bytes

r->{int c[][]={{2,3,4,5,6,7},{4,5,6,7,7,9},{2,2,3,4,6,7}},l=r.length,p="LUOEPM".indexOf(r[0].charAt(0))+1,a=p,i=0;String[]s={"YVOFDZ","VEKIBG","KRDNXS"};for(;i<l-1;)a+=(p+1)*c[i][s[i++].indexOf((l>3?r[i].replace("Ra","X"):r[i]).charAt(0))]/2;return a;}

Try it online!

The runes are input as a String[] (array of String), in the first case form (first letter is an uppercase, rest is lowercase).

It's the standard "find the n-th letter" method, with the twist that both Ros and Ra exist in the 4th segment. I treated that with an inline and explicit replacement of Ra to X.

\$\endgroup\$
1
\$\begingroup\$

Retina, 124 123 bytes

Gor
9
[ZIBS]\w+
7
Mon|Des|Kath|Ra
6
..l|Ew
5
Ee|Oh|Ven|Neta
4
[OVD]\w+
3
[UYKR]\w+
2
Lo
1
\d
$*
(?<=^(1+) .*1)
$1
\G1
11
11

Try it online! Link includes test cases. Takes space-separated runes. Explanation: The initial stages simply convert each rune to a digit, which is then converted to unary. The numbers after the first are multiplied by one more than the first number, following which the first number is doubled. The final stage integer divides all the result by 2 and takes the sum.

\$\endgroup\$
1
\$\begingroup\$

C, 274

#define c(p,r,x)(p+1)*b(r[x+1],x*17)/2
i;char*a="& ; $ # 4 %        ; B * 6 $ 8          6 5 - >3  +  A@( .   6 5    ";b(r,s)char*r;{for(i=0;i<17;i++)if(a[i+s]-3==(r[0]^r[1]))return i/2+1;return 0;}main(n,r)char**r;{n=b(r[1],0);printf("%d\n",n+c(n,r,1)+c(n,r,2)+c(n,r,3));}

More ungolfed:

#include<stdio.h>
char*a="& ; $ # 4 %      "
       "  ; B * 6 $ 8    "
       "      6 5 - >3  +"
       "  A@( .   6 5    ";
int b(char*r,int s){
  for(int i=0;i<17;i++)
    if(a[i+s]-3==(r[0]^r[1]))
      return i/2+1;
  return 0;
}
#define c(p,r,i)(p+1)*b(r[i+1],i*17)/2
int main(int n,char**r){
  int x=b(r[1],0);
  printf("%d\n",x+c(x,r,1)+c(x,r,2)+c(x,r,3));
}

You need to supply four command line arguments - so for the first test case you need to run ./a.out Lo Ful "" ""

\$\endgroup\$
1
\$\begingroup\$

Go, 205 bytes

func c(s []string)int{f,l:=strings.IndexByte,len(s)
p:=f("UOEPM",s[0][0])+3
r:=p-1+p*(f("VOFDZ",s[1][0])+3)/2
if l>2{r+=p*(f("war o",s[2][1])+5)/2}
if l>3{r+=p*(f("it Ra",s[3][len(s[3])-2])+3)/2}
return r}

It's a callable function, takes runes as a slice of strings, e.g. []string{"Um", "Ful"}.

Try it on the Go Playground.

\$\endgroup\$
0
\$\begingroup\$

Haskell, 623 bytes

Using ADTs instead of numerical voodoo.

NOTE: Add 36 for {-# LANGUAGE GADTs,ViewPatterns #-}

  • Score is computed assuming that it is compiled/run with -XGADTs -XViewPatterns
data P=Lo|Um|On|Ee|Pal|Mon deriving(Enum,Read,Eq)
data E=Ya|Vi|Oh|Ful|Des|Zo deriving(Enum,Read,Eq)
data F=Ven|Ew|Kath|Ir|Bro|Gor deriving(Enum,Read,Eq)
data C=Ku|Ros|Dain|Neta|Ra|Sar deriving(Enum,Read,Eq)
data S where
  S::P->E->S
  Q::P->E->F->S
  R::P->E->F->C->S
k(a:b:x)=let{p=read a;e=read b}in case x of{[]->S p e;[c]->Q p e(read c);[c,d]->R p e(read c)(read d)}
c,d::Enum a=>a->Int
c=succ.fromEnum
d=(+2).fromEnum
e Bro=7
e x=(+2).d$x
f x|c x`elem`[1,5,6]=d x|2>1=c x
g p f x =(`div`2).(*f x).succ$c p
h(S x y)=c x+g x d y
h(Q x y z)=h(S x y)+g x e z
h(R x y z t)=h(Q x y z)+g x f t
main=print.h.k.words=<<getLine

Input: a single spell as a normal string e.g.

Lo Ful

Um Ful

Multilining can be done by replacing the last line with

main=interact$unlines.map(show.h.k.words).lines

But this would add bytes to the count

\$\endgroup\$

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.