Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Code-Golf: Friendly Number Abbreviator

J, 61 63 65 characters

((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.


Python 2.x, 78 chars

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]

Perl 114 111 104 chars

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];

Output:

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

Javascript 114 chars

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}

Also 114 - Using spidermonkey - Input on STDIN

[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])

104 - Function

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 :)


Ruby - 79 77 75 83 chars

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.

74 72 80 chars, prints output within double quotes

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]]

66 74 chars, prints extra zeroes

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.


dc - 75 chars

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.


Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!