From 07d740d18cb7f0e9e9a80ecff1a6b6e8b4751ce3 Mon Sep 17 00:00:00 2001 From: Myoungjin JEON Date: Sun, 27 Sep 2020 23:11:49 +1000 Subject: [ch-079/jeongoon] add ch-1.hs, just little bit more better ch-1.pl, ch-1.raku --- challenge-079/jeongoon/haskell/ch-1.hs | 29 +++++++++++++++++++++++++++++ challenge-079/jeongoon/perl/ch-1.pl | 32 +++++++++++++++++--------------- challenge-079/jeongoon/raku/ch-1.raku | 17 +++++++++++------ 3 files changed, 57 insertions(+), 21 deletions(-) create mode 100644 challenge-079/jeongoon/haskell/ch-1.hs diff --git a/challenge-079/jeongoon/haskell/ch-1.hs b/challenge-079/jeongoon/haskell/ch-1.hs new file mode 100644 index 0000000000..9fba3eec85 --- /dev/null +++ b/challenge-079/jeongoon/haskell/ch-1.hs @@ -0,0 +1,29 @@ +import System.Environment +import System.Exit +import Data.Bits (shift, shiftR, bit, clearBit) +import Data.Char (isNumber) +import Data.Maybe (isJust, catMaybes) + +-- tested with: runhaskell ch-2.hs 99999 + +-- translated from ch-1.pl +-- I believed that this is not best solution but working fast enough. + +trunc = (`rem` 1000000007) + +countSetBits n + | n <= 2 = n + | n' == 0 = sumUptoPow2 + | True = sumUptoPow2 + n' + (countSetBits n') + where + sumUptoPow2 = ((pow * (1 `shift` pow)) `shiftR` 1) + 1 + n' = n `clearBit` pow -- === ( n - 2^pow ) + pow = (last.takeWhile ((n>=).bit)) [0..] + +main = do + (catMaybes.map (\nStr -> + if (all isNumber nStr) then Just(read nStr :: Int) + else Nothing )) `fmap` getArgs + >>= (\nums -> + if length nums < 1 then die( "one positive integer, please" ) + else (putStrLn.show.trunc.countSetBits.head) nums ) diff --git a/challenge-079/jeongoon/perl/ch-1.pl b/challenge-079/jeongoon/perl/ch-1.pl index 6190e498bc..26043eefe3 100644 --- a/challenge-079/jeongoon/perl/ch-1.pl +++ b/challenge-079/jeongoon/perl/ch-1.pl @@ -5,12 +5,7 @@ use strict; use warnings; use v5.26; use bignum; -use List::Util qw(sum); -# dec2bin -# credit: https://www.oreilly.com/library/view/perl-cookbook/1565922433/ch02s05.html -# but don't need to remove zero(es). -sub dec2bin { unpack "B32", pack("N", $_[0]); } sub TruncNum { 1000000007 } # spec sub usage { say "perl ch-1.pl # where N is positive integer"; @@ -21,16 +16,23 @@ BEGIN { $@ and usage(), exit 0; } -sub sumSection ($) { # sum of the counts of bits between 2^(m) .. 2^(m+1)-1 - state @K = (1, 3); - my $m = shift; - - exists $K[$m] ? $K[$m] : ( $K[$m] = sum( 1<<$m, @K[0..$m-1] ) ); -} - -sub sumUptoPow2 ($) { # sum of bits between 0 .. 2^pow - sum 1, # sumSection doesn't count the last bits of 2^pow - map { sumSection $_ } 0 .. $_[0]-1 +#sub sumSection ($) { # sum of the counts of bits between 2^(m) .. 2^(m+1)-1 +# state @K = (1, 3); +# my $m = shift; +# +# exists $K[$m] ? $K[$m] : ( $K[$m] = sum( 1<<$m, @K[0..$m-1] ) ); +#} + +#sub sumUptoPow2 ($) { # sum of bits between 0 .. 2^pow +# sum 1, # sumSection doesn't count the last bits of 2^pow +# map { sumSection $_ } 0 .. $_[0]-1 +#} + +# there is a simpler way to calculate, I realised today. +# but this is not significantly faster than before. +sub sumUptoPow2 ($) { + my $pow = shift; + 0.5 * $pow * (1 << $pow) + 1; } sub countSetBits ($); diff --git a/challenge-079/jeongoon/raku/ch-1.raku b/challenge-079/jeongoon/raku/ch-1.raku index 7e52b7b8e7..9957f92016 100644 --- a/challenge-079/jeongoon/raku/ch-1.raku +++ b/challenge-079/jeongoon/raku/ch-1.raku @@ -8,14 +8,19 @@ our &trunc = (*%(big-num)); # as spec requested. but no need in raku. our &naive = {[+] (.base(2).indices(1).elems for ^$_[0]+1)}; # this is the rule what I found. I guess this is not bad. -sub sum-a-section ($m) { - state @K = 1, 3; - # summation of the counts of bits between 2**(m) .. 2**(m+1)-1 - @K[$m]:exists ?? @K[$m] !! ( @K[$m] = [+] (1+<$m), |@K[0..$m-1] ); -} +#sub sum-a-section ($m) { +# state @K = 1, 3; +# # summation of the counts of bits between 2**(m) .. 2**(m+1)-1 +# @K[$m]:exists ?? @K[$m] !! ( @K[$m] = [+] (1+<$m), |@K[0..$m-1] ); +#} +# 27th Sep 2020: there is a simpler way to calculate but +# my implementation doesn't help much +#sub sum-upto-power2 ($pow) { # bits sum between 0 .. 2^pow +# [+] 1, |(sum-a-section($_) for 0..($pow-1)); +#} sub sum-upto-power2 ($pow) { # bits sum between 0 .. 2^pow - [+] 1, |(sum-a-section($_) for 0..($pow-1)); + 1 + 0.5 * $pow * (1+<$pow); } sub count-set-bits ( UInt \N ) { -- cgit From 0fe435254749250667c2f38566f12f617e270cab Mon Sep 17 00:00:00 2001 From: Myoungjin JEON Date: Mon, 28 Sep 2020 00:03:43 +1000 Subject: [ch-079/jeongoon] add ch-1.hs, just little bit more better ch-1.pl, ch-1.raku --- challenge-079/jeongoon/perl/ch-1.pl | 35 ++++++++++++++++++++--------------- challenge-079/jeongoon/raku/ch-1.raku | 2 +- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/challenge-079/jeongoon/perl/ch-1.pl b/challenge-079/jeongoon/perl/ch-1.pl index 26043eefe3..9790cf08a2 100644 --- a/challenge-079/jeongoon/perl/ch-1.pl +++ b/challenge-079/jeongoon/perl/ch-1.pl @@ -16,23 +16,28 @@ BEGIN { $@ and usage(), exit 0; } -#sub sumSection ($) { # sum of the counts of bits between 2^(m) .. 2^(m+1)-1 -# state @K = (1, 3); -# my $m = shift; -# -# exists $K[$m] ? $K[$m] : ( $K[$m] = sum( 1<<$m, @K[0..$m-1] ) ); -#} - -#sub sumUptoPow2 ($) { # sum of bits between 0 .. 2^pow -# sum 1, # sumSection doesn't count the last bits of 2^pow -# map { sumSection $_ } 0 .. $_[0]-1 -#} - -# there is a simpler way to calculate, I realised today. -# but this is not significantly faster than before. +package older; +use List::Util qw(sum); + +sub sumSection ($) { # sum of the counts of bits between 2^(m) .. 2^(m+1)-1 + state @K = (1, 3); + my $m = shift; + + exists $K[$m] ? $K[$m] : ( $K[$m] = sum( 1<<$m, @K[0..$m-1] ) ); +} + +sub sumUptoPow2 ($) { # sum of bits between 0 .. 2^pow + sum 1, # sumSection doesn't count the last bits of 2^pow + map { sumSection $_ } 0 .. $_[0]-1 +} + +package main; + +# there is a simpler way to calculate, which I realised today. +# but this method is not significantly faster than previous one. sub sumUptoPow2 ($) { my $pow = shift; - 0.5 * $pow * (1 << $pow) + 1; + ( $pow * (1 << $pow) >> 1 ) + 1; # eqv. ($pow * (2**$pow) / 2 ) + 1; } sub countSetBits ($); diff --git a/challenge-079/jeongoon/raku/ch-1.raku b/challenge-079/jeongoon/raku/ch-1.raku index 9957f92016..196bfb2cc4 100644 --- a/challenge-079/jeongoon/raku/ch-1.raku +++ b/challenge-079/jeongoon/raku/ch-1.raku @@ -20,7 +20,7 @@ our &naive = {[+] (.base(2).indices(1).elems for ^$_[0]+1)}; # [+] 1, |(sum-a-section($_) for 0..($pow-1)); #} sub sum-upto-power2 ($pow) { # bits sum between 0 .. 2^pow - 1 + 0.5 * $pow * (1+<$pow); + 1 + ( $pow * (1+<$pow) ) +> 1 } sub count-set-bits ( UInt \N ) { -- cgit