aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJörg Sommrey <28217714+jo-37@users.noreply.github.com>2021-02-01 14:38:01 +0100
committerJörg Sommrey <28217714+jo-37@users.noreply.github.com>2021-02-06 10:56:35 +0100
commit03b72227bc5710d91e03e35fd166c9b0e5e54975 (patch)
treee991f38730b0c8b0f93e410fcac86d22a7a1be8c
parent1f2c7e23ae48f105af23c803efbdb434b9c3b687 (diff)
downloadperlweeklychallenge-club-03b72227bc5710d91e03e35fd166c9b0e5e54975.tar.gz
perlweeklychallenge-club-03b72227bc5710d91e03e35fd166c9b0e5e54975.tar.bz2
perlweeklychallenge-club-03b72227bc5710d91e03e35fd166c9b0e5e54975.zip
Solution to task 1
-rwxr-xr-xchallenge-098/jo-37/perl/ch-1.pl104
-rw-r--r--challenge-098/jo-37/perl/ch-1_A.txt1
-rw-r--r--challenge-098/jo-37/perl/ch-1_B.txt1
-rw-r--r--challenge-098/jo-37/perl/ch-1_C.txt1
4 files changed, 107 insertions, 0 deletions
diff --git a/challenge-098/jo-37/perl/ch-1.pl b/challenge-098/jo-37/perl/ch-1.pl
new file mode 100755
index 0000000000..ac4435d70f
--- /dev/null
+++ b/challenge-098/jo-37/perl/ch-1.pl
@@ -0,0 +1,104 @@
+#!/usr/bin/perl -s
+
+use v5.16;
+use Test2::V0;
+use warnings FATAL => 'all';
+use experimental 'signatures';
+
+our ($tests, $examples);
+
+run_tests() if $tests || $examples; # does not return
+
+die <<EOS unless @ARGV > 1;
+usage: $0 [-examples] [-tests] [file1 c11... fileN cN1...]
+
+-examples
+ run examples from the challenge
+
+-tests
+ run some tests
+
+fileX (not numeric)
+ select file for following read operation(s)
+
+cij (numeric)
+ number of characters to read from selected file
+
+Operations on different files may be interleaved. The file position is
+kept separately for each filename.
+
+Example:
+
+ch-1_A.txt: 1234567890
+ch-1_B.txt: abcdefghij
+
+./ch-1.pl ch-1_A.txt 4 3 ch-1_B.txt 1 2 ch-1_A.txt 2 1 ch-1_B.txt 3 4
+
+Output:
+1234
+567
+a
+bc
+89
+0
+def
+ghij
+
+EOS
+
+
+### Input and Output
+
+binmode STDOUT, ':utf8';
+
+/^\d+$/ and say readN($a, $_) and next or $a = $_ for @ARGV;
+
+
+### Implementation
+
+# Read up to $n characters from named file at current position. Will
+# start over from the beginning after eof was detected for the named
+# file.
+sub readN ($file, $n) {
+
+ # Track filehandles for named files.
+ state %fh;
+
+ # Open filehandle for reading characters, not bytes.
+ open $fh{$file}, '<:encoding(utf8)', $file or die "$file: $!"
+ unless $fh{$file};
+
+ my $nchar = read $fh{$file}, (my $read), $n;
+ die "$file: $!" unless defined $nchar;
+
+ # Close filehandle if eof was detected.
+ delete $fh{$file} if $nchar < $n;
+
+ $read;
+}
+
+
+### Examples and tests
+
+sub run_tests {
+ SKIP: {
+ skip 'examples' unless $examples;
+ is readN('ch-1_A.txt', 4), '1234', 'example: first chunk';
+ is readN('ch-1_A.txt', 4), '5678', 'example: second chunk';
+ is readN('ch-1_A.txt', 4), '90', 'example: third chunk';
+ }
+
+ SKIP: {
+ skip 'tests' unless $tests;
+ is readN('ch-1_A.txt', 10), '1234567890', 'read all';
+ is readN('ch-1_A.txt', 1), '', 'at eof';
+ is readN('ch-1_A.txt', 1), '1', 'file reopened';
+ ok readN('ch-1_A.txt', 10), 'seek eof';
+ is readN('ch-1_A.txt', 11), '1234567890', 'read all, hit eof';
+ is readN('ch-1_A.txt', 1), '1', 'file reopened';
+ is readN('ch-1_C.txt', 3), 'Bär', 'multibyte character';
+ }
+
+ done_testing;
+ exit;
+}
diff --git a/challenge-098/jo-37/perl/ch-1_A.txt b/challenge-098/jo-37/perl/ch-1_A.txt
new file mode 100644
index 0000000000..6a537b5b36
--- /dev/null
+++ b/challenge-098/jo-37/perl/ch-1_A.txt
@@ -0,0 +1 @@
+1234567890 \ No newline at end of file
diff --git a/challenge-098/jo-37/perl/ch-1_B.txt b/challenge-098/jo-37/perl/ch-1_B.txt
new file mode 100644
index 0000000000..c76a96421b
--- /dev/null
+++ b/challenge-098/jo-37/perl/ch-1_B.txt
@@ -0,0 +1 @@
+abcdefghij \ No newline at end of file
diff --git a/challenge-098/jo-37/perl/ch-1_C.txt b/challenge-098/jo-37/perl/ch-1_C.txt
new file mode 100644
index 0000000000..bbfbdc9f01
--- /dev/null
+++ b/challenge-098/jo-37/perl/ch-1_C.txt
@@ -0,0 +1 @@
+Bär \ No newline at end of file