10
\$\begingroup\$

Multi-level marketing related challenge.

A peer wants to get rewarded. So it attracted N investors (N>=1), each i-th investor invested x[i]. When a total sum exceeds threshold x[0]+x[1]+...+x[N-1] >= T a peer could be rewarded. But only if a following conditions are satisfied:

  • Minimum amount of investors should be greater than M, (M<=N)
  • For at least one integer k, where k>=M and k<=N, any k investors have to invest at least T/k each;

Given N, x[], T, M you should determine whether the peer's reward is generated or not (boolean result, "yes" or "no"). Shortest code wins.

Examples:


N=5; M=3; T=10000, in order to generate the peer's reward one of the following must be satisfied:

  • any 3 invested at least 3334 each
  • any 4 invested at least 2500 each
  • all 5 invested at least 2000 each

N=6; M=2; T=5000:

  • any 2 invested at least 2500 each
  • any 3 invested at least 1667 each
  • any 4 invested at least 1250 each
  • any 5 invested at least 1000 each
  • all 6 invested at least 834 each

generalized: for any k, where k>=M and k<=N:

  • any k of N investors invested at least T/k each

Test cases:

format:

N, x[], T, M -> correct answer

6, [999, 999, 59, 0, 0, 0], 180, 3 -> 0
6, [0, 60, 0, 60, 60, 0], 180, 3 -> 1
6, [179, 89, 59, 44, 35, 29], 180, 3 -> 0
6, [179, 89, 59, 44, 35, 30], 180, 3 -> 1
6, [179, 89, 59, 44, 36, 29], 180, 3 -> 1
6, [179, 90, 59, 44, 35, 29], 180, 3 -> 0
6, [30, 30, 30, 30, 29, 30], 180, 3 -> 0
6, [30, 30, 30, 30, 30, 30], 180, 3 -> 1
\$\endgroup\$
  • 1
    \$\begingroup\$ @JonathanAllan Sure, if your language allows it, and writing len(x) will be shorter than writing N. That is made, because for dynamically allocated array x in C there is no direct len(x) function - so you may always refer to length as N. For convenience, you may consider all input data N, x[], T, M as some externally defined constants, or some language built-ins. \$\endgroup\$ – xakepp35 Jan 6 at 16:32
  • 1
    \$\begingroup\$ I don't think those notifications reached them (with the hyphens) as I got them in my inbox. \$\endgroup\$ – Jonathan Allan Jan 6 at 17:03
  • 1
    \$\begingroup\$ @JonathanAllan not quite familar with pinging syntax, and non-latin names.. maybe they will return some day :) \$\endgroup\$ – xakepp35 Jan 6 at 17:17
  • 1
    \$\begingroup\$ Also, can output be reversed? A falsey value for true and truthy value for false? \$\endgroup\$ – Shaggy Jan 6 at 23:25
  • 1
    \$\begingroup\$ @WîtWisarhd Code golf is a winning criterion... look at the tags. \$\endgroup\$ – mbomb007 Jan 8 at 0:47

15 Answers 15

4
\$\begingroup\$

Jelly,  12  9 bytes

ṢṚ×J$ṫ⁵<Ṃ

A full program which accepts x T M and prints 0 if the peer is rewarded and 1 if not.

Try it online!

How?

ṢṚ×J$ṫ⁵<Ṃ - Main Link: list of numbers, x; number, T   e.g. [100, 50, 77, 22, 14, 45], 180
Ṣ         - sort x                                          [ 14, 22, 45, 50, 77,100]
 Ṛ        - reverse                                         [100, 77, 50, 45, 22, 14]
    $     - last two links as a monad:
   J      -   range of length                               [  1,  2,  3,  4,  5,  6]
  ×       -   multiply                                      [100,154,150,180,110, 84]
     ṫ    - tail from index:
      ⁵   -   5th argument (3rd input), M   (e.g. M=3)      [        150,180,110, 84]
       <  - less than T?                                    [          1,  0,  1,  1]
        Ṃ - minimum                                         0
