aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--challenge-287/0rir/raku/ch-1.raku123
-rw-r--r--challenge-287/0rir/raku/ch-2.raku119
2 files changed, 242 insertions, 0 deletions
diff --git a/challenge-287/0rir/raku/ch-1.raku b/challenge-287/0rir/raku/ch-1.raku
new file mode 100644
index 0000000000..7940093300
--- /dev/null
+++ b/challenge-287/0rir/raku/ch-1.raku
@@ -0,0 +1,123 @@
+#!/usr/bin/env raku
+# :vim ft=raku sw=4 expandtab # 🦋 ∅∪∩∋∈∉⊆ ≡ ≢ «␤ » ∴
+use v6.d;
+use Test;
+
+=begin comment
+287-1: Strong Password Submitted by: Mohammad Sajid Anwar
+
+You are given a string, $str.
+Write a program to return the minimum number of steps required to make the given string very strong password. If it is already strong then return 0.
+
+Criteria:
+
+- It must have at least 6 characters.
+- It must contains at least one lowercase letter, at least one upper case letter and at least one digit.
+- It shouldn't contain 3 repeating characters in a row.
+Following can be considered as one step:
+
+- Insert one character
+- Delete one character
+- Replace one character with another
+Example 1
+Input: $str = "a"
+Output: 5
+Example 2
+Input: $str = "aB2"
+Output: 3
+Example 3
+Input: $str = "PaaSW0rd"
+Output: 0
+Example 4
+Input: $str = "Paaasw0rd"
+Output: 1
+Example 5
+Input: $str = "aaaaa"
+Output: 2
+=end comment
+
+my @Test =
+ # in exp run=2 ll=1 lu=1 nd=1
+ "", 6, 0, 1, 1, 1,
+ "a", 5, 0, 0, 1, 1,
+ "aB2", 3, 0, 0, 0, 0,
+ "PaaSW0rd", 0, 0, 0, 0, 0,
+ "Paaasw0rd", 1, 1, 0, 0, 0,
+ "aaaaa", 2, 1, 0, 1, 1,
+ "&&&&&", 3, 1, 1, 1, 1,
+ "&&&&&&", 3, 2, 1, 1, 1,
+ "aaaaa&&&&&&", 3, 3, 0, 1, 1,
+ "aaaaa&&&&&&bbb", 4, 4, 0, 1, 1,
+ "aaaaa&&&&&&", 3, 3, 0, 1, 1,
+ "abcdefg", 2, 0, 0, 1, 1,
+ "abcdef", 2, 0, 0, 1, 1,
+ "abcdef", 2, 0, 0, 1, 1,
+ "abcdef", 2, 0, 0, 1, 1,
+ "abCd5f", 0, 0, 0, 0, 0,
+ "abCd5", 1, 0, 0, 0, 0,
+;
+plan @Test × 1 ÷ 6; # 5 ÷ 6;
+
+ # It must have at least 6 characters.
+constant \min-length = 6;
+ # It must contains at least one lowercase letter,
+constant \min-Ll = 1;
+ # at least one upper case letter
+constant \min-Lu = 1;
+ # and at least one digit.
+constant \min-Nd = 1;
+ # It shouldn't contain 3 repeating characters in a row.
+constant \break-seq = 3;
+
+sub ll-need( $str) { max 0, min-Ll - ( $str ~~ m:g/ <:Ll> / ) }
+sub lu-need( $str) { max 0, min-Lu - ( $str ~~ m:g/ <:Lu> / ) }
+sub nd-need( $str) { max 0, min-Nd - ( $str ~~ m:g/ <:Nd> / ) }
+
+multi adjacent-count( $a where *.chars == 0 ) { 0 }
+multi adjacent-count( $a where *.chars > 0 ) {
+ my @rep;
+ my @char = $a.comb;
+
+ my $i = 1;
+ my $count;
+ while $i < @char {
+ $count = 1;
+ while $i < @char and @char[$i] eq @char[$i -1] {
+ ++$i; ++$count;
+ }
+ if $count ≥ break-seq {
+ @rep.push: $count div break-seq ;
+ } else {
+ ++$i;
+ }
+ }
+ sum @rep;
+}
+
+# I am pressuming that the specified minimum required length suffices
+# to contain all the other requirements.
+
+# Adding chars for length or changing chars for over long sequences, both
+# can make char class requirements also.
+
+multi task( '' ) { min-length }
+multi task( Str() $_ ) {
+ my ($len-or-brk, $missing);
+ $len-or-brk = max 0, min-length - .chars; # addition
+ $len-or-brk += sum .&adjacent-count;
+ $missing = .&ll-need + .&lu-need + .&nd-need;
+ $len-or-brk > $missing ?? $len-or-brk !! $missing;
+}
+
+for @Test -> $in, $exp, $adjacents, $ll, $lu, $nd {
+# is adjacent-count($in), $adjacents,
+# " breaks $adjacents <- '$in'";
+# is ll-need( $in), $ll, "Ll needed " ~ $ll ~ " <- '$in'";
+# is lu-need( $in), $lu, "Lu needed " ~ $lu ~ " <- '$in'";
+# is nd-need( $in), $nd, "Nd needed " ~ $nd ~ " <- '$in'";
+ is task($in), $exp, "$exp <- '$in'";
+}
+done-testing;
+
+my $str = '@!-$%,<.';
+say "\nInput: $str\nOutput: ", task $str;
diff --git a/challenge-287/0rir/raku/ch-2.raku b/challenge-287/0rir/raku/ch-2.raku
new file mode 100644
index 0000000000..488cf9d9d7
--- /dev/null
+++ b/challenge-287/0rir/raku/ch-2.raku
@@ -0,0 +1,119 @@
+#!/usr/bin/env raku
+# :vim ft=raku sw=4 expandtab # 🦋 ∅∪∩∋∈∉⊆ ≡ ≢ «␤ » ∴
+use v6.d;
+use Test;
+
+=begin comment
+287-2: Valid Number Submitted by: Mohammad Sajid Anwar
+You are given a string, $str.
+Write a script to find if it is a valid number.
+
+Conditions for a valid number:
+- An integer number followed by an optional exponent.
+- A decimal number followed by an optional exponent.
+- An integer number is defined with an optional sign '-' or '+' followed by digits.
+Decimal Number:
+
+A decimal number is defined with an optional sign '-' or '+' followed by one of the following definitions:
+- Digits followed by a dot '.'.
+- Digits followed by a dot '.' followed by digits.
+- A dot '.' followed by digits.
+Exponent:
+
+An exponent is defined with an exponent notation 'e' or 'E' followed by an integer number.
+Example 1
+Input: $str = "1"
+Output: true
+Example 2
+Input: $str = "a"
+Output: false
+Example 3
+Input: $str = "."
+Output: false
+Example 4
+Input: $str = "1.2e4.2"
+Output: false
+Example 5
+Input: $str = "-1."
+Output: true
+Example 6
+Input: $str = "+1E-8"
+Output: true
+Example 7
+Input: $str = ".44"
+Output: true
+=end comment
+
+
+
+my @Test =
+ "0", True,
+ "1", True,
+ "11", True,
+ "-1", True,
+ "-11", True,
+ "+1", True,
+ "+11", True,
+ "+1E8", True,
+ "-1E-8", True,
+ "+123e-8", True,
+ "-12e8", True,
+ ".1", True,
+ "+.1", True,
+ "-.1", True,
+ "-0.1", True,
+ '0.00', True,
+ '+0.001', True,
+ '-0.001', True,
+ '0.001e2', True,
+ '-0.001E2', True,
+ '+0.001e2', True,
+ '+0.1', True,
+ "1.2e4", True,
+ ".44", True,
+ "0.44", True,
+ "1a", False,
+ "a", False,
+ "a1", False,
+ ".", False,
+ "1.2e4.2", False,
+ "01.2e4", False,
+ "1.2e", False,
+ "1..2", False,
+ "1.2e4e2", False,
+;
+plan @Test ÷ 2;
+
+=begin comment
+ Disallowing padding zeros.
+=end comment
+
+grammar Number {
+ token TOP { ^
+ | <zero>
+ | [ [ <decimal> | <integer> ] <exponent>? ]
+ $
+ }
+
+ token decimal { | [ <integer> '.' <fraction>? ]
+ | [ [ <sign>? <zero>? ] '.' <fraction> ]
+ }
+
+ token integer { [ <sign>? <[1..9]> \d* ] } # [ <sign>? \d+ ] zed pad
+ token zero { '0' } # delete for zed pad
+ token fraction { \d+ }
+ token exponent { [ e | E ] <integer> }
+ token sign { [ '+' | '-' ] }
+}
+
+sub task( $a) { ? Number.parse( $a); }
+
+for @Test -> $in, $exp {
+ is task($in), $exp, "$exp <- $in";
+}
+
+done-testing;
+my $str = "+1234.567e890";
+say "\nInput: \$str = \"$str\"\nOutput: ", task $str;
+
+