site.base_url }}/">The Bear's Den -->

The Bear's Den

Enter at your own risk

Recurring Lotteries

Task 1: 6 out of 49

Submitted by: Andreas Voegele


6 out of 49 is a German lottery.

Write a script that outputs six unique random integers from the range 1 to 49.

Output

3
10
11
22
38
49

Solution

There is a trivial solution to this task using List::MoreUtils::sample:

sample 6, 1 .. 49;

Emulating a “lottery device” instead. There is a pool of initially 49 numbered balls. In every turn, one ball is selected randomly and removed from the pool.

The task description suggests the numbers being sorted in ascending order.

sub sixoutoffortynine {
	my @pool = (1..49);
    my @winning;
    push @winning, splice @pool, rand @pool, 1 for 1 .. 6;
    sort {$a <=> $b} @winning;
}

Task 2: Linear Recurrence of Second Order

Submitted by: Jörg Sommrey


You are given an array @a of five integers.

Write a script to decide whether the given integers form a linear recurrence of second order with integer factors.

A linear recurrence of second order has the form

a[n] = p * a[n-2] + q * a[n-1] with n > 1

where p and q must be integers.

Example 1

Input: @a = (1, 1, 2, 3, 5)
Output: true

@a is the initial part of the Fibonacci sequence a[n] = a[n-2] + a[n-1]
with a[0] = 1 and a[1] = 1.

Example 2

Input: @a = (4, 2, 4, 5, 7)
Output: false

a[1] and a[2] are even. Any linear combination of two even numbers with integer factors is even, too.
Because a[3] is odd, the given numbers cannot form a linear recurrence of second order with integer factors.

Example 3

Input: @a = (4, 1, 2, -3, 8)
Output: true

a[n] = a[n-2] - 2 * a[n-1]

Solution

In the following an asterisk * denotes matrix multiplication as well as vector or scalar multiplication depending on the type of its operands.

From the formula

a[n] = p[0] * a[n-2] + p[1] * a[n-1]

and an initial sequence a[0],...,a[3] we need to derive the ‘hidden’ parameters p[0] and p[1]:

a[2] = a[0] * p[0] + a[1] * p[1]
a[3] = a[1] * p[0] + a[2] * p[1]

Using vectors and a matrix

a23 = (a[2])
      (a[3])
p = (p[0])
    (p[1])
M = (a[0], a[1])
    (a[1], a[2])

we may write:

a23 = M * p

Regular case

Suppose M is regular, i.e. det(M) = a[0] * a[2] - a[1]^2 != 0

Then M has an inverse matrix and we find:

p = inv(M) * a23

We need to check if:

The latter is the case if

a[4] = pT * a23

Degenerated case

Next we need to consider the degenerated case where det(M) = 0, i.e.

a[0] * a[2] = a[1]^2

Here the middle element a[1] is the geometric mean of its neighbors. This is the characteristic property of a geometric sequence, which may be regarded as a linear recurrence of order 1:

a[n] = p[1] * a[n-1]

Suppose a[1] != 0. Then we have p[1] = a[2] / a[1]. The initial element a[0] becomes irrelevant and we need to check if

Doubly degenerated case

Finally we have the case where the determinant of M is zero and a[1] = 0.
From a[0] * a[2] = a[1]^2 it follows, that a[0] or a[2] must be zero, too. This means there are two neighboring zeroes in the sequence and thus we need to check if:


If you have a question about this post or if you like to comment on it, feel free to open an issue in my github repository.