Manusia membenci sapi dan programmer membenci manusia - mari kita hubungkan mereka!

8

Latar Belakang

Tugasnya sederhana tetapi setiap programmer telah mengimplementasikannya setidaknya sekali. Stackoverflow memiliki banyak sampel, tetapi apakah mereka cukup pendek untuk menang?

Cerita masalah

Anda adalah programmer pemarah yang diberi tugas menerapkan input ukuran file untuk pengguna. Karena pengguna tidak menggunakan byte, setiap orang hanya akan memasukkan "1M", "1K", "3G", "3,14M" - tetapi Anda membutuhkan byte! Jadi, Anda menulis program untuk melakukan konversi.

Kemudian manajer Anda memberi Anda lusinan laporan pengguna dengan keluhan tentang sejumlah besar aneh dalam ukuran input file. Sepertinya Anda perlu mengkode konversi balik juga.

Apa yang perlu kamu lakukan?

Inilah triknya: Anda harus menerapkan konversi dua arah dalam satu bagian kode. Dua fungsi terpisah digunakan sesuai kebutuhan? Nah, itu terlalu sederhana - mari kita buat, pendek!

Untuk keperluan tantangan ini, "kilobyte" berarti 1024 byte, "megabyte" berarti 1024 * 1024 = 1048576 byte, dan "gigabytle" berarti 1024 * 1024 * 1024 = 1073741824 byte.

Uji data

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

Aturan

  • Nilai tes tidak akan melebihi 2 * 1024 * 1024 * 1024 atau 2G
  • Postfix berikut digunakan oleh pengguna: K untuk kilobyte, M untuk megabyte, G untuk gigabyte
  • Kode tidak diperlukan untuk bekerja dengan angka negatif
  • Jangan gunakan perpustakaan eksternal (mis. BCMathDalam PHP) selain yang dibundel (mis. math.h)
  • Celah standar tidak diijinkan
  • Kode seharusnya tidak menghasilkan apa pun di stderr
  • Program Anda dapat mengambil input dan menghasilkan output menggunakan metode standar
kiler129
sumber
1
Biasanya program tidak mengambil input dan output variabel ...
TheDoctor
7
1024 bukan satu kilobyte (k); itu adalah kibibyte (KiB). Demikian pula, 1048576 bukan megabyte (M); itu adalah mebibyte (MiB).
Todd Lehman
5
Meskipun mungkin tidak berguna untuk kehidupan nyata, tantangan ini ditentukan dengan baik dan tugas yang tidak sepele. Saya pikir itu hanya perlu sedikit polesan pada kata-kata. FYI, @ kiler129, untuk tantangan di masa depan Anda bisa mendapatkan semua ketegaran ini bekerja sebelumnya dengan memposting di Sandbox terlebih dahulu.
DLosc
2
Kemungkinan rangkap: codegolf.stackexchange.com/questions/51928/…
Digital Trauma
4
berapa banyak angka desimal yang Anda inginkan? 1024 = 1k, 1025 = 1,0 k atau 1k? 1526398 = 1.45568656921 M ....
don bright

Jawaban:

4

Python 2, 204 190 byte

Ini adalah codegolf pertama saya.

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
sumber
1

Pip, 60 byte

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

Mengambil input dari baris perintah (ditugaskan ke avariabel) dan output ke stdout.

Versi tidak disatukan:

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)}

Algoritma:

  • Untuk idari 1 hingga 3:
    • Jika a >= 1024, ini adalah nilai byte yang perlu dikonversi ke unit yang lebih besar:
      • Bagi adengan 1024
      • Setel xmenjadi nilai saat ini yang adisatukan dengan unit saat ini
  • Jika xdiatur oleh langkah sebelumnya, keluarkan. Jika tidak, akurang dari 1024 (dengan kemungkinan akhiran unit), jadi:
    • Lakukan penggantian regex dengan fungsi aktif ajika memiliki salah satu KMGdi bagian akhir: terjemahkan surat ke kekuatan yang sesuai 1024 dan gandakan jumlahnya dengan hasilnya.
    • Untuk nilai kurang dari 1024 tanpa akhiran, ini membuat nilai tidak berubah.
DLosc
sumber
1

JavaScript, 144 106 byte

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)))

Ini pasti bisa dipersingkat, dan akan dilakukan nanti. Hanya ingin mendapatkan sesuatu yang jelek di sana;)

Mwr247
sumber
0

Python2 199 byte

ini konyol tapi berhasil (mengabaikan pertanyaan presisi desimal) selama Anda memiliki puluhan gigabytes RAM. jangan jalankan sebaliknya, mesin Anda mungkin membeku dan terkunci. Hal pertama yang dilakukannya adalah mengalokasikan bilangan bulat 2gigabyte.

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)]
jangan cerah
sumber
0

C 206 183 byte

Singkirkan sebanyak yang saya bisa.

#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);}

Keluaran

Input: 1023
Output: 1023.0

Input: 1M
Output: 1048576.0

Input: 1048576
Output: 1.0M

Penjelasan

#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
sumber