Menschen hassen Kriegsgefangene und Programmierer hassen Menschen - lassen Sie uns sie verbinden!

8

Hintergrund

Die Aufgabe ist einfach, aber jeder Programmierer hat sie mindestens einmal implementiert. Stackoverflow hat viele Samples, aber sind sie kurz genug, um zu gewinnen?

Problemgeschichte

Sie sind ein mürrischer Programmierer, der die Aufgabe erhalten hat, die Eingabe der Dateigröße für die Benutzer zu implementieren. Da Benutzer keine Bytes verwenden, geben alle nur "1M", "1K", "3G", "3.14M" ein - aber Sie benötigen Bytes! Sie schreiben also ein Programm für die Konvertierung.

Dann übergibt Ihnen Ihr Manager Dutzende von Benutzerberichten mit Beschwerden über seltsam große Zahlen bei der Eingabe der Dateigröße. Es scheint, dass Sie auch die umgekehrte Konvertierung codieren müssen.

Was musst du tun?

Hier ist der Trick: Sie sollten die bidirektionale Konvertierung in einem einzigen Code implementieren. Zwei separate Funktionen nach Bedarf verwendet? Nein, das ist zu einfach - machen wir eins, kurz!

Für die Zwecke dieser Herausforderung bedeutet "Kilobyte" 1024 Bytes, "Megabyte" 1024 * 1024 = 1048576 Bytes und "Gigabyte" 1024 * 1024 * 1024 = 1073741824 Bytes.

Testdaten

Input   -> Output  
5       -> 5  
1023    -> 1023  
1024    -> 1K  
1K      -> 1024  
1.5K    -> 1536  
1536    -> 1.5K  
1048576 -> 1M  
1M      -> 1048576  

Regeln

  • Der Testwert wird 2 * 1024 * 1024 * 1024 oder 2G nicht überschreiten
  • Die folgenden Postfixes werden von Benutzern verwendet: K für Kilobyte, M für Megabyte, G für Gigabyte
  • Code ist nicht erforderlich, um mit negativen Zahlen zu arbeiten
  • Verwenden Sie keine externen Bibliotheken (zB BCMathin PHP) neben gebündelt diejenigen (zB math.h)
  • Standardlücken sind nicht zulässig
  • Code sollte auf stderr nichts erzeugen
  • Ihr Programm kann nehmen Eingabe und erzeugen Ausgang mit Standardmethoden
kiler129
quelle
1
Normalerweise nehmen Programme keine variablen Ein- und Ausgaben ...
TheDoctor
7
1024 ist kein Kilobyte (k); Es ist ein Kibibyte (KiB). In ähnlicher Weise ist 1048576 kein Megabyte (M); Es ist ein Mebibyte (MiB).
Todd Lehman
5
Obwohl diese Herausforderung für das wirkliche Leben vielleicht nicht nützlich ist, ist sie genau festgelegt und eine nicht triviale Aufgabe. Ich denke, es braucht nur etwas mehr Glanz in der Formulierung. Zu Ihrer Information, @ kiler129, für zukünftige Herausforderungen können Sie all diese Probleme im Voraus lösen, indem Sie sie zuerst in der Sandbox veröffentlichen .
DLosc
2
Mögliches Duplikat: codegolf.stackexchange.com/questions/51928/…
Digitales Trauma
4
Wie viele Dezimalstellen möchten Sie? 1024 = 1 k, 1025 = 1,0 k oder 1 k? 1526398 = 1.45568656921 M ....
Don Bright

Antworten:

4

Python 2, 204 190 Bytes

Dies ist mein erster Codegolf.

s=raw_input()
p=' KMG'
if s[-1]<='9':
 e=0;r=int(s)
 while r>=1024:r/=1024.0;e+=1
else:
 e=p.index(s[-1]);r=eval(s[:-1])
 while e>0:r*=1024;e-=1
print(`r`if r%1!=0 else`int(r)`)+p[e].strip()
TFeld
quelle
1

Pip, 60 Bytes

l:" KMG"Fi1,4Ia>=Y1024x:(a/:y).l@ix|aR`.+([KMG])`_*y**(l@?B)

Übernimmt Eingaben über die Befehlszeile (der aVariablen zugewiesen ) und gibt sie an stdout aus.

Ungolfed Version:

l : " KMG"
Y 1024
F i 1,4
 I a>=y {
  a /: y
  x : a . l@i
 }
x | a R `.+([KMG])` {a*y**(l@?b)}

Algorithmus:

  • Für ivon 1 bis 3:
    • Wenn a >= 1024dies ein Bytewert ist, der in eine größere Einheit konvertiert werden muss:
      • Teilen Sie adurch 1024
      • Stellen Sie xden aktuellen Wert ein, der amit der aktuellen Einheit verknüpft ist
  • Wenn dies xim vorherigen Schritt festgelegt wurde, geben Sie es aus. Ansonsten awar weniger als 1024 (mit einem möglichen Einheitensuffix), also:
    • Führen Sie einen Regex-Ersatz mit einer Funktion durch, awenn KMGam Ende eine der folgenden steht: Übersetzen Sie den Buchstaben in die entsprechende Potenz von 1024 und multiplizieren Sie die Zahl mit dem Ergebnis.
    • Bei Werten unter 1024 ohne Suffix bleibt der Wert unverändert.
DLosc
quelle
1

JavaScript, 144 106 Bytes

n=>((G=(M=(K=2<<9)<<10)<<10),+n>0?n<K?n:n<M?n/K+'K':n<G?n/M+'M':n/G+'G':eval(n.replace(/[KMG]/,m=>'*'+m)))

Dies kann definitiv verkürzt werden und wird es später tun. Ich wollte nur etwas Hässliches da draußen haben;)

Mwr247
quelle
0

Python2 199 Bytes

Das ist albern, aber es funktioniert (ohne die Frage nach der Dezimalgenauigkeit), solange Sie Dutzende Gigabyte RAM haben. Führen Sie es nicht anders aus, da Ihr Computer möglicherweise einfriert und abstürzt. Als erstes wird ein 2-Gigabyte-Array von Ganzzahlen zugewiesen.

n,bn={'K':2**10,'M':2**20,'G':2**30},range(2**30+1)
for i in bn:
 for j in 'KMG':
  if i>=n[j]: bn[i]=str(float(i/n[j]))+j 
def f(i):
 if i[-1] in 'KMG': return n[i[-1]]*float(i[:-1])
 return bn[int(i)]
nicht hell
quelle
0

C. 206 183 Bytes

Ich habe so viel wie möglich losgeworden.

#include<stdlib.h>
main(y,z)char**z;{char*i="KMG";float f=atof(*++z);while(*++*z)y=**z;if(y>57){do f*=1024;while(y!=*i++);y=0;}else while(f>1023)y=*i++,f/=1024;printf("%.1lf%c",f,y);}

Ausgabe

Input: 1023
Output: 1023.0

Input: 1M
Output: 1048576.0

Input: 1048576
Output: 1.0M

Erläuterung

#include <stdlib.h> //needed for atof()
main(y,z)char **z; //y will hold the size indicator
{
    char *i="KMG";//holds the characters for the size indicators
    float f=atof(*++z); //get the number from the string

    while(*++*z) //loops through the string
        y=**z;
    if(y>57) //57 is ASCII for 9
    {
        do f*=1024;
        while(y!=*i++); //loop through until we hit the correct size
        y=0;
    }
    else
        while(f>1023) //loop through until number is less than 1024
            y=*i++,f/=1024; 
    printf("%.1lf%c",f,y); //print number and size character 
}
Chris Loonam
quelle