\$\endgroup\$
  • \$\begingroup\$ seems not working: tio.run/##y0rNyan8///hzkWHp/uoHJ5wbMnDnasfNW61ebiz6dCah7sW/P//… \$\endgroup\$ – xakepp35 Jan 6 at 18:08
  • \$\begingroup\$ in example third investor invested less than 1/3rd of T (less than 33), but result still counted as positive ("any k invested at least T/k each" failed) \$\endgroup\$ – xakepp35 Jan 6 at 18:10
  • \$\begingroup\$ Yeah, I created it using prefixes of reverse-sorted values and thought I could change it to postfixes of sorted, but actually couldn't because I'm then tailing... reverted :) \$\endgroup\$ – Jonathan Allan Jan 6 at 18:12
  • 1
    \$\begingroup\$ Yeah, now I've finished golfing I'm writing an explanation. \$\endgroup\$ – Jonathan Allan Jan 6 at 18:29
  • 1
    \$\begingroup\$ It now "prints 0 if the peer is rewarded and 1 if not". (i.e. 0 is "yes"). It saves 1 byte :) \$\endgroup\$ – Jonathan Allan Jan 6 at 18:43
3
\$\begingroup\$

05AB1E, 9 bytes

{Rƶ.ssè›ß

Try it online or verify all test cases.

Port of @JonathanAllan's Jelly answer, so also takes the inputs x T M and outputs 0 for "yes" and 1 for "no". If this is not allowed, and it should be inverted, a trailing _ can be added.

Explanation:

{           # Sort the (implicit) input `x`
            #  i.e. `x`=[100,50,77,22,14,45] → [14,22,45,50,77,100]
 R          # Reverse it
            #  i.e. [14,22,45,50,77,100] → [100,77,50,45,22,14]
  ƶ         # Multiply it by it's 1-indexed range
            #  i.e. [100,77,50,45,22,14] → [100,154,150,180,110,84]
   .s       # Get all the suffices of this list
            #  i.e. [100,154,150,180,110,84]
            #   → [[84],[110,84],[180,110,84],[150,180,110,84],[100,154,150,180,110,84]]
     s      # Swap to take the (implicit) input `T`
      è     # Get the prefix at index `T`
            #  i.e. [[84],[110,84],[180,110,84],[150,180,110,84],[100,154,150,180,110,84]]
            #   and `T=3` → [150,180,110,84]
       ›    # Check for each list-value if the (implicit) input `M` is larger than it
            #  i.e. [150,180,110,84] and `M`=180 → [1,0,1,1]
        ß   # And pop and push the minimum value in the list (which is output implicitly)
            #  i.e. [1,0,1,1] → 0

Alternative for .ssè:

sG¦}

Try it online or verify all test cases.

Explanation:

s       # Swap to take the (implicit) input `T`
 G }    # Loop `T-1` times:
  ¦     #  Remove the first item from the list that many times
        #   i.e. [100,154,150,180,110,84] and `T=3` → [150,180,110,84]
\$\endgroup\$
  • 1
    \$\begingroup\$ I didn't stated on "how should you map output", just that it have to be boolean (to has only 2 states). So yes, definetely you may use 0 for "yes" and 1 for "no" :) \$\endgroup\$ – xakepp35 Jan 7 at 9:04
2
\$\begingroup\$

JavaScript, 54 52 bytes

(x,t,m,n)=>x.sort((a,b)=>a-b).some(i=>i*n-->=t&n>=m)

Try it online

\$\endgroup\$
  • \$\begingroup\$ Also 35-40% more performant that 72-byted solution. Lovely code, felt like its ready to be embedded in production MLM-related web projects :^) \$\endgroup\$ – xakepp35 Jan 7 at 9:12
  • \$\begingroup\$ Just noticed. Test case #2 [0, 60, 0, 60, 60, 0], 180, 3 -> true seems to be not working! 72 byted bersion handles it ok. Bug or feature?) \$\endgroup\$ – xakepp35 Jan 24 at 14:23
2
\$\begingroup\$

Retina, 79 bytes

\d+
*
O^`_+(?=.*])
_+(?=.*])(?<=(\W+_+)+)
$#1*$&
+`\W+_+(.*_)_$
$1
(_+).*], \1,

Try it online! Takes input in the format [x], T, M. Link includes test cases. Explanation:

\d+
*

Convert to unary.

O^`_+(?=.*])

Sort [x] in descending order.

_+(?=.*])(?<=(\W+_+)+)
$#1*$&

Multiply each element of [x] by its index.

+`\W+_+(.*_)_$
$1

Delete the first M-1 elements of [x].

(_+).*], \1,

Test whether any remaining element of [x] is greater or equal to T.

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

Perl 6, 46 33 29 bytes

{$^b>all $^a.sort Z*[...] @_}

Try it online!

Anonymous code blocks that takes input in the form list, amount, length of list, minimum amount of investors and returns a truthy/falsey all Junction, where truthy is failed and falsey is success.

Explanation:

