Gaping Tuples!

How many ordered 6-tuplets of positive integers ( a 1 , a 2 , a 3 , a 4 , a 5 , a 6 ) (a_1, a_2, a_3, a_4, a_5, a_6) satisfies a 1 + 2 a 2 + 3 a 3 + 4 a 4 + 5 a 5 + 6 a 6 = 60 ? a_1 + 2a_2 + 3a_3 + 4a_4 + 5a_5 + 6a_6 = 60 ? Bonus: Can you generalize this?


The answer is 3331.

This section requires Javascript.
You are seeing this because something didn't load right. We suggest you, (a) try refreshing the page, (b) enabling javascript if it is disabled on your browser and, finally, (c) loading the non-javascript version of this page . We're sorry about the hassle.

2 solutions

Mark Hennings
Jan 21, 2021

If A k ( n ) A_{k}(n) is the number of k k -tuples of positive integers ( a 1 , a 2 , . . . , a k ) (a_1,a_2,...,a_k) such that a 1 + 2 a 2 + + k a k = n a_1 + 2a_2 + \cdots + ka_k = n , and if B k ( n ) B_{k}(n) is the number of k k -tuples of nonnegative integers ( b 1 , b 2 , . . . , b k ) (b_1,b_2,...,b_k) such that b 1 + 2 b 2 + + k b k = n b_1 + 2b_2 + \cdots + kb_k = n , then we see that A k ( n ) = { B k ( n 1 2 k ( k + 1 ) ) n 1 2 k ( k + 1 ) 0 n < 1 2 k ( k + 1 ) A_{k}(n) \; = \; \left\{ \begin{array}{lll} B_k\big(n-\tfrac12k(k+1)\big) & \hspace{1cm} & n \ge \tfrac12k(k+1) \\ 0 & & n < \tfrac12k(k+1) \end{array}\right. (comparing the k k -tuples a 1 , a 2 , . . . , a k a_1,a_2,...,a_k and b 1 , b 2 , . . . , b k b_1,b_2,...,b_k , where a j = b j + 1 a_j = b_j + 1 for 1 j k 1 \le j \le k ). The Mathematica code

B[k_, n_] := If[k == 1, 1, Sum[B[k - 1, n - j k], {j, 0, Floor[n/k]}]]

calculates A 6 ( 60 ) = B 6 ( 39 ) = 3331 A_6(60) = B_6(39) = \boxed{3331} .

Is it possible to apply the idea of Generating Functions, or does it make it more complicated ?

Sathvik Acharya - 4 months, 3 weeks ago

Log in to reply

The generating function of the sequence ( B k ( n ) ) n 0 \big(B_k(n)\big){n \ge 0} is the function n = 0 B k ( n ) x n = r = 1 k 1 1 x r \sum_{n=0}^\infty B_k(n)x^n \; =\; \prod_{r=1}^k \frac{1}{1 - x^r} which is not that easy to expand for general k k .

Mark Hennings - 4 months, 3 weeks ago

What's the difference between nonnegative and positive here?

asdasd asdasd - 4 months, 2 weeks ago

Log in to reply

Nonnegative includes zero; positive does not.

Mark Hennings - 4 months, 2 weeks ago

According to your equation, A 2(3) == 0. But A 2(3) is actually equal to 1. The solution to a 1 + 2*a 2 = 3 is clearly: [1, 1].

asdasd asdasd - 4 months, 2 weeks ago

Log in to reply

No. My formula says that A 2 ( 3 ) = B 2 ( 0 ) A_2(3)=B_2(0) , which is 1 1 .

Mark Hennings - 4 months, 2 weeks ago

Log in to reply

You're talking about the matematica code or the formula? In the matematica it may be right, but in the formula I don't think so.

asdasd asdasd - 4 months, 2 weeks ago

Log in to reply

@Asdasd Asdasd My formula relates the As to the Bs, and the code calculates the Bs. Both are correct.

Mark Hennings - 4 months, 2 weeks ago
Piotr Idzik
Jan 20, 2021

Below you will find my python and C++ solutions. In both cases I use recursion and caching of the solutions of the sub problems. The recursion is based on the following observation. For n , t N n, t \in \N let S n , t S_{n, t} be the number of positive solutions of the equation a 1 + 2 a 2 + 3 a 3 + + n a n = t . a_1 + 2a_2 + 3a_3 + \ldots + na_n = t. Note that for n , t N n, t \in \N , n > 1 n > 1

  • S 1 , t = 1 S_{1, t} = 1 ,
  • S n , t = k = 1 t n S n 1 , t k n S_{n, t} = \sum_{k=1}^{\lfloor\frac{t}{n}\rfloor} S_{n-1, t-kn} .

The C++ solution is a bit tricky. The computation is done at the compile time. The solutions of the sub-problems are cached, because each template is generated only once. The C++ version requires C++17.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
"""
solution of:
    https://brilliant.org/problems/gaping-tuples/
"""

def solve(in_len, in_target_val):
    """
    returns the number of tuples (a_1, a_2, ..., a_in_len)
    such that:
        a_1+2*a_2+...+in_len*a_in_len == in_target_val
    """
    res_data = {}
    def inner(in_len, in_target_val):
        if in_len == 1 and in_target_val > 0:
            res = 1
        elif (in_len, in_target_val) in res_data:
            res = res_data[(in_len, in_target_val)]
        else:
            res = \
                sum(inner(in_len-1, in_target_val-_)
                    for _ in range(in_len, in_target_val+1, in_len))
            res_data[(in_len, in_target_val)] = res
        return res
    return inner(in_len, in_target_val)


assert solve(6, 60) == 3331

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
template <unsigned InSize, unsigned TargetValue>
constexpr unsigned solve();

template <unsigned CurVal, unsigned EndVal, unsigned StepSize>
constexpr unsigned solve_sum()
{
    if constexpr (CurVal >= EndVal)
    {
        return 0;
    }
    else
    {
        return solve<StepSize-1, EndVal-CurVal>()+solve_sum<CurVal+StepSize, EndVal, StepSize>();
    }
}

template <unsigned InSize, unsigned TargetValue>
constexpr unsigned solve()
{
    if constexpr (InSize == 1 && TargetValue > 0)
    {
        return 1;
    }
    else
    {
        return solve_sum<InSize, TargetValue, InSize>();
    }
}

int main()
{
    constexpr auto solution = solve<6, 60>();
    static_assert(solution == 3331);
    return 0;
}

The k used to define the upper bound of the summation is defined by each iteration of the summation itself? Is that right?

asdasd asdasd - 4 months, 2 weeks ago

Log in to reply

This is my mistake, I have already corrected it. The summation bound should be t n \lfloor \frac{t}{n}\rfloor . The idea is to sum over all of the values k 1 k \geq 1 for which t k n > 0 t-kn > 0 (or in other words: consider all terms S n 1 , t k n S_{n-1, t-kn} , which make sense).

Piotr Idzik - 4 months, 2 weeks ago

Log in to reply

Thanks a lot! Now I can check it !

asdasd asdasd - 4 months, 2 weeks ago

0 pending reports

×

Problem Loading...

Note Loading...

Set Loading...