aboutsummaryrefslogtreecommitdiff
path: root/challenge-218
diff options
context:
space:
mode:
authorThomas Köhler <jean-luc@picard.franken.de>2023-05-22 21:23:53 +0200
committerThomas Köhler <jean-luc@picard.franken.de>2023-05-22 21:23:53 +0200
commit5e31a5257d8bc7d2a8b5363da2e56ddad298e569 (patch)
tree2f27c65e3dd8f133066c56cf8b06483ba50036f0 /challenge-218
parentc8670df894db150b6176b9128224122acf9a4a52 (diff)
downloadperlweeklychallenge-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.txt1
-rw-r--r--challenge-218/jeanluc2020/blog-2.txt1
-rwxr-xr-xchallenge-218/jeanluc2020/perl/ch-1.pl72
-rwxr-xr-xchallenge-218/jeanluc2020/perl/ch-2.pl162
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;
+}
+