8
\$\begingroup\$

Inspired by a challenge from the OUCC 2022 Seniors competition.

Background

Two teams are playing "capture the flag". They take turns invading each other's base and capturing their opposing team's flag in the shortest amount of time. The attacking players each have one soft ball they can throw at the defenders. Teams get to reduce the time they took to capture the flag by 3 seconds for each of the defenders team that gets hit with a ball.

Your Task

Write a program that calculates which team won based on who had the smallest accumulated time.

Clarifications

  • There are two teams.
  • There will be an even number of rounds played.
  • Both teams will attack an equal number of times but it could be in any order.

Example

Let's say we have the input [['A', 20, 0], ['A', 30, 1], ['B', 40, 6], ['B', 20, 2]]. We go through each inner list:

  • ['A', 20, 0]: The A tells us we need to add to team A. To get the number we need to add, we use time - 3*hits. In this case, it is 20-3*0 = 20.
  • ['A', 30, 1]: We again need to add to team A. This time it's 30-3*1 = 27. Team A is now on 47.
  • ['B', 40, 6]: This time it's 22
  • ['B', 20, 2]: 14. B is now at 36.

Now we get the team with the lower score, in this case B, and output.

Test cases

Input -> Output
[['A', 100, 5], ['B', 95, 2]] -> A
[['A', 20, 0], ['A', 30, 1], ['B', 40, 6], ['B', 20, 2]] -> B
['A', 50, 3], ['A', 70, 5], ['B', 35, 0], ['A', 25, 1], ['B', 60, 2], ['B', 40, 4] -> B
[] -> Draw

Input / Output formats

  • You must take an arbitrary even number of inputs (these can all be in a list, or taken separately).

  • Each input must be a list of three items (in whatever order you prefer):

    • The team. You must choose two distinct values for this, e.g. 0 and 1, 'A' and 'B', etc.
    • The time taken for the team to get the flag (a positive integer of seconds)
    • The number of hits they got (a positive integer)

    Note: The number of hits will never exceed the time taken / 5, so the score will never be negative.

  • You must have three distinct output possibilities:

    • One for the first team winning
    • One for the second team winning
    • One for a draw
  • This is , so shortest answer in bytes wins!

\$\endgroup\$
1

18 Answers 18

7
\$\begingroup\$

JavaScript (ES6), 43 bytes

-2 thanks to @l4m2

Expects 1 for 'A' and -1 for 'B'. Returns false, true or 0 for A wins, B wins and draw respectively.

a=>a.map(([i,t,n])=>s+=i*=t-n*3,s=0)|s&&s>0

Try it online!

Commented

a =>                 // a[] = input array
a.map(([i, t, n]) => // for each entry (i = team, t = time, n = hits):
  s +=               //   update the sum s:
    i *=             //     either add or subtract:
      t - n * 3,     //       t - 3n
  s = 0              //   start with s = 0
)                    // end of map()
| s                  // return 0 if s = 0
&& s > 0             // return true if s is positive, false otherwise
\$\endgroup\$
2
6
\$\begingroup\$

Vyxal, 12 10 8 bytes

ƛ÷T-*;∑±

Try it Online!

Inspired by Arnaulds answer. Expects -1 for 'A' and 1 for 'B'. Returns 1, -1 or 0 for A wins, B wins and draw respectively.

ƛ    ;   # map:
 ÷       #   push each on stack
  T      #   triple
   -     #   subtract
    *    #   multiply
      ∑  # sum
       ± # sign
\$\endgroup\$
1
  • \$\begingroup\$ aargh beat me to it :P \$\endgroup\$
    – math scat
    Jan 21, 2023 at 19:43
4
\$\begingroup\$

Charcoal, 28 21 bytes

≔↨¹Eθ×⊟ι↨±³ιθI∧θ÷θ±↔θ

Try it online! Link is to verbose version of code. Takes input as a list of [hits, time, team] where -1 is A and 1 is B and outputs the winning team or 0 for a tie. Explanation:

≔↨¹Eθ×⊟ι↨±³ιθ

Calculate sum of the accumulated times for each round with As times being negative and B's times being positive.

I∧θ÷θ±↔θ

Output the negated sign of the result.

No actual "base conversion" going on here - base -3 is used to calculate accumulated time and base 1 is used to take the sum of a list in case it's empty.

\$\endgroup\$
3
\$\begingroup\$

Nibbles, 6 5.5 bytes

`$+.$*-@*3

Attempt This Online!

Takes a list of tuples (hits,time,team) with 1 and -1 as the team names. Outputs the team with a bigger score, or 0 for a draw.

Explanation

`$ Sign of
+   sum of
.    map
$     input
      (x,y,z) =>
*     multiply
-      subtract
@       y
*3      multiply by 3
         x
       z

