Desafio e origem
No Stack Overflow, uma pergunta popular é: Como converter o tamanho de bytes em formato legível por humanos em java? A resposta mais votada tem um método bastante legal para fazer isso, mas esse é um codegolf e podemos fazer melhor, não podemos?
Seu desafio é escrever um método ou programa que cubra o número especificado de bytes no formato legível humano correto e imprima o resultado no padrão do seu idioma. *
* Veja as regras para mais esclarecimentos!
Entrada
A entrada sempre será um número positivo de bytes com um máximo de (2 ^ 31) -1.
Resultado
Você pode escolher se prefere o Sistema Internacional de Unidades ou a notação binária como saída (a notação SI provavelmente economiza alguns bytes).
SI: B, kB, MB, GB
Binary: B, KiB, MiB, GiB
Nota: Unidades superiores a GB ou GiB não são possíveis devido ao intervalo de entrada restrito.
Saída de exemplo
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
Binário:
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
Regras
- Funções internas para formatação de bytes não são permitidas!
- A saída deve sempre estar no mesmo padrão de notação; você não pode misturar SI ou binário;
- A saída deve sempre estar na maior unidade possível, onde o número resultante ainda é maior ou igual a um;
- A saída sempre deve ter um número decimal, mas você pode optar por imprimir um número inteiro quando a saída resultante estiver em bytes (B);
- Você pode escolher se deseja adicionar um espaço, tabulação ou nada entre o número e a unidade;
- A entrada é recebida via STDIN ou parâmetros de função;
- A saída é impressa no console ou retornada como string (ou contêiner de caractere semelhante);
- Isso é código de golfe, então a resposta mais curta vence. Diverta-se!
Edit: Esclarecimentos ainda mais
Alguns números têm comportamentos interessantes de arredondamento, como o número 999950. A maioria das implementações de código retornaria 1000,0 kB em vez de 1,0 MB. Por quê? Porque 999950/1000 é avaliado para 999.950, que é efetivamente arredondado para 1000.0 ao usar String.format em Java (na maioria das outras linguagens também). Hench algumas verificações extras são necessárias para lidar com casos como este.
Para esse desafio, os dois estilos são aceitos 1000,0 kB e 1,0 MB, embora o último estilo seja o preferido.
Pseudo-código / código de teste 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
(note a minúscula k)999999
e1000000
?160581
exibe arredondamento, então deveria ser1000.0kB
e1.0MB
?Respostas:
TI-BASIC, 44
Seria a ferramenta certa para o trabalho se o TI-BASIC tivesse uma manipulação decente de cadeias pela metade (eu tive que recorrer à substituição do expoente do número, exibido em notação de engenharia, com a unidade). Como é, arredonda e produz corretamente, mas não chega nem perto de ganhar entradas. Talvez um idioma diferente da calculadora possa ganhar este?
Entrada no formulário
[number]:[program name]
na tela inicial.Casos de teste dados:
fonte
CJam,
3527 bytesObrigado Dennis por remover 8 bytes.
Isso não é impresso
.0
no intérprete online . Mas como Dennis apontou , funciona bem no interpretador Java.Explicação
fonte
ri{_e-3XmO_i}g;o]," kMG"='B
(27 bytes)1mO
. Mas este código não funciona para1149999
...ri{_e-3_i}g;1mOo]," kMG"='B
devemos.999999
torna-se1000kB
. Lendo a pergunta novamente, não tenho certeza se1000kB
realmente estaria errado.Pitão,
2927 bytesDemonstração. Equipamento de teste.
Explicação:
fonte
CJam, 28
Experimente online
Nota: não mostra ".0" com o intérprete online, mas o faz com o interpretador java oficial .
Explicação:
fonte
Python 2 - 76 bytes
Usa o Sistema Internacional de Unidades, simplesmente porque é mais fácil de fazer na sua cabeça;)
fonte
f=1e3
POWERSHELL, 190
uso
fonte
Haskell, 119
Infelizmente, não consegui encontrar uma maneira mais curta em Haskell para garantir uma casa decimal em carros alegóricos, mas estou postando para a posteridade.
Uso:
Versão menos golfe:
fonte
Java, 106 bytes
Esse é um método que pega um número e retorna uma string.
fonte
1e3
-lo1000
; você pode convertê-lowhile()
em afor()
e usar o ponto e vírgula livre; e não sei se isso funciona porque parece exibir todos os dígitos decimais, não apenas um após a casa decimal.Python 2, 127 bytes
Usando o ISU. O trecho declara uma função 'C' que leva o número a ser convertido como argumento.
Algum código de teste:
fonte
1e3
vez de1000.0
JavaScript ( ES6 ), 71
Usando unidades SI - Uma função retornando a sequência solicitada.
Este menor segue as regras, particularmente 3 e 4
Infelizmente, desta forma, os resultados não correspondem aos exemplos.
Para corresponder aos exemplos, aqui está um mais longo, especial para números pequenos (82 bytes)
Execute o snippet para testar (sendo apenas EcmaScript 6, Firefox)
Mostrar snippet de código
fonte
Python, 61 bytes
Ligue como
f(999)
. Observe que1e3
é um flutuador, portanto, isso funciona com o Python 2 e o Python 3.fonte
PHP4.1,
63.62 bytesNão é o melhor golfe, mas certamente é bastante curto.
Para usá-lo, acesse através de POST / GET ou defina um valor em SESSION, na tecla
B
.Deixe a chave
I
desabilitada!fonte
SpecBAS - 100 bytes
Usando a convenção ISU.
Percebi que ter uma variável definida como 1e3 (que precisa de uma instrução LET para atribuí-la) e, em seguida, usar essa variável na elaboração, na verdade, usava mais caracteres do que apenas codificar o 1e3 onde era necessário.
fonte
Ruby, 128 bytes
Eu fiz o longo caminho, isso é muito ruim.
Resultado
Editar
Adicionada TB por 39 bytes extras
Resultado:
fonte
Sed
-r
, 218 + 1Eu estou usando unidades SI; Eu acho que escolher unidades binárias seria uma política corajosa . ;-)
Reformatado:
Resultado
Variações
As regras parecem implicar arredondar para o mais próximo, mas para exibição humana, acredito que o arredondamento é uma alternativa aceitável e salva 123 bytes (melhor que 50%):
A extensão natural para unidades maiores (ainda arredondando para baixo, 130 + 1 bytes):
Saída de variação:
fonte
C,
7775Isso usa unidades SI e aceita a opção 1000.0kB para arredondamento.
Código expandido:
Resultado
Variantes
Para obter unidades binárias, altere
1000
para1024
e adicionei
à string de formato, se houver um multiplicador. Para evitar o arredondamento de quatro dígitos, compare em>=.95
vez de>=1
. Para aceitar unidades maiores, estenda au
corda. Combinando todas essas opções, obtemos:Saída variante
Programa de teste
Passe qualquer número de entradas como argumentos da linha de comandos:
fonte
Ruby, 91 bytes
Eu provavelmente poderia me sair um pouco melhor se tentasse mais, mas aqui está o que tenho até agora.
fonte
1024.
vez de1024.0
.Javascript ES5, 69 bytes
Isso usa uma maneira diferente de alcançar a meta final que a resposta da @ edc65 .
Na verdade, isso é bem parecido com a minha resposta PHP .
Simplesmente execute o snippet da pilha ou cole-o no seu console.
fonte
Ruby, 90 bytes
fonte