---
id: 6a151d32d772271dd2448c2d
title: "Challenge 311: Spellcaster"
challengeType: 28
dashedName: challenge-311
---

# --description--

Given a string of spell codes you are casting, calculate the total score.

Each character in the string represents a spell:

| Code | Spell| Category | Base Score |
| - | - | - | - |
| `"f"` | Fire | Destruction | 3 |
| `"l"` | Lightning | Destruction | 3 |
| `"i"` | Ice | Control | 2 |
| `"w"` | Wind | Control | 2 |
| `"h"` | Heal | Restoration | 1 |
| `"s"` | Shield | Restoration | 1 |

A combo multiplier is applied based on how many spells in a row have been cast from different categories:

- The first spell always scores at base value.
- Each consecutive spell from a different category than the previous increases the multiplier by 1.
- Casting a spell from the same category as the previous resets the multiplier back to 1.
- The score for each spell is its base score multiplied by the current multiplier.

Return the total score from the sequence of spells.

# --hints--

`cast("fihwl")` should return `33`.

```js
assert.equal(cast("fihwl"), 33);
```

`cast("lwswfi")` should return `45`.

```js
assert.equal(cast("lwswfi"), 45);
```

`cast("wislhfl")` should return `37`.

```js
assert.equal(cast("wislhfl"), 37);
```

`cast("sihwlih")` should return `50`.

```js
assert.equal(cast("sihwlih"), 50);
```

`cast("wishlfihwslwifihl")` should return `101`.

```js
assert.equal(cast("wishlfihwslwifihl"), 101);
```

# --seed--

## --seed-contents--

```js
function cast(spells) {

  return spells;
}
```

# --solutions--

```js
function cast(spells) {
  const lookup = {
    f: { category: "destruction", score: 3 },
    l: { category: "destruction", score: 3 },
    i: { category: "control", score: 2 },
    w: { category: "control", score: 2 },
    h: { category: "restoration", score: 1 },
    s: { category: "restoration", score: 1 }
  };

  let total = 0;
  let multiplier = 1;
  let prevCategory = null;

  for (const spell of spells) {
    const { category, score } = lookup[spell];

    if (prevCategory && category !== prevCategory) {
      multiplier++;
    } else {
      multiplier = 1;
    }

    total += score * multiplier;
    prevCategory = category;
  }

  return total;
}
```
