And now we’re on to Weekly Challenge #246! 246 is the product of 2, 3, and 41. It is Untouchable.

### 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.

I got this wrong on first pass.

“Six random integers”? That’s cake.

“Between the range of 1 and 49?” More cake.

The word I missed is “unique”. That’s the word that makes this work.

If you want to include all the input, use a `for` loop, but if you’re concerned about the output, use a `while` loop. Here, we’re watching the number of keys in the hash, so we’re randomizing a number, making it a key, and checking. The count doesn’t matter, so we set to `1` instead of incrementing. I mean, we could do that, but that makes a moving part that the next guy could get obsessed by. “Why increment?”

(Forgive me; I’ve been looking at something recently that I’m only 80% sure is someone using more shell than they understand, but trying to understand the possible cleverness in that 20%. Code, I believe, is like musical notation and mathematical expressions: most important as communication to others. When you write something ambiguous, you aren’t showing off cleverness, just writing something intentionally confusing for your colleagues.)

#### Show Me The Code

``````#!/usr/bin/env perl

use strict;
use warnings;
use experimental qw{ say postderef signatures state };

my %hash;

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

# I had missed 'unique', which means we have to be sure we
# deal with duplicates. Use the random number as keys to a hash
# and you won't get duplicates.

# Adding the numeric sort just makes it pretty.

while ( scalar keys %hash < 6 ) {
my \$n = 1 + int rand 49;
\$hash{\$n} = 1;
}

say join "\n", sort { \$a <=> \$b } keys %hash;

# And here is my first pass, which ignored "unique".
# Because of that, it was very simple.

# say join "\n",
#     sort { \$a <=> \$b }      # and the example is sorted numerically, so we will
#     map { 1 + int rand 49 } # which are random and between 1 and 49
#                             # but int rand ( n ) will give a number between 0 and n-1
#                             # so adding 1 will put it at the right range
#     1 .. 6;                 # we want six numbers
``````
``````\$ ./ch-1.pl
6
19
34
36
40
49
``````

### Task 2: Linear Recurrence of Second Order

Submitted by: Jorg 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.

`p` and `q` must be integers, so we go through a lot of integers, do the math, and go `next` to the outer loop if you find one. If there’s ever a case where, after a large array of integers, you don’t find something that matches, we return true.

First pass, I had two different loops for both `p` and `q`, for both `1..100` and `-1, 1`, but it became much simpler when I rewrote for `-100..100`. There’s no division to worry about.

And once you’ve sorted your `\$p`s and `\$q`s, it’s simple mathematics and named loops.

#### Show Me The Code

``````#!/usr/bin/env perl

use strict;
use warnings;
use experimental qw{ say postderef signatures state };

my @examples = (

[ 1, 1, 2, 3,  5 ],
[ 4, 2, 4, 5,  7 ],
[ 4, 1, 2, -3, 8 ],
);

for my \$e (@examples) {
my \$input  = join ', ', \$e->@*;
my \$output = lrso( \$e->@* );

say <<~"END";
Input:  \\$input = (\$input)
Output:          \$output
END
}

sub lrso (@input) {
OUTER: for my \$n ( 2 .. -1 + scalar @input ) {
for my \$p ( -100 .. 100 ) {
my \$pp = \$p * \$input[ \$n - 2 ];
for my \$q ( -100 .. 100 ) {
my \$qq = \$q * \$input[ \$n - 1 ];
my \$rr = \$pp + \$qq;
next OUTER if \$rr == \$input[\$n];
}
}
return 'false';
}
return 'true';
}
``````
``````\$ ./ch-2.pl
Input:  \$input = (1, 1, 2, 3, 5)
Output:          true

Input:  \$input = (4, 2, 4, 5, 7)
Output:          false

Input:  \$input = (4, 1, 2, -3, 8)
Output:          true
``````