Desafío y origen
En Stack Overflow, una pregunta popular es: ¿Cómo convertir el tamaño de byte en formato legible para humanos en Java? La respuesta más votada tiene un método bastante bueno para hacer esto, pero esto es codegolf y podemos hacerlo mejor, ¿no?
Su desafío es escribir un método o programa que convierta el número dado de bytes al formato legible por humanos correcto e imprima el resultado al estándar de su idioma. *
* ¡Vea las reglas para más aclaraciones!
Entrada
La entrada siempre será un número positivo de bytes con un máximo de (2 ^ 31) -1.
Salida
Puede elegir si prefiere el Sistema internacional de unidades o la notación binaria como salida (la notación SI probablemente le ahorre algunos bytes).
SI: B, kB, MB, GB
Binary: B, KiB, MiB, GiB
Nota: Las unidades superiores a GB o GiB no son posibles debido al rango de entrada restringido.
Salida de ejemplo
Sistema Internacional de Unidades:
Input Output
0 0.0 B
999 999.0 B
1000 1.0 kB
1023 1.0 kB
1024 1.0 kB
1601 1.6 kB
160581 160.6 kB
4066888 4.1 MB
634000000 634.0 MB
2147483647 2.1 GB
Binario:
Input Output
0 0.0 B
999 999.0 B
1000 1000.0 B
1023 1023.0 B
1024 1.0 KiB
1601 1.6 KiB
160581 156.8 KiB
4066888 3.9 MiB
634000000 604.6 MiB
2147483647 2.0 GiB
Reglas
- ¡Las funciones incorporadas para el formato de bytes no están permitidas!
- La salida siempre debe estar en el mismo estándar de notación, no puede mezclar SI o binario;
- La salida siempre debe estar en la unidad más grande posible donde el número resultante sea aún mayor o igual a uno;
- La salida siempre debe tener un número decimal, pero puede elegir imprimir un número entero cuando la salida resultante esté en bytes (B);
- Puede elegir si desea agregar un espacio, tabulación o nada entre el número y la unidad;
- La entrada se recibe a través de STDIN o parámetros de función;
- La salida se imprime en la consola o se devuelve como una cadena (o un contenedor de caracteres similar);
- Este es el código de golf, por lo que gana la respuesta más corta. ¡Que te diviertas!
Editar: incluso más aclaraciones
Algunos números tienen comportamientos de redondeo interesantes como el número 999950. La mayoría de las implementaciones de código devolverían 1000.0 kB en lugar de 1.0 MB. ¿Por qué? Porque 999950/1000 se evalúa como 999.950, que se redondea efectivamente a 1000.0 cuando se utiliza String.format en Java (en la mayoría de los otros idiomas también). Hench necesita algunos controles adicionales para manejar casos como este.
Para este desafío, se aceptan ambos estilos, 1000.0 kB y 1.0 MB, aunque se prefiere el último estilo.
Pseudocódigo / código de prueba de Java:
public static String bytesToSI(long bytes){ if (bytes < 1000){ return bytes + ".0 B"; } //Without this rounding check: //999950 would be 1000.0 kB instead of 1.0 MB //999950000 would be 1000.0 MB instead of 1.0 GB int p = (int) Math.ceil(Math.log(bytes) / Math.log(1000)); if(bytes/Math.pow(1000, p) < 0.99995){ p--; } //Format return String.format("%.1f %sB", bytes/Math.pow(1000, p), "kMGTPE".charAt(p-1)); }
kB
(tenga en cuenta la minúscula k)999999
y1000000
?160581
exhibe redondeo, entonces debería ser1000.0kB
y1.0MB
?Respuestas:
TI-BASIC, 44
Sería la herramienta adecuada para el trabajo si TI-BASIC tuviera una manipulación de cadena decente (tenía que recurrir a sobrescribir el exponente del número, que se muestra en notación de ingeniería, con la unidad). Como es, se redondea y sale correctamente, pero ni siquiera está cerca de las entradas ganadoras. ¿Quizás un lenguaje de calculadora diferente podría ganar este?
Ingrese el formulario
[number]:[program name]
en la pantalla de inicio.Dados casos de prueba:
fuente
CJam,
3527 bytesGracias Dennis por eliminar 8 bytes.
Esto no se imprime
.0
en el intérprete en línea . Pero como Dennis ha señalado , funciona bien en el intérprete de Java.Explicación
fuente
ri{_e-3XmO_i}g;o]," kMG"='B
(27 bytes)1mO
. Pero este código no funciona para1149999
...ri{_e-3_i}g;1mOo]," kMG"='B
debería.999999
se convierte1000kB
. Al leer la pregunta nuevamente, no estoy seguro de si1000kB
realmente estaría mal.Pyth
2927 bytesDemostración. Arnés de prueba.
Explicación:
fuente
CJam, 28
Pruébalo en línea
Nota: no muestra ".0" con el intérprete en línea, pero sí con el intérprete oficial de Java .
Explicación:
fuente
Python 2 - 76 bytes
Utiliza el Sistema Internacional de Unidades, simplemente porque es más fácil de hacer en tu cabeza;)
fuente
f=1e3
POWERSHELL, 190
uso
fuente
Haskell, 119
Lamentablemente, no pude encontrar un camino más corto en Haskell para asegurar 1 lugar decimal en las carrozas, pero estoy publicando para la posteridad.
Uso:
Versión moderadamente menos golfizada:
fuente
Java, 106 bytes
Este es un método que toma un número y devuelve una cadena.
fuente
1e3
para1000
; puedes convertir esowhile()
afor()
ay usar los puntos y comas libres; y no sé si esto funciona porque parece mostrar todos los dígitos decimales, no solo uno más allá del decimal.Python 2, 127 bytes
Usando la ISU. El fragmento declara una función 'C' que toma el número a convertir como argumento.
Algún código de prueba:
fuente
1e3
lugar de1000.0
JavaScript ( ES6 ), 71
Usar unidades SI: una función que devuelve la cadena solicitada.
Este más corto sigue las reglas, particularmente 3 y 4
Por desgracia, de esta manera, los resultados no coinciden con los ejemplos.
Para que coincida con los ejemplos, aquí hay uno más largo, en mayúsculas especiales para números pequeños (82 bytes)
Ejecute el fragmento para probar (siendo EcmaScript 6, solo Firefox)
Mostrar fragmento de código
fuente
Python, 61 bytes
Llama como
f(999)
. Tenga en cuenta que1e3
es flotante, por lo que funciona tanto con Python 2 como con Python 3.fuente
PHP4.1,
6362 bytesNo es el mejor golf, pero seguramente es bastante corto.
Para usarlo, acceda a través de POST / GET o configure un valor en la SESIÓN, en la tecla
B
.Deje la llave sin
I
configurar!fuente
SpecBAS - 100 bytes
Usando la convención ISU.
Me di cuenta de que tener una variable establecida en 1e3 (que necesita una instrucción LET para asignarla), y luego usar esa variable en el ejercicio, en realidad usaba más caracteres que simplemente codificar el 1e3 donde era necesario.
fuente
Ruby, 128 bytes
Lo hice a lo largo, esto es bastante malo.
Salida
Editar
TB agregada para 39 bytes adicionales
Salida:
fuente
Sed
-r
, 218 + 1Estoy usando unidades SI; Creo que elegir unidades binarias sería una política valiente . ;-)
Reformateado:
Salida
Variaciones
Las reglas parecen implicar redondear al más cercano, pero para la visualización humana, creo que redondear hacia abajo es una alternativa aceptable y ahorra 123 bytes (mejor que el 50%):
La extensión natural a unidades más grandes (aún redondeando hacia abajo, 130 + 1 bytes):
Salida de variación:
fuente
C,
7775Esto usa unidades SI y toma la opción 1000.0kB para redondear.
Código ampliado:
Salida
Variantes
Para obtener unidades binarias, el cambio
1000
a1024
, y añadiri
a la cadena de formato si hay un multiplicador. Para evitar el redondeo de 4 dígitos, compare en>=.95
lugar de>=1
. Para aceptar unidades más grandes, extienda lau
cadena. Combinando todas estas opciones, obtenemos:Salida variante
Programa de prueba
Pase cualquier número de entradas como argumentos de línea de comandos:
fuente
Ruby, 91 bytes
Probablemente podría hacerlo un poco mejor si me esforzara más, pero esto es lo que tengo hasta ahora.
fuente
1024.
lugar de1024.0
.Javascript ES5, 69 bytes
Esto utiliza una forma diferente de alcanzar el objetivo final que la respuesta de @ edc65 .
En realidad, esto está bastante cerca de mi respuesta PHP .
Simplemente ejecute el fragmento de pila o péguelo en su consola.
fuente
Rubí, 90 bytes.
fuente