Nibbles' implicit tuple unpacking came in really handy here.

-0.5 by using my freedom to choose the order of the tuple.

\$\endgroup\$
3
\$\begingroup\$

Japt -g, 14 bytes

x_Ì*3)nZg1)*ZÎ

Try it or verify all test cases.

Port of @AndrovT's Vyxal answer. Takes -1 for A and 1 for B. Outputs 1 for A, -1 for B, and 0 for draw.

x_Ì*3)nZg1)*ZÎ  implicit input array
x_              sum after mapping each to:
  Ì*3)            the last item (hits) * 3
      nZg1)       subtracted from the second item (time)
           *ZÎ    multiplied by first item
                  (A or B, -1 for A and 1 for B)
      -g flag:  output sign of the number 
\$\endgroup\$
2
  • \$\begingroup\$ You can pass the empty array test case by adding the -E"0" flag: Try it \$\endgroup\$
    – The Thonnu
    Jan 22, 2023 at 9:55
  • \$\begingroup\$ @TheThonnu I know, but it's considered a cheating flag so I didn't add it to the question. I used it on a different challenge the other day (-E"🔵🔵🔵🔵🔵🔵🔵🔵🔵🔵") . I'm going to work on finding a way to work even with the empty test case without increasing the byte count too much \$\endgroup\$
    – noodle man
    Jan 22, 2023 at 13:13
2
\$\begingroup\$

Wolfram Language, 39 35 bytes

Solution 2. Thanks to these tips, we can remove 4 bytes:

Sign@Tr[#&@@#(#[[2]]-3#[[3]])&/@#]&
  • Tr is the same as Total for 1-dimensional lists (-3 bytes)
  • a[[1]] is the same as #&@@a (-1 byte).

Note that we now have three anonymous functions stacked within each other like matryoshka dolls!

Solution 1. We encode 'A' as 1 and 'B' as -1.

Sign@Total[#[[1]](#[[2]]-3#[[3]])&/@#]&

The solution converts each list element {a,b,c} into an expression a(b-3c), using an anonymous function. We then calculate the sum (total) of this list and compute its arithmetic sign. It returns 1 if 'A' wins, 0 if there is a tie, and -1 if 'B' wins (for obvious reasons).

Some comments about the notation:

  • @ is function application: f[x] is the same as f@x.
  • Sign and Total does what they say on the tin (Total accepts a list argument).
  • # and & define an anonymous function: #+1& is a function that adds 1 to its argument.
  • a[[i]] is the $i$-th element of list a, and list elements are enumerated starting from 1.
  • /@ is Map, which applies a function on the left to list on the right.
  • Finally, Wolfram Language does not require explicit multiplication signs in obvious cases like a(b+c) or 2x.

One final comment: the solution is 39 bytes but 33 glyphs, as Wolfram allows using U+301A〚 and U+301B 〛instead of double brackets.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Welcome to Code Golf, and nice answer! You might want to include a Try it online! link so people can test your code online. \$\endgroup\$
    – The Thonnu
    Jan 22, 2023 at 8:08
  • \$\begingroup\$ Are they not called Babushka dolls? \$\endgroup\$
    – noodle man
    Jan 23, 2023 at 22:38
  • \$\begingroup\$ (assuming you are not joking). No. "babushka" is grandmother in Russian. "Матрёшка" or "matryoshka" is the name of the doll: en.wikipedia.org/wiki/Matryoshka_doll \$\endgroup\$
    – Victor K.
    Jan 23, 2023 at 23:05
2
\$\begingroup\$

Factor + math.unicode, 33 bytes

[ [ first3 3 * - * ] map Σ sgn ]

Try it online!

This answer uses the following values:

  • -1 for Team A
  • 1 for Team B
  • 1 for Team A victory
  • -1 for Team B victory
  • 0 for draw

How?

For each triplet,

  • Multiply the last number by three
  • Subtract this value from the second number
  • Multiply this by the first number (the team value [-1 or 1])

Then,

  • Sum the results
  • Get the sign (returning -1, 0 or 1 for negative, zero, and positive)
\$\endgroup\$
2
\$\begingroup\$

Jelly, 8 bytes

Employs the team identification trick from Arnauld's JavaScript ES6 answer.

Ḣ×)ḅ-3SṠ

A monadic Link that accepts a list of triples, [team, hits, time] with teams represented as -1 and 1, and yields the losing team or 0 for a draw (i.e. -1 if 1 won and vice versa).

Try it online! Or see the test-suite.

How?

Ḣ×)ḅ-3SṠ - Link: list of [team, hits, time] triples
  )      - for each triple:
Ḣ        -   head -> removes team and yields it
 ×       -   multiply by ([hits, time]) -> [team * hits, team * time]
   ḅ-3   - convert (each) from base -3  -> -3 ** 1 * team * hits + -3 ** 0 * team * time
                                           = team * (time - 3 * hits)
      S  - sum
       Ṡ - sign

Equivalently, Ḣ×ḅ-3)SṠ.

Similarly, Ḣ)ḋḅ-3$Ṡ (using a dot-product).

\$\endgroup\$
1
  • 1
    \$\begingroup\$ You tied with AndrovT's Vyxal answer for 8 bytes but that solution was edited in before you answered, so I accepted that answer. Sorry. \$\endgroup\$
    – The Thonnu
    Jan 26, 2023 at 7:26
2
\$\begingroup\$

Japt -g, 10 bytes

Port of Jonathan's Jelly solution.

xÈm*Xv)ì3n

Try it

xÈm*Xv)ì3n     :Implicit input of 2D array
x              :Reduce by addition after
 È             :Passing each X through the following function
  m*           :  Map & multiply by
    Xv         :    Remove & return the first element, mutating the original array
      )        :  End map
       ì       :  Convert from base
        3n     :    -3
               :Implicit output of sign of result
\$\endgroup\$
1
\$\begingroup\$

Arturo, 52 bytes

$[a][n:sum map a't->t\0*t\1-t\2*3(0=n)?->0->n/abs n]

Try it

A port of my Factor answer, though it suffers from a lack of sign function.

$[a][               ; a function taking an argument a
  n:                ; assign n to
  sum               ; sum
  map a 't ->       ; map over a and assign current element to t
    t\2 * 3         ; last number in triplet times three
    t\1 -           ; subtracted from second number in triplet
    t\0 *           ; times first number in triplet
  (0=n)?            ; is n zero?
  -> 0              ; zero if so
  -> n / abs n      ; n divided by the absolute value of n if not
]                   ; end function
\$\endgroup\$
1
\$\begingroup\$

Julia,44 bytes

a->sign(mapfoldl(i->i[1]*(i[2]-3*i[3]),+,a))

I'm taking the strategy everyone else is using by using -1 for A and 1 for B, then multiplying that by the number of seconds after deductions. Outputting the sign of the output is the team who wins, and zero is a draw.

\$\endgroup\$
1
\$\begingroup\$

05AB1E, 10 bytes

ε`3*-*}O.±

Port of almost any other answer, with input-triplets in the order [team, time, hits] and using 1 and -1 for teams \$A\$ and \$B\$ respectively, with an output of -1, 1, or 0 for Team \$B\$ wins; Team \$A\$ wins; and draw respectively.

Try it online or verify all test cases.

A port of @JonathanAllan's Jelly's answer is 10 bytes as well:

εć*3(β}O.±

Takes the inputs in the order [team, hits, time] instead. The other I/O is the same.

Try it online or verify all test cases.

Explanation:

ε      # Map over the (implicit) input-list of triplets:
 `     #  Pop and push all three values separately to the stack
  3*   #  Multiply the top `hits` by 3
    -  #  Subtract it from the `time`
     * #  Multiply it to the `team`
}O     # After the map: sum the list together
  .±   # Pop and output its sign
       # (which is output implicitly as result)

ε      # Map over the (implicit) input-list of triplets:
 ć     #  Extract head; pop and push remainder-list [hits,time] & head `team` separately
  *    #  Multiply `team` to the values in the pair: [hits*team,time*team]
   3(β #  Convert it from a base-(-3) list to an integer: team*(time-3*hits)
}O.±   # After the map: same as above (and also output implicitly)
\$\endgroup\$
1
\$\begingroup\$

Nim, 77 bytes

import math,sequtils
proc c[S](s:S):int=sgn sum s.mapIt it[0]*(it[1]-3*it[2])

Attempt This Online!

Takes 1 and -1 as the team names. Outputs the team with a bigger score, or 0 for a draw.

\$\endgroup\$
1
\$\begingroup\$

awk, 78 76 71 69 bytes