{                           }  # Anonymous code block
     all                       # Are all of
         $^a.sort                # The sorted list
                  Z*             # Zip multiplied by
                     [...] @_    # The range from length of list to the minimum amount
 $^b>                          # Not smaller than the given amount?
\$\endgroup\$
2
\$\begingroup\$

05AB1E, 6 bytes

Input taken in the order T, N, x[], M
Output is 0 for peer reward and 1 if not

Ÿs{*›W

Try it online! or as a Test Suite

Explanation

Ÿ        # push the range [N ... T]
 s{      # push the list x[] sorted ascending
   *     # elementwise multiplication (crops to shortest list)
    ›    # for each element, check if M is greater than it
     W   # push min of the result
         # output implicitly
\$\endgroup\$
  • \$\begingroup\$ Nice trick of using * with the range to implicitly crop the list! \$\endgroup\$ – Kevin Cruijssen Jan 7 at 14:03
2
\$\begingroup\$

C# (.NET Core), 129, 89 bytes

EDIT: Thanks to Kevin Cruijssen for golfing off 40 bytes while explaining the mechanics as to why!

(n,q,t,m)=>{int c=0,j;for(;m<=n&c<1;c=c<m++?0:1)for(j=n;j-->0;)c+=q[j]<t/m?0:1;return c;}

Try it online!

\$\endgroup\$
  • 1
    \$\begingroup\$ 106 bytes Some of the things I've changed: Removed the input n since you don't use it anywhere; removed k since you can use m itself; added a variable l for q.Length since you use it twice; combined the variables int c=0,l=q.Length,j; so you don't need the additional var; removed the unnecessary brackets by putting everything in the for-loop body; changed the c>=k check to c<k; and changed the if(c>0)break; to m=c>0?l+1:m;, since the loop stops if m<=l, changing m to l+1 saves a byte over break (and it also saves on 2 brackets). :) \$\endgroup\$ – Kevin Cruijssen Jan 8 at 16:09
  • 1
    \$\begingroup\$ If you haven't seen it yet, Tips for golfing in C# and Tips for golfing in <all languages> might be interesting to read, through. \$\endgroup\$ – Kevin Cruijssen Jan 8 at 16:10
  • 1
    \$\begingroup\$ 89 bytes Some additions to the golfs in my first comment. The m=c>0?l+1:m can be removed completely and a &c<1 check can be added to the loop instead. And by taking the input n again, you don't need the q.Length anymore but can use n instead. \$\endgroup\$ – Kevin Cruijssen Jan 8 at 16:46
2
\$\begingroup\$

C# (Visual C# Interactive Compiler) with flag /u:System.Linq.Enumerable, 69 bytes

(n,x,t,m)=>Range(0,n-m+1).Where(b=>x.Count(a=>a>=t/(b+m))>=b+m).Any()

Try it online!

// Takes in 4 parameters as input
(n,x,t,m)=>
// Create a new array with the length of all the numbers from m to n, inclusive
Range(0,n-m+1)
// And filter the results by
.Where((_,b)=>
// If the number of people that invested more than the total amount divided by the index plus m
x.Count(a=>a>=t/(b+m))
// Is greater than the index plus m
>= b+m)
// And check if there is at least one value in the filtered IEnumerable<int>, and if there is, return true
.Any()

Without any flags, 73 bytes

(n,x,t,m)=>new int[n-m+1].Where((_,b)=>x.Count(a=>a>=t/(b+m))>=b+m).Any()

Try it online!

\$\endgroup\$
  • \$\begingroup\$ I thought of that, and stated in the description that N>=1, and M<=N So you may shorten your solution a bit :) \$\endgroup\$ – xakepp35 Jan 7 at 9:02
1
\$\begingroup\$

JavaScript, 72 bytes

Code

(x,T,M)=>x.sort(t=(d,e)=>e-d).map((s,i)=>s*i+s).slice(M-1).sort(t)[0]>=T

Try it online!

Accepts input in format (x[],T,M)

Explanation

x.sort(t=(d,e)=>e-d)     \\sort numbers in reverse numerical order
.map((s,i)=>s*i+s)       \\Multiply each number in array by position(1 indexed) in array
.slice(M-1)              \\Remove the first M-1 elements (at least M people)
.sort(t)[0]              \\Get the maximum value in the array
>=T                      \\True if the maximum value is >= the threshold
\$\endgroup\$
  • \$\begingroup\$ 54 bytes? \$\endgroup\$ – Arnauld Jan 6 at 22:26
  • 1
    \$\begingroup\$ (Or 53 bytes if the meaning of the Boolean value can be inverted.) \$\endgroup\$ – Arnauld Jan 6 at 22:52
  • \$\begingroup\$ @Arnauld, 52 bytes ;) \$\endgroup\$ – Shaggy Jan 6 at 23:23
  • \$\begingroup\$ (By the way, I came up with my solution independently of your comment, in case you were wondering - it's a port of my Japt solution. On mobile so can't see timestamps properly to tell who posted first.) \$\endgroup\$ – Shaggy Jan 6 at 23:40
