aboutsummaryrefslogtreecommitdiff
path: root/challenge-081
diff options
context:
space:
mode:
authorAndinus <andinus@nand.sh>2020-10-24 01:27:30 +0530
committerAndinus <andinus@nand.sh>2020-10-24 01:27:30 +0530
commit7790390e48a88a4ec5f313e46f80e4c1884b17c8 (patch)
treecc7e473cd8151c1a06651cea153cc15e1b6e8da0 /challenge-081
parent4943cf327b0b3e226447e25087770ed57c4fbfd7 (diff)
downloadperlweeklychallenge-club-7790390e48a88a4ec5f313e46f80e4c1884b17c8.tar.gz
perlweeklychallenge-club-7790390e48a88a4ec5f313e46f80e4c1884b17c8.tar.bz2
perlweeklychallenge-club-7790390e48a88a4ec5f313e46f80e4c1884b17c8.zip
Add all README.org files
These files generate README, it's better to commit them than keep in `.gitignore'.
Diffstat (limited to 'challenge-081')
-rw-r--r--challenge-081/andinus/README.org135
1 files changed, 135 insertions, 0 deletions
diff --git a/challenge-081/andinus/README.org b/challenge-081/andinus/README.org
new file mode 100644
index 0000000000..1d9a22f8db
--- /dev/null
+++ b/challenge-081/andinus/README.org
@@ -0,0 +1,135 @@
+#+SETUPFILE: ~/.emacs.d/org-templates/level-2.org
+#+HTML_LINK_UP: ../../writings/
+#+OPTIONS: toc:2
+#+EXPORT_FILE_NAME: index
+#+TITLE: Challenge 081
+
+* Task 1 - Common Base String
+You are given 2 strings, =$A= and =$B=.
+
+Write a script to find out common base strings in =$A= and =$B=.
+
+#+BEGIN_QUOTE
+A substring of a string $S is called base string if repeated
+concatenation of the substring results in the string.
+#+END_QUOTE
+** Perl
+- Program: [[file:perl/ch-1.pl]]
+
+We will break =$A= & check if any subset of =$A= join to make =$B=. To speed
+up the process we only break =$A= by common divisors of both =$A= & =$B=.
+
+I assume that the length of =$B= is greater than =$A= in later parts so we
+make sure that it's true.
+#+BEGIN_SRC perl
+my $A = shift @ARGV;
+my $B = shift @ARGV;
+
+# We assume length($B) is greater than length($A).
+unless (length($B) > length($A)) {
+ my $tmp = $A;
+ $A = $B;
+ $B = $tmp;
+}
+#+END_SRC
+
+If the strings have different sets of characters then common base string
+cannot exists so we exit early.
+#+BEGIN_SRC perl
+# Check if common base string is even possible.
+my (%chars_in_A, %chars_in_B);
+$chars_in_A{$_} = 1 foreach split //, $A;
+$chars_in_B{$_} = 1 foreach split //, $B;
+foreach my $char (sort keys %chars_in_A) {
+ last if exists $chars_in_B{$char} ;
+ print "No common base string.\n" and exit 0
+}
+#+END_SRC
+
+Get all the common divisors of =$A= & =$B=.
+#+BEGIN_SRC perl
+# Get all common divisors.
+my %divisors_of_A = divisors(length($A));
+my %divisors_of_B = divisors(length($B));
+my @common_divisors;
+foreach my $num (sort { $a <=> $b } keys %divisors_of_A) {
+ push @common_divisors, $num
+ if exists $divisors_of_B{$num};
+}
+
+# Returns all divisors of a number.
+sub divisors {
+ my $n = shift @_;
+ my %divisors;
+ foreach my $i ( 1 ... $n){
+ if ($n % $i == 0) {
+ $divisors{$i} = 1;
+ }
+ }
+ return %divisors;
+}
+#+END_SRC
+
+We check if any subset of =$A= joins to make =$B=.
+#+BEGIN_SRC perl
+my @common;
+
+foreach my $num (@common_divisors){
+ my $tmp;
+ my $base = substr($A, 0, $num);
+ foreach (1 ... length($B) / $num) {
+ $tmp .= $base;
+ }
+ push @common, $base if $tmp eq $B;
+}
+
+print "No common base string.\n" and exit 0
+ unless scalar @common;
+print join(', ', @common), "\n";
+#+END_SRC
+* Task 2 - Frequency Sort
+You are given file named input.
+
+Write a script to find the frequency of all the words.
+
+It should print the result as first column of each line should be the
+frequency of the the word followed by all the words of that frequency
+arranged in lexicographical order. Also sort the words in the ascending
+order of frequency.
+
+For the sake of this task, please ignore the following in the input
+file: =. " ( ) , 's --=
+** Perl
+- Program: [[file:perl/ch-2.pl]]
+
+Swap unwanted characters with a space.
+#+BEGIN_SRC perl
+my $file = path(shift @ARGV)->slurp;
+
+$file =~ s/(--|'s)/ /g;
+$file =~ s/[."(),]+/ /g;
+$file =~ s/ / /g;
+$file =~ s/\n/ /g;
+#+END_SRC
+
+Get frequency of each word.
+#+BEGIN_SRC perl
+my %words;
+foreach my $word (split / /, $file) {
+ $words{$word} = 1 and next unless exists $words{$word};
+ $words{$word}++;
+}
+#+END_SRC
+
+Format the output.
+#+BEGIN_SRC perl
+my %out;
+foreach my $word (sort keys %words) {
+ my $freq = $words{$word};
+ push @{$out{$freq}}, $word;
+}
+
+foreach my $freq (sort { $a <=> $b} keys %out) {
+ print "$freq ", join(' ', @{$out{$freq}}, "\n");
+}
+#+END_SRC