12
\$\begingroup\$

You are the captain of a world-famous wrestling team. An Olympic-grade match is coming up, and you are determined not to let your team down. You also happen to be a competent programmer, so you are going to write a program to help your team win!

You have access to the strength ratings for each of your own team wrestlers, and each of the opponent wrestlers. A wrestler will win their match only when their strength rating is greater than their opponent's strength rating. You have to write a program that will calculate the optimum pairing for each of your own wrestlers against each of the opponent wrestlers, and then output the maximum number of matches that can be won as a result.

Input

Your program will take as input three arguments:

  1. The number of members per team, there will be an equal number of wrestlers on each team. (Optional)
  2. The strength rating of each of your team wrestlers, which is a number between 1 and 10.
  3. The strength rating of each of the opponent wrestlers, which is a number between 1 and 10.

Output

Calculate the optimum pairing for each of your own wrestlers against each of the opponent wrestlers, and then output the maximum number of matches that can be won as a result.

Test cases

Test case 1:

Input:
5
2  4 6 2 6
3 10 6 7 7


Output: 1

Test case 2:

Input:
10
1  9 5 5 1 6 2 8  3  6
6 10 2 8 2 3 5 6 10 10


Output: 6
```
\$\endgroup\$
5
  • 5
    \$\begingroup\$ Hello, and welcome to CG&CC! In general when writing a new challenge you want to post it to the Sandbox first, to fix issues before answers can be submitted. The challenge itself seems fine (although I wouldn't be surprised if it's a duplicate), but the input format is stricter than is customary on this site and it would help to have outputs from the given test cases. \$\endgroup\$ May 21, 2020 at 21:48
  • 1
    \$\begingroup\$ Leaving aside for the moment that this very much feels like a dupe (I vaguely remember something with armies instead of wrestlers), this is in desperate need of a couple of worked examples and much looser I/O formats. \$\endgroup\$
    – Shaggy
    May 21, 2020 at 22:44
  • 3
    \$\begingroup\$ Do we have to take the first number? \$\endgroup\$
    – Wezl
    May 21, 2020 at 22:47
  • \$\begingroup\$ @Wezl you don't have to if you don't want to. It's there if you want it for help iterating through the list \$\endgroup\$ May 21, 2020 at 22:48
  • 1
    \$\begingroup\$ @Wezl As a side note, input can always be ignored as per this consensus. \$\endgroup\$
    – Arnauld
    May 22, 2020 at 12:16

14 Answers 14

11
\$\begingroup\$

Python 2, 59 57 bytes

-2 bytes thanks to @dingledooper!

lambda a,b:sum(b.sort()<b<[x]>b.pop(0)for x in sorted(a))

Try it online!

A function that takes 2 lists as arguments, and returns the maximum number of matches that can be won.

Approach

For each opponent (from weakest to strongest), match that opponent with the weakest available member of my team that can win.

For example, let's say the strength of 2 teams (sorted) are as follow:

No.       1  2  3  4  5
Me       [2, 2, 4, 5, 8]
Opponent [3, 6, 7, 7, 9]
  • The 1st opponent has strength 3, so we need to match that with our 3rd team member.
  • The 2nd opponent has strength 6, so we match that with our 5th.

We cannot win any more match. So in total we can win at most 2 matches.

Ungolfed code

a,b=map(sorted,input())  # sorted strength of my team and opponent team
s = 0                    # number of matches that can be won
for x in a:              # loop through my team, in order of increasing strength
  if x > b[0]:             # if current member can beat the weakest opponent left
    s += 1                   # then match those two
    b.pop(0)                 # and remove the weakest opponent
                           # (otherwise, current member is useless)
print s
\$\endgroup\$
3
  • 2
    \$\begingroup\$ I like the idea with the b<[x]>b.pop(0). I think you can get 57 bytes with a function, though. \$\endgroup\$ May 21, 2020 at 22:55
  • \$\begingroup\$ @dingledooper Thanks! I was having trouble sorting b in a function, that's really clever. \$\endgroup\$ May 21, 2020 at 22:58
  • \$\begingroup\$ This is very nice, and - annoyingly - the R ported version is shorter than my own first attempt (so I'm stealing it, with acknowledgement) \$\endgroup\$ May 22, 2020 at 9:48
6
\$\begingroup\$

C (gcc) -zexecstack, 124 \$\cdots\$ 105 103 bytes

Saved a whopping 2 17 19 21 bytes thanks to ceilingcat!!!

#define q(x)qsort(x,i=n,4,L"\x62b078bǃ");
i;j;f(a,b,n)int*a,*b;{q(a)q(b)for(j=0;i--;j+=*a++>b[j]);i=j;}

Try it online!

How

Sorts the two teams from weakest to strongest. Then goes through our side, starting from weakest, comparing it to the \$j^{\text{th}}\$ member of the opponent's team starting at \$j=0\$, their weakest wrestler. If we are ever stronger than the \$j^{\text{th}}\$ member we increment \$j\$. After we go through all our wrestlers, \$j\$ will be the maximum number we can beat.

\$\endgroup\$
1
  • 2
    \$\begingroup\$ +1 for algorithm, now adapted to R with acknowledgement \$\endgroup\$ May 22, 2020 at 10:14
4
\$\begingroup\$

Jelly, 5 bytes

Œ!>§Ṁ

Try it online!

The second test case times out on TIO, but I have verified it locally. Takes your lineup as the left argument and theirs as the right.

Œ!       Find every permutation of your lineups' strengths,
  >      compare each matchup for each permutation,
   §     sum your wins for each permutation,
    Ṁ    and return the maximum number of wins.
\$\endgroup\$
4
\$\begingroup\$

APL (Dyalog Extended), 16 bytes

(+/⊢≥⍋)0~⍨1⊥<\⍥∧

Try it online!

An almost direct port of Jonah's J answer. But unfortunately, I found that, despite having the same name "interval index", J's I. and APL's don't have the identical behavior; J finds the indices before identical elements, but APL does after them.

  • J: echo 1 3 5 I. 0 1 2 3 4 5 6 gives 0 0 1 1 2 2 3
  • APL: ⎕←1 3 5 ⍸ 0 1 2 3 4 5 6 gives 0 1 1 2 2 3 3

That makes hard to use for this problem, so I had to fall back to outer product (which is used in the previous version of Jonah's answer).

How it works

(+/⊢≥⍋)0~⍨1⊥<\⍥∧  ⍝ Left: opponent strengths, Right: ours
              ⍥∧  ⍝ Ascending sort both args
          1⊥<\    ⍝ Outer product by < and then sum;
                  ⍝ count the opponents who each of ours can win against
       0~⍨  ⍝ Remove zeros
(    ⍋)     ⍝ Grade up; this is identical to ⍳∘≢ here since the arg is sorted
   ⊢≥       ⍝ Check if each number is at least its index
 +/         ⍝ Sum; count ones
\$\endgroup\$
2
  • \$\begingroup\$ But am I screwing-up, or are there cases for which this doesn't work? \$\endgroup\$ May 22, 2020 at 9:45
  • \$\begingroup\$ @Bubbler, He's correct (my error). See my update for a simple fix that ended up improving my score. \$\endgroup\$
    – Jonah
    May 22, 2020 at 13:49
4
\$\begingroup\$

05AB1E, 5 bytes

Coincidental port of Unrelated String's Jelly answer.

œ€‹Oà

Try it online!

Explanation

œ     All permutations to your team's combination
 €‹   Does your team win at this position?
   O  Sum the resulting lists to get all wins
    à Return the largest item of the list
\$\endgroup\$
4
\$\begingroup\$

J, 25 22 20 bytes

0(]+>)/@|.@,I.&(/:~)

Try it online!

-3 bytes thanks to Bubbler

Thanks to Dominic van Essen for spotting a subtle bug (now fixed)


This could be shorter using brute force, but I wanted to see how short I could make an efficient solution.

Our team = right arg, their team = left arg.

Using 2nd test case an example:

6 10 2 8 2 3 5 6 10 10 f 1 9 5 5 1 6 2 8 3 6 
  • &(/:~) Sort both arguments:

    2 2 3 5 6 6 8 10 10 10
    1 1 2 3 5 5 6  6  8  9
    
  • I. Uses Interval Index to determine how many of their players each of our players beats:

    0 0 0 2 3 3 4 4 6 7
    
  • 0...|.@, Prepend a 0 and reverse:

    2 3 3 4 4 6 7
    
  • (]+>)/ Now reduce from the right as follows: Take the right arg ] (the running sum, seeded at 0), compare the two args using > (returns 1 if left arg is greater than running sum, 0 otherwise), and add the two.

    This means the running sum will increment exactly when "the number of opponents the current wrestler can beat" is greater than "opponents already beaten by other teammates".

    The final result will be the total number of players our team can beat.

\$\endgroup\$
4
  • \$\begingroup\$ I.~&(/:~) (interval index) gives the same results as 1#.>/&(/:~), and you can remove ~ by swapping args. \$\endgroup\$
    – Bubbler
    May 22, 2020 at 0:55
  • \$\begingroup\$ Nice observation! Tyvm. \$\endgroup\$
    – Jonah
    May 22, 2020 at 1:02
  • \$\begingroup\$ But what about us: 1 2 3 3 5 5 6 6 7 9, them: 0 0 2 2 3 6 6 6 7 9 ? Our 1 beats their 0, 2 beats 0, 3 beats 2, 3 beats 2, 5 beats 3, 7 beats 6, and 9 beats 6, so total = 7. \$\endgroup\$ May 22, 2020 at 9:40
  • \$\begingroup\$ @DominicvanEssen Great spot! I've fixed the problem which ended up leading to a solution that's 2 bytes shorter. \$\endgroup\$
    – Jonah
    May 22, 2020 at 13:27
3
\$\begingroup\$

R, 58 54 bytes

function(a,b){for(i in sort(a))F=F+(i>sort(b)[F+1]);F}

Try it online!

Algorithm based on Noodle9's solution; this could be made shorter than my own original recursive solution 76 bytes or than one based on the elegant algorithm of Surculose Sputum 73 bytes in R

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

Io, 66 bytes

Algorithm based on Noodle9's solution.

method(x,y,F :=0;x sort map(i,F=F+if(i>y sort at(F+1),1,0))last+1)

Try it online!

Explanation

method(x, y,      // Take 2 arguments.
    F := 0        // Initialize the counter to 0.
    x sort map(i, // For every item in sorted x:
        F = F + if( // Add the counter by:
            i>y sort at(F+1), // if the current item is larger than sorted y at the same position
            1,0)    // converted to an integer
    ) last + 1)     // Add the last item of the map by 1
\$\endgroup\$
2
\$\begingroup\$

Charcoal, 41 bytes

≔I⪪η η≔I⪪ζ ζWΦη›κ⌊ζ«§≔η⌕η⌊ι⁰§≔ζ⌕ζ⌊ζχ»I№η⁰

Try it online! Link is to verbose version of code. Explanation:

≔I⪪η η

Input the ratings of your wrestlers.

≔I⪪ζ ζ

Input the ratings of your opponents.

WΦη›κ⌊ζ«

Repeat while at least one of your wrestlers can beat one of your opponents.

§≔η⌕η⌊ι⁰

Set the strength of the weakest such wrestler to 0, so it will no longer be considered.

§≔ζ⌕ζ⌊ζχ

Similarly set the strength of its opponent to 10, so it will also no longer be considered.

»I№η⁰

Count and output the number of wins.

If the input was sorted, the calculation could be done in 19 bytes. Unfortunately it takes me 30 bytes to sort the input...

\$\endgroup\$
2
\$\begingroup\$

JavaScript (ES6), 61 bytes

A shorter version inspired by @SurculoseSputum's answer.

a=>b=>(g=a=>a.sort((a,b)=>a-b))(a).map(x=>k+=x>g(b)[k],k=0)|k

Try it online!

That would be 31 bytes if the arrays were already sorted in ascending order:

a=>b=>a.map(x=>k+=x>b[k],k=0)|k

JavaScript (ES6),  85  75 bytes

Takes input as two lists of integers (team, opponents).

a=>b=>a.map(x=>(b[i=b.sort((a,b)=>b-a).findIndex(y=>x>y)]=a,~i&&++k),k=0)|k

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Wolfram Language (Mathematica), 48 bytes

Max[t=#2;Tr@Boole@Thread[#>t]&/@Permutations@#]&

Try it online!

Unnamed function taking two arguments as input (first our team, then their team), each as comma-separated lists such as {2,4,6,2,6}. Brute-force check over all Permutations of the input, taking the Max. Mathematica doesn't automatically compare lists elementwise, but Thread[#>t] forces it to; Boole converts Trues and Falses to 0s and 1s, respectively, so that Tr counts the number of wins. Mathematica is bad with currying when it's not programmed into the builtins, so I couldn't see a better way to handle the arguments than t=#2;.

\$\endgroup\$
2
\$\begingroup\$

k4, 27 bytes

{{x+y>x}/binr/{x@<x}'(y;x)}

Another port of Jonah's J answer, this time to k4.

If the input can be taken as a single list of two vectors, e.g. (3 10 6 7 7;2 4 6 2 6) (with the opposing team as the first list item, and our team as the second), the code can be simplified to 22 bytes as:

{{x+y>x}/binr/x@'<:'x}
\$\endgroup\$
1
\$\begingroup\$

Japt -h, 10 bytes

á Ëí>V xÃn

Try it

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

Scala, 168 bytes

Golfed version. Attempt this online!

def f(a:Array[Int],b:Array[Int])={var B=b.sorted;var sA=a.sorted;sA.foldLeft(0){(s,x)=>val C=B.dropWhile(_<x);val c=C.nonEmpty&&C(0)==x;if(c){B=B.drop(1);s+1}else s}-1}

Ungolfed version. Attempt this online!

def f(a: Array[Int], b: Array[Int]): Int = {
  var sortedB = b.sorted
  var sortedA = a.sorted
  sortedA.foldLeft(0) { (sum, x) =>
    val removedB = sortedB.dropWhile(_ < x)
    val condition = removedB.nonEmpty && removedB.head == x
    if (condition) {
      sortedB = sortedB.drop(1)
      sum + 1
    } else sum
  } - 1
}

But the scala code fails at the case val input3 = Array(Array(10), Array(3,6,7,5,3,5,6,2,9,1), Array(2,7,0,9,3,6,0,6,2,6)). Any help would be appreciated.

\$\endgroup\$

Your Answer

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

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