From ef14c20e2e2d61abe4cc73e5389733122df02d42 Mon Sep 17 00:00:00 2001 From: Paulo Custodio Date: Sun, 14 Feb 2021 16:32:59 +0000 Subject: Add Awk solution to challenge 004 Fix Awk syntax on previouws submissions - semicolon is needed at the end of statements --- challenge-001/paulo-custodio/awk/ch-1.awk | 26 +++++++-------- challenge-001/paulo-custodio/awk/ch-2.awk | 13 ++++---- challenge-001/paulo-custodio/test.pl | 23 +++++++++++--- challenge-002/paulo-custodio/awk/ch-1.awk | 8 ++--- challenge-002/paulo-custodio/awk/ch-2.awk | 42 ++++++++++++------------ challenge-003/paulo-custodio/awk/ch-1.awk | 50 ++++++++++++++--------------- challenge-003/paulo-custodio/awk/ch-2.awk | 51 +++++++++++++++--------------- challenge-004/paulo-custodio/awk/ch-1.awk | 21 ++++++++++++ challenge-004/paulo-custodio/awk/ch-2.awk | 33 +++++++++++++++++++ challenge-004/paulo-custodio/perl/ch-1.pl | 3 +- challenge-004/paulo-custodio/perl/ch-2.pl | 8 +++-- challenge-004/paulo-custodio/t/test-1.yaml | 9 ++++++ challenge-004/paulo-custodio/t/test-2.yaml | 19 +++++++++++ challenge-004/paulo-custodio/test.pl | 35 +------------------- challenge-098/paulo-custodio/awk/ch-1.awk | 23 +++++++------- challenge-098/paulo-custodio/awk/ch-2.awk | 47 ++++++++++++++------------- challenge-099/paulo-custodio/awk/ch-1.awk | 26 +++++++-------- challenge-099/paulo-custodio/awk/ch-2.awk | 14 ++++---- 18 files changed, 257 insertions(+), 194 deletions(-) create mode 100644 challenge-004/paulo-custodio/awk/ch-1.awk create mode 100644 challenge-004/paulo-custodio/awk/ch-2.awk create mode 100644 challenge-004/paulo-custodio/t/test-1.yaml create mode 100644 challenge-004/paulo-custodio/t/test-2.yaml diff --git a/challenge-001/paulo-custodio/awk/ch-1.awk b/challenge-001/paulo-custodio/awk/ch-1.awk index da8e38182a..001f74cd23 100644 --- a/challenge-001/paulo-custodio/awk/ch-1.awk +++ b/challenge-001/paulo-custodio/awk/ch-1.awk @@ -3,29 +3,29 @@ # Challenge 001 # # Challenge #1 -# Write a script to replace the character ‘e’ with ‘E’ in the string -# ‘Perl Weekly Challenge’. Also print the number of times the character ‘e’ +# Write a script to replace the character 'e' with 'E' in the string +# "Perl Weekly Challenge". Also print the number of times the character 'e' # is found in the string. function join(array, start, end, sep, result, i) { if (sep == "") - sep = " " + sep = " "; else if (sep == SUBSEP) # magic value - sep = "" - result = array[start] + sep = ""; + result = array[start]; for (i = start + 1; i <= end; i++) - result = result sep array[i] - return result + result = result sep array[i]; + return result; } function alen(a, i, k) { - k = 0 - for(i in a) k++ - return k + k = 0; + for(i in a) k++; + return k; } BEGIN { - text = join(ARGV, 1, alen(ARGV)) - print gsub(/e/, "E", text) " " text - exit 0 + text = join(ARGV, 1, alen(ARGV)); + print gsub(/e/, "E", text) " " text; + exit 0; } diff --git a/challenge-001/paulo-custodio/awk/ch-2.awk b/challenge-001/paulo-custodio/awk/ch-2.awk index f4c9a9fafb..2c04b2a074 100644 --- a/challenge-001/paulo-custodio/awk/ch-2.awk +++ b/challenge-001/paulo-custodio/awk/ch-2.awk @@ -5,13 +5,12 @@ # Challenge #2 # Write a one-liner to solve the FizzBuzz problem and print the numbers 1 # through 20. However, any number divisible by 3 should be replaced by the word -# ‘fizz’ and any divisible by 5 by the word ‘buzz’. Those numbers that are both -# divisible by 3 and 5 become ‘fizzbuzz’. +# 'fizz' and any divisible by 5 by the word 'buzz'. Those numbers that are both +# divisible by 3 and 5 become 'fizzbuzz'. BEGIN { - num = ARGV[1] ? ARGV[1] : 20 - for (i=1; i<=num; i++) { - print (i%15)==0 ? "fizzbuzz" : (i%3)==0 ? "fizz" : (i%5)==0 ? "buzz" : i - } - exit 0 + num = ARGV[1] ? ARGV[1] : 20; + for (i=1; i<=num; i++) + print (i%15)==0 ? "fizzbuzz" : (i%3)==0 ? "fizz" : (i%5)==0 ? "buzz" : i; + exit 0; } diff --git a/challenge-001/paulo-custodio/test.pl b/challenge-001/paulo-custodio/test.pl index 41c54fdb5e..f97677a0f0 100644 --- a/challenge-001/paulo-custodio/test.pl +++ b/challenge-001/paulo-custodio/test.pl @@ -35,14 +35,17 @@ else { $TESTS{$_}=1 for @ARGV; } +# to be used in eval{} in the tests +use vars qw( $prog $exec); + for my $lang (grep {-d} sort keys %LANG) { next unless $TESTS{$lang}; - for my $prog (path($lang)->children(qr/\.$LANG{$lang}$/)) { + for $prog (path($lang)->children(qr/\.$LANG{$lang}$/)) { $prog->basename =~ /^ch[-_](.*)\.$LANG{$lang}$/ or die $prog; my $task = $1; # compile if needed - my $exec = build($lang, $prog); + $exec = build($lang, $prog); for my $test (path("t")->children(qr/test-$task\.yaml$/)) { # execute each test from test-N.yaml @@ -55,15 +58,17 @@ for my $lang (grep {-d} sort keys %LANG) { $@ and die $@; # build test command line - my $cmd = "$exec ".($spec->{args} // ""); + my $cmd = "$exec ".value_or_eval($spec->{args}); chomp($cmd); + + # input if(defined($spec->{input})) { - path("in.txt")->spew($spec->{input}); + path("in.txt")->spew(value_or_eval($spec->{input})); $cmd .= " < in.txt"; } if (defined($spec->{output})) { $spec->{output} =~ s/^\|//mg; # delete initial bar - path("out_exp.txt")->spew($spec->{output}); + path("out_exp.txt")->spew(value_or_eval($spec->{output})); $cmd .= " > out.txt"; } @@ -139,3 +144,11 @@ sub run { my($cmd) = @_; ok 0==system($cmd), $cmd; } + +sub value_or_eval { + my($str) = @_; + $str //= ""; + my $value = ($str =~ /^eval\b/) ? eval($str) : $str; + $@ and die "eval '$str' failed: $@"; + return $value; +} diff --git a/challenge-002/paulo-custodio/awk/ch-1.awk b/challenge-002/paulo-custodio/awk/ch-1.awk index c5adaa5282..1db88fd0eb 100644 --- a/challenge-002/paulo-custodio/awk/ch-1.awk +++ b/challenge-002/paulo-custodio/awk/ch-1.awk @@ -6,10 +6,10 @@ # Write a script or one-liner to remove leading zeros from positive numbers. BEGIN { - num = ARGV[1] + num = ARGV[1]; if (match(num, /^0*([0-9]+)/, capture)) - print capture[1] + print capture[1]; else - print num - exit 0 + print num; + exit 0; } diff --git a/challenge-002/paulo-custodio/awk/ch-2.awk b/challenge-002/paulo-custodio/awk/ch-2.awk index 67b75f5c8d..752f93173b 100644 --- a/challenge-002/paulo-custodio/awk/ch-2.awk +++ b/challenge-002/paulo-custodio/awk/ch-2.awk @@ -9,55 +9,55 @@ function format_number(n, base, negative, output, d) { if (n < 0) { - negative = 1 + negative = 1; n = -n } else { - negative = 0 + negative = 0; } output = "" do { - d = n % base - n = int(n / base) - output = substr(digits, d+1, 1) output + d = n % base; + n = int(n / base); + output = substr(digits, d+1, 1) output; } while (n > 0) if (negative) - output = "-" output + output = "-" output; - return output + return output; } function scan_number(str, base, n, negative, ch, d) { n = 0; if (sub(/^-/, "", str)) - negative = 1 + negative = 1; else - negative = 0 + negative = 0; while (str != "") { - ch = toupper(substr(str, 1, 1)) - str = substr(str, 2) - d = index(digits, ch) - 1 + ch = toupper(substr(str, 1, 1)); + str = substr(str, 2); + d = index(digits, ch) - 1; if (d < 0 || d >= base) { - print "cannot parse '" str "'" - exit(1) + print "cannot parse '" str "'"; + exit(1); } - n = base * n + d + n = base * n + d; } if (negative) - n = -n - return n + n = -n; + return n; } BEGIN { - BASE = 35 - digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" + BASE = 35; + digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; if (ARGV[1] == "-r") - print scan_number(ARGV[2], 35) + print scan_number(ARGV[2], 35); else - print format_number(ARGV[1], 35) + print format_number(ARGV[1], 35); exit 0 } diff --git a/challenge-003/paulo-custodio/awk/ch-1.awk b/challenge-003/paulo-custodio/awk/ch-1.awk index 12c7cea74a..024d960e91 100644 --- a/challenge-003/paulo-custodio/awk/ch-1.awk +++ b/challenge-003/paulo-custodio/awk/ch-1.awk @@ -12,54 +12,54 @@ function min(a, b) { } function min3(a, b, c) { - return min(a, min(b, c)) + return min(a, min(b, c)); } function alen(a, i, k) { - k = 0 - for(i in a) k++ - return k + k = 0; + for(i in a) k++; + return k; } function push(a, v, n) { - n = alen(a) - while (n in a) n++ - a[n] = v + n = alen(a); + while (n in a) n++; + a[n] = v; } function shift(a, i, v) { - v = a[0] + v = a[0]; for (i=1; i 0) { + gsub(/\\/, "", temp); + pi = pi temp; + } + pi = substr(pi, 1, size+1) + print pi; +} diff --git a/challenge-004/paulo-custodio/awk/ch-2.awk b/challenge-004/paulo-custodio/awk/ch-2.awk new file mode 100644 index 0000000000..18eb2cb3ae --- /dev/null +++ b/challenge-004/paulo-custodio/awk/ch-2.awk @@ -0,0 +1,33 @@ +#!/usr/bin/gawk + +# Challenge 004 +# +# Challenge #2 +# You are given a file containing a list of words (case insensitive 1 word per +# line) and a list of letters. Print each word from the file that can be made +# using only letters from the list. You can use each letter only once (though +# there can be duplicates and you can use each of them once), you don't have to +# use all the letters. +# (Disclaimer: The challenge was proposed by Scimon Proctor) + +function matches(word, letters, i, j, ch) { + for (i = 1; i <= length(letters); i++) { + ch = substr(letters, i, 1); + j = index(word, ch); + if (j > 0) + word = substr(word, 1, j-1) substr(word, j+1) + if (word == "") return 1; + } + return 0; +} + +BEGIN { + letters = tolower(ARGV[1]); + while ((getline word < "words.txt") > 0 ) { + if (length(word) >= 2 && + !(word ~ /[^a-zA-Z]/) && + matches(word, letters)) + print word; + } + exit 0; +} diff --git a/challenge-004/paulo-custodio/perl/ch-1.pl b/challenge-004/paulo-custodio/perl/ch-1.pl index 776f2286e9..356e712c44 100644 --- a/challenge-004/paulo-custodio/perl/ch-1.pl +++ b/challenge-004/paulo-custodio/perl/ch-1.pl @@ -3,7 +3,8 @@ # Challenge 004 # # Challenge #1 -# Write a script to output the same number of PI digits as the size of your script. Say, if your script size is 10, it should print 3.141592653. +# Write a script to output the same number of PI digits as the size of your script. +# Say, if your script size is 10, it should print 3.141592653. # # we need a big-math library to compute any large number of digits diff --git a/challenge-004/paulo-custodio/perl/ch-2.pl b/challenge-004/paulo-custodio/perl/ch-2.pl index 88e7e259b8..faaa875806 100644 --- a/challenge-004/paulo-custodio/perl/ch-2.pl +++ b/challenge-004/paulo-custodio/perl/ch-2.pl @@ -3,7 +3,12 @@ # Challenge 004 # # Challenge #2 -# You are given a file containing a list of words (case insensitive 1 word per line) and a list of letters. Print each word from the file that can be made using only letters from the list. You can use each letter only once (though there can be duplicates and you can use each of them once), you don’t have to use all the letters. (Disclaimer: The challenge was proposed by Scimon Proctor) +# You are given a file containing a list of words (case insensitive 1 word per +# line) and a list of letters. Print each word from the file that can be made +# using only letters from the list. You can use each letter only once (though +# there can be duplicates and you can use each of them once), you don't have to +# use all the letters. +# (Disclaimer: The challenge was proposed by Scimon Proctor) use strict; use warnings; @@ -22,7 +27,6 @@ while (<$fh>) { say $_ if matches($_, $letters); } - sub matches { my($word, $letters) = @_; for my $c (split //, $letters) { diff --git a/challenge-004/paulo-custodio/t/test-1.yaml b/challenge-004/paulo-custodio/t/test-1.yaml new file mode 100644 index 0000000000..f84bc1f9e2 --- /dev/null +++ b/challenge-004/paulo-custodio/t/test-1.yaml @@ -0,0 +1,9 @@ +- setup: + cleanup: + args: eval{-s $prog} + input: + output: | + |eval{ + | use Math::BigFloat; + | Math::BigFloat->bpi(-s $prog)."\n"; + |} diff --git a/challenge-004/paulo-custodio/t/test-2.yaml b/challenge-004/paulo-custodio/t/test-2.yaml new file mode 100644 index 0000000000..c9bcca786f --- /dev/null +++ b/challenge-004/paulo-custodio/t/test-2.yaml @@ -0,0 +1,19 @@ +- setup: 0==system("aspell -d en dump master | aspell -l en expand > words.txt"); + cleanup: unlink "words.txt" + args: world + input: + output: | + |or + |ow + |owl + |old + |lo + |low + |lord + |row + |rd + |rod + |do + |wold + |world + |word diff --git a/challenge-004/paulo-custodio/test.pl b/challenge-004/paulo-custodio/test.pl index 243a023078..a61c28ebb7 100644 --- a/challenge-004/paulo-custodio/test.pl +++ b/challenge-004/paulo-custodio/test.pl @@ -5,37 +5,4 @@ use warnings; use Test::More; use 5.030; -is capture("perl perl/ch-1.pl 20"), < words.txt"); - -is capture("perl perl/ch-2.pl world"), < Read N-characters # Submitted by: Mohammad S Anwar # You are given file $FILE. # @@ -18,21 +18,20 @@ # read next N chars from file function readN(filename, read_len) { - skip_len = 0 - if (read_files[filename]) { - skip_len = read_files[filename] - } - read_files[filename] = skip_len + read_len + skip_len = 0; + if (read_files[filename]) + skip_len = read_files[filename]; + read_files[filename] = skip_len + read_len; - dd = "dd if=" filename " status=none bs=1 skip=" skip_len " count=" read_len - dd | getline text - return text + dd = "dd if=" filename " status=none bs=1 skip=" skip_len " count=" read_len; + dd | getline text; + return text; } BEGIN { for (i = 1; i < ARGC - 1; i += 2) { - text = readN(ARGV[i], ARGV[i+1]) - print text + text = readN(ARGV[i], ARGV[i+1]); + print text; } - exit 0 + exit 0; } diff --git a/challenge-098/paulo-custodio/awk/ch-2.awk b/challenge-098/paulo-custodio/awk/ch-2.awk index cbb40fd7dc..65b0234116 100644 --- a/challenge-098/paulo-custodio/awk/ch-2.awk +++ b/challenge-098/paulo-custodio/awk/ch-2.awk @@ -2,7 +2,7 @@ # Challenge 098 # -# TASK #2 › Search Insert Position +# TASK #2 > Search Insert Position # Submitted by: Mohammad S Anwar # You are given a sorted array of distinct integers @N and a target $N. # @@ -27,22 +27,21 @@ # print contents of array (nums, nums_size) function print_array() { - sep = "" + sep = ""; printf "(" for (i=0; ip; i--) { - nums[i] = nums[i-1] - } - nums[p] = n + nums_size++; + for (i=nums_size-1; i>p; i--) + nums[i] = nums[i-1]; + nums[p] = n; } # use bisect method to search for position @@ -52,7 +51,7 @@ function search_insert(n) { return 0; } else if (n < nums[0]) { # before first - insert(0, n) + insert(0, n); return 0; } else if (n > nums[nums_size-1]) {# after last @@ -60,33 +59,33 @@ function search_insert(n) { return nums_size-1; } else { # bisect - bot = 0; top = nums_size - mid = int((top + bot) / 2) + bot = 0; top = nums_size; + mid = int((top + bot) / 2); while (bot+1 < top) { if (n == nums[mid]) return mid; else if (n < nums[mid]) - top = mid + top = mid; else - bot = mid + bot = mid; mid = int((top + bot) / 2) } # not found, insert at mid+1 - insert(mid+1, n) - return mid+1 + insert(mid+1, n); + return mid+1; } } BEGIN { - n = ARGV[1] - nums_size = 0 # nums[] size + n = ARGV[1]; + nums_size = 0; # nums[] size for (i = 2; i < ARGC; i++) { - nums[nums_size++] = ARGV[i] + nums[nums_size++] = ARGV[i]; } - p = search_insert(n) - print p - print_array() - exit 0 + p = search_insert(n); + print p; + print_array(); + exit 0; } diff --git a/challenge-099/paulo-custodio/awk/ch-1.awk b/challenge-099/paulo-custodio/awk/ch-1.awk index e69e053735..e090e3fe64 100644 --- a/challenge-099/paulo-custodio/awk/ch-1.awk +++ b/challenge-099/paulo-custodio/awk/ch-1.awk @@ -1,6 +1,6 @@ #!/usr/bin/gawk -# TASK #1 › Pattern Match +# TASK #1 > Pattern Match # Submitted by: Mohammad S Anwar # You are given a string $S and a pattern $P. # @@ -27,32 +27,32 @@ function match_pattern(s, p) { while (1) { if (s=="" && p=="") # string and pattern finished - return 1 + return 1; else if (s=="" || p=="") # either string or pattern finished - return 0 + return 0; else if (p ~ /^\?/) { # match any character - s = substr(s, 2) - p = substr(p, 2) + s = substr(s, 2); + p = substr(p, 2); } else if (p ~ /^\*/) { # match any sub-sequence - p = substr(p, 2) + p = substr(p, 2); for (i = 1; i <= length(s); i++) { if (match_pattern(substr(s, i), p)) - return 1 + return 1; } - return 0 + return 0; } else if (substr(p,1,1) != substr(s,1,1)) { # chars different - return 0 + return 0; } else { # search next char - s = substr(s, 2) - p = substr(p, 2) + s = substr(s, 2); + p = substr(p, 2); } } } BEGIN { - print match_pattern(ARGV[1], ARGV[2]) - exit 0 + print match_pattern(ARGV[1], ARGV[2]); + exit 0; } diff --git a/challenge-099/paulo-custodio/awk/ch-2.awk b/challenge-099/paulo-custodio/awk/ch-2.awk index 5c7a28d2fb..8fd50fa366 100644 --- a/challenge-099/paulo-custodio/awk/ch-2.awk +++ b/challenge-099/paulo-custodio/awk/ch-2.awk @@ -1,6 +1,6 @@ #!/usr/bin/gawk -# TASK #2 › Unique Subsequence +# TASK #2 > Unique Subsequence # Submitted by: Mohammad S Anwar # You are given two strings $S and $T. # @@ -27,24 +27,24 @@ function count_subsequences(s, t) { while (1) { if (t=="") { # t is empty, matched - return 1 + return 1; } else if (s=="") { # s is empty, did not match - return 0 + return 0; } else if (substr(s,1,1) == substr(t,1,1)) { # same char, # check two paths matching # and not matching return count_subsequences(substr(s,2), substr(t,2)) \ - + count_subsequences(substr(s,2), t) + + count_subsequences(substr(s,2), t); } else { # different char, keep pattern - s = substr(s,2) + s = substr(s,2); } } } BEGIN { - print count_subsequences(ARGV[1], ARGV[2]) - exit 0 + print count_subsequences(ARGV[1], ARGV[2]); + exit 0; } -- cgit