From 262ffe516d240b77c52436c8bb8707913564bcc5 Mon Sep 17 00:00:00 2001 From: 冯昶 Date: Mon, 23 Nov 2020 15:47:50 +0800 Subject: challenge 087, raku solutions --- challenge-088/feng-chang/raku/ch-1.raku | 5 +++++ challenge-088/feng-chang/raku/ch-2.raku | 20 ++++++++++++++++++++ challenge-088/feng-chang/raku/data-01.txt | 3 +++ challenge-088/feng-chang/raku/data-02.txt | 4 ++++ challenge-088/feng-chang/raku/data-03.txt | 3 +++ challenge-088/feng-chang/raku/data-04.txt | 6 ++++++ 6 files changed, 41 insertions(+) create mode 100755 challenge-088/feng-chang/raku/ch-1.raku create mode 100755 challenge-088/feng-chang/raku/ch-2.raku create mode 100644 challenge-088/feng-chang/raku/data-01.txt create mode 100644 challenge-088/feng-chang/raku/data-02.txt create mode 100644 challenge-088/feng-chang/raku/data-03.txt create mode 100644 challenge-088/feng-chang/raku/data-04.txt diff --git a/challenge-088/feng-chang/raku/ch-1.raku b/challenge-088/feng-chang/raku/ch-1.raku new file mode 100755 index 0000000000..ed4f30ac3e --- /dev/null +++ b/challenge-088/feng-chang/raku/ch-1.raku @@ -0,0 +1,5 @@ +#!/bin/env raku + +sub MAIN(*@N) { + say @N.map: ([*] @N) / *; +} diff --git a/challenge-088/feng-chang/raku/ch-2.raku b/challenge-088/feng-chang/raku/ch-2.raku new file mode 100755 index 0000000000..5e6a885633 --- /dev/null +++ b/challenge-088/feng-chang/raku/ch-2.raku @@ -0,0 +1,20 @@ +#!/bin/env raku + +my @N; +@N.push($_.words.Array) for $*IN.lines; + +my @A; +while (@N) { + @A.push($_) for @N.shift.Array; + last unless @N[0].elems > 0; + + @A.push(@N[$_].pop) for ^@N.elems; + last unless @N.elems > 0; + + @A.push($_) for @N.pop.Array.reverse; + last unless @N[0].elems > 0; + + @A.push(@N[$_].shift) for @N.elems^...0; +} + +put @A; diff --git a/challenge-088/feng-chang/raku/data-01.txt b/challenge-088/feng-chang/raku/data-01.txt new file mode 100644 index 0000000000..50ecbb5964 --- /dev/null +++ b/challenge-088/feng-chang/raku/data-01.txt @@ -0,0 +1,3 @@ +1 2 3 +4 5 6 +7 8 9 diff --git a/challenge-088/feng-chang/raku/data-02.txt b/challenge-088/feng-chang/raku/data-02.txt new file mode 100644 index 0000000000..f41c06ce06 --- /dev/null +++ b/challenge-088/feng-chang/raku/data-02.txt @@ -0,0 +1,4 @@ +1 2 3 4 +5 6 7 8 +9 10 11 12 +13 14 15 16 diff --git a/challenge-088/feng-chang/raku/data-03.txt b/challenge-088/feng-chang/raku/data-03.txt new file mode 100644 index 0000000000..01e79c32a8 --- /dev/null +++ b/challenge-088/feng-chang/raku/data-03.txt @@ -0,0 +1,3 @@ +1 +2 +3 diff --git a/challenge-088/feng-chang/raku/data-04.txt b/challenge-088/feng-chang/raku/data-04.txt new file mode 100644 index 0000000000..c6c3a55bc4 --- /dev/null +++ b/challenge-088/feng-chang/raku/data-04.txt @@ -0,0 +1,6 @@ +1 2 3 4 5 6 7 8 +9 10 11 12 13 14 15 16 +17 18 19 20 21 22 23 24 +25 26 27 28 29 30 31 32 +33 34 35 36 37 38 39 40 +41 42 43 44 45 46 47 48 -- cgit From 1b7d45333cead3ae471b9d179076146ef7e7cded Mon Sep 17 00:00:00 2001 From: Abigail Date: Mon, 23 Nov 2020 14:43:19 +0100 Subject: Copy test program from previous week --- challenge-088/abigail/test.pl | 279 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 279 insertions(+) create mode 100755 challenge-088/abigail/test.pl diff --git a/challenge-088/abigail/test.pl b/challenge-088/abigail/test.pl new file mode 100755 index 0000000000..c0f19b9646 --- /dev/null +++ b/challenge-088/abigail/test.pl @@ -0,0 +1,279 @@ +#!/opt/perl/bin/perl + +# +# Test the solutions. Either call it with the directory name you +# want to test in, or call it as "../test.pl" from within the directory. +# + +use 5.032; + +use strict; +use warnings; +no warnings 'syntax'; + +chdir ".." if -f "../test.pl"; + +use experimental 'signatures'; + +use Test::More; +use DBI; + +use Getopt::Long; + +GetOptions 'slow' => \my $run_slow_tests, + 'lang|language=s' => \my @languages, +; + + +my %languages = ( + Perl => { + exe => "/opt/perl/bin/perl", + ext => "pl", + }, + JavaScript => { + exe => "/usr/local/bin/node", + ext => "js", + dir => "node", + }, + bc => { + exe => "/usr/bin/bc", + ext => "bc", + filter => 's/.*/main($&)/', + }, + awk => { + exe => "/usr/bin/awk", + ext => "awk", + args => ["-f"], + }, + C => { + exe => "/usr/bin/cc", + ext => "c", + dir => "c", + }, + SQL => { + ext => "sql", + }, +); + +my $perl_exe = $languages {Perl} {exe}; + +@languages = sort keys %languages if !@languages; +my @challenges = @ARGV ? @ARGV : (1, 2); + +foreach my $challenge (@challenges) { + my ($dbh, $query, $tables_info); # Only for SQL tests. + + my @inputs = or next; + subtest "Challenge $challenge" => sub { + foreach my $language (@languages) { + my $info = $languages {$language}; + my $exe = $$info {exe}; + my $ext = $$info {ext}; + my $dir = $$info {dir} // lc $language; + my @args = @{$$info {args} // []}; + my $filter = $$info {filter} // ''; + my $ext_out = $$info {ext_out} // "out"; + my $source = "$dir/ch-$challenge.$ext"; + my $compiled; + next unless -r $source; + + # + # C requires special handling. The source needs to be compiled. + # + if ($language eq "C") { + $compiled = $source =~ s/\.$ext$/.$ext_out/r; + system $exe, "-o", $compiled, $source; + } + + # + # SQL requires requires creating an in-memory database, + # and loading some tables. For that, we need a .tables + # file. We also read the actual query at this time. + # + if ($language eq "SQL") { + my $tables = $source =~ s/\.\Q$ext\E$/.table/r; + next unless -r $tables; + ($dbh, $query, $tables_info) = init_sql ($source, $tables); + } + + subtest $language => sub { + foreach my $input (@inputs) { + SKIP: { + my $output_exp = ($input =~ s/input/output/r) . ".exp"; + my $exp = `cat $output_exp`; + + my $name = $input; + my %pragma; + my @options; + + while ($exp =~ s/^\s*#%\s*(.*)\n//) { + my $pragma = $1; + $pragma =~ s/\s+$//; + if (lc $pragma eq "slow") { + $pragma {slow} = 1; + next; + } + if ($pragma =~ /^\s*(\w+):\s*(.*)/) { + my ($key, $value) = ($1, $2); + if (lc $key eq "opt") { + push @options => $value; + } + } + } + + if ($exp =~ s/^\s*#\s*(.*)\n//) { + $name = $1; + } + + skip "Skipping slow test", 1 + if $pragma {slow} && !$run_slow_tests; + + my $got; + if ($compiled) { + $got = `$perl_exe -ple '$filter' $input |\ + ./$compiled @options`; + } + elsif ($language eq "SQL") { + $got = test_sql ($dbh, $query, $tables_info, $input); + } + else { + $got = `$perl_exe -ple '$filter' $input |\ + $exe @args ./$source @options`; + } + + s/\h+$//gm for $exp, $got; + is $got, $exp, $name; + }} + }; + + unlink $compiled if $compiled; + } + } +} + +done_testing; + +# +# Parse the tables SQL, extract the table names, and the column names, +# *EXCLUDING* any primary key of the form "integer PRIMARY KEY" +# We're assuming some sane formatting (one column per line). +# +# Returns an array of arrays. Each (inner) array consists of a table +# name, followed by the name of the columns of that table. +# +# We will also create the database handle, use it to create the tables, +# and return the database handle as a second value. +# +sub init_sql ($query_file, $tables_file) { + my $query = `cat $query_file`; + my $tables = `cat $tables_file`; + + my $in_table = 0; + my @info; + foreach (split /\n/ => $tables) { + if (!$in_table) { + if (/^\s* CREATE \s+ TABLE \s+ (\w+)/xi) { + $in_table = 1; + push @info => [$1]; + } + next; + } + else { + if (/^\s* \)/x) { + $in_table = 0; + next; + } + # Any other line is a column definition + next if /^ \s* \w+ \s+ integer \s+ PRIMARY \s+ KEY \s*,/xi; + if (/^ \s* (\w+)/x) { + push @{$info [-1]} => $1; + } + } + } + # + # Does the query have place holders? + # + if ($query =~ /\?/) { + push @info => ["Placeholder"]; + } + + my $dbh = DBI:: -> connect ("dbi:SQLite:dbname=:memory:", "", "", + {RaiseError => 1, + PrintError => 1, + AutoCommit => 1}); + $dbh -> do ($tables); + + return ($dbh, $query, \@info); +} + + +sub test_sql ($dbh, $query, $tables_info, $input) { + # + # For now, assume we each set of N lines, where N is the number of tables + # is a test. We also assume that if a line has P items (space separated), + # and the corresponing table has Q columns (not counting any integer primary + # keys, as SQLite fills them automatically), we have to fill int (P/Q) rows. + # + + # + # Read the input + # + open my $i_fh, "<", $input or die "Failed to open $input: $!"; + my @input = <$i_fh>; + + my $output = ""; + + TEST: + while (@input >= @$tables_info) { + my $real_query = $query; + foreach my $table_info (@$tables_info) { + my ($table, @fields) = @$table_info; + my $input = shift @input; + my @values = split ' ' => $input; + last TEST if @values < @fields && $table ne "Placeholder"; + + # + # Handle place holder queries + # + if ($table eq "Placeholder") { + $real_query =~ s/\?/shift @values/eg; + next; + } + + # + # Clear the table + # + $dbh -> do ("DELETE FROM $table"); + + # + # Construct an input query + # + my $place = "(" . join (", " => ("?") x @fields) . ")"; + my $insert = do {local $" = ", "; <<~ "--"}; + INSERT + INTO $table + (@fields) + VALUES @{[($place) x (@values / @fields)]} + -- + + $dbh -> do ($insert, undef, @values); + } + + + # + # Run the query. If we have multiple results, join columns + # by spaces, and rows by newlines. + # + my $result = $dbh -> selectall_arrayref ($real_query); + + $output .= join "\n" => map {join " " => @$_} @$result; + $output .= "\n"; + } + + $output; +} + + + + +__END__ -- cgit From de7a89f2a58da89e06cef7c422be94b8ee6cacf6 Mon Sep 17 00:00:00 2001 From: Abigail Date: Mon, 23 Nov 2020 15:08:12 +0100 Subject: Examples for week 88/part 1 --- challenge-088/abigail/t/input-1-1 | 2 ++ challenge-088/abigail/t/input-1-2 | 1 + challenge-088/abigail/t/input-1-3 | 1 + challenge-088/abigail/t/output-1-1.exp | 3 +++ challenge-088/abigail/t/output-1-2.exp | 2 ++ challenge-088/abigail/t/output-1-3.exp | 2 ++ 6 files changed, 11 insertions(+) create mode 100644 challenge-088/abigail/t/input-1-1 create mode 100644 challenge-088/abigail/t/input-1-2 create mode 100644 challenge-088/abigail/t/input-1-3 create mode 100644 challenge-088/abigail/t/output-1-1.exp create mode 100644 challenge-088/abigail/t/output-1-2.exp create mode 100644 challenge-088/abigail/t/output-1-3.exp diff --git a/challenge-088/abigail/t/input-1-1 b/challenge-088/abigail/t/input-1-1 new file mode 100644 index 0000000000..5c409ad78d --- /dev/null +++ b/challenge-088/abigail/t/input-1-1 @@ -0,0 +1,2 @@ +5 2 1 4 3 +2 1 4 3 diff --git a/challenge-088/abigail/t/input-1-2 b/challenge-088/abigail/t/input-1-2 new file mode 100644 index 0000000000..514e1a71c7 --- /dev/null +++ b/challenge-088/abigail/t/input-1-2 @@ -0,0 +1 @@ +1073741824 536870912 2147483648 diff --git a/challenge-088/abigail/t/input-1-3 b/challenge-088/abigail/t/input-1-3 new file mode 100644 index 0000000000..14d53468d3 --- /dev/null +++ b/challenge-088/abigail/t/input-1-3 @@ -0,0 +1 @@ +2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 diff --git a/challenge-088/abigail/t/output-1-1.exp b/challenge-088/abigail/t/output-1-1.exp new file mode 100644 index 0000000000..ab1640c620 --- /dev/null +++ b/challenge-088/abigail/t/output-1-1.exp @@ -0,0 +1,3 @@ +# Given examples +24, 60, 120, 30, 40 +12, 24, 6, 8 diff --git a/challenge-088/abigail/t/output-1-2.exp b/challenge-088/abigail/t/output-1-2.exp new file mode 100644 index 0000000000..0fb3d09d47 --- /dev/null +++ b/challenge-088/abigail/t/output-1-2.exp @@ -0,0 +1,2 @@ +# Product of all numbers exceeds 2^64 +1152921504606846976, 2305843009213693952, 576460752303423488 diff --git a/challenge-088/abigail/t/output-1-3.exp b/challenge-088/abigail/t/output-1-3.exp new file mode 100644 index 0000000000..22f526f4d4 --- /dev/null +++ b/challenge-088/abigail/t/output-1-3.exp @@ -0,0 +1,2 @@ +# Product of primes +307444891294245705, 204963260862830470, 122977956517698282, 87841397512641630, 55899071144408310, 47299214045268570, 36169987211087730, 32362620136236390, 26734338373412670, 21203095951327290, 19835154277048110, 16618642772661930, 14997311770451010, 14299762385778870, 13082761331670030 -- cgit From 0d8ea5eeca2048cbb5b64219c3e54849dee74d96 Mon Sep 17 00:00:00 2001 From: Abigail Date: Mon, 23 Nov 2020 15:08:22 +0100 Subject: Perl solution for week 88/part 1. --- challenge-088/abigail/perl/ch-1.pl | 47 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 challenge-088/abigail/perl/ch-1.pl diff --git a/challenge-088/abigail/perl/ch-1.pl b/challenge-088/abigail/perl/ch-1.pl new file mode 100644 index 0000000000..91804c967c --- /dev/null +++ b/challenge-088/abigail/perl/ch-1.pl @@ -0,0 +1,47 @@ +#!/opt/perl/bin/perl + +use 5.032; + +use strict; +use warnings; +no warnings 'syntax'; + +use experimental 'signatures'; +use experimental 'lexical_subs'; + +# +# Challenge +# +# You are given an array of positive integers @N. +# +# Write a script to return an array @M where $M[i] is the product of +# all elements of @N except the index $N[i]. +# + +# +# We first calculate the result for M [0], by multiplying all +# numbers N [1 ..]. Then, for each i > 0, we calculate M [i] as +# +# M [i] = (M [i - 1] / N [i]) * N [i - 1] +# +# Assuming the challenge is created such that each M [i] fits in an +# integer, this will not result in an overflow, as long as we first do +# the division, then the multiplication. +# Note that N [i] evenly divides M [i - 1] by definition. +# + +use List::Util qw [product]; + +while (<>) { + # Read in a line of data. + my @N = /[1-9][0-9]*/g; + # Calculate M [0], and print it. + printf "%d", my $P = product @N [1 .. $#N]; + # For each i > 0, calculate M [i] from M [i - 1], N [i] and N [i - 1], + # and print it. + printf ", %d", $P = $P / $N [$_] * $N [$_ - 1] for 1 .. $#N; + print "\n"; +} + + +__END__ -- cgit From fa6a22f755c308e647c182dce94ca5655d2e86ed Mon Sep 17 00:00:00 2001 From: Abigail Date: Mon, 23 Nov 2020 16:38:09 +0100 Subject: C solution for week 88/part 1 --- challenge-088/abigail/c/ch-1.c | 97 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 challenge-088/abigail/c/ch-1.c diff --git a/challenge-088/abigail/c/ch-1.c b/challenge-088/abigail/c/ch-1.c new file mode 100644 index 0000000000..f12d59c0a5 --- /dev/null +++ b/challenge-088/abigail/c/ch-1.c @@ -0,0 +1,97 @@ +# include +# include + +/* + * Challenge + * + * You are given an array of positive integers @N. + * + * Write a script to return an array @M where $M[i] is the product of + * all elements of @N except the index $N[i]. + */ + +/* + * We first calculate the result for M [0], by multiplying all + * numbers N [1 ..]. Then, for each i > 0, we calculate M [i] as + * + * M [i] = (M [i - 1] / N [i]) * N [i - 1] + * + * Assuming the challenge is created such that each M [i] fits in an + * integer, this will not result in an overflow, as long as we first do + * the division, then the multiplication. + * Note that N [i] evenly divides M [i - 1] by definition. + */ + + +# define DEFAULT_BUF_SIZE 128 + +typedef long long number; + +int main (void) { + /* Arguments for getline () */ + char * line = NULL; + size_t len = 0; + + /* We'll store the numbers in array, which we will reuse for each * + * line we're processing. We also need to keep track of how much * + * memory we have allocated for the array. */ + number * array = NULL; + size_t buf_size = DEFAULT_BUF_SIZE; + + /* Give the array some starting memory to work with. */ + if ((array = (number *) malloc (buf_size * sizeof (number))) == NULL) { + fprintf (stderr, "Out of memory\n"); + return (1); + } + + size_t size = 0; /* Number of integers in array. */ + + while (getline (&line, &len, stdin) != -1) { + int offset; + char * line_ptr = line; + size = 0; /* Reset size of array */ + number input; /* Each number read from the line */ + + /* Scan the line just read, one number at a time */ + while (sscanf (line_ptr, "%lld%n", &input, &offset) == 1) { + line_ptr += offset; + + if (++ size >= buf_size) { + /* Get twice the amount of memory */ + buf_size = buf_size * 2; + if ((array = (number *) realloc (array, + buf_size * sizeof (number))) == NULL) { + fprintf (stderr, "Out of memory\n"); + return (1); + } + } + + /* Store it */ + array [size - 1] = input; + } + + /* + * Get the first product (M [0]), and print it. + */ + number product = 1; + for (size_t i = 1; i < size; i ++) { + product = product * array [i]; + } + + printf ("%lld", product); + + /* + * We can now calculate each next product by first + * dividing by array [i], then multiplying by array [i - 1]. + */ + for (size_t i = 1; i < size; i ++) { + product = product / array [i]; + product = product * array [i - 1]; + printf (", %lld", product); + } + + printf ("\n"); + } + free (line); + free (array); +} -- cgit From 9aa87989b37435bbfdedf2e07c8f63b774881cdf Mon Sep 17 00:00:00 2001 From: Abigail Date: Mon, 23 Nov 2020 19:11:05 +0100 Subject: Node.js solution for week 88/part 1 --- challenge-088/abigail/node/ch-1.js | 71 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 challenge-088/abigail/node/ch-1.js diff --git a/challenge-088/abigail/node/ch-1.js b/challenge-088/abigail/node/ch-1.js new file mode 100644 index 0000000000..1cfbb3eff3 --- /dev/null +++ b/challenge-088/abigail/node/ch-1.js @@ -0,0 +1,71 @@ +// +// Challenge +// +// You are given an array of positive integers @N. +// +// Write a script to return an array @M where $M[i] is the product of +// all elements of @N except the index $N[i]. +// + +// +// We first calculate the result for M [0], by multiplying all +// numbers N [1 ..]. Then, for each i > 0, we calculate M [i] as +// +// M [i] = (M [i - 1] / N [i]) * N [i - 1] +// +// Assuming the challenge is created such that each M [i] fits in an +// integer, this will not result in an overflow, as long as we first do +// the division, then the multiplication. +// Note that N [i] evenly divides M [i - 1] by definition. +// + +// +// Node.js doesn't have 64 bit integers. We need to explicitly make numbers +// into BigInt objects to deal with number larger than about 53 bits. +// And Node.js doesn't always cast numbers to BigInts with arithmetic. +// + +// +// Read STDIN. Split on newlines, then on whitespace, and turn the results +// into (BigInt) numbers. +// +let lines = require ("fs") + . readFileSync (0) // Read all. + . toString () // Turn it into a string. + . split ("\n") // Split on newlines. + . filter (_ => _ . length) // Filter empty lines. + . map (_ => _ . split (" ") // Split lines + // on spaces + . map (_ => BigInt (_))) // Numify. +; + + +// +// Iterate over the lines +// +lines . forEach (array => { + // + // Get the first product + // + let product = array . reduce ((acc, val, idx) => { + return idx ? acc * val : 1n; + }, 1); + + // + // Print it + // + process . stdout . write ("" + product); + + // + // Get the other products + // + array . forEach ((val, idx, array) => { + if (idx) { + product = product / array [idx]; + product = product * array [idx - 1]; + process . stdout . write (", " + product); + } + }); + + process . stdout . write ("\n"); +}); -- cgit From f371f6bda28b720ea65506f936b8b7e95e125562 Mon Sep 17 00:00:00 2001 From: Abigail Date: Mon, 23 Nov 2020 20:01:28 +0100 Subject: Examples for week 88/part 2 --- challenge-088/abigail/t/input-2-1 | 3 +++ challenge-088/abigail/t/input-2-2 | 4 ++++ challenge-088/abigail/t/input-2-3 | 2 ++ challenge-088/abigail/t/output-2-1.exp | 2 ++ challenge-088/abigail/t/output-2-2.exp | 2 ++ challenge-088/abigail/t/output-2-3.exp | 2 ++ 6 files changed, 15 insertions(+) create mode 100644 challenge-088/abigail/t/input-2-1 create mode 100644 challenge-088/abigail/t/input-2-2 create mode 100644 challenge-088/abigail/t/input-2-3 create mode 100644 challenge-088/abigail/t/output-2-1.exp create mode 100644 challenge-088/abigail/t/output-2-2.exp create mode 100644 challenge-088/abigail/t/output-2-3.exp diff --git a/challenge-088/abigail/t/input-2-1 b/challenge-088/abigail/t/input-2-1 new file mode 100644 index 0000000000..50ecbb5964 --- /dev/null +++ b/challenge-088/abigail/t/input-2-1 @@ -0,0 +1,3 @@ +1 2 3 +4 5 6 +7 8 9 diff --git a/challenge-088/abigail/t/input-2-2 b/challenge-088/abigail/t/input-2-2 new file mode 100644 index 0000000000..611c030f5d --- /dev/null +++ b/challenge-088/abigail/t/input-2-2 @@ -0,0 +1,4 @@ + 1 2 3 4 + 5 6 7 8 + 9 10 11 12 +13 14 15 16 diff --git a/challenge-088/abigail/t/input-2-3 b/challenge-088/abigail/t/input-2-3 new file mode 100644 index 0000000000..c676f61aa3 --- /dev/null +++ b/challenge-088/abigail/t/input-2-3 @@ -0,0 +1,2 @@ + 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 +16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 diff --git a/challenge-088/abigail/t/output-2-1.exp b/challenge-088/abigail/t/output-2-1.exp new file mode 100644 index 0000000000..f93e6811f3 --- /dev/null +++ b/challenge-088/abigail/t/output-2-1.exp @@ -0,0 +1,2 @@ +# Given example 1 +1, 2, 3, 6, 9, 8, 7, 4, 5 diff --git a/challenge-088/abigail/t/output-2-2.exp b/challenge-088/abigail/t/output-2-2.exp new file mode 100644 index 0000000000..4e8f353109 --- /dev/null +++ b/challenge-088/abigail/t/output-2-2.exp @@ -0,0 +1,2 @@ +# Given example 2 +1, 2, 3, 4, 8, 12, 16, 15, 14, 13, 9, 5, 6, 7, 11, 10 diff --git a/challenge-088/abigail/t/output-2-3.exp b/challenge-088/abigail/t/output-2-3.exp new file mode 100644 index 0000000000..4fec774397 --- /dev/null +++ b/challenge-088/abigail/t/output-2-3.exp @@ -0,0 +1,2 @@ +# Non-square matrix +1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16 -- cgit From 0e53db64b65207aeef87d639758757bf2befb9a4 Mon Sep 17 00:00:00 2001 From: Abigail Date: Mon, 23 Nov 2020 20:01:44 +0100 Subject: Perl solution for week 88/part 2. --- challenge-088/abigail/perl/ch-2.pl | 126 +++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 challenge-088/abigail/perl/ch-2.pl diff --git a/challenge-088/abigail/perl/ch-2.pl b/challenge-088/abigail/perl/ch-2.pl new file mode 100644 index 0000000000..5455a70ed6 --- /dev/null +++ b/challenge-088/abigail/perl/ch-2.pl @@ -0,0 +1,126 @@ +#!/opt/perl/bin/perl + +use 5.032; + +use strict; +use warnings; +no warnings 'syntax'; + +use experimental 'signatures'; +use experimental 'lexical_subs'; + +# +# Challenge +# +# You are given m x n matrix of positive integers. +# +# Write a script to print spiral matrix as list. +# + +# +# We solve this by keeping track of the boundaries (min_x, min_y, max_x, +# max_y) of the part of the matrix which still needs to be processed. +# Initially, min_x and min_y are 0, max_x is the index of the bottom row, +# and max_y is the index of the right most column. The boundaries are +# stored in an array @boundaries, using indices $MIN_X, $MIN_Y, $MAX_X, +# $MAX_Y. +# +# We also keep track of the current position, that is, the position +# of the value which should be printed next. This starts off as (0, 0), +# the index of the top left corner. +# +# Next thing we keep track of is the direction of travel, the change in +# (x, y) coordinate we take at each step. This will be initialized as +# (0, 1), as we start off moving to the right. +# +# We now move through the matrix in the direction of travel, printing +# the current value. If we hit the end of the yet-to-be-printed matrix, +# we rotate the direction of movement by 90 degrees, and update one of +# the boundaries: +# - If we have travelled the top row, we increment $min_x; +# - If we have travelled the right column, we decrement $max_y; +# - If we have travelled the bottom row, we decrement $max_x; +# - If we have travelled the left column, we increment $min_y. +# +# Note that we always travel the edges in the same order: +# top row (left to right), right edge (top to bottom), +# bottom row (right to left), left edge (bottom to top), and then repeat. +# +# We stop if $min_x > $max_x, or $min_y > $max_y. +# + +my @matrix = map {[/[1-9][0-9]*/g]} <>; + +# +# Check whether all lines are the same size +# +die "Not a matrix" if grep {@$_ != @{$matrix [0]}} @matrix; + +# +# Boundaries +# +my @boundaries; + $boundaries [my $MIN_X = 0] = 0; + $boundaries [my $MAX_Y = 1] = $#{$matrix [0]}; + $boundaries [my $MAX_X = 2] = $#matrix; + $boundaries [my $MIN_Y = 3] = 0; +my $boundary_change = 0; + +my $X = 0; +my $Y = 1; + +# +# Current pointer and direction. +# +my (@position, @direction); + @position [$X, $Y] = (0, 0); + @direction [$X, $Y] = (0, 1); + + +my $comma = ""; +while ($boundaries [$MIN_X] <= $boundaries [$MAX_X] && + $boundaries [$MIN_Y] <= $boundaries [$MAX_Y]) { + # + # Print the value at the current position. + # + print $comma, $matrix [$position [$X]] [$position [$Y]]; + $comma = ", "; + + # + # Where would we end up if we move one step. + # + my @next_position = ($position [$X] + $direction [$X], + $position [$Y] + $direction [$Y]); + + # + # Next if we're still in bounds. + # + if ($boundaries [$MIN_X] <= $next_position [$X] && + $next_position [$X] <= $boundaries [$MAX_X] && + $boundaries [$MIN_Y] <= $next_position [$Y] && + $next_position [$Y] <= $boundaries [$MAX_Y]) { + @position = @next_position; + next; + } + + # + # We're running off of the matrix, change direction, and + # update or decrement a minimum or maximum value. + # Note that we always hit boundaries in the same order. + # + $boundaries [$boundary_change] += ($boundary_change == 0 || + $boundary_change == 3) ? 1 : -1; + $boundary_change = ($boundary_change + 1) %4; + + # + # Rotate the movement direction 90 degrees clockwise, + # and update the position. + # + @direction = ($direction [$Y], -$direction [$X]); + @position = ($position [$X] + $direction [$X], + $position [$Y] + $direction [$Y]); +} + +print "\n"; + +__END__ -- cgit From e8e54f4afad9d72e41b64d20a671bf1445f97031 Mon Sep 17 00:00:00 2001 From: Walt Mankowski Date: Mon, 23 Nov 2020 18:36:13 -0500 Subject: Perl code for Challenge 88 Task 1 --- challenge-088/walt-mankowski/perl/ch-1.pl | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 challenge-088/walt-mankowski/perl/ch-1.pl diff --git a/challenge-088/walt-mankowski/perl/ch-1.pl b/challenge-088/walt-mankowski/perl/ch-1.pl new file mode 100644 index 0000000000..b47524db20 --- /dev/null +++ b/challenge-088/walt-mankowski/perl/ch-1.pl @@ -0,0 +1,24 @@ +#!/usr/bin/env perl +use strict; +use warnings; +use feature qw(:5.32); +use experimental qw(signatures); + +# TASK #1 › Array of Product +# Submitted by: Mohammad S Anwar +# +# You are given an array of positive integers @N. +# +# Write a script to return an array @M where $M[i] is the product of +# all elements of @N except the index $N[i]. + +my @n = @ARGV; +my @res = map {1} 0..$#n; + +for my $i (0..$#n) { + for my $j (0..$#n) { + $res[$j] *= $n[$i] unless $i == $j; + } +} + +say "@res"; -- cgit From faa90e31db32bf327a43f0d1761bdc0b7e18edae Mon Sep 17 00:00:00 2001 From: Kang-min Liu Date: Tue, 24 Nov 2020 10:10:18 +0900 Subject: @gugod's solution to pwc 088.2 --- challenge-088/gugod/raku/ch-2.raku | 77 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 challenge-088/gugod/raku/ch-2.raku diff --git a/challenge-088/gugod/raku/ch-2.raku b/challenge-088/gugod/raku/ch-2.raku new file mode 100644 index 0000000000..48f999db52 --- /dev/null +++ b/challenge-088/gugod/raku/ch-2.raku @@ -0,0 +1,77 @@ +my @directions = [ + [ 1, 0], # → + [ 0, 1], # ↓ + [-1, 0], # ← + [ 0,-1], # ↑ +]; + +sub turn ($curdir is rw, @boundary) of Nil { # ⤵ + @boundary[$curdir] += ($curdir == 0|3) ?? 1 !! -1; + $curdir = ($curdir + 1) % 4; + return; +} + +sub next-step (@cursor, $curdir) { + @cursor >>+<< @directions[$curdir]; +} + +sub inside-boundary(@cursor, @boundary) of Bool { + return ((@boundary[3] < @cursor[0] < @boundary[1]) + and (@boundary[0] < @cursor[1] < @boundary[2])); +} + +sub spiral-matrix (@M) { + my $width = @M[0].elems; + my $height = @M.elems; + my @cursor = [0,0]; + + # The index here is arranged in thee way to make it easier to implement turn(). + my $curdir = 0; + my @boundary = [ + -1, # ↑ + $width, # → + $height, # ↓ + -1, # ← + ]; + + my @spiral; + while inside-boundary(@cursor, @boundary) { + @spiral.push(@M[@cursor[1]][@cursor[0]]); + + my @next = next-step(@cursor, $curdir); + unless inside-boundary(@next, @boundary) { + turn($curdir, @boundary); + @next = next-step(@cursor, $curdir); + } + + @cursor = @next; + } + + return @spiral; +} + +sub print-matrix(@matrix) { + for ^@matrix -> $y { + say "[" ~ @matrix[$y].map(-> $it { sprintf("%2d", $it) }).join(" ") ~ "]"; + } +} + +my @examples = ( + [[1,2], + [3,4]], + [[1,2,3], + [4,5,6]], + [[1,2,3], + [4,5,6], + [7,8,9]], + [[1,2,3], + [4,5,6], + [7,8,9], + [10,11,12],], +); + +for @examples -> @M { + say "----\nInput: "; + print-matrix(@M); + say "Output: " ~ spiral-matrix(@M).gist; +} -- cgit From 4daef39f53ebc4f7395c538e17e628945696abb1 Mon Sep 17 00:00:00 2001 From: Walt Mankowski Date: Mon, 23 Nov 2020 20:13:53 -0500 Subject: Perl code for Challenge 88 Task 2 --- challenge-088/walt-mankowski/perl/ch-2.pl | 78 +++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 challenge-088/walt-mankowski/perl/ch-2.pl diff --git a/challenge-088/walt-mankowski/perl/ch-2.pl b/challenge-088/walt-mankowski/perl/ch-2.pl new file mode 100644 index 0000000000..e260462a73 --- /dev/null +++ b/challenge-088/walt-mankowski/perl/ch-2.pl @@ -0,0 +1,78 @@ +#!/usr/bin/env perl +use strict; +use warnings; +use feature qw(:5.32); +use experimental qw(signatures); + +# TASK #2 › Spiral Matrix +# Submitted by: Mohammad S Anwar +# +# You are given m x n matrix of positive integers. +# +# Write a script to print spiral matrix as list. + +my $fname = $ARGV[0]; +my $grid = parse_input($fname); + +my $rows = $grid->@*; +my $cols = $grid->[0]->@*; + +my %turn = (e => 's', + s => 'w', + w => 'n', + n => 'e', + ); + +my %dir = (e => [0,1], + s => [1,0], + w => [0,-1], + n => [-1,0], + ); + +my %seen; +my @res; +my $r = 0; +my $c = 0; +my $dir = 'e'; + +while (@res < $rows * $cols) { + push @res, $grid->[$r][$c]; + $seen{"$r,$c"} = 1; + my $r1 = $r + $dir{$dir}->[0]; + my $c1 = $c + $dir{$dir}->[1]; + if ($r1 < 0 || $r1 >= $rows || + $c1 < 0 || $c1 >= $cols || + defined $seen{"$r1,$c1"}) { + + # turn and recalculate $r1 and $c1 + $dir = $turn{$dir}; + $r1 = $r + $dir{$dir}->[0]; + $c1 = $c + $dir{$dir}->[1]; + } + ($r,$c) = ($r1,$c1); +} + +say "@res"; + +# read in the matrix +sub parse_input($fname) { + my @grid; + + open my $fh, '<', $fname; + my $row = 0; + while (my $line = <$fh>) { + # remove whitespace; + $line =~ s/\s//g; + + # convert to array + my @c = split /,/, $line; + + for my $i (0..$#c) { + $grid[$row][$i] = $c[$i]; + } + $row++; + } + + # return the grid + return \@grid; +} -- cgit From bbf75140ed797dd1a263413258ce376022ae952a Mon Sep 17 00:00:00 2001 From: Kang-min Liu Date: Tue, 24 Nov 2020 18:09:15 +0900 Subject: add a test case --- challenge-088/gugod/raku/ch-2.raku | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/challenge-088/gugod/raku/ch-2.raku b/challenge-088/gugod/raku/ch-2.raku index 48f999db52..b630611493 100644 --- a/challenge-088/gugod/raku/ch-2.raku +++ b/challenge-088/gugod/raku/ch-2.raku @@ -64,6 +64,10 @@ my @examples = ( [[1,2,3], [4,5,6], [7,8,9]], + [[ 1, 2, 3, 4 ], + [ 5, 6, 7, 8 ], + [ 9, 10, 11, 12 ], + [ 13, 14, 15, 16 ]], [[1,2,3], [4,5,6], [7,8,9], -- cgit From 5389f71ab4b021f54bebce65de9002c403b81cad Mon Sep 17 00:00:00 2001 From: Kang-min Liu Date: Tue, 24 Nov 2020 18:19:50 +0900 Subject: add a naive solution for 088.1 --- challenge-088/gugod/raku/ch-1.raku | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 challenge-088/gugod/raku/ch-1.raku diff --git a/challenge-088/gugod/raku/ch-1.raku b/challenge-088/gugod/raku/ch-1.raku new file mode 100644 index 0000000000..a5723ffb40 --- /dev/null +++ b/challenge-088/gugod/raku/ch-1.raku @@ -0,0 +1,16 @@ +sub array-of-product (@N) { + my $p = [*] @N; + return @N.map(-> $n { $p / $n }); +} + +my @examples = [ + [5, 2, 1, 4, 3], + [2, 1, 4, 3], + [1, 3, 3, 7], +]; + +for @examples -> @N { + say "Input @N = { @N.gist }"; + say "Output @M = " ~ array-of-product(@N).gist; + say "----"; +} -- cgit From cb8e9359613d4b55fe20222f3ca1975d3c362e1e Mon Sep 17 00:00:00 2001 From: Kang-min Liu Date: Tue, 24 Nov 2020 19:01:43 +0900 Subject: put everything in the same subroutine. --- challenge-088/gugod/raku/ch-2.raku | 72 ++++++++++++++++++++------------------ 1 file changed, 37 insertions(+), 35 deletions(-) diff --git a/challenge-088/gugod/raku/ch-2.raku b/challenge-088/gugod/raku/ch-2.raku index b630611493..e5a21065b7 100644 --- a/challenge-088/gugod/raku/ch-2.raku +++ b/challenge-088/gugod/raku/ch-2.raku @@ -1,32 +1,20 @@ -my @directions = [ - [ 1, 0], # → - [ 0, 1], # ↓ - [-1, 0], # ← - [ 0,-1], # ↑ -]; - -sub turn ($curdir is rw, @boundary) of Nil { # ⤵ - @boundary[$curdir] += ($curdir == 0|3) ?? 1 !! -1; - $curdir = ($curdir + 1) % 4; - return; -} - -sub next-step (@cursor, $curdir) { - @cursor >>+<< @directions[$curdir]; -} - -sub inside-boundary(@cursor, @boundary) of Bool { - return ((@boundary[3] < @cursor[0] < @boundary[1]) - and (@boundary[0] < @cursor[1] < @boundary[2])); -} sub spiral-matrix (@M) { - my $width = @M[0].elems; - my $height = @M.elems; - my @cursor = [0,0]; + # Things don'tt change + my $width := @M[0].elems; + my $height := @M.elems; + my @directions := [ + [ 1, 0], # → + [ 0, 1], # ↓ + [-1, 0], # ← + [ 0,-1], # ↑ + ]; - # The index here is arranged in thee way to make it easier to implement turn(). + # Things change. + my @cursor = [0,0]; my $curdir = 0; + + # The order of boundary is arranged in thee way to make it easier to implement turn(). my @boundary = [ -1, # ↑ $width, # → @@ -34,20 +22,34 @@ sub spiral-matrix (@M) { -1, # ← ]; - my @spiral; - while inside-boundary(@cursor, @boundary) { - @spiral.push(@M[@cursor[1]][@cursor[0]]); + my sub turn ($curdir is rw, @boundary) of Nil { # ⤵ + @boundary[$curdir] += ($curdir == 0|3) ?? 1 !! -1; + $curdir = ($curdir + 1) % 4; + return; + } - my @next = next-step(@cursor, $curdir); - unless inside-boundary(@next, @boundary) { - turn($curdir, @boundary); - @next = next-step(@cursor, $curdir); - } + my sub next-step (@cursor, $curdir) { + @cursor >>+<< @directions[$curdir]; + } - @cursor = @next; + my sub inside-boundary(@cursor, @boundary) of Bool { + return ((@boundary[3] < @cursor[0] < @boundary[1]) + and (@boundary[0] < @cursor[1] < @boundary[2])); } - return @spiral; + return gather { + while inside-boundary(@cursor, @boundary) { + take @M[@cursor[1]][@cursor[0]]; + + my @next = next-step(@cursor, $curdir); + unless inside-boundary(@next, @boundary) { + turn($curdir, @boundary); + @next = next-step(@cursor, $curdir); + } + + @cursor = @next; + } + }; } sub print-matrix(@matrix) { -- cgit From 37e3de628deb7c89e06cb1a0d66d566cca636bda Mon Sep 17 00:00:00 2001 From: Kang-min Liu Date: Wed, 25 Nov 2020 08:32:44 +0900 Subject: links to blog posts. --- challenge-088/gugod/README | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/challenge-088/gugod/README b/challenge-088/gugod/README index 9a4443f23b..552c5afaa1 100644 --- a/challenge-088/gugod/README +++ b/challenge-088/gugod/README @@ -1,6 +1,6 @@ Solutions by Kang-min Liu. Blog posts: -- https://gugod.org/2020/11/pwc-087/ -- https://gugod.org/2020/11/pwc-087-en/ -- https://dev.to/gugod/solvintg-perl-weekly-challenge-087-1f09 +- https://gugod.org/2020/11/pwc-088/ +- https://gugod.org/2020/11/pwc-088-en/ +- https://dev.to/gugod/solving-perl-weekly-challenge-088-array-of-prodict-vs-spiral-matrix-13ni -- cgit From 783f4bed20188b8713c558e0e501d037a90f58af Mon Sep 17 00:00:00 2001 From: drbaggy Date: Wed, 25 Nov 2020 08:58:43 +0000 Subject: pushing changes --- challenge-086/james-smith/perl/ch-1.pl | 17 +++++++++++++++++ challenge-086/james-smith/perl/ch-2.pl | 17 +++++++++++++++++ challenge-087/james-smith/perl/ch-1.pl | 16 ++++++++++++++++ challenge-087/james-smith/perl/ch-2.pl | 16 ++++++++++++++++ 4 files changed, 66 insertions(+) create mode 100644 challenge-086/james-smith/perl/ch-1.pl create mode 100644 challenge-086/james-smith/perl/ch-2.pl create mode 100644 challenge-087/james-smith/perl/ch-1.pl create mode 100644 challenge-087/james-smith/perl/ch-2.pl diff --git a/challenge-086/james-smith/perl/ch-1.pl b/challenge-086/james-smith/perl/ch-1.pl new file mode 100644 index 0000000000..e87f9990c9 --- /dev/null +++ b/challenge-086/james-smith/perl/ch-1.pl @@ -0,0 +1,17 @@ +#!/usr/local/bin/perl + +use strict; + +use warnings; +use feature qw(say); +use Test::More; + +# is( my_function(), 1 ); + +done_testing(); + +sub my_function() { + + return; +} + diff --git a/challenge-086/james-smith/perl/ch-2.pl b/challenge-086/james-smith/perl/ch-2.pl new file mode 100644 index 0000000000..e87f9990c9 --- /dev/null +++ b/challenge-086/james-smith/perl/ch-2.pl @@ -0,0 +1,17 @@ +#!/usr/local/bin/perl + +use strict; + +use warnings; +use feature qw(say); +use Test::More; + +# is( my_function(), 1 ); + +done_testing(); + +sub my_function() { + + return; +} + diff --git a/challenge-087/james-smith/perl/ch-1.pl b/challenge-087/james-smith/perl/ch-1.pl new file mode 100644 index 0000000000..930d91cc65 --- /dev/null +++ b/challenge-087/james-smith/perl/ch-1.pl @@ -0,0 +1,16 @@ +#!/usr/local/bin/perl + +use strict; + +use warnings; +use feature qw(say); +use Test::More; + +is( my_function(), 1 ); + +done_testing(); + +sub my_function { + return 1; +} + diff --git a/challenge-087/james-smith/perl/ch-2.pl b/challenge-087/james-smith/perl/ch-2.pl new file mode 100644 index 0000000000..930d91cc65 --- /dev/null +++ b/challenge-087/james-smith/perl/ch-2.pl @@ -0,0 +1,16 @@ +#!/usr/local/bin/perl + +use strict; + +use warnings; +use feature qw(say); +use Test::More; + +is( my_function(), 1 ); + +done_testing(); + +sub my_function { + return 1; +} + -- cgit From ee4ca50a9ae8434166c8de2eea5121e58ea7d7db Mon Sep 17 00:00:00 2001 From: drbaggy Date: Wed, 25 Nov 2020 09:31:47 +0000 Subject: adding files --- challenge-085/james-smith/perl/ch-1.pl | 4 +-- challenge-086/james-smith/perl/ch-1.pl | 14 +++++--- challenge-086/james-smith/perl/ch-2.pl | 65 ++++++++++++++++++++++++++++++++-- challenge-087/james-smith/perl/ch-1.pl | 45 +++++++++++++++++++++-- challenge-087/james-smith/perl/ch-2.pl | 31 +++++++++++++--- challenge-088/james-smith/perl/ch-2.pl | 19 ++++++---- 6 files changed, 156 insertions(+), 22 deletions(-) diff --git a/challenge-085/james-smith/perl/ch-1.pl b/challenge-085/james-smith/perl/ch-1.pl index 352ddbfcdd..60cadd5f50 100644 --- a/challenge-085/james-smith/perl/ch-1.pl +++ b/challenge-085/james-smith/perl/ch-1.pl @@ -11,9 +11,9 @@ is( trip_sum(qw(0.5 1.1 0.3 0.7)), 1 ); done_testing; sub trip_sum { - for my $i (0.. (@_-3) ) { + for my $i ( 0 :W.. (@_-3) ) { next unless $_[$i] < 2; ## For large arrays this might save some time...; - for my $j ( ($i+1).. (@_-2) ) { + for my $j ( ($i+1) .. (@_-2) ) { next unless $_[$i]+$_[$j] < 2; ## For large arrays this might save some time...; for ( ($j+1) .. (@_-1) ) { return 1 if 1 < $_[$i]+$_[$j]+$_[$_] && $_[$i]+$_[$j]+$_[$_] < 2; diff --git a/challenge-086/james-smith/perl/ch-1.pl b/challenge-086/james-smith/perl/ch-1.pl index e87f9990c9..0055f568a1 100644 --- a/challenge-086/james-smith/perl/ch-1.pl +++ b/challenge-086/james-smith/perl/ch-1.pl @@ -6,12 +6,18 @@ use warnings; use feature qw(say); use Test::More; -# is( my_function(), 1 ); +is( pair_diff(7,qw(10 8 12 15 5)), 1 ); +is( pair_diff(6,qw(1 5 2 9 7)), 1 ); +is( pair_diff(15,qw(10 30 20 50 40)), 0 ); done_testing(); -sub my_function() { - - return; +sub pair_diff { + my ($A,@N) = @_; + while(@N) { + my $l = shift @N; + return 1 if grep { $_-$l == $A || $l-$_ == $A } @N; + } + return 0; } diff --git a/challenge-086/james-smith/perl/ch-2.pl b/challenge-086/james-smith/perl/ch-2.pl index e87f9990c9..e49c74b0dd 100644 --- a/challenge-086/james-smith/perl/ch-2.pl +++ b/challenge-086/james-smith/perl/ch-2.pl @@ -5,13 +5,72 @@ use strict; use warnings; use feature qw(say); use Test::More; +use Data::Dumper qw(Dumper); -# is( my_function(), 1 ); +my @input = ( + [qw( _ _ _ 2 6 _ 7 _ 1 )], + [qw( 6 8 _ _ 7 _ _ 9 _ )], + [qw( 1 9 _ _ _ 4 5 _ _ )], + [qw( 8 2 _ 1 _ _ _ 4 _ )], + [qw( _ _ 4 6 _ 2 9 _ _ )], + [qw( _ 5 _ _ _ 3 _ 2 8 )], + [qw( _ _ 9 3 _ _ _ 7 4 )], + [qw( _ 4 _ _ 5 _ _ 3 6 )], + [qw( 7 _ 3 _ 1 8 _ _ _ )], +); +my @i2 = ( + [qw( _ 5 _ _ _ _ _ 8 _ )], + [qw( 3 _ 9 _ _ _ 7 _ 2 )], + [qw( _ 8 _ 9 _ 1 _ 3 _ )], + [qw( _ _ 1 7 4 3 8 _ _ )], + [qw( _ _ _ 2 _ 5 _ _ _ )], + [qw( _ _ 5 1 9 8 4 _ _ )], + [qw( _ 4 _ 8 _ 9 _ 6 _ )], + [qw( 6 _ 8 _ _ _ 5 _ 1 )], + [qw( _ 9 _ _ _ _ _ 4 _ )], +); +is( display(solve(@input)), '[ 4 3 5 2 6 9 7 8 1 ] +[ 6 8 2 5 7 1 4 9 3 ] +[ 1 9 7 8 3 4 5 6 2 ] +[ 8 2 6 1 9 5 3 4 7 ] +[ 3 7 4 6 8 2 9 1 5 ] +[ 9 5 1 7 4 3 6 2 8 ] +[ 5 1 9 3 2 6 8 7 4 ] +[ 2 4 8 9 5 7 1 3 6 ] +[ 7 6 3 4 1 8 2 5 9 ]' ); +is( display(solve(@i2)), 'x' ); done_testing(); -sub my_function() { +sub display { + return join "\n", map { "[ @{[ map { ref($_) ? join '',@{$_} : $_ } @{$_} ]} ]"; } @_; +} - return; +sub solve { + my @grid = map { [ map { $_ eq '_' ? [1..9] : 1*$_ } @{$_} ] } @_; + my $previous_flag = 0; + while( 1 ) { ## Naive sweep.... + my $flag = 0; + foreach my $i (0..8) { + foreach my $j (0..8) { + next unless ref $grid[$i][$j]; + my %values = map { $_=>$_ } @{$grid[$i][$j]}; + foreach (0..8) { + delete $values{$grid[$i][$_]} if !ref $grid[$i][$_]; + delete $values{$grid[$_][$j]} if !ref $grid[$_][$j]; + my $x = 3*int($i/3) + $_%3; + my $y = 3*int($j/3) + int($_/3); + delete $values{$grid[$x][$y]} if !ref $grid[$x][$y]; + } + my @Q = keys %values; + $grid[$i][$j] = @Q == 1 ? 1*$Q[0] : \@Q; + $flag += @Q unless @Q==1; + } + } + last unless $flag; + last if $flag == $previous_flag; + $previous_flag = $flag; + } + return @grid; } diff --git a/challenge-087/james-smith/perl/ch-1.pl b/challenge-087/james-smith/perl/ch-1.pl index 930d91cc65..06d1180f84 100644 --- a/challenge-087/james-smith/perl/ch-1.pl +++ b/challenge-087/james-smith/perl/ch-1.pl @@ -5,12 +5,51 @@ use strict; use warnings; use feature qw(say); use Test::More; +use Data::Dumper qw(Dumper); -is( my_function(), 1 ); +is( display_lcf( lcf(qw(100 4 50 3 2)) ), '(2, 3, 4)' ); +is( display_lcf( lcf(qw(20 30 10 40 50)) ), '0' ); +is( display_lcf( lcf(qw(20 19 9 11 10)) ), '(9, 10, 11)' ); +is( display_lcf( lcf(reverse 1..100) ), display_lcf(1..100) ); done_testing(); -sub my_function { - return 1; +sub display_lcf { + return @_ ? sprintf '(%s)', join q(, ), @_ : 0; +} + +sub lcf { + my @n = @_; + my %seq; + ## Start by collecting together those numbers which + ## match the criteria of both value and value+1 are + ## in array... + foreach my $a (@n) { + $seq{$a} = $a+1 if grep {$_==$a+1} @n; + } + ## Now we are going to collapse the structure; + ## $seq{$_} exists in %seq we remove it and update + ## the value of $seq{$_} to that value. + ## (delete removes element from hash - return value + ## is element removed) + my $flag = 1; + while($flag) { + $flag = 0; + foreach (keys %seq) { + next unless exists $seq{$_} && exists $seq{$seq{$_}}; + $seq{$_} = delete $seq{$seq{$_}}; + $flag = 1; + } + } + ## Now we look for the longest sequence + ## (note we only return the first sequence of a given + ## length we find) + my $k = undef; + foreach ( keys %seq ) { + $k = $_ if !defined $k || $seq{$_}-$_ > $seq{$k}-$k; + } + ## Return it if there is a longest sequence. + return unless defined $k; + return $k..$seq{$k}; } diff --git a/challenge-087/james-smith/perl/ch-2.pl b/challenge-087/james-smith/perl/ch-2.pl index 930d91cc65..b6dac95cef 100644 --- a/challenge-087/james-smith/perl/ch-2.pl +++ b/challenge-087/james-smith/perl/ch-2.pl @@ -3,14 +3,37 @@ use strict; use warnings; -use feature qw(say); +use featureqw(say); use Test::More; -is( my_function(), 1 ); +is( display_rect( largest_rect( [qw(0 0 0 1 0 0)], [qw(1 1 1 0 0 0)], [qw(0 0 1 0 0 1)], [qw(1 1 1 1 1 0)], [qw(1 1 1 1 1 0)] ) ), + display_rect( [qw(1 1 1 1 1)], [qw(1 1 1 1 1)] ) ); +is( display_rect( largest_rect( [qw(1 0 1 0 1 0)], [qw(0 1 0 1 0 1)], [qw(1 0 1 0 1 0)], [qw(0 1 0 1 0 1)] ) ), 0 ); +is( display_rect( largest_Rect( [qw(0 0 0 1 1 1)], [qw(1 1 1 1 1 1)], [qw(0 0 1 0 0 1)], [qw(0 0 1 1 1 1)], [qw(0 0 1 1 1 1)] )), + display_rect( [qw(1 1 1 1)], [qw(1 1 1 1)] ) ); done_testing(); -sub my_function { - return 1; +sub display_rect { + my @h; + return 0 unless @h; + return join "\n", map { "[ @{$_} ]" } @h; +} +sub largest_rect { + my @grid = @_; + my $h = @grid; + my $w = @{$grid[0]}); + my ($m_h,$m_w) = (0,0); + foreach my $l (0..($w-1)) { + OUTER: foreach my $t (0..($h-1)) { + my $flag = 1; + foreach my $r ($l+1..($w-1)) { + foreach my $b ($l+1..($w-1)) { + next OUTER unless $grid[$r][$b]; + } + } + if( $ + } + } } diff --git a/challenge-088/james-smith/perl/ch-2.pl b/challenge-088/james-smith/perl/ch-2.pl index 3ea3d71715..98794b2f6a 100644 --- a/challenge-088/james-smith/perl/ch-2.pl +++ b/challenge-088/james-smith/perl/ch-2.pl @@ -12,13 +12,20 @@ is( "@{ spiral_matrix([1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]) }", '1 2 3 done_testing(); sub spiral_matrix { - my @rows = @_; + my @rows = map { [@{$_}] } @_; + ## Note this is a destructive method... So we take a copy of the elements of the array o/w we will blow contents of sub-arrays away. my @res; - while(@rows) { - push @res, @{shift @rows}; - push @res, pop @{$_} foreach grep { @{$_} } @rows; - push @res, reverse @{ pop @rows } if @rows; ## Make sure we have data! - push @res, shift @{$_} foreach grep { @{$_} } reverse @rows; + while( @rows && @{$rows[0]} ) { + ## We work around the square..... + ## TOP >>>> we just push to the answers... (and remove them from the array!) + ## RIGHT vvvv Remaining rows we take off the last element... and push to the answer array + ## BOTTOM <<<< (if there is one) we add it to the answers in reverse and remove from the array + ## LEFT ^^^^ Finally we push the first element of each row into the answers {note we go up the array + ## Repeat until the array is empty (either has no rows or no columns [entries in first row]) + push @res, @{shift @rows}; + push @res, pop @{$_ } foreach grep { @{$_} } @rows; + push @res, reverse @{pop @rows} if @rows; + push @res, shift @{$_ } foreach grep { @{$_} } reverse @rows; } return \@res; } -- cgit From 6ae4688bd7504282a3a1bb311e83abcd90e9e712 Mon Sep 17 00:00:00 2001 From: drbaggy Date: Wed, 25 Nov 2020 09:32:46 +0000 Subject: oops --- challenge-085/james-smith/perl/ch-1.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/challenge-085/james-smith/perl/ch-1.pl b/challenge-085/james-smith/perl/ch-1.pl index 60cadd5f50..c838a2845a 100644 --- a/challenge-085/james-smith/perl/ch-1.pl +++ b/challenge-085/james-smith/perl/ch-1.pl @@ -11,7 +11,7 @@ is( trip_sum(qw(0.5 1.1 0.3 0.7)), 1 ); done_testing; sub trip_sum { - for my $i ( 0 :W.. (@_-3) ) { + for my $i ( 0 .. (@_-3) ) { next unless $_[$i] < 2; ## For large arrays this might save some time...; for my $j ( ($i+1) .. (@_-2) ) { next unless $_[$i]+$_[$j] < 2; ## For large arrays this might save some time...; -- cgit From f3b73a726dfa294a9e585ed93284d41498a1a0e0 Mon Sep 17 00:00:00 2001 From: Myoungjin JEON Date: Wed, 25 Nov 2020 21:55:37 +1100 Subject: [ch-087/jeongoon] ch-2.hs added --- challenge-087/jeongoon/haskell/ch-2.hs | 106 +++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 challenge-087/jeongoon/haskell/ch-2.hs diff --git a/challenge-087/jeongoon/haskell/ch-2.hs b/challenge-087/jeongoon/haskell/ch-2.hs new file mode 100644 index 0000000000..02328a8458 --- /dev/null +++ b/challenge-087/jeongoon/haskell/ch-2.hs @@ -0,0 +1,106 @@ +import System.Exit +import Data.List (isPrefixOf, groupBy, subsequences, union + , intersperse, replicate) +import Data.Char (digitToInt) +import qualified Data.Map as M + +{- tested with: +echo '[000111][111111][001001][001111][001111]' | runhaskell ch-2.hs + +-} + +-- solution +getMatrixFromStdin :: IO [[Int]] +getMatrixFromStdin = ( convertToInteger + -- . filterEmptyRow + . parseMatrixLines + . toMatrixLines ) `fmap` getContents + where + parseMatrixLines = map (filter (not.isPrefixOf " "). + groupBy (\a b -> a == ' ' && a == b). + filter (\c -> c `elem` " 10")) + toMatrixLines = lines . unlines . groupBy (\_ b -> b /= ']') + --filterEmptyRow = filter ((0/=).length) + convertToInteger = map (map (\x -> (map digitToInt x)!!0)) + + -- a line between column A to B +data ConsecutivePoints = ConsecutivePoints { begin :: Int, + end :: Int } + deriving (Eq, Ord, Show) + +groupByConsecutiveNumber_ :: (Eq a, Num a) => [a] -> [[a]] +groupByConsecutiveNumber_ = + foldl (\acc x -> if ((not.null) acc) + then if (x -(last (last acc))) == 1 + then (init acc) ++ [(last acc) ++ [x]] + else acc ++ [[x]] + else [[x]] ) [] + +getConsecutivePointsFromMatrix :: [[Int]] -> [(ConsecutivePoints, Int)] +getConsecutivePointsFromMatrix = + ( foldr (\x acc -> let (pts, r) = x + in acc ++ (map (\p -> (p, r)) pts) ) [] + . zipWithRowNum -- -> [([ConsecutivePoints], Int)] + . map ( map toConsecutivePoints + . consecutiveLinesFromIndices + . binariesToIndices ) ) + where + subsequences' = filter ((0<).length) . subsequences + binariesToIndices :: [Int] -> [Int] + binariesToIndices row = foldl (\acc x -> if ((1==).snd) x + then acc ++ [(fst x)] + else acc ) [] (zip [0..] row) + consecutiveLinesFromIndices :: [Int] -> [[Int]] + consecutiveLinesFromIndices = ( foldr (++) [] -- flatten + . map subsequences' + . groupByConsecutiveNumber_ ) + zipWithRowNum = (flip zip) [0..] + + toConsecutivePoints :: [Int] -> ConsecutivePoints + toConsecutivePoints = (\xs -> ConsecutivePoints (head xs) (last xs)) + +groupByConsecutivePoints :: [(ConsecutivePoints, Int)] + -> [(ConsecutivePoints,[Int])] +groupByConsecutivePoints ls = (M.toList . M.fromListWith union) + $ map (\(k,v) -> (k,[v])) ls + +groupByArea :: [(ConsecutivePoints, [Int])] + -> [((ConsecutivePoints, [Int]), Int)] +groupByArea = + foldr (++) [] + . map (\(ps , rs) -> + map (\rs' -> ((ps, rs'), ((length rs') + * ((end ps) - (begin ps) + 1)))) + (groupByConsecutiveNumber_ rs)) + +findMaximumAreas :: [((ConsecutivePoints, [Int]), Int)] + -> [((ConsecutivePoints, [Int]), Int)] +findMaximumAreas = foldr (\x@(_, area) acc -> + let maxarea = if null acc then 0 + else (snd.head) acc + in if area > maxarea then [x] + else if area == maxarea then acc ++ [x] + else acc) [] +showMaxAreas :: [((ConsecutivePoints, [Int]), Int)] -> [[String]] +showMaxAreas = + map (\((cpts, rs), area) -> + if area == 1 then [] + else let nc = (end cpts) - (begin cpts) + 1 + nr = length rs + in (replicate nr.intersperse ' '. replicate nc) '1') + +-- testing +main = do + aSample <- getMatrixFromStdin; + putStrLn "Given Matrix:" + mapM_ (putStrLn.unwords.map show) aSample + + if length aSample < 1 + then die "0 as given data is not sufficient" + else let visibleMaxAreas = ( showMaxAreas + . findMaximumAreas + . groupByArea + . groupByConsecutivePoints + . getConsecutivePointsFromMatrix ) aSample + in if null visibleMaxAreas then putStrLn "0" + else mapM_ (mapM_ putStrLn) visibleMaxAreas -- cgit From 6bebdc5ac2c140f354a90face0ddf5739e1f7e84 Mon Sep 17 00:00:00 2001 From: Myoungjin JEON Date: Wed, 25 Nov 2020 22:27:51 +1100 Subject: [ch-086/jeongoon] ch-1.hs added --- challenge-086/jeongoon/haskell/ch-1.hs | 41 ++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 challenge-086/jeongoon/haskell/ch-1.hs diff --git a/challenge-086/jeongoon/haskell/ch-1.hs b/challenge-086/jeongoon/haskell/ch-1.hs new file mode 100644 index 0000000000..235f84e555 --- /dev/null +++ b/challenge-086/jeongoon/haskell/ch-1.hs @@ -0,0 +1,41 @@ +import System.Environment +import System.Exit +import Data.Char (isNumber) +import Data.Maybe (isNothing, catMaybes) +import Data.List (sort) + +{- tested with: +runhaskell ch-1.hs 1 3 2 -1 -2 -3 6 7 9 1 +1 as 3 -2 = 1 +-} + +usageMessage = "Usage: runhaskell ch-1.hs " + ++ " ..." + +pairDifference _ [] = Nothing +pairDifference target ls = pairdiff target (head sorted) (tail sorted) 1 + where + sorted = sort ls + pairdiff _ _ [] _ = Nothing + pairdiff t f rst@(r:_) i = -- t: target, f: first, i: index + if i >= (length rst) then Nothing + else case ((rst !! i) - f) `compare` t of + LT -> pairdiff t f rst (succ i) + GT -> pairdiff t r rst 1 + EQ -> Just (f, (rst !! i)) + +main = do + ints <- (catMaybes.map (\nStr -> + if (all isNumber nStr) then Just(read nStr :: Int) + else Nothing )) `fmap` getArgs; + + let d = (head ints) in + + if (length ints) < 2 + then die usageMessage + else if d < 0 + then die usageMessage + else case pairDifference d (tail ints) of + Nothing -> putStrLn "0" + Just (a,b) -> putStrLn $ "1 as " ++ (show b) ++ " - " + ++ (show a) ++ " = " ++ (show d) -- cgit From 33a55e5a133102653ae742d8641d1c2947795527 Mon Sep 17 00:00:00 2001 From: Myoungjin JEON Date: Wed, 25 Nov 2020 22:42:23 +1100 Subject: allow negative integer value as input --- challenge-086/jeongoon/haskell/ch-1.hs | 31 ++++++++++++++++--------------- challenge-087/jeongoon/haskell/ch-1.hs | 6 ++++-- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/challenge-086/jeongoon/haskell/ch-1.hs b/challenge-086/jeongoon/haskell/ch-1.hs index 235f84e555..59a46bb9ec 100644 --- a/challenge-086/jeongoon/haskell/ch-1.hs +++ b/challenge-086/jeongoon/haskell/ch-1.hs @@ -6,7 +6,7 @@ import Data.List (sort) {- tested with: runhaskell ch-1.hs 1 3 2 -1 -2 -3 6 7 9 1 -1 as 3 -2 = 1 +1 as 3 - 2 = 1 -} usageMessage = "Usage: runhaskell ch-1.hs " @@ -25,17 +25,18 @@ pairDifference target ls = pairdiff target (head sorted) (tail sorted) 1 EQ -> Just (f, (rst !! i)) main = do - ints <- (catMaybes.map (\nStr -> - if (all isNumber nStr) then Just(read nStr :: Int) - else Nothing )) `fmap` getArgs; - - let d = (head ints) in - - if (length ints) < 2 - then die usageMessage - else if d < 0 - then die usageMessage - else case pairDifference d (tail ints) of - Nothing -> putStrLn "0" - Just (a,b) -> putStrLn $ "1 as " ++ (show b) ++ " - " - ++ (show a) ++ " = " ++ (show d) + (catMaybes.map (\nStr -> + -- poor parser + if (all (`elem` "0123456789+-") nStr) + then Just(read nStr :: Int) + else Nothing )) `fmap` getArgs + >>= ( \ints -> + let d = (head ints) in + if (length ints) < 2 + then die usageMessage + else if d < 0 + then die usageMessage + else case pairDifference d (tail ints) of + Nothing -> putStrLn "0" + Just (a,b) -> putStrLn $ "1 as " ++ (show b) ++ " - " + ++ (show a) ++ " = " ++ (show d) ) diff --git a/challenge-087/jeongoon/haskell/ch-1.hs b/challenge-087/jeongoon/haskell/ch-1.hs index dc2d24e980..23879e69f2 100644 --- a/challenge-087/jeongoon/haskell/ch-1.hs +++ b/challenge-087/jeongoon/haskell/ch-1.hs @@ -1,6 +1,5 @@ import System.Environment import System.Exit -import Data.Char (isNumber) import Data.Maybe (catMaybes) import Data.List (sort, sortBy) @@ -8,6 +7,7 @@ import Data.List (sort, sortBy) (only shows one answer) -} + answerLongestConsecutiveSequence :: [Int] -> [Int] answerLongestConsecutiveSequence = ( head @@ -22,7 +22,9 @@ answerLongestConsecutiveSequence = main = do (catMaybes.map (\nStr -> - if (all isNumber nStr) then Just(read nStr :: Int) + -- poor parser + if (all (`elem` "0123456789+-") nStr) + then Just(read nStr :: Int) else Nothing )) `fmap` getArgs >>= (\nums -> if length nums < 1 then -- cgit From 49fc1359ebc1ce2cd202de3efa83cba1d8e51bb6 Mon Sep 17 00:00:00 2001 From: chirvasitua Date: Wed, 25 Nov 2020 10:12:37 -0500 Subject: 1st commit on 001-004 --- challenge-001/stuart-little/README | 1 + challenge-001/stuart-little/raku/ch-1.p6 | 8 ++++++++ challenge-001/stuart-little/raku/ch-2.p6 | 6 ++++++ challenge-002/stuart-little/README | 1 + challenge-002/stuart-little/raku/ch-1.p6 | 6 ++++++ challenge-002/stuart-little/raku/ch-2.p6 | 12 ++++++++++++ challenge-003/stuart-little/README | 1 + challenge-003/stuart-little/raku/ch-1.p6 | 10 ++++++++++ challenge-003/stuart-little/raku/ch-2.p6 | 10 ++++++++++ challenge-004/stuart-little/README | 1 + challenge-004/stuart-little/raku/ch-1.p6 | 12 ++++++++++++ challenge-004/stuart-little/raku/ch-2.p6 | 12 ++++++++++++ 12 files changed, 80 insertions(+) create mode 100644 challenge-001/stuart-little/README create mode 100755 challenge-001/stuart-little/raku/ch-1.p6 create mode 100755 challenge-001/stuart-little/raku/ch-2.p6 create mode 100644 challenge-002/stuart-little/README create mode 100755 challenge-002/stuart-little/raku/ch-1.p6 create mode 100755 challenge-002/stuart-little/raku/ch-2.p6 create mode 100644 challenge-003/stuart-little/README create mode 100755 challenge-003/stuart-little/raku/ch-1.p6 create mode 100755 challenge-003/stuart-little/raku/ch-2.p6 create mode 100644 challenge-004/stuart-little/README create mode 100755 challenge-004/stuart-little/raku/ch-1.p6 create mode 100755 challenge-004/stuart-little/raku/ch-2.p6 diff --git a/challenge-001/stuart-little/README b/challenge-001/stuart-little/README new file mode 100644 index 0000000000..78439907de --- /dev/null +++ b/challenge-001/stuart-little/README @@ -0,0 +1 @@ +Solutions by Stuart Little diff --git a/challenge-001/stuart-little/raku/ch-1.p6 b/challenge-001/stuart-little/raku/ch-1.p6 new file mode 100755 index 0000000000..bee62eddb9 --- /dev/null +++ b/challenge-001/stuart-little/raku/ch-1.p6