From 79ea68a3e085f2c7ce681ac2229f262e07430376 Mon Sep 17 00:00:00 2001 From: Myoungjin JEON Date: Wed, 7 Oct 2020 23:38:04 +1100 Subject: [ch-081/jeongoon] Perl, Raku, Go solution added --- challenge-081/jeongoon/go/ch-1.go | 62 ++++++++++++++++++++ challenge-081/jeongoon/go/ch-2.go | 103 ++++++++++++++++++++++++++++++++++ challenge-081/jeongoon/go/input | 1 + challenge-081/jeongoon/perl/ch-1.pl | 45 +++++++++++++++ challenge-081/jeongoon/perl/ch-2.pl | 41 ++++++++++++++ challenge-081/jeongoon/perl/input | 3 + challenge-081/jeongoon/raku/ch-1.raku | 39 +++++++++++++ challenge-081/jeongoon/raku/ch-2.raku | 52 +++++++++++++++++ challenge-081/jeongoon/raku/input | 1 + 9 files changed, 347 insertions(+) create mode 100644 challenge-081/jeongoon/go/ch-1.go create mode 100644 challenge-081/jeongoon/go/ch-2.go create mode 120000 challenge-081/jeongoon/go/input create mode 100644 challenge-081/jeongoon/perl/ch-1.pl create mode 100644 challenge-081/jeongoon/perl/ch-2.pl create mode 100644 challenge-081/jeongoon/perl/input create mode 100644 challenge-081/jeongoon/raku/ch-1.raku create mode 100644 challenge-081/jeongoon/raku/ch-2.raku create mode 120000 challenge-081/jeongoon/raku/input diff --git a/challenge-081/jeongoon/go/ch-1.go b/challenge-081/jeongoon/go/ch-1.go new file mode 100644 index 0000000000..f1b43ef184 --- /dev/null +++ b/challenge-081/jeongoon/go/ch-1.go @@ -0,0 +1,62 @@ +/* +Ref: +https://golangbyexample.com/length-of-string-golang/ +https://golangdocs.com/concatenate-strings-in-golang +*/ + +// test with: go run ch-1.go abcabc abcabcabcabc + + +package main + +import ( + "os" + "fmt" + "strings" +) + +func commonDivisors ( a int, b int ) []int { + var result []int + var min int + if a < b { + min = a + } else { + min = b } + + for i := 1; i <= min; i++ { + if ( a % i == 0 && b % i ==0 ) { + result = append( result, i ); + } + } + return result +} + +// trying to make a method but it wasn't good idea :-/ +type StrTest string +//https://stackoverflow.com/questions/28800672/how-to-add-new-methods-to-an-existing-type-in-go +func (substr StrTest) RepeatedIn(str string) bool { + return ( + len(str) % len(substr) == 0 && + str == strings.Repeat( string(substr), + len(str) / len(substr) ) ) +} + +func main() { + AB := os.Args[1:3] + + var baseStrings []string; + + next_common_divisor: + for _, dv := range commonDivisors( len(AB[0]), len(AB[1]) ) { + mbs := AB[0][0:dv] // maybe base string + for _, x := range AB { + if ! StrTest(mbs).RepeatedIn( x ) { + continue next_common_divisor; + } + } + // copying is the only way?? + baseStrings = append( baseStrings, mbs ) + } + + fmt.Println( strings.Join(baseStrings, " " ) ) +} diff --git a/challenge-081/jeongoon/go/ch-2.go b/challenge-081/jeongoon/go/ch-2.go new file mode 100644 index 0000000000..0f5af73735 --- /dev/null +++ b/challenge-081/jeongoon/go/ch-2.go @@ -0,0 +1,103 @@ +/* +Ref: +https://golangdocs.com/reading-files-in-golang +https://golangdocs.com/split-string-in-golang +https://golang.org/pkg/sort/ +*/ + +/* test with: go run ./ch-1.go +# reading from file named "input" in PWD +*/ + +package main +import ( + "fmt" + "io/ioutil" + "log" + "sort" + "strings" +) + +func FilterStr(vs string, fs []string) string { + var vss []string + vslen := len(vs) + + through_string: + for i := 0; i < vslen; { + for _, f := range fs { + flen := len(f) + if i+flen >= vslen { + break through_string + } + subv := vs[i:i+flen] + if subv == f { + i += flen + continue through_string + } + } + vss = append( vss, vs[i:i+1] ) + i++ + } + return strings.Join( vss, "" ) +} + +type WordBag map[string]int +type FrequencyToWords map[int][]string + +func (wb *WordBag) FromSlice(ws []string) { + for _, w := range ws { + (*wb)[w]++ + } +} + +func (f2w *FrequencyToWords) Add(c int, w string) { + (*f2w)[c] = append( (*f2w)[c], w ) +} + +func (f2w *FrequencyToWords) Find(freq int) ([]string, bool) { + words, ok := (*f2w)[freq] + return words, ok +} + +func (wb *WordBag) ExportFrequencyToWords() ([]int, *FrequencyToWords) { + frq_only := []int{} + f2w := make(FrequencyToWords) + + for word, count := range (*wb) { + found := false + for _, cnt := range (frq_only) { + if count == cnt { + found = true + break + } + } + if ! found { + frq_only = append(frq_only, count) + } + f2w.Add(count, word) + } + sort.Ints(frq_only) // sorted in place + return frq_only, &f2w +} + +func main() { + content, err := ioutil.ReadFile("input") + if err != nil { + log.Fatal(err) + } + + words := strings.Fields( + FilterStr( string(content), + []string{ ".", ",", "(", ")", "\"", "'s", "--" }, + ) ) + bag := make(WordBag) + bag.FromSlice(words) + frq_sorted, freq_to_words := bag.ExportFrequencyToWords() + for _, frq := range(frq_sorted) { + ws, ok := freq_to_words.Find(frq) + if ok { + sort.Strings(ws) + fmt.Printf("%d\t%v\n", frq, strings.Join(ws, " ")) + } + } +} diff --git a/challenge-081/jeongoon/go/input b/challenge-081/jeongoon/go/input new file mode 120000 index 0000000000..8f1f9ce80d --- /dev/null +++ b/challenge-081/jeongoon/go/input @@ -0,0 +1 @@ +../perl/input \ No newline at end of file diff --git a/challenge-081/jeongoon/perl/ch-1.pl b/challenge-081/jeongoon/perl/ch-1.pl new file mode 100644 index 0000000000..bf2b8cc99f --- /dev/null +++ b/challenge-081/jeongoon/perl/ch-1.pl @@ -0,0 +1,45 @@ +#!/usr/bin/env perl +# -*- Mode: cperl; cperl-indent-level:4 tab-width: 8; indent-tabs-mode: nil -*- +# -*- coding: utf-8 -*- + +use strict; use warnings; +use v5.26; +use List::Util qw(all); + +sub usage { + say 'perl ch-1.pl [-v] ', "\n", + 'ex) perl ch-1.pl "perlraku" "perlrakuperlrakuperlraku"'; +} + +sub unsafe_commonDivisors($$) { + my ( $l, $r ) = @_; + all { int($_) eq $_ } $l, $r or die "both should be numbers"; + + my $min = $l < $r ? $l : $r; + map { ( $l % $_ or $r % $_ ) ? () : $_ } 1 .. $min; +} + +my @f_ARGV = grep { ! /-(v|d|-*verbsose|-*debug)/ } @ARGV; +my ( $A, $B ) = @f_ARGV; + +our $d = @f_ARGV != @ARGV; # turn on verbose + +all { defined $_ and length $_ > 0 } $A, $B or usage, exit 0; + +my @commonBaseWords; + +for my $cdv ( unsafe_commonDivisors( length $A, length $B ) ) { + my $mcb = substr( $A, 0, $cdv ); # (m)aybe (c)ommon (b)ase string + ( all + { my @m = /$mcb/g; + + say STDERR "`$_' contains `$mcb'", ": ", + (scalar @m), ", must be ", (length($_) / $cdv) if $d; + + scalar( @m ) == (length($_) / $cdv) + + } $A, $B + ) and push @commonBaseWords, $mcb; +} + +say join(", ", @commonBaseWords); diff --git a/challenge-081/jeongoon/perl/ch-2.pl b/challenge-081/jeongoon/perl/ch-2.pl new file mode 100644 index 0000000000..3ba377515d --- /dev/null +++ b/challenge-081/jeongoon/perl/ch-2.pl @@ -0,0 +1,41 @@ +#!/usr/bin/env perl +# -*- Mode: cperl; cperl-indent-level:4 tab-width: 8; indent-tabs-mode: nil -*- +# -*- coding: utf-8 -*- + +use strict; use warnings; +use v5.26; +use List::Util 1.39 qw(pairs); + +sub usage { + say 'perl ch-1.pl # no option: reading from a file named `input\''; +} + +my @f_ARGV = grep { ! /-(h|-*help)/ } @ARGV; +@f_ARGV == @ARGV or usage, exit 0; + +my ( $file_path, @words ) = "input"; +-r $file_path or usage, exit 0; + +open my $fh, '<', $file_path or die $@; + +{ + local $/ = undef; + @words = split /\s/, <$fh>; +}; + +# filtering and add to bag +my %prada; +for my $w (@words) { + $w =~ s/'s|--|[^a-zA-Z_0-9\-]//g; + ++$prada{$w}; +} + +# invert frequency and word +my %evilWares; +for my $pair ( pairs %prada ) { + push @{$evilWares{$pair->value}}, $pair->key; +} + +for my $freq ( sort ( keys %evilWares ) ) { + say "$freq @{[sort @{$evilWares{$freq}}]}"; +} diff --git a/challenge-081/jeongoon/perl/input b/challenge-081/jeongoon/perl/input new file mode 100644 index 0000000000..37001629ad --- /dev/null +++ b/challenge-081/jeongoon/perl/input @@ -0,0 +1,3 @@ +West Side Story + +The award-winning adaptation of the classic romantic tragedy "Romeo and Juliet". The feuding families become two warring New York City gangs, the white Jets led by Riff and the Latino Sharks, led by Bernardo. Their hatred escalates to a point where neither can coexist with any form of understanding. But when Riff's best friend (and former Jet) Tony and Bernardo's younger sister Maria meet at a dance, no one can do anything to stop their love. Maria and Tony begin meeting in secret, planning to run away. Then the Sharks and Jets plan a rumble under the highway--whoever wins gains control of the streets. Maria sends Tony to stop it, hoping it can end the violence. It goes terribly wrong, and before the lovers know what's happened, tragedy strikes and doesn't stop until the climactic and heartbreaking ending. diff --git a/challenge-081/jeongoon/raku/ch-1.raku b/challenge-081/jeongoon/raku/ch-1.raku new file mode 100644 index 0000000000..005aee4818 --- /dev/null +++ b/challenge-081/jeongoon/raku/ch-1.raku @@ -0,0 +1,39 @@ +#!/usr/bin/env raku +# -*- Mode: Raku; indent-tabs-mode: nil; coding: utf-8 -*- +# vim: set et ts=4 sw=4: + +use v6.d; + +# tested with: raku jeongoon/raku/ch-1.raku perlraku perlrakuperlrakuperlraku + +=begin unfolded + +sub MAIN( *@a where @a.elems == 2 ) { + (1..[gcd] @a».chars). + map( ->\k { + my \w = @a[0].substr(^k); # a possible base (w)ord + # `-> it doesn't matter which words are in use + next if any @a.map({ + .indices(w).elems + != + .chars / k + } ); + w # take + } ).join(", ").put +} + +=end unfolded + +# https://dev.to/jeongoon/weekly-challenge-081-task-1-422l +# folded +sub MAIN(*@a){put (1..[gcd] @a».chars).map(->\k{my \w=@a[0].substr(^k);next if any @a.map({.indices(w)!= .chars/k});w})} + +=begin off-the-challenge + +# credit: markus-holzer +# thank you :-) + +#sub MAIN(*@a){put ([\~] @a[0].substr(^ [gcd] @a».chars)).grep(->\w{all @a.map({.indices(w)==.chars/w.chars})})} +sub MAIN(*@a){put ([\~] @a.min).grep(->\w{all @a.map({.indices(w)==.chars/w.chars})})} + +=end off-the-challenge diff --git a/challenge-081/jeongoon/raku/ch-2.raku b/challenge-081/jeongoon/raku/ch-2.raku new file mode 100644 index 0000000000..b77fff0b4e --- /dev/null +++ b/challenge-081/jeongoon/raku/ch-2.raku @@ -0,0 +1,52 @@ +#!/usr/bin/env raku +# -*- Mode: Raku; indent-tabs-mode: nil; coding: utf-8 -*- +# vim: set et ts=4 sw=4: + +# test with: +our $usage="cd jeongoon/raku; raku ch-2.raku; cd -"; +# because reading "input" from current directory + +=begin unfolded + +with "input".IO { + .r or die "no `input' file"; + my %r; + %r{.value}.push(.key) .= sort # not efficent but note that + # left hand side is still left value + for bag(.words». + subst( / \'s + | + <[\W]-[-]> # non ascii num but `-' allowed + | + "--" /, # `-' is allowed but `--' is not + '',:g ) + ); + %r.sort(*.key). # `*.key' is not needed but has clearer meaning + join("\n"). + put; +} + +=end unfolded + +# https://dev.to/jeongoon/weekly-challenge-081-task-2-1lbj +with "input".IO { + .r or die "no `input' file"; + my %r; + %r{.value}.push(.key).=sort + for bag(.words».subst(/\'s|<[\W]-[-]>|"--"/,'',:g)); + %r.sort.join("\n").put; +} + +=begin off-the-challenge + +# credit: mark-anderson +# thank you :-) + +"input".IO.slurp andthen { + my %r; + %r{.value}.push(.key).=sort + for bag(.subst(/\'s|<[,."()]>|"--"/,'',:g).words); + %r.sort.join("\n").put; +} + +=end off-the-challenge diff --git a/challenge-081/jeongoon/raku/input b/challenge-081/jeongoon/raku/input new file mode 120000 index 0000000000..8f1f9ce80d --- /dev/null +++ b/challenge-081/jeongoon/raku/input @@ -0,0 +1 @@ +../perl/input \ No newline at end of file -- cgit