1
\$\begingroup\$

Python 3, 136 bytes

Just tests the conditions to make sure they are met. 1 if the reward is given, 0 if not.

lambda N,x,T,M:(sum(x)>=T)*(M<=N)*any(any(all(j>=T/k for j in i)for i in combinations(x,k))for k in range(M,N+1))
from itertools import*

Try it online!

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

Python,  71  65 bytes

lambda x,T,M:all(i*v<T for i,v in enumerate(sorted(x)[-M::-1],M))

Try it online!

An unnamed function; port of my Jelly answer. As such "yes" is False and "no" is True. Here, however, we discard test-cases as a part of the reversal and take advantage of the ability to initiate the enumerate count to M. (min would also work in place of all)

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

R, 43 42 bytes

-1 bytes by implementing the approach even more closely

function(N,x,S,M)min(sort(x,T)[M:N]*M:N<S)

Try it online!

Simple R implementation of Jonathan's Jelly approach. I tried a bunch of variations but this pips the best I could think of by a few bytes.

1 implies failure, 0 implies success.

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

Japt, 16 14 13 11 bytes

ñ í*WõX)d¨V

Try it

ñ í*WõX)d¨V
                  :Implicit input of array U=x and integers V=T, W=M & X=N
ñ                 :Sort U
  í               :Interleave with
    WõX           :  Range [W,X]
   *              :  And reduce each pair of elements by multiplication
       )          :End interleaving
        d         :Any
         ¨V       :  Greater than or equal to V
\$\endgroup\$
0
\$\begingroup\$

Java 8, 91 (or 89?) bytes

(N,x,T,M)->{int c=0,j;for(;M<=N&c<1;c=c<M++?0:1)for(j=N;j-->0;)c+=x[j]<T/M?0:1;return c;}

Port of @Destroigo's C# .NET answer (after I golfed it some more), so make sure to upvote him!

Takes inputs N,x,T,M and outputs true/false for "yes"/"no" respectively.

Since the challenge specifically asks for boolean results, I can't return the 1/0 as is, since those aren't valid truthy/falsey values in Java. If any two distinct output values for "yes"/"no" is valid for this challenge instead, the >0 in the return can be dropped to save two bytes, in which case it'll return 1/0 for "yes"/"no" respectively.

Try it online.

Explanation:

(N,x,T,M)->{           // Method with the four parameters and boolean return-type
  int c=0,             //  Count integer, starting at 0
      j;               //  Temp index integer
  for(;M<=N            //  Loop as long as `M` is smaller than or equal to `N`
       &c<1            //  and `c` is not 1 yet:
      ;                //    After every iteration:
       c=c<M++?        //     If `M` is smaller than `c`:
                       //     (and increase `M` by 1 afterwards with `M++`)
          0            //      Set `c` to 0
         :             //     Else:
          1)           //      Set `c` to 1
    for(j=N;j-->0;)    //   Inner loop `j` in the range (`N`,0]:
       c+=             //    Increase the counter `c` by:
          x[j]         //     If the `j`'th value in `x`
              <T/M?    //     is smaller than `T` divided by `M`:
                   0   //      Leave the counter `c` unchanged by adding 0
                  :    //     Else:
                   1;  //      Increase the counter `c` by 1
  return c>0;}         //  Return whether the counter `c` is 1
\$\endgroup\$
0
\$\begingroup\$

C# (Visual C# Interactive Compiler), 66 bytes

(n,x,t,m)=>Enumerable.Range(m,n-m+1).Any(k=>x.Count(y=>y>=t/k)>=k)

Try it online!

Inspired by @EmbodimentOfIgnorance's answer.

I've mentioned this before, but C# 8 has a range literal which could make this answer something like this:

(n,x,t,m)=>[m..n-m+1].Any(k=>x.Count(y=>y>=t/k)>=k)

I saw a link to SharpLab with an example, but I wasn't able to get it to work myself.

One thing I changed was the x and t values are decimals. This handles the case where t is not divisible by k a little better.

\$\endgroup\$

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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