aboutsummaryrefslogtreecommitdiff
path: root/challenge-055/noud
diff options
context:
space:
mode:
authorNoud Aldenhoven <noud.aldenhoven@gmail.com>2020-04-12 15:01:04 +0200
committerNoud Aldenhoven <noud.aldenhoven@gmail.com>2020-04-12 15:01:04 +0200
commit4bb6c5f0a7d9246542c83a0de3226449fb9a0e36 (patch)
tree4aabb866fa11ad5d503dd89f6d5c7705bcd9b7fb /challenge-055/noud
parenta52907eb62a81a3f8c50aa55d479e2ffc897a5f7 (diff)
downloadperlweeklychallenge-club-4bb6c5f0a7d9246542c83a0de3226449fb9a0e36.tar.gz
perlweeklychallenge-club-4bb6c5f0a7d9246542c83a0de3226449fb9a0e36.tar.bz2
perlweeklychallenge-club-4bb6c5f0a7d9246542c83a0de3226449fb9a0e36.zip
Solutions for challenge 055 task 1 and 2 in Raku by Noud
Diffstat (limited to 'challenge-055/noud')
-rw-r--r--challenge-055/noud/raku/ch-1.p659
-rw-r--r--challenge-055/noud/raku/ch-2.p662
2 files changed, 121 insertions, 0 deletions
diff --git a/challenge-055/noud/raku/ch-1.p6 b/challenge-055/noud/raku/ch-1.p6
new file mode 100644
index 0000000000..c90db8e2e2
--- /dev/null
+++ b/challenge-055/noud/raku/ch-1.p6
@@ -0,0 +1,59 @@
+# Flip Binary
+#
+# You are given a binary number B, consisting of N binary digits 0 or 1: s0,
+# s1, …, s(N-1).
+#
+# Choose two indices L and R such that 0 ≤ L ≤ R < N and flip the digits s(L),
+# s(L+1), …, s(R). By flipping, we mean change 0 to 1 and vice-versa.
+#
+# For example, given the binary number 010, the possible flip pair results are
+# listed below:
+#
+# L=0, R=0 the result binary: 110
+# L=0, R=1 the result binary: 100
+# L=0, R=2 the result binary: 101
+# L=1, R=1 the result binary: 000
+# L=1, R=2 the result binary: 001
+# L=2, R=2 the result binary: 011
+#
+# Write a script to find the indices (L,R) that results in a binary number with
+# maximum number of 1s. If you find more than one maximal pair L,R then print
+# all of them.
+#
+# Continuing our example, note that we had three pairs (L=0, R=0), (L=0, R=2),
+# and (L=2, R=2) that resulted in a binary number with two 1s, which was the
+# maximum. So we would print all three pairs.
+
+
+sub binflip($n is copy, $size, $L, $R) {
+ for $L..$R -> $i {
+ $n = $n +^ 2**($size - $i - 1);
+ }
+ return $n;
+}
+
+sub count-ones($n) {
+ $n.base(2).Str.comb().grep({ $_ == '1'; }).elems;
+}
+
+sub task($bin, $N) {
+ my @results = [];
+ for 0..^$N X 0..^$N -> ($L, $R) {
+ if ($L <= $R) {
+ my $flip = binflip($bin, $N, $L, $R);
+ my $count1 = count-ones($flip);
+ @results.push(($count1, $L, $R, $flip));
+ }
+ }
+ @results = @results.sort.reverse;
+ my $max-ones = @results[0][0];
+ return [-> ($c1, $L, $R, $f) {
+ ($L, $R, $f) if $c1 == $max-ones } for @results];
+}
+
+
+my $bin = 0b010;
+my $N = 2; # Number of binary digits to extend to.
+for task($bin, $N) -> ($L, $R, $f) {
+ say "(L=$L, R=$R) binary: ", $f.base(2);
+}
diff --git a/challenge-055/noud/raku/ch-2.p6 b/challenge-055/noud/raku/ch-2.p6
new file mode 100644
index 0000000000..0ae0ed46c1
--- /dev/null
+++ b/challenge-055/noud/raku/ch-2.p6
@@ -0,0 +1,62 @@
+# Wave Array
+#
+# Any array N of non-unique, unsorted integers can be arranged into a wave-like
+# array such that n1 ≥ n2 ≤ n3 ≥ n4 ≤ n5 and so on.
+#
+# For example, given the array [1, 2, 3, 4], possible wave arrays include [2,
+# 1, 4, 3] or [4, 1, 3, 2], since 2 ≥ 1 ≤ 4 ≥ 3 and 4 ≥ 1 ≤ 3 ≥ 2. This is not
+# a complete list.
+#
+# Write a script to print all possible wave arrays for an integer array N of
+# arbitrary length.
+#
+# Notes:
+#
+# When considering N of any length, note that the first element is always
+# greater than or equal to the second, and then the ≤, ≥, ≤, … sequence
+# alternates until the end of the array.
+
+
+# The difficulty is that we have to find all wave arrays. If we only had to
+# give one wave function you could easily sort the array and flip some
+# neighbours.
+# I created a recurrent subroutine that takes two elements from the the array,
+# sorts them descending, and computes all wave arrays of the remaining elements
+# in the array. Combining the two elements with the wave (sub)arrays, when the
+# second element is smaller than the first element in the wave (sub)array,
+# gives all wave arrays. I'm curious to find out if there are better ways.
+
+sub wave-sort(@a) {
+ if (@a.elems == 0) {
+ return [[],];
+ } elsif (@a.elems == 1) {
+ return [[@a.head],];
+ }
+
+ my @ret = [];
+
+ @a = @a.sort.reverse;
+ for 0..^@a.elems -> $i {
+ for ($i+1)..^@a.elems -> $j {
+ my $cur1 = @a[$i];
+ my $cur2 = @a[$j];
+ my @rest = [|(@a[0..^$i]), |(@a[($i+1)..^$j]), |(@a[($j+1)..*-1])];
+ if (@rest.elems > 0) {
+ for wave-sort(@rest) -> @r {
+ if ($cur2 <= @r.head) {
+ @ret.push([$cur1, $cur2, |(@r)]);
+ }
+ }
+ } else {
+ @ret.push([$cur1, $cur2]);
+ }
+ }
+ }
+ return @ret;
+}
+
+say wave-sort([1]);
+say wave-sort([1, 2]);
+say wave-sort([1, 2, 3]);
+say wave-sort([1, 2, 3, 4]);
+say wave-sort([1, 2, 3, 4, 5]);