diff options
| author | Thomas Köhler <jean-luc@picard.franken.de> | 2023-05-22 21:23:53 +0200 |
|---|---|---|
| committer | Thomas Köhler <jean-luc@picard.franken.de> | 2023-05-22 21:23:53 +0200 |
| commit | 5e31a5257d8bc7d2a8b5363da2e56ddad298e569 (patch) | |
| tree | 2f27c65e3dd8f133066c56cf8b06483ba50036f0 /challenge-218 | |
| parent | c8670df894db150b6176b9128224122acf9a4a52 (diff) | |
| download | perlweeklychallenge-club-5e31a5257d8bc7d2a8b5363da2e56ddad298e569.tar.gz perlweeklychallenge-club-5e31a5257d8bc7d2a8b5363da2e56ddad298e569.tar.bz2 perlweeklychallenge-club-5e31a5257d8bc7d2a8b5363da2e56ddad298e569.zip | |
Add solution 218.
Signed-off-by: Thomas Köhler <jean-luc@picard.franken.de>
Diffstat (limited to 'challenge-218')
| -rw-r--r-- | challenge-218/jeanluc2020/blog-1.txt | 1 | ||||
| -rw-r--r-- | challenge-218/jeanluc2020/blog-2.txt | 1 | ||||
| -rwxr-xr-x | challenge-218/jeanluc2020/perl/ch-1.pl | 72 | ||||
| -rwxr-xr-x | challenge-218/jeanluc2020/perl/ch-2.pl | 162 |
4 files changed, 236 insertions, 0 deletions
diff --git a/challenge-218/jeanluc2020/blog-1.txt b/challenge-218/jeanluc2020/blog-1.txt new file mode 100644 index 0000000000..c669294ffe --- /dev/null +++ b/challenge-218/jeanluc2020/blog-1.txt @@ -0,0 +1 @@ +http://gott-gehabt.de/800_wer_wir_sind/thomas/Homepage/Computer/perl/theweeklychallenge-218-1.html diff --git a/challenge-218/jeanluc2020/blog-2.txt b/challenge-218/jeanluc2020/blog-2.txt new file mode 100644 index 0000000000..f9b28f55a1 --- /dev/null +++ b/challenge-218/jeanluc2020/blog-2.txt @@ -0,0 +1 @@ +http://gott-gehabt.de/800_wer_wir_sind/thomas/Homepage/Computer/perl/theweeklychallenge-218-2.html diff --git a/challenge-218/jeanluc2020/perl/ch-1.pl b/challenge-218/jeanluc2020/perl/ch-1.pl new file mode 100755 index 0000000000..27e35dd4db --- /dev/null +++ b/challenge-218/jeanluc2020/perl/ch-1.pl @@ -0,0 +1,72 @@ +#!/usr/bin/perl +# https://theweeklychallenge.org/blog/perl-weekly-challenge-218/#TASK1 +# +# Task 1: Maximum Product +# ======================= +# +# You are given a list of 3 or more integers. +# +# Write a script to find the 3 integers whose product is the maximum and return it. +# +## Example 1 +## +## Input: @list = (3, 1, 2) +## Output: 6 +## +## 1 x 2 x 3 => 6 +# +## Example 2 +## +## Input: @list = (4, 1, 3, 2) +## Output: 24 +## +## 2 x 3 x 4 => 24 +# +## Example 3 +## +## Input: @list = (-1, 0, 1, 3, 1) +## Output: 3 +## +## 1 x 1 x 3 => 3 +# +## Example 4 +## +## Input: @list = (-8, 2, -9, 0, -4, 3) +## Output: 216 +## +## -9 × -8 × 3 => 216 +# +############################################################ +## +## discussion +## +############################################################ +# +# Using 3 index variables i, j, k we walk the list from +# beginning to end, calculate the product at the current +# 3 index positions, and then return the maximum + +use strict; +use warnings; + +maximum_product(3, 1, 2); +maximum_product(4, 1, 3, 2); +maximum_product(-1, 0, 1, 3, 1); +maximum_product(-8, 2, -9, 0, -4, 3); + +sub maximum_product { + my @list = @_; + my $maximum; + print "Input: (" . join(", ", @list) . ")\n"; + foreach my $i (0..$#list-2) { + foreach my $j ($i+1..$#list-1) { + foreach my $k ($j+1..$#list) { + my $prod = $list[$i] * $list[$j] * $list[$k]; + $maximum //= $prod; + $maximum = $prod if $prod > $maximum; + } + } + } + print "Output: $maximum\n"; +} + diff --git a/challenge-218/jeanluc2020/perl/ch-2.pl b/challenge-218/jeanluc2020/perl/ch-2.pl new file mode 100755 index 0000000000..ff85c99a06 --- /dev/null +++ b/challenge-218/jeanluc2020/perl/ch-2.pl @@ -0,0 +1,162 @@ +#!/usr/bin/perl +# https://theweeklychallenge.org/blog/perl-weekly-challenge-218/#TASK2 +# +# Task 2: Matrix Score +# ==================== +# +# You are given a m x n binary matrix i.e. having only 1 and 0. +# +# You are allowed to make as many moves as you want to get the highest score. +# +### A move can be either toggling each value in a row or column. +# +# To get the score, convert the each row binary to dec and return the sum. +# +## Example 1: +## +## Input: @matrix = [ [0,0,1,1], +## [1,0,1,0], +## [1,1,0,0], ] +## Output: 39 +## +## Move #1: convert row #1 => 1100 +## [ [1,1,0,0], +## [1,0,1,0], +## [1,1,0,0], ] +## +## Move #2: convert col #3 => 101 +## [ [1,1,1,0], +## [1,0,0,0], +## [1,1,1,0], ] +## +## Move #3: convert col #4 => 111 +## [ [1,1,1,1], +## [1,0,0,1], +## [1,1,1,1], ] +## +## Score: 0b1111 + 0b1001 + 0b1111 => 15 + 9 + 15 => 39 +# +## Example 2: +## +## Input: @matrix = [ [0] ] +## Output: 1 +# +############################################################ +## +## discussion +## +############################################################ +# +# Each row and each column can either be flipped or not, since +# flipping it twice returns it into its previous state. So we +# can get all possible scores by calculating the score with +# each column and row either flipped or not and then select +# the maximum. To calculate each combination, we can say we flip +# row $i if the $i-th bit of a bitfield is set, and column $i +# if the ($i-$number_of_rows)-th bit of the bitfield is set. +# In order to create the bitfield, we count from 0 to +# 2**($rows+$columns)-1 and convert the result into a bitfield +# of length ($rows+$columns). Then we calculate the new matrix +# with the corresponding rows and columns flipped, and then the +# score for this new matrix. In the end we take the maximum of +# those values. + +use strict; +use warnings; + +matrix_score( [ [0,0,1,1], [1,0,1,0], [1,1,0,0], ] ); +matrix_score( [ [0] ] ); + +sub matrix_score { + my $matrix = shift; + my ($rows, $columns) = get_dimensions($matrix); + my $highest = 0; + print "Input:\n"; + print_matrix($matrix); + foreach my $index (0..2**($rows+$columns)-1) { + my $score = get_score($matrix, $index, $rows, $columns); + $highest = $score if $score > $highest; + } + print "Output: $highest\n"; +} + +# this helper function calculates the number of rows and columns +# of the matrix, and also checks if all rows have the same amount +# of columns +sub get_dimensions { + my $matrix = shift; + my $rows = @$matrix; + my $columns = scalar(@{$matrix->[0]}); + foreach my $row (@$matrix) { + my $c = scalar(@$row); + die "Not a matrix, dimension mismatch!" unless $c == $columns; + } + return ($rows, $columns); +} + +# helper function to print the matrix, just for the output +sub print_matrix { + my $matrix = shift; + my $first = 1; + foreach my $row (@$matrix) { + if($first) { + $first = 0; + print "[ "; + } else { + print " "; + } + print "[" . join(",", @$row) . "],\n"; + } + print "]\n"; +} + +# given the original matrix and the index (the number we will turn +# into the bitfield for determining which rows and columns to flip), +# this function will first create a copy of the matrix, then flip +# the corresponding rows and columns, and then calculate the score. +sub get_score { + my ($matrix, $index, $rows, $columns) = @_; + my $copy_matrix; + # create a copy of the matrix + foreach my $row (0..$rows-1) { + foreach my $column (0..$columns-1) { + $copy_matrix->[$row]->[$column] = $matrix->[$row]->[$column]; + } + } + # turn the index into a bitfield + my $x = $rows+$columns; + my @bits = split //, sprintf("%0${x}b", $index); + foreach my $i (0..$rows+$columns-1) { + if($bits[$i]) { # the bit is set + if($i < $rows) { + # flip everything in row $i + foreach my $j (0..$columns-1) { + $copy_matrix->[$i]->[$j] = $copy_matrix->[$i]->[$j] ? 0 : 1; + } + } else { + # flip everything in column $i-$rows + foreach my $j (0..$rows-1) { + $copy_matrix->[$j]->[$i-$rows] = $copy_matrix->[$j]->[$i-$rows] ? 0 : 1; + } + } + } + } + # calculate the score + my $score = 0; + foreach my $row (0..$rows-1) { + $score += bin_to_dec($copy_matrix->[$row]); + } + return $score; +} + +# helper function to turn an array of bits into an integer +sub bin_to_dec { + my $digits = shift; + my $result = 0; + foreach my $digit (@$digits) { + $result*=2; + $result+=$digit; + } + return $result; +} + |
