Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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
share|improve this question
1  
YAY!!! My chat post is linked!!! :P – Eᴀsᴛᴇʀʟʏ Iʀᴋ Jan 9 at 2:35
8  
Looks like I'm in trouble... – NinjaBearMonkey Jan 9 at 2:48
    
So the order of events is "die if <=0, read a number, add to total, repeat"? – lirtosiast Jan 9 at 2:56
    
@ThomasKwa yeah, but the dying can happen multiple times – Maltysen Jan 9 at 2:57
1  
Can ninjas regenerate like time lords? Please? – Ashwin Gupta Jan 9 at 7:20

10 Answers 10

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.
share|improve this answer
    
¯_(ツ)_/¯ Dennis wins – downrep_nation Jan 12 at 7:59

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
share|improve this answer

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
share|improve this answer
    
Would d--&&a work, or b.reduce(...)&&d<1?"dead":d? – ETHproductions Jan 9 at 21:57
    
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 Jan 9 at 22:01
    
@ETHproductions thanks, I don't think .reduce(...)&& would work because of .reduce returns 0, it won't work. – Upgoat Jan 10 at 1:01
    
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 Jan 10 at 4:03

CJam, 35 bytes

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

Try it online!

share|improve this answer

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"

share|improve this answer

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

share|improve this answer

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"
share|improve this answer

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'
share|improve this answer

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.

share|improve this answer

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.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.