Multi-level marketing "legs" investment rule

10

0

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

xakepp35

Posted 2019-01-06T16:12:27.540

Reputation: 293

N is implied by len(x), I suppose we can but do not have to take it as an input, right? – Jonathan Allan – 2019-01-06T16:30:15.127

1@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. – xakepp35 – 2019-01-06T16:32:57.540

@luis-mendo It's unclear "what is exactly unclear?" – xakepp35 – 2019-01-06T16:55:43.030

@erik-the-outgolfer Could you explain? – xakepp35 – 2019-01-06T16:55:54.623

1I don't think those notifications reached them (with the hyphens) as I got them in my inbox. – Jonathan Allan – 2019-01-06T17:03:22.767

1@JonathanAllan not quite familar with pinging syntax, and non-latin names.. maybe they will return some day :) – xakepp35 – 2019-01-06T17:17:58.917

It might be worth adding some test cases ...including some at edges like: 6, [100, 50, 77, 22, 14, 44], 180, 3 -> 0; and 6, [100, 50, 77, 22, 14, 45], 180, 3 -> 1. – Jonathan Allan – 2019-01-06T17:48:09.293

Does M have a minimum value? e.g. at least more than 0, or can it also be negative? – Embodiment of Ignorance – 2019-01-06T20:58:06.930

Can M be 0-indexed? (i.e., 2 in each of the test cases) – Shaggy – 2019-01-06T22:51:34.897

1Also, can output be reversed? A falsey value for true and truthy value for false? – Shaggy – 2019-01-06T23:25:27.957

@EmbodimentofIgnorance, I don't think it would be possible to have a negative number of investors! But the first part of your question does need answering; the current requirements that M<=N>=1 do imply that M could be 0. – Shaggy – 2019-01-06T23:57:52.433

Can't the second bullet point be more simply put as "Each investor must invest $T/N$"? If there is any $k$ that fulfills the requirements it holds that $k=N$ fulfills the requirement and of course the converse is trivial. Am I missing something? – Post Rock Garf Hunter – 2019-01-07T18:15:16.533

There also doesn't seem to be a winning criterion? – Post Rock Garf Hunter – 2019-01-07T18:17:36.867

1@WîtWisarhd Code golf is a winning criterion... look at the tags. – mbomb007 – 2019-01-08T00:47:33.080

@WitWisarhd Initially it was there, but was removed after a bit of thinking - it does distract away from real condition point, and it can be derived, (just check condition for a case k==N) – xakepp35 – 2019-01-08T09:41:20.613

I noticed the example for N=5; M=3; T=10000 allows for 3 investors with 3334. This implies that "integer division" (i.e. round down) wouldn't work. Was this intentional? – dana – 2019-01-10T17:43:39.627

Answers

4

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

Jonathan Allan

Posted 2019-01-06T16:12:27.540

Reputation: 67 804

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) – xakepp35 – 2019-01-06T18:10:29.870

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 :) – Jonathan Allan – 2019-01-06T18:12:41.303

Yes, now border test case [179, 89, 59, 44, 35, 29], 180, 3 correctly gives 0. And any increment of four last values will yield 1 – xakepp35 – 2019-01-06T18:19:07.330

Saved a couple of bytes by noticing I don't actually need each prefix, but only the last value of each prefix. Also flipped around 0 and 1 to save a byte – Jonathan Allan – 2019-01-06T18:26:00.860

Added test cases, for convenience. Can you please explain how does that code work? :) I dont know Jelly.. – xakepp35 – 2019-01-06T18:27:36.963

1Yeah, now I've finished golfing I'm writing an explanation. – Jonathan Allan – 2019-01-06T18:29:30.820

Elegant solution, but strange, output is 1 now again. Even for [0, 0, 0, 0, 0, 0] output is 1 – xakepp35 – 2019-01-06T18:42:04.760

1It now "prints 0 if the peer is rewarded and 1 if not". (i.e. 0 is "yes"). It saves 1 byte :) – Jonathan Allan – 2019-01-06T18:43:29.280

I think yours is to be accepted! You were the first to post it, given a great explanation, a port to python, and had most influence to many's other answers. Also its still shortest. Well done, great job! – xakepp35 – 2019-01-20T15:57:26.463

Btw, are you familar with hilbert curve? Could you help me to find efficient algorithm to converting 2D image to 1D representation with spatial locality property?

– xakepp35 – 2019-01-20T16:00:27.117

3

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]

Kevin Cruijssen

Posted 2019-01-06T16:12:27.540

Reputation: 67 575

1I 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" :) – xakepp35 – 2019-01-07T09:04:31.477

2

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!

Embodiment of Ignorance

Posted 2019-01-06T16:12:27.540

Reputation: 7 014

I thought of that, and stated in the description that N>=1, and M<=N So you may shorten your solution a bit :) – xakepp35 – 2019-01-07T09:02:26.200

2

JavaScript, 54 52 bytes

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

Try it online

Shaggy

Posted 2019-01-06T16:12:27.540

Reputation: 24 623

Also 35-40% more performant that 72-byted solution. Lovely code, felt like its ready to be embedded in production MLM-related web projects :^) – xakepp35 – 2019-01-07T09:12:16.827

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?)

– xakepp35 – 2019-01-24T14:23:29.663

2

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.

Neil

Posted 2019-01-06T16:12:27.540

Reputation: 95 035

2

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?

Jo King

Posted 2019-01-06T16:12:27.540

Reputation: 38 234

2

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

Emigna

Posted 2019-01-06T16:12:27.540

Reputation: 50 798

Nice trick of using * with the range to implicitly crop the list! – Kevin Cruijssen – 2019-01-07T14:03:15.973

2

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!

Destroigo

Posted 2019-01-06T16:12:27.540

Reputation: 401

1106 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). :) – Kevin Cruijssen – 2019-01-08T16:09:15.807

1

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.

– Kevin Cruijssen – 2019-01-08T16:10:17.240

189 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. – Kevin Cruijssen – 2019-01-08T16:46:33.527

1

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

fəˈnɛtɪk

Posted 2019-01-06T16:12:27.540

Reputation: 4 166

54 bytes? – Arnauld – 2019-01-06T22:26:15.207

1

(Or 53 bytes if the meaning of the Boolean value can be inverted.)

– Arnauld – 2019-01-06T22:52:46.937

@Arnauld, 52 bytes ;)

– Shaggy – 2019-01-06T23:23:06.243

(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.) – Shaggy – 2019-01-06T23:40:29.157

1

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!

Neil A.

Posted 2019-01-06T16:12:27.540

Reputation: 2 038

1

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

Shaggy

Posted 2019-01-06T16:12:27.540

Reputation: 24 623

1

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)

Jonathan Allan

Posted 2019-01-06T16:12:27.540

Reputation: 67 804

1

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.

CriminallyVulgar

Posted 2019-01-06T16:12:27.540

Reputation: 501

0

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

Kevin Cruijssen

Posted 2019-01-06T16:12:27.540

Reputation: 67 575

0

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.

dana

Posted 2019-01-06T16:12:27.540

Reputation: 2 541