Herausforderung und Herkunft
Bei Stack Overflow lautet eine häufig gestellte Frage: Wie konvertiert man Bytes in ein für Menschen lesbares Format in Java? Die am häufigsten gewählte Antwort hat eine ganz gute Methode, um dies zu tun, aber das ist Codegolf und wir können es besser machen, nicht wahr?
Ihre Herausforderung besteht darin, eine Methode oder ein Programm zu schreiben, die bzw. das die angegebene Anzahl von Bytes in das korrekte, für Menschen lesbare Format konvertiert und das Ergebnis gemäß dem Standard in Ihrer Sprache ausgibt. *
* Siehe die Regeln für mehr Klarheit!
Eingang
Die Eingabe ist immer eine positive Anzahl von Bytes mit einem Maximum von (2 ^ 31) -1.
Ausgabe
Sie können wählen, ob Sie das Internationale Einheitensystem oder die Binärnotation als Ausgabe bevorzugen (die SI-Notation spart Ihnen wahrscheinlich einige Bytes).
SI: B, kB, MB, GB
Binary: B, KiB, MiB, GiB
Hinweis: Höhere Einheiten als GB oder GiB sind aufgrund des eingeschränkten Eingangsbereichs nicht möglich.
Beispielausgabe
Internationales Einheitensystem:
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är:
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
Regeln
- Eingebaute Funktionen zur Byte-Formatierung sind nicht erlaubt!
- Die Ausgabe sollte immer im selben Notationsstandard sein, Sie dürfen SI oder Binär nicht mischen;
- Die Ausgabe sollte immer in der größtmöglichen Einheit erfolgen, wobei die resultierende Zahl immer noch höher oder gleich eins ist.
- Die Ausgabe sollte immer eine Dezimalzahl haben. Sie können jedoch auch eine Ganzzahl ausgeben, wenn die resultierende Ausgabe in Byte (B) vorliegt.
- Sie können wählen, ob Sie ein Leerzeichen, einen Tabulator oder nichts zwischen der Nummer und der Einheit einfügen möchten.
- Die Eingabe erfolgt über STDIN oder Funktionsparameter;
- Die Ausgabe wird auf die Konsole gedruckt oder als Zeichenfolge (oder ähnlicher Zeichencontainer) zurückgegeben.
- Das ist Codegolf, also gewinnt die kürzeste Antwort. Habe Spaß!
Edit: Noch mehr Klarheit
Einige Zahlen haben ein interessantes Rundungsverhalten wie die Zahl 999950. Die meisten Codeimplementierungen würden 1000,0 kB anstelle von 1,0 MB zurückgeben. Warum? Denn 999950/1000 ergibt 999.950, was bei Verwendung von String.format in Java (auch in den meisten anderen Sprachen) effektiv auf 1000.0 gerundet wird. Um solche Fälle zu bearbeiten, sind einige zusätzliche Überprüfungen erforderlich.
Für diese Herausforderung werden beide Stile mit 1000,0 kB und 1,0 MB akzeptiert, obwohl der letzte Stil bevorzugt wird.
Pseudocode / Java-Testcode:
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
(beachten Sie den Kleinbuchstaben k)999999
und1000000
?160581
Ausstellungsrundung, so soll es sein1000.0kB
und1.0MB
?Antworten:
TI-BASIC, 44
Wäre das richtige Werkzeug für den Job, wenn TI-BASIC eine halbwegs vernünftige String-Manipulation hätte (ich musste den Exponenten der Zahl, der in technischer Notation angezeigt wird, mit der Einheit überschreiben). Wie es ist, rundet es und gibt es korrekt aus, aber es ist noch nicht einmal nah an dem Gewinn von Einträgen. Vielleicht könnte eine andere Rechnersprache diese gewinnen?
Eingabe in das Formular
[number]:[program name]
auf dem Homescreen.Gegebene Testfälle:
quelle
CJam,
3527 BytesDanke Dennis für das Entfernen von 8 Bytes.
Dies wird
.0
in der nicht gedruckt Online-Interpreter . Aber wie Dennis betont hat , funktioniert es im Java-Interpreter einwandfrei.Erläuterung
quelle
ri{_e-3XmO_i}g;o]," kMG"='B
(27 Bytes)1mO
. Aber dieser Code funktioniert nicht für1149999
...ri{_e-3_i}g;1mOo]," kMG"='B
sollte.999999
wird1000kB
. Wenn ich die Frage noch einmal lese, bin ich mir nicht sicher, ob1000kB
es wirklich falsch wäre.Pyth,
2927 BytesDemonstration. Testgeschirr.
Erläuterung:
quelle
CJam, 28
Probieren Sie es online aus
Hinweis: Beim Online-Interpreter wird ".0" nicht angezeigt, beim offiziellen Java-Interpreter jedoch .
Erläuterung:
quelle
Python 2 - 76 Bytes
Verwendet das Internationale Einheitensystem, einfach weil es einfacher ist, es im Kopf zu tun;)
quelle
f=1e3
POWERSHELL, 190
Verwendung
quelle
Haskell, 119
Leider konnte ich in Haskell keinen kürzeren Weg finden, um eine Dezimalstelle in Floats zu erhalten, aber ich poste für die Nachwelt.
Verwendung:
Mäßig weniger Golf Version:
quelle
Java, 106 Bytes
Dies ist eine Methode, die eine Zahl nimmt und eine Zeichenfolge zurückgibt.
quelle
1e3
für verwenden1000
; Sie können daswhile()
in ein konvertierenfor()
und die freien Semikolons verwenden; und ich weiß nicht, ob dies funktioniert, weil es scheint, alle Dezimalstellen anzuzeigen, nicht nur eine nach der Dezimalstelle.Python 2, 127 Bytes
Verwenden der ISU. Das Snippet deklariert eine Funktion 'C', die die zu konvertierende Zahl als Argument verwendet.
Ein Testcode:
quelle
1e3
anstelle von1000.0
JavaScript ( ES6 ), 71
SI-Einheiten verwenden - Eine Funktion, die die angeforderte Zeichenfolge zurückgibt.
Diese kürzere folgt den Regeln, insbesondere 3 und 4
Auf diese Weise stimmen die Ergebnisse leider nicht mit den Beispielen überein.
Um den Beispielen zu entsprechen, ist hier ein längeres, spezielles Gehäuse für kleine Zahlen (82 Bytes).
Führen Sie das zu testende Snippet aus (nur in EcmaScript 6, Firefox)
Code-Snippet anzeigen
quelle
Python, 61 Bytes
Rufen Sie gerne an
f(999)
. Beachten Sie, dass dies1e3
ein Float ist, sodass dies sowohl mit Python 2 als auch mit Python 3 funktioniert.quelle
PHP4.1,
6362 BytesNicht das beste Golfspiel, aber sicherlich recht kurz.
Um es zu benutzen, greifen Sie über POST / GET zu oder setzen Sie einen Wert in der SESSION auf den Schlüssel
B
.Lass den Schlüssel frei
I
!quelle
SpecBAS - 100 Bytes
Verwendung der ISU-Konvention.
Ich erkannte, dass eine Variable, die auf 1e3 gesetzt war (für deren Zuweisung eine LET-Anweisung erforderlich ist), mehr Zeichen verwendete, als nur die 1e3 dort zu codieren, wo sie benötigt wurde.
quelle
Ruby, 128 Bytes
Ich habe es lange gemacht, das ist ziemlich schlimm.
Ausgabe
Bearbeiten
TB für zusätzliche 39 Bytes hinzugefügt
Ausgabe:
quelle
Sed
-r
, 218 + 1Ich verwende SI-Einheiten. Ich denke, dass die Wahl von binären Einheiten eine mutige Politik wäre . ;-)
Neuformatiert:
Ausgabe
Variationen
Die Regeln scheinen das Runden auf die nächste Stelle zu implizieren, aber für die menschliche Darstellung halte ich das Runden für eine akzeptable Alternative und spart 123 Bytes (besser als 50%):
Die natürliche Erweiterung auf größere Einheiten (noch aufgerundet, 130 + 1 Byte):
Variationsausgabe:
quelle
C
77,75Dies verwendet SI-Einheiten und verwendet die 1000.0kB-Option zum Runden.
Erweiterter Code:
Ausgabe
Varianten
Um binäre Einheiten zu erhalten, ändern Sie diese
1000
in1024
und ergänzen Siei
die Formatzeichenfolge, wenn ein Multiplikator vorhanden ist. Vergleichen Sie>=.95
statt , um eine Rundung mit 4 Stellen zu vermeiden>=1
. Wenn Sie größere Einheiten akzeptieren möchten, verlängern Sie dieu
Zeichenfolge. Durch die Kombination all dieser Optionen erhalten wir:Variantenausgabe
Testprogramm
Übergeben Sie eine beliebige Anzahl von Eingaben als Befehlszeilenargumente:
quelle
Ruby, 91 Bytes
Ich könnte es wahrscheinlich ein bisschen besser machen, wenn ich mich mehr anstrengen würde, aber hier ist, was ich bisher habe.
quelle
1024.
anstelle von1024.0
.Javascript ES5, 69 Bytes
Dies verwendet einen anderen Weg, um das Endziel der Antwort von @ edc65 zu erreichen .
Eigentlich ist das ziemlich nah an meiner PHP-Antwort .
Führen Sie einfach das Stack-Snippet aus oder fügen Sie es in Ihre Konsole ein.
quelle
Ruby, 90 Bytes
quelle