9 Deaths of the Ninja

12

1

Inspired by this conversation in chat.

Your goal in this challenge is to emulate a ninja and count how many deaths he has left.

Specs

You ninja starts out with 9 deaths left. He also gets an integral starting health as an input.

Then, he takes as input a list of events in his life that alter his health. These can be negative, positive, or zero integers.

At any point, if his health reaches at or below zero, he loses a life and his health goes back to the starting health.

Your program should report the number of deaths he has left. If he has zero or less left, you should output dead instead.

This is , so shortest code in bytes wins!

Test Cases

3, [] -> 9
100, [-20, 5, -50, 15, -30, -30, 10] -> 8
10, [-10, -10, -10, -10] -> 5
10, [-10, -10, -10, -10, -10, -10, -10, -10, -10] -> dead
0, [] -> dead
0, [1] -> dead
100, [10, -100] -> 9

Maltysen

Posted 2016-01-09T02:33:54.313

Reputation: 25 023

1YAY!!! My chat post is linked!!! :P – Rɪᴋᴇʀ – 2016-01-09T02:35:53.777

8Looks like I'm in trouble... – NinjaBearMonkey – 2016-01-09T02:48:49.937

So the order of events is "die if <=0, read a number, add to total, repeat"? – lirtosiast – 2016-01-09T02:56:20.703

@ThomasKwa yeah, but the dying can happen multiple times – Maltysen – 2016-01-09T02:57:12.077

1Can ninjas regenerate like time lords? Please? – Ashwin Gupta – 2016-01-09T07:20:16.333

Can the starting health be negative? – ETHproductions – 2016-01-09T14:08:41.123

Answers

8

Jelly, 30 28 26 bytes

»0o⁴+
;@ñ\<1S_9«0N“dead”×?

Try it online!

How it works

;@ñ\<1S_9«0N“dead”×?  Main link. Input: e (events), h (initial health)

;@                    Prepend h to e.
  ñ\                  Reduce the resulting array by the next, dyadic link.
                      This returns the array of intermediate results.
    <1                Check each intermediate value for non-positivity.
      S               Sum. This calculates the number of event deaths.
       _9             Subtract 9 from the result.
         «0           Take the minimum of the result and 0. This yields 0 if no
                      lives are left, the negated amount of lives otherwise.
                   ?  Conditional:
                  ×     If the product of the minimum and h is non-zero:
           N              Return the negated minimum.
            “dead”      Else, return "dead".


»0o⁴+                 Dyadic helper link. Arguments: x, y

»0                    Take the maximum of x and 0.
                      This yields x if x > 0 and 0 otherwise.
  o⁴                  Take the logical OR of the result and the second input (h).
    +                 Take the sum of the result and y.

Dennis

Posted 2016-01-09T02:33:54.313

Reputation: 196 637

¯_(ツ)_/¯ Dennis wins – downrep_nation – 2016-01-12T07:59:57.850

7

Japt, 40 39 32 bytes

U¬©(9-Vf@T=X+(T¬²ªU)<1} l)¬²ª`Ü%

Try it online!

How it works

While trying to golf this last night (away from a computer, no less), I ran across an interesting replacement for >0: ¬. On numbers, this takes the square root, which returns NaN for negative numbers. NaN is falsy, so this returns exactly the same truthily/falsily as >0.

Extending this trick a little further, we can reset T to U iff it's >=0 in only five bytes: T¬²ªU. How does this work? Let's take a look:

T    ¬      ²       ªU
     sqrt   square  if falsy, set to U (JS's || operator)
4    2      4       4
7   ~2.646  7       7
0    0      0       U
-4   NaN    NaN     U
-7   NaN    NaN     U

As you can see, T¬² returns NaN if T is negative; otherwise, it returns T. Since NaN and 0 are both falsy, this provides an easy way to reset the ninja's health with ªU. This trick is also used to return the ninja's lives left if that number is positive, or "dead" if negative.

Putting this all together:

           // Implicit: U = starting health, V = events, T = 0
U©        // If U is positive,
Vf@     }  // Filter out the items X in V that return truthily from this function:
 T=X+      //  Set T to X plus
 (T¬²ªU)   //   If T is positive, T; otherwise, U.
           //  This keeps a running total of the ninja's health, resetting upon death.
 <1        //  Return (T < 1).
9-    l)   // Take the length of the resulting array and subtract from 9.
           // This returns the number of lives the ninja has left.
¬²         // If the result is negative, set it to NaN.
ª`Ü%       // If the result of EITHER of the two parts above is falsy, return "dead".
           //  (`Ü%` is "dead" compressed.)
           // Otherwise, return the result of the middle part (lives left).
           // Implicit: output last expression

If the input is guaranteed to be non-negative, or even positive, we can golf of 1 or 4 bytes:

U©(9-Vf@T=X+(T¬²ªU)<1} l)¬²ª`Ü%  // U is non-negative
9-Vf@T=X+(T¬²ªU)<1} l)¬²ª`Ü%     // U is positive

ETHproductions

Posted 2016-01-09T02:33:54.313

Reputation: 47 880

6

JavaScript ES6, 62 60 58 bytes

Saved 4 bytes thanks to @ETHproductions

(a,b,d=9,l=a)=>b.map(i=>l=l+i<1?d--&&a:l+i,a)|d<1?"dead":d

Try it online (All browsers work)

Explanation

(a,b,    // a = 1st input, b = 2nd input
 d=9)=>  // Lives counter

  (b.reduce((l,i)=>     // Loop through all the health changes
    l+i<1                 // If (health + health change) < 1
    ?(d--,a)              // Decrease life, reset health
    :l+i                  // Return new health
  ,a)                   // Sets starting health to `a`
  ,d<1?        // Lives is less than 1
   "dead":d);  // Output "dead" otherwise lives left

