Roll for Initiative!
Introduction
In tabletop games like Dungeons and Dragons, when you begin a battle, all involved parties roll for initiative. In DnD 5e, this is 1d20 + DEX + Other bonuses
, where DEX
is the bonus given by your Dexterity stat. The characters that roll higher numbers go first. We'll use a similar, deterministic system in this challenge.
The Challenge
Write a program or function that, when given a list of characters, will output a list of characters in order of initiative.
A character is defined as this:
character = {
name: "name" // a string
statblock: [SPD, DEX, WHT] // a list of numbers
// DEX = dexterity, SPD = speed, WHT = weight
}
The formula for initiative is the following: $$\text{Initiative} = \left\lfloor{ \frac{\text{SPD}^2}{\sqrt{\lvert\text{DEX}\rvert}} }\right\rfloor - \text{WHT}$$
Input
A list of characters, unsorted. This can be a JSON object, a list of lists, a list of dictionaries, a series of strings etc.
It is guaranteed that all names will be unique.
Output
A list of characters, or character names, sorted by initiative order from highest to lowest, based on the above formula.
Rules
- IO can be used with any convenient method.
- Standard loopholes are forbidden.
- This is code-golf, so smallest program wins!
Sample IO
Input --> Output
[[Name, SPD, DEX, WHT], ...]
--> [[Name, SPD, DEX, WHT], ...] (or [Name, Name, ...])
---------
[[Alice,1,2,3],[Bob,10,5,0],[Charlie,3,2,1]]
--> [Bob, Charlie, Alice]
// Alice = -3, Bob = 44, Charlie = 5
[[Z,1,1,1],[B,1,1,1],[XY,5,1,1]]
--> [XY, Z, B]
// Retain the order of characters from the input if they have the same initiative.
// Z = 0, B = 0, XY = 24
[[Neg,-3,-3,-1],[SomeNeg,5,-2,-4],[NoNeg,4,6,8]]
--> [SomeNeg, Neg, NoNeg]
// Negative values are valid.
// Neg = 6, SomeNeg = 21, NoNeg = -2
[[Flo,1.5,2.5,3.5],[MoreFlo,2,2.5,3.5]]
--> [[MoreFlo,2,2.5,3.5], [Flo,1.5,2.5,3.5]]
// Floats are also valid.
// Flo = -2.5, MoreFlo = -1.5
[[Lonely,1,2,3]]
--> [[Lonely,1,2,3]]
// Input with 1 item.
[]
--> []
// Empty input leads to empty output.
[[Foo,2,1,4], [Baz,5,5,4], [Bar,5,1,4]]
--> [Bar, Baz, Foo]
// Foo = 0, Bar = 21, Baz = 7
[['Adam', 2, 4, 1], ['Eve', 2, 3, 1]]
--> [Adam, Eve]
// Adam = 2, Eve = 2
// If you do not floor, you'll end up with [Eve, Adam] (Adam = 2, Eve ~= 2.3)