diff options
| author | Michael Manring <michael@manring> | 2022-03-12 01:46:33 +0700 |
|---|---|---|
| committer | Michael Manring <michael@manring> | 2022-03-12 10:53:47 +0700 |
| commit | ba22ce99dfe4a2ac1185cc57a0382cb4ba234906 (patch) | |
| tree | 058a5ea8621173225b2a92916ad8f7f65c2e150f /challenge-155 | |
| parent | 05ef2a173372747beaa65322ed4ddfd1e99c449b (diff) | |
| download | perlweeklychallenge-club-ba22ce99dfe4a2ac1185cc57a0382cb4ba234906.tar.gz perlweeklychallenge-club-ba22ce99dfe4a2ac1185cc57a0382cb4ba234906.tar.bz2 perlweeklychallenge-club-ba22ce99dfe4a2ac1185cc57a0382cb4ba234906.zip | |
solutions in GO and refactored ch-2.pl
Diffstat (limited to 'challenge-155')
| -rw-r--r-- | challenge-155/pokgopun/go/README | 1 | ||||
| -rw-r--r-- | challenge-155/pokgopun/go/ch-1.go | 87 | ||||
| -rw-r--r-- | challenge-155/pokgopun/go/ch-2.go | 45 | ||||
| -rw-r--r-- | challenge-155/pokgopun/perl/ch-2.pl | 60 |
4 files changed, 150 insertions, 43 deletions
diff --git a/challenge-155/pokgopun/go/README b/challenge-155/pokgopun/go/README new file mode 100644 index 0000000000..33dfd303a4 --- /dev/null +++ b/challenge-155/pokgopun/go/README @@ -0,0 +1 @@ +Solution by PokGoPun diff --git a/challenge-155/pokgopun/go/ch-1.go b/challenge-155/pokgopun/go/ch-1.go new file mode 100644 index 0000000000..11106b2af7 --- /dev/null +++ b/challenge-155/pokgopun/go/ch-1.go @@ -0,0 +1,87 @@ +package main + +import ( + "fmt" + "sort" +) + +func main() { + // find the first 8 fortunate number + n := 8 + var ( + i int + j int + prime int + ) + // declare with literal to allow append + primes := []int{} + fortunes := []int{} + for len(fortunes) < n { + // add next prime if not enough to calculate + if i <= len(primes) || j <= len(primes) { + primes = append(primes, nextPrime(prime)) + prime = primes[len(primes)-1] + } + pn := 1 + for k := 0; k <= j; k++ { + pn *= primes[k] + } + m := primes[i] + if isPrime(pn + m) { + //fmt.Println("Found Fortunate number", m) + fortunes = append(fortunes, m) + // sort slice by standard library which need passing a closure that defined how to sort + sort.Slice(fortunes, func(i, j int) bool { + return fortunes[i] < fortunes[j] + }) + // remove duplicated slice member by just writing unseen members back to the slice + // this does not interfere for range because for range copy the slice before iterating + // s to store slice's member already seen, initial value of 0 work because it's not a fortunate number + // c is used as index to write unseen member back to the slice and counter of written at the same time + // final step is to slice the original slice up to c + var c, s int + for _, v := range fortunes { + if v == s { + continue + } else { + fortunes[c] = v + s = v + c++ + } + } + fortunes = fortunes[:c] + j++ + i = 0 + } else { + i++ + } + } + fmt.Println(fortunes) +} + +// function to check for prime number, copy from wiki +func isPrime(n int) bool { + if n <= 3 { + return n > 1 + } else if n%2 == 0 || n%3 == 0 { + return false + } + for i := 5; i*i <= n; i += 6 { + if n%i == 0 || n%(i+2) == 0 { + return false + } + } + return true +} + +// a basic function to generate next prime number, basing on the isPrime function +// farily works on support calculating fortunate number up to 13 but freeze on 14 +func nextPrime(n int) int { + for { + n++ + if isPrime(n) { + return n + } + } + return 0 +} diff --git a/challenge-155/pokgopun/go/ch-2.go b/challenge-155/pokgopun/go/ch-2.go new file mode 100644 index 0000000000..5674c747b6 --- /dev/null +++ b/challenge-155/pokgopun/go/ch-2.go @@ -0,0 +1,45 @@ +package main + +import "fmt" + +func main() { + // Generating the first twelve Pisano periods and their cycles + // https://en.wikipedia.org/wiki/Pisano_period => section "Table" + for n := 1; n <= 12; n++ { + // Sequence for storing Fibonacci numbers + fseq := []int{0, 1} + // Sequence for calculating Pisano periods + var mseq string + // Avoid looping more than 1000 times during the calcuation + for i := 0; i < 1000; i++ { + f1 := fseq[1] + f0 := fseq[0] + // ascii offset for convert number 0-9 to string 0-9, 10-35 to A-Z, 36-61 to a-z + var o int + switch { + case f0 < 10: + o = 48 + case f0 < 36: + o = 55 + default: + o = 61 + } + mseq += string(f0%n + o) + // check for repeated cycle when mseq contains even number of charactors, that is when latest index is odd + if i%2 == 1 { + m := len(mseq) / 2 + if string(mseq[:m]) == string(mseq[m:]) { + fmt.Println("n =", n, ",Pisano period =", m, ",Cycle =", mseq[:m]) + //fmt.Println("i = ", i) + break + } + } + // fn = f1 + f0 as fseq will contain only the latest two values + // fseq = append(fseq, f1+f0) + // We can just store fn%n instead of fn as (f1+f2)%n seems to be always equal to (f1%n + f0%n)%n + fseq = append(fseq, (f1+f0)%n) + // fseq to contain only the latest two values + fseq = fseq[len(fseq)-2:] + } + } +} diff --git a/challenge-155/pokgopun/perl/ch-2.pl b/challenge-155/pokgopun/perl/ch-2.pl index 0635eeeae1..12b647666d 100644 --- a/challenge-155/pokgopun/perl/ch-2.pl +++ b/challenge-155/pokgopun/perl/ch-2.pl @@ -1,70 +1,44 @@ use strict; use warnings; -use Math::Base::Convert; ## Take n from argument if specified when running the script otherwise assign 3 which is the number the challenge's task asked to solve -## Support n = 1 to 36 my $n = shift; $n = 3 unless $n; -die "n has to be an interger between 1 and 36\n" unless $n && $n =~ /^\d+$/ && $n <= 36; - -my($conv4n2d,$conv4d2n); -{ - last unless $n > 10; - my $baseChar = [@{[0..9,'A'..'Z']}[0..$n-1]]; - $conv4n2d = new Math::Base::Convert( $baseChar, '10'); - $conv4d2n = new Math::Base::Convert('10', $baseChar); -} ## Initial sequence of Fibonacci numbers, only need two to calculate the next one -my $fseq = "0 + 1"; +my @f = qw/0 1/; ## Initial Sequence of Fibonacci numbers modulo n, Fi modulo n my $mseq = ''; my $i = 0; -## Detect repeated cycle, start from period of j = 1 - -my $j = 1; - { - ## Calcuate next Fibonacci number + ## Calculate next F number, modulo n first before pushing to @f and take off Fi + ## this to keep @f minimal while Fi modulo n still produce the same result - #my $f = eval($fseq); - - ## Extracting Fi from the sequence and replace the squence with the latest two numbers - ## For Fibonacci number modulo 10, we only need the last digit of the number to calculate + push @f, ($f[0] + $f[1]) % $n; + my $fi = shift @f; - #my $fi; - #($fi, $fseq) = $fseq =~ /(\d+) \+ (\d+)/ && $n==10 ? (substr($1,-1), join(" + ",substr($2,-1),substr($f,-1))) : ($1, "$2 + $f"); + ## Get offset to convert number 0..35 to char 0..9,A..Z , + ## 36... to char a..z and whatever come next in ascii table + ## This make the repeated cycle in $mseq comparable - ## Generate sequence of Fi modulo n - - #$mseq .= $fi % $n; - - ## Evolve from the logic above for n==10, we can do the same for n > 10 by converting to base n before store/use the last base char + my $o = $fi < 10 ? 48 : + $fi < 36 ? 55 : 61; - $fseq =~ /(\w+) \+ (\w+)/; - my $f = $n > 10 ? $conv4n2d->cnv($1) + $conv4n2d->cnv($2) : $1 + $2; - my $fi; - ($fi, $fseq) = $n < 10 ? ($1, "$2 + $f") : - $n == 10 ? ( substr($1,-1), join(" + ", map{substr($_,-1)} ($2,$f)) ) : - ( scalar($conv4n2d->cnv(substr($1,-1))), join(" + ", map{substr($_,-1)} ($2,scalar($conv4d2n->cnv($f)))) ); - $mseq .= $n > 10 ? $conv4d2n->cnv($fi % $n) : $fi % $n; - - ## When the sequence reach j * 2, check for a repeated period of j - ## If found, display j and the repeated cycle and exit the loop - ## If not, continue the loop to check the period of j + 1 + $mseq .= chr(($fi % $n) + $o); + + ## Check for repeated cycle when number char of sequence is even (i.e. when $i is odd ), compare 1st and 2nd half - if ( $j * 2 == length($mseq) ){ - if( substr($mseq,0,$j) eq substr($mseq,-$j) ){ - print "#$n Pisano Period is ".$j." => ".substr($mseq,0,$j)."\n"; + if ( $i % 2 == 1 ){ + my $l = ($i + 1)/2; + if( substr($mseq,0,$l) eq substr($mseq,-$l) ){ + print "#$n Pisano period is ".$l.", repeated cycle is ".substr($mseq,0,$l)."\n"; last; } - $j++; } ## Continue with the next Fi |
