Score a game of Load, Defend and Shoot

Jelly, 33 32 24 bytes

Zæ%1.»0$+¥\>-‘żZḅ3Ff5,7Ḣ

This prints 5 instead of -1, and 7 instead of 1. Try it online! or verify all test cases.

How it works

Zæ%1.»0$+¥\>-‘żZḅ3Ff5,7Ḣ  Main link. Argument: A (digit list array)

Z                         Zip; group corresponding digits.
 æ%1.                     Map the digits in (-1.5, 1.5].
                          This replaces [1, 2, 3] with [1, -1, 0].
          \               Cumulatively reduce the pairs by doing the following.
     »0$                    Take the maximum of the left value and 0, i.e., replace
                            a -1 with a 0.
        +¥                  Add the modified left value to the right value.
                          This computes the available ammo after each action. An
                          ammo of -1 indicates a cheating attempt.
           >-             Compare the results with -1.
             ‘            Increment. And unilateral cheating attempt is now [1, 2]
                          or [2, 1], where 1 signals the cheater and 2 the winner.
              żZ          Pair each result with the corr., original digits.
                ḅ3        Convert each pair from base 3 to integer.
                          This maps [1, 2] and [2, 1] to 5 and 7.
                  F       Flatten the resulting, nested list.
                   f5,7   Discard all but 5's and 7's.
                       Ḣ  Grab the first element (5 or 7).
                          If the list is empty, this returns 0.

Pyth, 48 46 49 47 bytes

.xhfT|M.e,-FmgF.b/<dhkY2S2Q?}b_BS2-FbZ.b,NYCQ)0

Try it here!

Thanks to @isaacg for saving 2 4 bytes!

Takes input as a 2-tuple with the list of the moves of player A first and the moves of player B second. Output is the same as in the challenge.

Explanation

Short overview

  • First we group the moves of both players together, so we get a list of 2-tuples.
  • Then we map each of those tuples to another 2-tuple in the form [cheating win, fair win] with the possible values -1, 0, 1 for each of it, to indicate if a player won at this point (-1, 1) or if the game goes on (0)
  • Now we just need to get the first tuple which is not [0,0], and take the first non-zero element of it which indicates the winner

Code breakdown

.xhfT|M.e,-FmgF.b/<dhkY2S2Q?}b_BS2-FbZ.b,NYCQ)0  # Q = list of the move lists

                                      .b,NYCQ    # pair the elements of both input lists
       .e                                        # map over the list of pairs with 
                                                 # b being the pair and k it's index
            m             Q                      # map each move list d
               .b      2S2                       # map over [1,2], I can't use m because it's
                                                 # lambda variable conflicts with the one from .e
                  <dhk                           # d[:k+1]
                 /    Y                          # count occurences of 1 or 2 in this list
          -F                                     # (count of 1s)-(count of 2s), indicates cheating win
                           ?}b_BS2               # if b is (1,2) or (2,1)
                                  -Fb            # take the difference, indicates fair win
                                     Z           # else 0, no winner yet
         ,                                       # pair those 2 values
     |M                                          # For each resulting pair, take the first one if
                                                 # its not zero, otherwise the second one
   fT                                            # filter all zero values out
.xh                                              # try to take the first value which indicates the winner
                                             )0  # if thats not possible because the list is empty
                                                 # output  zero to indicate a draw

Tags:

Code Golf

Game