Downgoat

Posted 2016-01-09T02:33:54.313

Reputation: 27 116

Would d--&&a work, or b.reduce(...)&&d<1?"dead":d? – ETHproductions – 2016-01-09T21:57:43.193

map beats reduce in most scenarios: (a,b,d=9,l=a)=>b.map(i=>l=l+i<1?d--&&a:l+i)&&d<1?"dead":d is 57. – ETHproductions – 2016-01-09T22:01:22.323

@ETHproductions thanks, I don't think .reduce(...)&& would work because of .reduce returns 0, it won't work. – Downgoat – 2016-01-10T01:01:27.243

Would (a,b,d=9,l=a)=>b.map(i=>l=l+i<1?d--&&a:l+i,a)|d<1?"dead":d work instead? – ETHproductions – 2016-01-10T04:03:08.647

4

CJam, 35 bytes

q~_@{+_1<{W$}&}/](\,_A<@*A@-"dead"?

Try it online!

Dennis

Posted 2016-01-09T02:33:54.313

Reputation: 196 637

2

Haskell, 81 77 75 bytes

p l i h a|l<1="dead"|i<1=p(l-1)h h a|[]<-a=show l|x:y<-a=p l(i+x)h y
p 10 0

Usage example: p 10 0 100 [-20, 5, -50, 15, -30, -30, 10] -> "8"

nimi

Posted 2016-01-09T02:33:54.313

Reputation: 34 639

1

TeaScript, 36 34 31 bytes

yR#l+i<1?e─·x:l+i,x);e≥0?e:D`Ü%

Similar to my JavaScript answer. the last 4 characters are the decompression of the string "dead".

TeaScript's online interpreter doesn't support array input so you're going to need to open the console, and run this by typing:

TeaScript( `yR#l+i<1?(e─,x):l+i,x);─e>0?e:D\`Ü%` ,[
  10, [-10, -10, -10, -10]
],{},TEASCRIPT_PROPS);

Explanation

      // Implicit: x = 1st input, y = 2nd input
yR#   // Reduce over 2nd input
  l+i<1?  // If pending health is less then 1
  (e─,x): // then, decrease life counter, reset health
  l+i     // else, modify health
,x);  // Set starting health
─e>0? // Ninja is alive?
e:    // Output lives left
D`Ü%  // Decompress and output "dead"

Downgoat

Posted 2016-01-09T02:33:54.313

Reputation: 27 116

1

Pyth, 32

 u+?>GZG&=hZQH+E0Q?&Q<Z9-9Z"dead

Note that there is a leading space. This probably isn't the best approach, but it was the first thing that came to mind. It reduces over input by adding the values to the ninja's health, and incrementing a counter and resetting the health when it drops below zero. We add a zero to the end of the list to count if the last change kills the ninja, and then just do some checking to see if the ninja is dead. The zero starting health case is hard coded.

Test Suite

FryAmTheEggman

Posted 2016-01-09T02:33:54.313

Reputation: 16 206

1

MATL, 32

9yi"@+t0>~?x1-y]]g*wxt0>~?x'dead'

Explanation

9        # push 9
y        # duplicate 2nd value to top (there is none -> get it from input first)
i        # get input and push it

The stack now looks like this (for input 100, [-20, 5, -50, 15, -30, -30, 10]):

100        9        100        [-20, 5, -50, 15, -30, -30, 10]

reload   deaths    health
value    left

Pop the array and loop

"            ]    # loop
 @+               # add to health
   t0>~?    ]     # if health is zero or less
        x1-y      # delete health counter, decrement life counter, reload health

If the health is zero, set death counter to zero. Special case handling for initial health = 0.

g        # health to bool
*        # multiply with death counter

Delete the reload value from stack

wx

If the death counter is zero or less, delete it and print 'dead' instead.

t0>~?x'dead'

Rainer P.

Posted 2016-01-09T02:33:54.313

Reputation: 2 457

1

Python 2.7, 82 66 55 106 bytes

Thanks to @RikerW for -16 bytes.:(

Thanks to @Maltysen for -11 bytes. :(

i=input;h=[i()]*9;d=i()
if 0==h[0]:print'dead';exit()
for x in d:
 h[0]+=x
 if h[0]<=0:h=h[1:]
y=len(h)
print['dead',y][y!=0]

First type health, then enter, then events in list form.

Alex

Posted 2016-01-09T02:33:54.313

Reputation: 417

0

C# 207

class P{static void Main(string[]a){int h=int.Parse(a[0]),H=h,l=9,i=1;if(a.Length!=1){for(;i<a.Length;i++){H+=int.Parse(a[i]);if(H<=0){l--;H=h;}}}System.Console.Write(h==0?"dead":l<=0?"dead":l.ToString());}}

Takes the input through argument stream. The first argument is the amount of health and all the rest is the list of events.

Readable / ungolfed version

class Program
{
    static void Main(string[]a)
    {
        int health = int.Parse(a[0]);
        int Health = health;
        int lives = 9;

        if(a.Length!=1)
        {
            for (int i = 1;i < a.Length;i++)
            {
                Health += int.Parse(a[i]);
                if (Health <= 0)
                {
                    lives--;
                    Health = health;
                }
            }
        }

        System.Console.Write(health == 0 ? "dead" : lives <= 0 ? "dead" : lives.ToString());
    }
}

Examples:

  • CSharp.exe 3 => 9

  • CSharp.exe 100 -20 5 -50 15 -30 -30 10 => 8

(Psst.) CSharp.exe is name used as an example. You have to call like this in reality: [program_name.exe] arguments, without the square parentheses.

Yytsi

Posted 2016-01-09T02:33:54.313

Reputation: 3 582