diff options
| author | Noud Aldenhoven <noud.aldenhoven@gmail.com> | 2020-04-12 15:01:04 +0200 |
|---|---|---|
| committer | Noud Aldenhoven <noud.aldenhoven@gmail.com> | 2020-04-12 15:01:04 +0200 |
| commit | 4bb6c5f0a7d9246542c83a0de3226449fb9a0e36 (patch) | |
| tree | 4aabb866fa11ad5d503dd89f6d5c7705bcd9b7fb /challenge-055/noud | |
| parent | a52907eb62a81a3f8c50aa55d479e2ffc897a5f7 (diff) | |
| download | perlweeklychallenge-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.p6 | 59 | ||||
| -rw-r--r-- | challenge-055/noud/raku/ch-2.p6 | 62 |
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]); |
