Weekly Challenge 300
Each week Mohammad S. Anwar sends out The Weekly Challenge, a chance for all of us to come up with solutions to two weekly tasks. My solutions are written in Python first, and then converted to Perl. It's a great way for us all to practice some coding.
With this being the three hundredth challenge, let me personally thank Mohammad for all the work he does each week on behalf of everyone in Team PWC.
Task 1: Beautiful Arrangement
Task
You are given a positive integer, $int
.
Write a script to return the number of beautiful arrangements that you can construct.
A permutation of n
integers, 1-indexed, is considered a beautiful arrangement if for every i
(1 <= i <= n) either of the following is true:
-
perm[i]
is divisible byi
-
i
is divisible byperm[i]
My solution
For this task, I use the permutations function from the itertool module to work through all permutations.
Then it's just a matter of determining if this permutation meets the specified criteria. If it doesn't, I move to the next permutation. If it does, I add one to the count
variable.
def beautiful_arrangement(n: list) -> str:
count = 0
for p in permutations(range(1, n+1)):
for i in range(n):
if p[i] % (i+1) != 0 and (i+1) % p[i] != 0:
break
else:
count += 1
return count
There may be a more efficient way to compute the results that doesn't involve brute force. My code would become very inefficient on larger numbers. I didn't not spend any time investigating this.
Examples
$ ./ch-1.py 1
1
$ ./ch-1.py 2
2
$ ./ch-1.py 10
700
Task 2: Nested Array
Task
You are given an array of integers, @ints
of length n
containing permutation of the numbers in the range [0, n - 1]
.
Write a script to build a set, set[i] = ints[i], ints[ints[i]], ints[ints[ints[i]]], ...
, subjected to the following rules:
- The first element in
set[i]
starts with the selection of elementsints[i]
. - The next element in
set[i]
should beints[ints[i]]
, and thenints[ints[ints[i]]]
, and so on. - We stop adding right before a duplicate element occurs in
set[i]
.
My solution
This is relatively straight forward. I start with a variable called longest_set
, set to 0. I then iterate through each starting position and set the this_set
list to be the first item of the set (i.e ints[i]
). I keep adding to this set while ints[this_set[-1]]
does not appear in the this_set
list. After this is done, I compare the length of the this_set
list against the longest_set
value. If it is greater, I update the longest_set
value.
def nested_array(ints: list) -> int:
longest_set = 0
for start in range(len(ints)):
this_set = [ints[start]]
while ints[this_set[-1]] not in this_set:
this_set.append(ints[this_set[-1]])
if longest_set < len(this_set):
longest_set = len(this_set)
return longest_set
Examples
$ ./ch-2.py 5 4 0 3 1 6 2
4
$ ./ch-2.py 0 1 2
1
$ ./ch-2.py 1 2 0 4 5 2
5
Top comments (0)