In the following, remove newline (that's only for readability) and save one byte.

  1. 79 bytes
    {s[$1]=s[$1]+$2-(3*$3)}
    END{print (s["A"]>s["B"])?"A":(s["A"]<s["B"])?"B":"="}
    
  2. 77 bytes
    {s[$1]=s[$1]+$2-(3*$3)}
    END{a=s["A"];b=s["B"];print (a>b)?"A":(a<b)?"B":"="}
    
  3. 72 bytes
    {s[$1]+=$2-(3*$3)}
    END{a=s["A"];b=s["B"];print (a>b)?"A":(a<b)?"B":"="}
    
  4. 70 bytes
    {s[$1]+=$2-3*$3}
    END{a=s["A"];b=s["B"];print (a>b)?"A":(a<b)?"B":"="}
    

There must be some tricks, I dunno, to make it shorter.

Usage and notes

Use of AWK require some adaptation of the input.

  • The outer list is a file to pass to the script.
  • The inner lists are lines of the input file.
  • Items in sub lists are separated by blanks only.

The example given (1 line for 57 bytes)

[['A', 20, 0], ['A', 30, 1], ['B', 40, 6], ['B', 20, 2]]

becomes then (4 lines for 28 bytes)

A 20 0
A 30 1
B 40 6
B 20 2

Once the data file created, let's say match.list, call the script, let's say twist.awk, by issuing the command line

awk -f twist.awk match.list

You can also replace -f twist.awk with the script directly.

Ungolfed/explanation

For golfing purposes I've used s instead of a more useful variable name.

{                       # This is the main block, executed for each line
  s[$1]=s[$1]+$2-(3*$3) # Update Score table indexed by first field (team)
                        # precisely, creation then update next iterations
}
END{                    # This block is executed once after main processing
  print "A=" s["A"],    # add this for debug purpose
        "B=" s["B"], "" ;
  (s["A"]>s["B"])       # if team A scores more than team B
    ?                   # then
    print "A"           # says that A wins
    :                   # else
    (s["A"]<s["B"])     # if team A scores less than team B
      ?                 # then
      print "B"         # says that B wins
      :                 # else
      print "="         # says it's a drawn
}

For golfing purpose, we use ternary operator in place of the if-then statement, and replace the if (cond) {foo} else {bar} becomes (cond)?{foo}:{bar} By the same way, if (cond) {foo} else if (alt) {baz} else {bar} becomes (cond)?{foo}:(alt)?{baz}:{bar} and here we can factorise print.

\$\endgroup\$
1
\$\begingroup\$

BQN, 42 bytes

Anonymous tacit prefix function.

((2⊸=≠)+(⊢⊐⌊˝))(({𝕨-3×𝕩}´+˝)¨(⊐⊏˘)⊔(1⊸↓˘))

Try it online!

Explanation

((2⊸=≠)+(⊢⊐⌊˝))(({𝕨-3×𝕩}´+˝)¨(⊐⊏˘)⊔(1⊸↓˘))
                                   ⊔        Partition...
                                    (1⊸↓˘)  the input with the first column dropped
                              (⊐⊏˘)         by the first column.
                (           )¨              Then for each partition (team)...
                          +˝                sum-reduce it...
                 {𝕨-3×𝕩}´                   and calculate its score.
(      +       )                            Then sum...
         (⊢⊐⌊˝)                             the index with the minimum value...
 (2⊸=≠)                                     to whether the length is 2

Some positives include that the code works on the original input as is (i.e.

[['A', 100, 5], ['B', 95, 2]]

is a valid input), and that it accepts any labelling of the teams (A/B, -1/1).

Some negatives include that it doesn't apply the neat sign trick that everyone else is using and that it's (albeit lightly) hardcoded the number of teams to 2.

Oh and that it's so damn long. Any help translating the regular strategy to an array language (APL, J, K etc.)?

\$\endgroup\$
1
\$\begingroup\$

C (clang), 59 58 bytes

s;f(*p){for(s=0;*p;)s+=*p++*(*p++-*p++*3);*p=(s>0)-(s<0);}

Try it online!

Saved a byte thanks to ceilingcat!!!

Inputs a pointer to a \$0\$ terminated (because pointers in C don't carry any length info) array of integer triplets of the side (\$1\$ for the first team and \$-1\$ for the second), the time, and the number of hits.
Returns (at the end of the input array) \$-1\$ for a win by the first team, \$1\$ for a win by the second, and \$0\$ for a draw.

\$\endgroup\$
1
  • \$\begingroup\$ @ceilingcat Nice one - thanks! :D \$\endgroup\$
    – Noodle9
    Jan 3 at 14:52
1
\$\begingroup\$

Perl 5 -pa, 35 bytes

${$F[0]}+=$F[1]-$F[2]*3}{$\=$A<=>$B

Try it online!

Teams are A & B. Input is one turn per line with numbers space separated from the team name. Output is -1 for team A, 0 for draw, 1 for team B.

\$\endgroup\$
0
\$\begingroup\$

Thunno, \$ 11 \log_{256}(96) \approx \$ 9.05 bytes

eAu3*-*ESza

Attempt This Online! or verify all test cases.

Port of AndrovT's Vyxal answer

Explanation

eAu3*-*ESza  # Implicit input
e      E     # Map over the input:
 Au          #  Dump the contents onto the stack
   3*        #  Triple (the hits)
     -       #  Subtract (from the time)
      *      #  Multiply (by the team)
        S    # Sum
         za  # Sign
             # Implicit output
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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