Con người ghét pows ​​và lập trình viên ghét con người - hãy kết nối chúng!


8

Lý lịch

Nhiệm vụ rất đơn giản nhưng mọi lập trình viên đã thực hiện nó ít nhất một lần. Stackoverflow có rất nhiều mẫu, nhưng chúng có đủ ngắn để giành chiến thắng không?

Vấn đề

Bạn là một lập trình viên cục cằn, người được giao nhiệm vụ triển khai đầu vào kích thước tệp cho người dùng. Vì người dùng không sử dụng byte nên mọi người sẽ chỉ nhập "1M", "1K", "3G", "3.14M" - nhưng bạn cần byte! Vì vậy, bạn viết một chương trình để thực hiện chuyển đổi.

Sau đó, người quản lý của bạn cung cấp cho bạn hàng tá báo cáo người dùng với các khiếu nại về số lượng lớn kỳ lạ trong kích thước tệp. Có vẻ như bạn cũng sẽ cần mã chuyển đổi ngược lại.

Bạn cần làm gì?

Đây là mẹo: bạn nên thực hiện chuyển đổi hai chiều trong một đoạn mã. Hai chức năng riêng biệt được sử dụng khi cần thiết? Không, điều đó quá đơn giản - hãy tạo một, ngắn một!

Đối với mục đích của thử thách này, "kilobyte" có nghĩa là 1024 byte, "megabyte" có nghĩa là 1024 * 1024 = 1048576 byte và "gigabyussy" có nghĩa là 1024 * 1024 * 1024 = 1073741824 byte.

Dữ liệu kiểm tra

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

Quy tắc

  • Giá trị thử nghiệm sẽ không vượt quá 2 * 1024 * 1024 * 1024 hoặc 2G
  • Các hậu tố sau đây được người dùng sử dụng: K cho kilobyte, M cho megabyte, G cho gigabyte
  • Mã không bắt buộc phải làm việc với số âm
  • Không sử dụng bất kỳ thư viện bên ngoài nào (ví dụ: BCMathtrong PHP) bên cạnh các thư viện được đóng gói (ví dụ math.h)
  • Các sơ hở tiêu chuẩn không được phép
  • Mã không nên sản xuất bất cứ thứ gì trên stderr
  • Chương trình của bạn có thể lấy đầu vào và tạo đầu ra bằng các phương thức tiêu chuẩn

1
Thông thường các chương trình không lấy đầu vào và đầu ra thay đổi ...
TheDoctor

7
1024 không phải là kilobyte (k); đó là một kibibyte (KiB). Tương tự, 1048576 không phải là megabyte (M); đó là một mebibyte (MiB).
Todd Lehman

5
Mặc dù có lẽ không hữu ích cho cuộc sống thực, thử thách này được chỉ định rõ và là một nhiệm vụ không hề nhỏ. Tôi nghĩ rằng nó chỉ cần thêm một chút đánh bóng về từ ngữ. FYI, @ kiler129, cho những thách thức trong tương lai, bạn có thể giải quyết tất cả các kink này trước thời hạn bằng cách đăng lên Sandbox trước.
DLosc


4
bạn muốn bao nhiêu chữ số thập phân? 1024 = 1k, 1025 = 1.0 k hay 1k? 1526398 = 1.45568656921 M ....
don sáng

Câu trả lời:


4

Python 2, 204 190 byte

Đây là codegolf đầu tiên của tôi.

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

1

Pip, 60 byte

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

Lấy đầu vào từ dòng lệnh (được gán cho abiến) và đầu ra cho thiết bị xuất chuẩn.

Phiên bản bị đánh cắp:

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

Thuật toán:

  • Cho itừ 1 đến 3:
    • Nếu a >= 1024, đây là một giá trị byte cần được chuyển đổi thành một đơn vị lớn hơn:
      • Chia acho 1024
      • Đặt xthành giá trị hiện tại được anối với đơn vị hiện tại
  • Nếu xđược đặt bởi bước trước, hãy xuất nó. Mặt khác, anhỏ hơn 1024 (với hậu tố đơn vị có thể), vì vậy:
    • Thực hiện thay thế regex bằng một hàm trên anếu nó có một trong số KMGcuối: dịch chữ cái thành lũy thừa 1024 và nhân số đó với kết quả.
    • Đối với các giá trị nhỏ hơn 1024 không có hậu tố, giá trị này sẽ không thay đổi.

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

Điều này chắc chắn có thể được rút ngắn, và sẽ làm sau. Chỉ muốn nhận được một cái gì đó xấu xí ngoài đó;)


0

Python2 199 byte

Điều này thật ngớ ngẩn nhưng nó hoạt động (bỏ qua câu hỏi chính xác thập phân) miễn là bạn có hàng tá GB RAM. Không chạy nó nếu không, máy của bạn có thể đóng băng và bị khóa. Điều đầu tiên nó làm là phân bổ một mảng số nguyên 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)]

0

C 206 183 byte

Loại bỏ càng nhiều càng tốt.

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

Đầu ra

Input: 1023
Output: 1023.0

Input: 1M
Output: 1048576.0

Input: 1048576
Output: 1.0M

Giải trình

#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 
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.