aboutsummaryrefslogtreecommitdiff
path: root/challenge-077
diff options
context:
space:
mode:
Diffstat (limited to 'challenge-077')
-rw-r--r--challenge-077/andinus/README94
-rw-r--r--challenge-077/andinus/blog-1.txt1
-rwxr-xr-xchallenge-077/andinus/perl/ch-1.pl25
-rw-r--r--challenge-077/arne-sommer/blog.txt1
-rwxr-xr-xchallenge-077/arne-sommer/raku/ch-1.p660
-rwxr-xr-xchallenge-077/arne-sommer/raku/ch-2.p643
-rwxr-xr-xchallenge-077/arne-sommer/raku/fibonacci-sum60
-rwxr-xr-xchallenge-077/arne-sommer/raku/fibonacci-sum-first82
-rwxr-xr-xchallenge-077/arne-sommer/raku/fibonacci-sum-first-verbose84
-rwxr-xr-xchallenge-077/arne-sommer/raku/lonely-x43
-rw-r--r--challenge-077/arne-sommer/raku/matrix1.txt3
-rw-r--r--challenge-077/arne-sommer/raku/matrix2.txt4
-rw-r--r--challenge-077/ash/cpp/ch-2a.cpp65
-rw-r--r--challenge-077/ash/cpp/ch-2b.cpp82
-rw-r--r--challenge-077/ash/html/ch-2.html106
-rw-r--r--challenge-077/ash/perl/ch-2.pl38
-rw-r--r--challenge-077/ash/python/ch-2.py42
-rw-r--r--challenge-077/aviral-goel/README1
-rw-r--r--challenge-077/aviral-goel/haskell/ch-1.hs30
-rw-r--r--challenge-077/aviral-goel/haskell/ch-2.hs58
-rw-r--r--challenge-077/laurent-rosenfeld/blog.txt1
-rw-r--r--challenge-077/laurent-rosenfeld/perl/ch-1.pl22
-rw-r--r--challenge-077/laurent-rosenfeld/perl/ch-2.pl35
-rw-r--r--challenge-077/laurent-rosenfeld/raku/ch-1.raku8
-rw-r--r--challenge-077/laurent-rosenfeld/raku/ch-1a.raku15
-rw-r--r--challenge-077/laurent-rosenfeld/raku/ch-2.raku31
-rw-r--r--challenge-077/markus-holzer/raku/ch-2.input3
-rw-r--r--challenge-077/markus-holzer/raku/ch-2.input.24
-rw-r--r--challenge-077/markus-holzer/raku/ch-2.raku14
-rw-r--r--challenge-077/markus-holzer/raku/ch-2.twitter.raku5
-rw-r--r--challenge-077/nunovieira220/perl/ch-1.pl50
-rw-r--r--challenge-077/nunovieira220/perl/ch-2.pl45
-rw-r--r--challenge-077/p6steve/README1
-rwxr-xr-xchallenge-077/p6steve/raku/ch-1.raku8
-rwxr-xr-xchallenge-077/p6steve/raku/ch-2.raku48
-rwxr-xr-xchallenge-077/perlboy1967/perl/ch-1.pl85
-rwxr-xr-xchallenge-077/perlboy1967/perl/ch-2.pl85
37 files changed, 1310 insertions, 72 deletions
diff --git a/challenge-077/andinus/README b/challenge-077/andinus/README
index 1653e8e915..9437e98f28 100644
--- a/challenge-077/andinus/README
+++ b/challenge-077/andinus/README
@@ -1,102 +1,52 @@
━━━━━━━━━━━━━━━
- CHALLENGE 076
+ CHALLENGE 077
━━━━━━━━━━━━━━━
Table of Contents
─────────────────
-1 Task 1 - Prime Sum
+1 Task 1 - Fibonacci Sum
.. 1.1 Perl
-1 Task 1 - Prime Sum
-════════════════════
+1 Task 1 - Fibonacci Sum
+════════════════════════
- You are given a number `$N'. Write a script to find the minimum number
- of prime numbers required, whose summation gives you `$N'.
+ You are given a positive integer `$N'.
- • For the sake of this task, please assume 1 is not a prime number.
+ Write a script to find the total number of Fibonacci Numbers required
+ to get `$N' on addition. You are NOT allowed to repeat a number. Print
+ 0 if none found.
+
+ *Note*: This solution is incomplete. Others have pushed complete
+ solutions, look at those.
1.1 Perl
────────
• Program: [file:perl/ch-1.pl]
- • Help taken from: [https://stackoverflow.com/a/35756072].
-
- User input is stored in `$input'.
- ┌────
- │ my $input = shift @ARGV;
- │ chomp $input;
- └────
-
- 1 is assumed not to be a prime number so we reject numbers less than
- or equal to 1.
- ┌────
- │ die "Invalid input, enter numbers greater than 1.\n" if $input <= 1;
- └────
-
- If it's a prime number then the minimum sum is the number itself so we
- just return it & exit.
- ┌────
- │ say $input and exit 0 if is_prime($input) == 1;
- └────
-
- If `$input' is even then we loop from 2 to `$input / 2' & check if
- both `$i' & `$diff' are primes. If both are primes then we have our
- numbers.
- Eventually we'll find 2 primes to be a sum of even numbers. From
- WikiPedia, [Goldbach's conjecture] has been shown to hold for all
- integers less than `4 × 10^18'.
+ Make a list of all possible sums of `$input'.
┌────
- │ if ($input % 2 == 0) {
- │ foreach my $i (2 ... $input / 2) {
- │ my $diff = $input - $i;
- │ say "$i + $diff"
- │ if is_prime($i) and is_prime($diff);
- │ }
+ │ my @sums;
+ │ foreach my $num (0 ... $input / 2) {
+ │ my $diff = $input - $num;
+ │ push @sums, [$diff, $num];
│ }
└────
- If the input is odd then we first check if `$input - 2' is a prime, if
- it is then input is the sum of two primes, 2 & `$input - 2'.
+ Loop over `@sums' & then print those sets which have both `$sums->[0]'
+ & `$sums->[1]' in fibonacci series.
┌────
- │ elsif (is_prime($input - 2)) {
- │ say "2 + $input";
- │ }
- └────
-
- If even that doesn't match then the minimum sum will have three
- numbers. 3 & then we use the same function as for even numbers to find
- the other two primes.
- ┌────
- │ else {
- │ foreach my $i (2 ... ($input - 3) / 2) {
- │ my $diff = $input - 3 - $i;
- │ say "3 + $i + $diff"
- │ if is_prime($i) and is_prime($diff);
- │ }
- │ }
- └────
-
- If $num is divisible by any number between 2 & `sqrt($num)' then it's
- not prime.
- ┌────
- │ sub is_prime {
- │ my $num = shift @_;
+ │ sub is_fib { return Math::Fibonacci::isfibonacci(@_) }
- │ foreach my $i (2 ... sqrt($num)) {
- │ return 0 if $num % $i == 0;
- │ }
- │ return 1;
+ │ foreach (@sums) {
+ │ next unless is_fib($_->[0]) and is_fib($_->[1]);
+ │ say "$_->[0] + $_->[1]";
│ }
└────
-
-
-[Goldbach's conjecture]
-https://en.wikipedia.org/wiki/Goldbach%2527s_conjecture
diff --git a/challenge-077/andinus/blog-1.txt b/challenge-077/andinus/blog-1.txt
new file mode 100644
index 0000000000..3758cbc1da
--- /dev/null
+++ b/challenge-077/andinus/blog-1.txt
@@ -0,0 +1 @@
+https://andinus.tilde.institute/pwc/challenge-077/
diff --git a/challenge-077/andinus/perl/ch-1.pl b/challenge-077/andinus/perl/ch-1.pl
new file mode 100755
index 0000000000..83a03c6069
--- /dev/null
+++ b/challenge-077/andinus/perl/ch-1.pl
@@ -0,0 +1,25 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use feature 'say';
+
+use Math::Fibonacci;
+
+my $input = shift @ARGV;
+chomp $input;
+
+die "Invalid input, enter numbers greater than 0.\n" if $input < 0;
+
+my @sums;
+foreach my $num (0 ... $input / 2) {
+ my $diff = $input - $num;
+ push @sums, [$diff, $num];
+}
+
+sub is_fib { return Math::Fibonacci::isfibonacci(@_) }
+
+foreach (@sums) {
+ next unless is_fib($_->[0]) and is_fib($_->[1]);
+ say "$_->[0] + $_->[1]";
+}
diff --git a/challenge-077/arne-sommer/blog.txt b/challenge-077/arne-sommer/blog.txt
new file mode 100644
index 0000000000..80ea989b42
--- /dev/null
+++ b/challenge-077/arne-sommer/blog.txt
@@ -0,0 +1 @@
+https://raku-musings.com/lonely-sum.html
diff --git a/challenge-077/arne-sommer/raku/ch-1.p6 b/challenge-077/arne-sommer/raku/ch-1.p6
new file mode 100755
index 0000000000..719e169ecf
--- /dev/null
+++ b/challenge-077/arne-sommer/raku/ch-1.p6
@@ -0,0 +1,60 @@
+#! /usr/bin/env raku
+
+subset PositiveInt of Int where * >= 1;
+
+unit sub MAIN (PositiveInt $N, :v(:$verbose), :u(:$upto));
+
+my $label;
+my $found;
+
+
+$upto
+ ?? (1..$N).map({ fibonal-decomposition($_) })
+ !! fibonal-decomposition($N);
+
+sub fibonal-decomposition($target)
+{
+ $found = False;
+ $label = 'a';
+
+ my @fibs;
+ my $fibonacci := (1, 1, * + * ... Inf);
+
+ for $fibonacci -> $fib { last if $fib > $target; @fibs.unshift: $fib; }
+ @fibs.pop;
+
+ if $verbose
+ {
+ say ": Target: $target" if $upto;
+ say ": Fibonacci (reverse): { @fibs.join(", ") }";
+ }
+
+ recurse(0, (), @fibs, $target);
+
+ say "0" unless $found;
+ say "" if $upto;
+}
+
+sub recurse ($value is copy, @values is copy, @fibonacci is copy, $input)
+{
+ if $value < $input
+ {
+ while @fibonacci
+ {
+ my $add = @fibonacci.shift;
+
+ if $value + $add <= $input
+ {
+ my $value2 = $value + $add;
+ my @values2 = @values.clone.push: $add;
+ recurse($value2, @values2, @fibonacci, $input);
+ }
+ }
+ }
+
+ elsif $value == $input
+ {
+ say "{ $label++ }) { @values.join(' + ') } = $input";
+ $found = True;
+ }
+}
diff --git a/challenge-077/arne-sommer/raku/ch-2.p6 b/challenge-077/arne-sommer/raku/ch-2.p6
new file mode 100755
index 0000000000..035cf2d973
--- /dev/null
+++ b/challenge-077/arne-sommer/raku/ch-2.p6
@@ -0,0 +1,43 @@
+#! /usr/bin/env raku
+
+unit sub MAIN ($matrix where $matrix.IO.f && $matrix.IO.r = 'matrix1.txt',
+ :v(:$verbose));
+
+my @matrix = $matrix.IO.lines.map( *.words.list );
+
+die "Uneven grid row length" unless [==] @(@matrix)>>.elems;
+
+die "Single characters only in the grid" if @(@matrix)>>.chars>>.max.max > 1;
+
+my $rows = @matrix.elems;
+my $cols = @matrix[0].elems;
+
+my $is_lonely = 0;
+
+for ^$rows -> $row
+{
+ for ^$cols -> $col
+ {
+ say ": [$row,$col] -> @matrix[$row][$col] { is_lonely(@matrix, $row, $col) ?? 'is lonely' !! '' }" if $verbose;
+ $is_lonely++ if is_lonely(@matrix, $row, $col);
+ }
+}
+
+say $is_lonely;
+
+sub is_lonely (@matrix, $row, $col)
+{
+ return False if @matrix[$row][$col] eq 'O';
+
+ for (-1, 0, 1) -> $r
+ {
+ for (-1, 0, 1) -> $c
+ {
+ next if $r == $c == 0;
+ next unless @matrix[$row + $r][$col + $c].defined;
+
+ return False if @matrix[$row + $r][$col + $c] eq 'X';
+ }
+ }
+ return True;
+}
diff --git a/challenge-077/arne-sommer/raku/fibonacci-sum b/challenge-077/arne-sommer/raku/fibonacci-sum
new file mode 100755
index 0000000000..719e169ecf
--- /dev/null
+++ b/challenge-077/arne-sommer/raku/fibonacci-sum
@@ -0,0 +1,60 @@
+#! /usr/bin/env raku
+
+subset PositiveInt of Int where * >= 1;
+
+unit sub MAIN (PositiveInt $N, :v(:$verbose), :u(:$upto));
+
+my $label;
+my $found;
+
+
+$upto
+ ?? (1..$N).map({ fibonal-decomposition($_) })
+ !! fibonal-decomposition($N);
+
+sub fibonal-decomposition($target)
+{
+ $found = False;
+ $label = 'a';
+
+ my @fibs;
+ my $fibonacci := (1, 1, * + * ... Inf);
+
+ for $fibonacci -> $fib { last if $fib > $target; @fibs.unshift: $fib; }
+ @fibs.pop;
+
+ if $verbose
+ {
+ say ": Target: $target" if $upto;
+ say ": Fibonacci (reverse): { @fibs.join(", ") }";
+ }
+
+ recurse(0, (), @fibs, $target);
+
+ say "0" unless $found;
+ say "" if $upto;
+}
+
+sub recurse ($value is copy, @values is copy, @fibonacci is copy, $input)
+{
+ if $value < $input
+ {
+ while @fibonacci
+ {
+ my $add = @fibonacci.shift;
+
+ if $value + $add <= $input
+ {
+ my $value2 = $value + $add;
+ my @values2 = @values.clone.push: $add;
+ recurse($value2, @values2, @fibonacci, $input);
+ }
+ }
+ }
+
+ elsif $value == $input
+ {
+ say "{ $label++ }) { @values.join(' + ') } = $input";
+ $found = True;
+ }
+}
diff --git a/challenge-077/arne-sommer/raku/fibonacci-sum-first b/challenge-077/arne-sommer/raku/fibonacci-sum-first
new file mode 100755
index 0000000000..47bdb4503c
--- /dev/null
+++ b/challenge-077/arne-sommer/raku/fibonacci-sum-first
@@ -0,0 +1,82 @@
+#! /usr/bin/env raku
+
+subset PositiveInt of Int where * >= 1;
+
+unit sub MAIN (PositiveInt $N, :v(:$verbose), :u(:$upto), :f(:$first));
+
+my $label;
+my $found;
+my $found2 = True;
+
+if $first
+{
+ my $current = 1;
+
+ while ( $found2 )
+ {
+ fibonal-decomposition($current);
+ say ": Checking $current" if $verbose;
+ $current++;
+ }
+}
+else
+{
+ $upto
+ ?? (1..$N).map({ fibonal-decomposition($_) })
+ !! fibonal-decomposition($N);
+}
+
+sub fibonal-decomposition($target)
+{
+ $found = False;
+ $label = 'a';
+
+ my @fibs;
+ my $fibonacci := (1, 1, * + * ... Inf);
+
+ for $fibonacci -> $fib { last if $fib > $target; @fibs.unshift: $fib; }
+ @fibs.pop;
+
+ if $verbose && ! $first
+ {
+ say ": Target: $target" if $upto;
+ say ": Fibonacci (reverse): { @fibs.join(", ") }";
+ }
+
+ recurse(0, (), @fibs, $target);
+
+ unless $first
+ {
+ say "0" unless $found;
+ say "" if $upto;
+ }
+}
+
+
+sub recurse ($value is copy, @values is copy, @fibonacci is copy, $input)
+{
+ if $value < $input
+ {
+ while @fibonacci
+ {
+ my $add = @fibonacci.shift;
+
+ if $value + $add <= $input
+ {
+ my $value2 = $value + $add;
+ my @values2 = @values.clone.push: $add;
+ recurse($value2, @values2, @fibonacci, $input);
+ }
+ }
+ }
+
+ elsif $value == $input
+ {
+ say "{ $label++ }) { @values.join(' + ') } = $input" unless $first;
+ $found = True;
+ }
+ elsif $first
+ {
+ $found2 = False;
+ }
+}
diff --git a/challenge-077/arne-sommer/raku/fibonacci-sum-first-verbose b/challenge-077/arne-sommer/raku/fibonacci-sum-first-verbose
new file mode 100755
index 0000000000..33e8296265
--- /dev/null
+++ b/challenge-077/arne-sommer/raku/fibonacci-sum-first-verbose
@@ -0,0 +1,84 @@
+#! /usr/bin/env raku
+
+subset PositiveInt of Int where * >= 1;
+
+unit sub MAIN (PositiveInt $N, :v(:$verbose), :u(:$upto), :f(:$first));
+
+my $label;
+my $found;
+my $found2 = True;
+my $recursion;
+
+if $first
+{
+ my $current = 1;
+
+ while ( $found2 )
+ {
+ $recursion = 0;
+ fibonal-decomposition($current);
+ say ": Checking $current [Recursive calls: $recursion]" if $verbose;
+ $current++;
+ }
+}
+else
+{
+ $upto
+ ?? (1..$N).map({ fibonal-decomposition($_) })
+ !! fibonal-decomposition($N);
+}
+
+sub fibonal-decomposition($target)
+{
+ $found = False;
+ $label = 'a';
+
+ my @fibs;
+ my $fibonacci := (1, 1, * + * ... Inf);
+
+ for $fibonacci -> $fib { last if $fib > $target; @fibs.unshift: $fib; }
+ @fibs.pop;
+
+ if $verbose && ! $first
+ {
+ say ": Target: $target" if $upto;
+ say ": Fibonacci (reverse): { @fibs.join(", ") }";
+ }
+
+ recurse(0, (), @fibs, $target);
+
+ unless $first
+ {
+ say "0" unless $found;
+ say "" if $upto;
+ }
+}
+
+sub recurse ($value is copy, @values is copy, @fibonacci is copy, $input)
+{
+ $recursion++;
+ if $value < $input
+ {
+ while @fibonacci
+ {
+ my $add = @fibonacci.shift;
+
+ if $value + $add <= $input
+ {
+ my $value2 = $value + $add;
+ my @values2 = @values.clone.push: $add;
+ recurse($value2, @values2, @fibonacci, $input);
+ }
+ }
+ }
+
+ elsif $value == $input
+ {
+ say "{ $label++ }) { @values.join(' + ') } = $input" unless $first;
+ $found = True;
+ }
+ elsif $first
+ {
+ $found2 = False;
+ }
+}
diff --git a/challenge-077/arne-sommer/raku/lonely-x b/challenge-077/arne-sommer/raku/lonely-x
new file mode 100755
index 0000000000..035cf2d973
--- /dev/null
+++ b/challenge-077/arne-sommer/raku/lonely-x
@@ -0,0 +1,43 @@
+#! /usr/bin/env raku
+
+unit sub MAIN ($matrix where $matrix.IO.f && $matrix.IO.r = 'matrix1.txt',
+ :v(:$verbose));
+
+my @matrix = $matrix.IO.lines.map( *.words.list );
+
+die "Uneven grid row length" unless [==] @(@matrix)>>.elems;
+
+die "Single characters only in the grid" if @(@matrix)>>.chars>>.max.max > 1;
+
+my $rows = @matrix.elems;
+my $cols = @matrix[0].elems;
+
+my $is_lonely = 0;
+
+for ^$rows -> $row
+{
+ for ^$cols -> $col
+ {
+ say ": [$row,$col] -> @matrix[$row][$col] { is_lonely(@matrix, $row, $col) ?? 'is lonely' !! '' }" if $verbose;
+ $is_lonely++ if is_lonely(@matrix, $row, $col);
+ }
+}
+
+say $is_lonely;
+
+sub is_lonely (@matrix, $row, $col)
+{
+ return False if @matrix[$row][$col] eq 'O';
+
+ for (-1, 0, 1) -> $r
+ {
+ for (-1, 0, 1) -> $c
+ {
+ next if $r == $c == 0;
+ next unless @matrix[$row + $r][$col + $c].defined;
+
+ return False if @matrix[$row + $r][$col + $c] eq 'X';
+ }
+ }
+ return True;
+}
diff --git a/challenge-077/arne-sommer/raku/matrix1.txt b/challenge-077/arne-sommer/raku/matrix1.txt
new file mode 100644
index 0000000000..f8beeb613f
--- /dev/null
+++ b/challenge-077/arne-sommer/raku/matrix1.txt
@@ -0,0 +1,3 @@
+O O X
+X O O
+X O O
diff --git a/challenge-077/arne-sommer/raku/matrix2.txt b/challenge-077/arne-sommer/raku/matrix2.txt
new file mode 100644
index 0000000000..d81104f1b2
--- /dev/null
+++ b/challenge-077/arne-sommer/raku/matrix2.txt
@@ -0,0 +1,4 @@
+O O X O
+X O O O
+X O O X
+O X O O
diff --git a/challenge-077/ash/cpp/ch-2a.cpp b/challenge-077/ash/cpp/ch-2a.cpp
new file mode 100644
index 0000000000..b0c250a7f6
--- /dev/null
+++ b/challenge-077/ash/cpp/ch-2a.cpp
@@ -0,0 +1,65 @@
+/*
+ Task 2 from
+ https://perlweeklychallenge.org/blog/perl-weekly-challenge-077/
+
+ Comments: https://andrewshitov.com/2020/09/08/lonely-x-the-weekly-challenge-77-task-2/
+
+ Compile as:
+ $ g++ -std=c++17 ch-2.cpp
+
+ Output for the given example of matrix:
+ $ ./a.out
+ 0, 3
+ 1, 1
+ 2, 3
+*/
+
+#include <iostream>
+#include <vector>
+
+using namespace std;
+
+int test_move_calls = 0;
+vector<int> test_move(vector<vector<char>> matrix, vector<int> current, vector<int> shift) {
+ test_move_calls++;
+
+ current[0] += shift[0];
+ current[1] += shift[1];
+
+ if (current[0] < 0 || current[0] >= matrix.size() ||
+ current[1] < 0 || current[1] >= matrix[0].size()) {
+ return vector<int>();
+ }
+ else {
+ return current;
+ }
+}
+
+int main() {
+ vector<vector<char>> matrix = {
+ {'X', 'O', 'O', 'X'},
+ {'O', 'O', 'X', 'O'},
+ {'X', 'O', 'O', 'X'}
+ };
+
+ vector<vector<int>> neighbours = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}};
+
+ for (auto row = 0; row != matrix.size(); row++) {
+ for (auto col = 0; col != matrix[0].size(); col++) {
+ if (matrix[row][col] == 'O') continue;
+
+ bool ok = true;
+ for (auto neighbour : neighbours) {
+ auto move = test_move(matrix, vector<int>{row, col}, neighbour);
+ if (move.empty()) continue;
+ if (matrix[move[0]][move[1]] == 'X') {
+ ok = false;
+ break;
+ }
+ }
+ if (ok) cout << row << ", " << col << endl;
+ }
+ }
+
+ cout << test_move_calls << " checks made" << endl;
+}
diff --git a/challenge-077/ash/cpp/ch-2b.cpp b/challenge-077/ash/cpp/ch-2b.cpp
new file mode 100644
index 0000000000..85e142c642
--- /dev/null
+++ b/challenge-077/ash/cpp/ch-2b.cpp
@@ -0,0 +1,82 @@
+/*
+ Task 2 from
+ https://perlweeklychallenge.org/blog/perl-weekly-challenge-077/
+
+ Comments: https://andrewshitov.com/2020/09/08/lonely-x-the-weekly-challenge-77-task-2/
+
+ Compile as:
+ $ g++ -std=c++17 ch-2.cpp
+
+ Output for the given example of matrix:
+ $ ./a.out
+ 0, 3
+ 1, 1
+ 2, 3
+
+
+ If there Xs that have other Xs as their neighbours, then
+ this program makes less cell checks than ch-2.cpp:
+
+ $ g++ -std=c++17 ch-2.cpp
+ bash-3.2$ ./a.out
+ 0, 0
+ 2, 0
+ 35 checks made
+
+ $ g++ -std=c++17 ch-2a.cpp
+ $ ./a.out
+ 0, 0
+ 2, 0
+ 30 checks made
+*/
+
+#include <iostream>
+#include <vector>
+
+using namespace std;
+
+int test_move_calls = 0;
+vector<int> test_move(vector<vector<char>> matrix, vector<int> current, vector<int> shift) {
+ test_move_calls++;
+
+ current[0] += shift[0];
+ current[1] += shift[1];
+
+ if (current[0] < 0 || current[0] >= matrix.size() ||
+ current[1] < 0 || current[1] >= matrix[0].size()) {
+ return vector<int>();
+ }
+ else {
+ return current;
+ }
+}
+
+int main() {
+ vector<vector<char>> matrix = {
+ {'X', 'O', 'O', 'X'},
+ {'O', 'O', 'X', 'O'},
+ {'X', 'O', 'O', 'X'}
+ };
+
+ vector<vector<int>> neighbours = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}};
+
+ for (auto row = 0; row != matrix.size(); row++) {
+ for (auto col = 0; col != matrix[0].size(); col++) {
+ if (matrix[row][col] != 'X') continue;
+
+ bool ok = true;
+ for (auto neighbour : neighbours) {
+ auto move = test_move(matrix, vector<int>{row, col}, neighbour);
+ if (move.empty()) continue;
+ if (matrix[move[0]][move[1]] != 'O') {
+ matrix[move[0]][move[1]] = 'Y';
+ ok = false;
+ break;
+ }
+ }
+ if (ok) cout << row << ", " << col << endl;
+ }
+ }
+
+ cout << test_move_calls << " checks made" << endl;
+}
diff --git a/challenge-077/ash/html/ch-2.html b/challenge-077/ash/html/ch-2.html
new file mode 100644
index 0000000000..3b1cd76bb6
--- /dev/null
+++ b/challenge-077/ash/html/ch-2.html
@@ -0,0 +1,106 @@
+<html>
+
+<!--
+ Task 2 from
+ https://perlweeklychallenge.org/blog/perl-weekly-challenge-077/
+
+ Comments: https://andrewshitov.com/2020/09/08/lonely-x-the-weekly-challenge-77-task-2/
+-->
+
+<head>
+ <meta charset="UTF-8"/>
+ <title>Lonely X</title>
+ <style>
+ * {
+ text-align: center;
+ font-family: Arial, sans-serif;
+ }
+ #Shape table {
+ margin: auto;
+ /* border-collapse: collapse; */
+ }
+ /* #Shape table tr td input {
+ width: 50px;
+ height: 50px;
+ } */
+ #Shape table tr td {
+ border: 5px solid white;
+ }
+ #Shape table tr td.lonely {
+ border: 5px solid green;
+ }
+ </style>
+</head>
+<body>
+ <p>
+ <input type="text" name="width" id="MatrixWidth" size="3" value="3" />
+ ×
+ <input type="text" name="height" id="MatrixHeight" size="3" value="3" />
+ &nbsp;
+ <input type="submit" value="Set the shape" onclick="set_shape()" />
+ </p>
+
+ <div id="Shape"></div>
+
+ <p>Note: Lonely X is marked green.</p>
+
+ <script>
+ let w = 0;
+ let h = 0;
+
+ function set_shape() {
+ w = parseInt(document.getElementById('MatrixWidth').value);
+ h = parseInt(document.getElementById('MatrixHeight').value);
+
+ let table = '<table>';
+ for (let y = 0; y != h; y++) {
+ table += '<tr>';
+ for (let x = 0; x != w; x++) {
+ table += '<td><input type="checkbox" data-x="' + x + '" data-y="' + y + '" onclick="update_lonely()" /></td>';
+ }
+ table += '</tr>';
+ }
+ table += '</table>';
+ document.getElementById('Shape').innerHTML = table;
+ }
+
+ function update_lonely() {
+ let cells = document.getElementById('Shape').getElementsByTagName('input');
+
+ let neigbours = [[0, 1], [0, -1], [1, 0], [-1, 0], [1, 1], [-1, -1], [1, -1], [-1, 1]];
+
+ for (let i = 0; i != cells.length; i++) {
+ cells[i].parentNode.className = '';
+
+ if (!cells[i].checked) continue;
+ let x = parseInt(cells[i].getAttribute('data-x'));
+ let y = parseInt(cells[i].getAttribute('data-y'));
+
+ let is_ok = true;
+ for (let c = 0; c != neigbours.length; c++) {
+ if (!test_cell(x + neigbours[c][0], y + neigbours[c][1])) {
+ is_ok = false;
+ break;
+ }
+ }
+
+ if (is_ok) {
+ cells[i].parentNode.className = 'lonely';
+ }
+ }
+ }
+
+ function test_cell(x, y) {
+ if (x < 0 || y < 0 || x >= w || y >= h) {
+ return true;
+ }
+ else {
+ let cell = document.querySelector('#Shape tr td input[data-x="'+ x + '"][data-y="' + y + '"]');
+ return !cell.checked;
+ }
+ }
+
+ set_shape();
+ </script>
+</body>