aboutsummaryrefslogtreecommitdiff
path: root/challenge-098
diff options
context:
space:
mode:
Diffstat (limited to 'challenge-098')
-rw-r--r--challenge-098/colin-crain/perl/ch-1.pl66
-rw-r--r--challenge-098/colin-crain/perl/ch-2.pl137
-rw-r--r--challenge-098/colin-crain/raku/ch-1.raku41
-rw-r--r--challenge-098/colin-crain/raku/ch-2.raku69
4 files changed, 313 insertions, 0 deletions
diff --git a/challenge-098/colin-crain/perl/ch-1.pl b/challenge-098/colin-crain/perl/ch-1.pl
new file mode 100644
index 0000000000..39059a63c7
--- /dev/null
+++ b/challenge-098/colin-crain/perl/ch-1.pl
@@ -0,0 +1,66 @@
+#!/Users/colincrain/perl5/perlbrew/perls/perl-5.32.0/bin/perl
+#
+# readin-ritin-and-random-characters.pl
+#
+# TASK #1 › Read N-characters
+# Submitted by: Mohammad S Anwar
+# You are given file $FILE.
+#
+# Create subroutine readN($FILE, $number) returns the first n-characters
+# and moves the pointer to the (n+1)th character.
+#
+# Example:
+# Input: Suppose the file (input.txt) contains "1234567890"
+# Output:
+# print readN("input.txt", 4); # returns "1234"
+# print readN("input.txt", 4); # returns "5678"
+# print readN("input.txt", 4); # returns "90"
+#
+# © 2021 colin crain
+## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
+
+
+
+use warnings;
+use strict;
+use feature ":5.26";
+
+use open qw( :encoding(utf-8) :std );
+
+my $len = 20;
+my $file = './unicode-text-test.txt';
+
+open( my $fh, '<', $file ) or die "no such file $file : $!";
+
+say readN($fh, 20);
+say readN($fh, 20);
+say readN($fh, 20);
+
+sub readN {
+ no warnings qw( uninitialized );
+ my ($fh, $length, $offset) = @_;
+ my $buffer;
+ read( $fh, $buffer, $length, $offset );
+ return $buffer;
+}
+
+==pod
+
+the input file looks like this:
+
+A☀3♠5¿7A901☀3♠5¿7A101☀3♠5¿7A☀01☀3♠5¿7A301☀3♠5¿7A♠01☀3♠5¿7A50
+B☀3♠5¿7B901☀3♠5¿7B101☀3♠5¿7B☀01☀3♠5¿7B301☀3♠5¿7B♠01☀3♠5¿7B50
+C☀3♠5¿7C901☀3♠5¿7C101☀3♠5¿7C☀01☀3♠5¿7C301☀3♠5¿7C♠01☀3♠5¿7C50
+D☀3♠5¿7D901☀3♠5¿7D101☀3♠5¿7D☀01☀3♠5¿7D301☀3♠5¿7D♠01☀3♠5¿7D50
+E☀3♠5¿7E901☀3♠5¿7E101☀3♠5¿7E☀01☀3♠5¿7E301☀3♠5¿7E♠01☀3♠5¿7E50
+
+the output from the above:
+
+A☀3♠5¿7A901☀3♠5¿7A10
+1☀3♠5¿7A☀01☀3♠5¿7A30
+
+as you can see, 20 characters are delivered, even if they are composed of
+multi-byte unicode codepoints.
+
+==cut
+
diff --git a/challenge-098/colin-crain/perl/ch-2.pl b/challenge-098/colin-crain/perl/ch-2.pl
new file mode 100644
index 0000000000..8e173c10ed
--- /dev/null
+++ b/challenge-098/colin-crain/perl/ch-2.pl
@@ -0,0 +1,137 @@
+#!/Users/colincrain/perl5/perlbrew/perls/perl-5.32.0/bin/perl
+#
+# know-your-place.pl
+#
+# TASK #2 › Search Insert Position
+# Submitted by: Mohammad S Anwar
+# You are given a sorted array of distinct integers @N and a target $N.
+#
+# Write a script to return the index of the given target if found
+# otherwise place the target in the sorted array and return the index.
+#
+# Example 1:
+# Input: @N = (1, 2, 3, 4) and $N = 3
+# Output: 2 since the target 3 is in the array at the index 2.
+#
+# Example 2:
+# Input: @N = (1, 3, 5, 7) and $N = 6
+# Output: 3 since the target 6 is missing and should be placed at the index 3.
+#
+# Example 3:
+# Input: @N = (12, 14, 16, 18) and $N = 10
+# Output: 0 since the target 10 is missing and should be placed at the index 0.
+#
+# Example 4:
+# Input: @N = (11, 13, 15, 17) and $N = 19
+# Output: 4 since the target 19 is missing and should be placed at the index 4.
+#
+#
+# method:
+# We could take a naive approach — a brute force assault of the
+# citadel, boldly running the gauntlet through the front door up to
+# the insert point, but we can do better. We can be sneaky and
+# improve our idea of where we're going with every step we take. If
+# we by start in the middle and successively subdivide the remaining
+# range, we can home in on the correct placement.
+
+# This method is a version of a binary search: we start off knowing
+# that the correct location, whatever that may be, lies within the
+# bounds of the array after the new element has been added. I mean,
+# it might be tautologically obvious that after the element has been
+# added, it will be held at some position within the array, but you
+# have to start somewhere. We know, thus, before we start that the
+# lower bound for the correct placement is 0, and the upper bound is
+# the length of starting array plus one, for the new element. The
+# known range is quite broad at this point, but through a series of
+# actions we can refine it until there is only one position left,
+# which is the correct place to insert the new element.
+#
+# We start by looking to add the element at the half-way point. At
+# every trial, first we see whether the index we're examining is the
+# value we're inserting. If it is, we've found the placement and
+# we're done.
+#
+# In the more-likely chance it's not equal, the value will either
+# greater than or less than that at the position. Again, stands to
+# reason. And with that calculation we've learned some new
+# information: for example, if the value is greater, than the
+# correct location cannot be less than that index. We can now adjust
+# our boundaries; the lower limit can be moved upwards to our mark.
+# We can also reset it to be one greater than the checked postion,
+# as we know it doesn't lie there either. Likewise, if the value is
+# less, we move the pointer for the upper bound to be the index one
+# less than the one tried.
+#
+# We've now constricted the known range for the correct insert index
+# by one-half. Not bad. We can continue to do this repeatedly, at
+# each pass redefining the available range for the result, until
+# either we land on an existing element with the value or the the
+# value at the index one below is less and the value at the index is
+# greater. If this is the case then we have located to correctly
+# sorted location for the new element.
+#
+# Because the directives say to insert the element into the list,
+# we'll take the list in as an array reference, then apply the
+# splice to the referenced list once we've found the insert point.
+# If the element is already there we'll of course leave things be.
+# In any case the list is altered in-place and the position of the
+# new element is returned
+#
+#
+# © 2021 colin crain
+## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
+
+
+
+use warnings;
+use strict;
+use feature ":5.32";
+
+sub insert {
+ my ($num, $arr) = @_;
+ $num > $arr->[-1] and do { push $arr->@*, $num; return $#$arr };
+ $num < $arr->[0] and do { unshift $arr->@*, $num; return 0 };
+
+ my $lower = 0;
+ my $upper = $#$arr;
+ while ( $lower <= $upper ) {
+ my $pos = int( ($lower+$upper)/2 ); ## midpoint
+
+ return $pos if $arr->[$pos] == $num;
+ if ($arr->[$pos-1] < $num < $arr->[$pos]) {
+ splice( $arr->@*, $pos, 0, $num );
+ return $pos;
+ }
+
+ $arr->[$pos] > $num ? ($upper = $pos-1) ## restrict the range
+ : ($lower = $pos+1);
+ }
+
+}
+
+
+
+use Test::More;
+
+is insert( 3, [1, 2, 3, 4] ), 2, 'ex-1, exists already';
+is insert( 6, [1, 3, 5, 7] ), 3, 'ex-2, insert into middle';
+is insert( 10, [12, 14, 16, 18] ), 0, 'ex-3, less than first';
+is insert( 19, [11, 13, 15, 17] ), 4, 'ex-4, more than last';
+
+for my $n (1..13) {
+ $n = 500 - 37*$n;
+ is insert( $n, [1..500] ), $n-1, "long list: target -> $n";
+}
+
+is insert( 1, [2, 4, 6, 8] ), 0, 'insert into idx 0';
+is insert( 3, [2, 4, 6, 8] ), 1, 'insert into idx 1';
+is insert( 5, [2, 4, 6, 8] ), 2, 'insert into idx 2';
+is insert( 7, [2, 4, 6, 8] ), 3, 'insert into idx 3';
+is insert( 9, [2, 4, 6, 8] ), 4, 'insert into idx 4';
+
+is insert( 2, [2, 4, 6, 8] ), 0, 'match idx 0';
+is insert( 4, [2, 4, 6, 8] ), 1, 'match idx 1';
+is insert( 6, [2, 4, 6, 8] ), 2, 'match idx 2';
+is insert( 8, [2, 4, 6, 8] ), 3, 'match idx 3';
+
+done_testing();
diff --git a/challenge-098/colin-crain/raku/ch-1.raku b/challenge-098/colin-crain/raku/ch-1.raku
new file mode 100644
index 0000000000..3c169a1436
--- /dev/null
+++ b/challenge-098/colin-crain/raku/ch-1.raku
@@ -0,0 +1,41 @@
+#!/usr/bin/env perl6
+#
+#
+# readin-ritin-and-random-characters.raku
+#
+# TASK #1 › Read N-characters
+# Submitted by: Mohammad S Anwar
+# You are given file $FILE.
+#
+# Create subroutine readN($FILE, $number) returns the first n-characters
+# and moves the pointer to the (n+1)th character.
+#
+# Example:
+# Input: Suppose the file (input.txt) contains "1234567890"
+# Output:
+# print readN("input.txt", 4); # returns "1234"
+# print readN("input.txt", 4); # returns "5678"
+# print readN("input.txt", 4); # returns "90"
+#
+#
+# © 2021 colin crain
+## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
+
+
+
+unit sub MAIN (Str $file = 'unicode-text-test.txt', Int $length = 20 ) ;
+
+my $fh = open $file, :r;
+
+## read first 20 chars
+say readN($fh, $length);
+
+## read next 40 chars starting at postion 21
+say readN($fh, $length*2);
+
+$fh.close;
+
+sub readN( $fh, $length ) {
+ my $out ~= $fh.getc for ^$length;
+ return $out;
+}
diff --git a/challenge-098/colin-crain/raku/ch-2.raku b/challenge-098/colin-crain/raku/ch-2.raku
new file mode 100644
index 0000000000..1bc2e0e140
--- /dev/null
+++ b/challenge-098/colin-crain/raku/ch-2.raku
@@ -0,0 +1,69 @@
+#!/usr/bin/env perl6
+#
+#
+# know-your-place.raku
+#
+# TASK #2 › Search Insert Position
+# Submitted by: Mohammad S Anwar
+# You are given a sorted array of distinct integers @N and a target $N.
+#
+# Write a script to return the index of the given target if found
+# otherwise place the target in the sorted array and return the index.
+#
+# Example 1:
+# Input: @N = (1, 2, 3, 4) and $N = 3
+# Output: 2 since the target 3 is in the array at the index 2.
+#
+# Example 2:
+# Input: @N = (1, 3, 5, 7) and $N = 6
+# Output: 3 since the target 6 is missing and should be placed at the index 3.
+#
+# Example 3:
+# Input: @N = (12, 14, 16, 18) and $N = 10
+# Output: 0 since the target 10 is missing and should be placed at the index 0.
+#
+# Example 4:
+# Input: @N = (11, 13, 15, 17) and $N = 19
+# Output: 4 since the target 19 is missing and should be placed at the index 4.
+#
+#
+# © 2021 colin crain
+## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
+
+
+
+unit sub MAIN () ;
+
+
+use Test;
+plan 17;
+
+is insert( 3, (1, 2, 3, 4) ), 2, 'ex-1';
+is insert( 6, (1, 3, 5, 7) ), 3, 'ex-2';
+is insert( 10, (12, 14, 16, 18) ), 0, 'ex-3';
+is insert( 19, (11, 13, 15, 17) ), 4, 'ex-4';
+for 1..13 -> $n is copy {
+ $n = 500 - 37*$n;
+ is insert( $n, (1..500) ), $n-1, "long list: target -> $n";
+}
+
+
+
+
+sub insert ($num, @arr) {
+ $num > @arr[*-1] and return @arr.elems;
+ $num < @arr[0] and return 0;
+
+ my $lower = 0;
+ my $upper = @arr.end;
+
+ while ( $lower <= $upper ) {
+ my $pos = (($lower+$upper)/2).floor;
+ return $pos if @arr[$pos] == $num or @arr[$pos-1] < $num < @arr[$pos];
+
+ @arr[$pos] > $num ?? ($upper = $pos-1)
+ !! ($lower = $pos+1);
+ }
+
+}
+