Código-Golf: Número friendly abreviador
Pregunta
En base a esta pregunta: ¿hay una manera de números redondos en un formato amigable?
EL RETO! - ACTUALIZADO (cientos eliminado abreviatura de especificación)
El código más corto por el recuento de caracteres que va a abreviar un número entero (sin decimales).
Código debe incluir el programa completo.
rango relevante es de 0 - 9,223,372,036,854,775,807
(el límite superior de entero de 64 bits).
El número de decimales para abreviatura será positivo. No tendrá que calcular lo siguiente:. 920535 abbreviated -1 place
(que sería algo así como 0.920535M
)
Los números de las decenas y centenas (0-999
) debe no abreviarse (la abreviatura para el número 57
a lugares 1+
decimales es 5.7dk
- que es innecesario y no muy agradable)
Recuerde medio ronda lejos de cero (23.5 consigue redondeado a 24). redondeo bancario está prohibido.
Estas son las abreviaturas de números correspondientes:
h = hundred (10
2
)
k = thousand (10
3
)
M = million (10
6
)
G = billion (10
9
)
T = trillion (10
12
)
P = quadrillion (10
15
)
E = quintillion (10
18
)
MUESTRA ENTRADAS / SALIDAS (entradas puede ser pasado como argumentos separados):
El primer argumento será el número entero para abreviar. El segundo es el número de cifras decimales.
12 1 => 12 // tens and hundreds places are never rounded
1500 2 => 1.5k
1500 0 => 2k // look, ma! I round UP at .5
0 2 => 0
1234 0 => 1k
34567 2 => 34.57k
918395 1 => 918.4k
2134124 2 => 2.13M
47475782130 2 => 47.48G
9223372036854775807 3 => 9.223E
// ect...
Respuesta original de la pregunta relacionada (JavaScript, no sigue las especificaciones):
function abbrNum(number, decPlaces) {
// 2 decimal places => 100, 3 => 1000, etc
decPlaces = Math.pow(10,decPlaces);
// Enumerate number abbreviations
var abbrev = [ "k", "m", "b", "t" ];
// Go through the array backwards, so we do the largest first
for (var i=abbrev.length-1; i>=0; i--) {
// Convert array index to "1000", "1000000", etc
var size = Math.pow(10,(i+1)*3);
// If the number is bigger or equal do the abbreviation
if(size <= number) {
// Here, we multiply by decPlaces, round, and then divide by decPlaces.
// This gives us nice rounding to a particular decimal place.
number = Math.round(number*decPlaces/size)/decPlaces;
// Add the letter for the abbreviation
number += abbrev[i];
// We are done... stop
break;
}
}
return number;
}
Solución
J, 61 63 65 caracteres
((j.&(1&{)":({.%&1e3{:));{&' kMGTPE'@{.)(([:<.1e3^.{.),{:,{.)
Salida:
((j.&(1&{)":({.%&1e3{:));{&' kMGTPE'@{.)(([:<.1e3^.{.),{:,{.) 1500 0
┌─┬─┐
│2│k│
└─┴─┘
((j.&(1&{)":({.%&1e3{:));{&' kMGTPE'@{.)(([:<.1e3^.{.),{:,{.) 987654321987654321 4
┌────────┬─┐
│987.6543│P│
└────────┴─┘
(La razón la salida se "caja" como que se debe a J no admite una lista que consiste en diferentes tipos)
Explicación (de derecha a izquierda):
(([:<.1000^.{.),{:,{.)
Hacemos una nueva lista de 3 elementos, utilizando ,
para unirse ([:<.1000^.{.)
(el registro <.
base de ^.
suelo de 1000 de la primera {.
parámetro. Nos unimos con el segundo {:
parámetro y luego la primera {.
parámetro.
Así que después del primer bit, hemos transformado 12345 2
digamos en 1 2 12345
usos ((j.&(1&{)":({.%&1000{:));{&' kMGTPE'@{.)
;
para unir las dos mitades de la expresión en una caja para producir la salida final.
El primer medio es ((j.&(1&{)":({.%&1000{:))
que divide (%
) el último número de entrada ({:
) por 1000, el primer número de veces. Luego se coloca la ":
precisión usando el segundo número en la lista de entrada (1&{
).
El segundo medio {&' kMGTPE'@{.
-. Este utiliza el primer número para seleccionar ({
) el carácter apropiado de la lista 0-indexada de abreviaturas
Otros consejos
Python 2.x, 78 caracteres
a=input()
i=0
while a>=1e3:a/=1e3;i+=1
print"%g"%round(a,input())+" kMGTPE"[i]
Esta versión ( 75 caracteres ) utiliza printf que imprimirá ceros adicionales y sigue la regla de todo el año, incluso a.
a=input()
i=0
while a>=1e3:a/=1e3;i+=1
print"%%.%df"%input()%a+" kMGTPE"[i]
Perl 114 111 104 caracteres
Mi primera entrada de código de golf nunca!
Argumentos expuestos de la entrada estándar: 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];
Salida:
918.4k
versión (con explicación)
De-golfed:
( $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 caracteres
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}
También 114 - Usando spidermonkey - Entrada de la entrada estándar
[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 - Función
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]
}
Lo que también se convierte en 99 si se reemplaza la (''+a)
con a
y la promesa de pasar solamente cadenas:)
Ruby - 79 77 75 83 caracteres
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]
lee de argumentos de línea de comandos.
74 72 80 caracteres, de salida grabados dentro de comillas dobles
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 caracteres, impresiones adicional ceros
n,d=ARGV
l=n.to_s.length
p"%.#{d}f%s"%[n.to_f/10**(l-l%3)," kMGTPE"[l/3]]
Basado en esta solución , y el código de ejemplo.
DC - 75 caracteres
A7 1:U77 2:U71 3:U84 4:U80 5:U69 6:U[3+r1-r]sJ?sddZd3~d0=Jrsp-Ar^ldk/nlp;UP
Usos Z
(número de dígitos) %3
para encontrar la unidad. La mayor parte del código se utiliza para configurar la matriz de unidades de carácter, el código real es de 39 caracteres. Los macro ajusta J
cuando %3
es igual 0
, para evitar la impresión 0.918M
en el séptimo. caso de prueba. Lo hace no redondos correctamente.
Si usted habla dc
, sentir la libertad de mejorarla.
PHP 57 caracteres
for($a=num+1;$a>=1;$a=$a/26)$c=chr(--$a%26+65).$c;echo$c;
Haskell, 126 (sin importar, que es una función que toma dos argumentos):
f n p|l>3=showFFloat (Just p) (c n/c 10^(l-w)) [" kMGTPE"!!f]|True=show n where(f,w)=divMod l 3;c=fromIntegral;l=length$show n
Ampliado:
import Numeric
doit :: Integer -> Int -> String
doit n p
| l > 3 = showFFloat (Just p) d [" kMGTPE" !! f]
| otherwise = show n
where
d = (fromIntegral n) / fromIntegral (10^(l-w))
(f,w) = divMod l 3
l = length $ show n
Perl 94 Chars
($_,$d)=@ARGV;$l=length;@u=' kMGTPE'=~/./g;printf"%.".($l>3?$d:0)."f$u[$l/3]",$_/10**($l-$l%3)
Uso:
perl abbreviator.pl 47475782130 2
Salida:
47.48G