((j.&(1&{)":({.%&1e3{:));{&' kMGTPE'@{.)(([:<.1e3^.{.),{:,{.)
Output:
((j.&(1&{)":({.%&1e3{:));{&' kMGTPE'@{.)(([:<.1e3^.{.),{:,{.) 1500 0
┌─┬─┐
│2│k│
└─┴─┘
((j.&(1&{)":({.%&1e3{:));{&' kMGTPE'@{.)(([:<.1e3^.{.),{:,{.) 987654321987654321 4
┌────────┬─┐
│987.6543│P│
└────────┴─┘
(The reason the output is "boxed" like that is because J doesn't support a list consisting of varying types)
Explanation (from right to left):
(([:<.1000^.{.),{:,{.)
We make a new 3-element list, using ,
to join ([:<.1000^.{.)
(the floored <.
base 1000 log ^.
of the first param {.
. We join it with the second param {:
and then the first param {.
.
So after the first bit, we've transformed say 12345 2
into 1 2 12345
((j.&(1&{)":({.%&1000{:));{&' kMGTPE'@{.)
uses ;
to join the two halves of the expression together in a box to produce the final output.
The first half is ((j.&(1&{)":({.%&1000{:))
which divides (%
) the last input number ({:
) by 1000, the first number of times. Then it sets the precision ":
using the second number in the input list (1&{
).
The second half {&' kMGTPE'@{.
- this uses the first number to select ({
) the appropriate character from the 0-indexed list of abbreviations.
a=input()
i=0
while a>=1e3:a/=1e3;i+=1
print"%g"%round(a,input())+" kMGTPE"[i]
This version (75 chars) uses printf which will print extra zeros and follows the round-to-even rule.
a=input()
i=0
while a>=1e3:a/=1e3;i+=1
print"%%.%df"%input()%a+" kMGTPE"[i]
My first ever code-golf entry!
Arguments provided from standard input: perl fna.pl 918395 1
($n,$d)=@ARGV;
@n=$n=~/./g;
@s=' kMGTPE'=~/./g;
printf"%.".(@n>3?$d:0)."f%s",$n/(10**($#n-$#n%3)),$s[@n/3];
918.4k
De-golfed version (with explanation):
( $number, $dp ) = @ARGV; # Read in arguments from standard input
@digits = split //, $number; # Populate array of digits, use this to count
# how many digits are present
@suffix = split //, ' kMGTPE'; # Generate suffix array
$number/(10**($#n-$#n%3)); # Divide number by highest multiple of 3
$precision = @n>3 ? $dp : 0; # Determine number of decimal points to print
sprintf "%.".$precision."f%s", # "%.2f" prints to 2 dp, "%.0f" prints integer
$number, $suffix[@n/3];# Select appropriate suffix
function m(n,d){p=M.pow
d=p(10,d)
i=7
while(i)(s=p(10,i--*3))<=n&&(n=M.round(n*d/s)/d+"kMGTPE"[i])
return n}
[n,d]=readline().split(' '),x=n.length,p=Math.pow,d=p(10,d)
x-=x%3
print(Math.round(n*d/p(10,x))/d+" kMGTPE"[x/3])
function(a,b,c,d){
c=(''+a).length;
d=Math.pow;
b=d(10,b);
return((a*b/d(10,c-=c%3))+.5|0)/b+' kMGTPE'[c/3]
}
Which also becomes 99 if you replace the (''+a)
with a
and promise to only pass strings :)
n,d=ARGV
l=n.to_s.length
printf"%.#{l>3?d:0}f%s",n.to_f/10**(l-l%3)," kMGTPE"[l/3]
Reads from command line arguments.
n,d=ARGV
l=n.to_s.length
p"%.#{l>3?d:0}f%s"%[n.to_f/10**(l-l%3)," kMGTPE"[l/3]]
n,d=ARGV
l=n.to_s.length
p"%.#{d}f%s"%[n.to_f/10**(l-l%3)," kMGTPE"[l/3]]
Based on this solution, and the sample code.
A7 1:U77 2:U71 3:U84 4:U80 5:U69 6:U[3+r1-r]sJ?sddZd3~d0=Jrsp-Ar^ldk/nlp;UP
Uses Z
(number of digits) %3
to find the unit. Most of the code is for setting the units character array, the real code is 39 chars. The J
macro adjusts when %3
equals 0
, to avoid printing 0.918M
in the 7th. test case. It doesn't round properly.
If you speak dc
, feel free to improve it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With