Chuyển đổi giữa các tiền tố SI


8

Giới thiệu

Hệ thống đơn vị quốc tế là một hệ thống đo lường trên toàn thế giới, ngoại trừ một số quốc gia bao gồm cả Hoa Kỳ . Hệ thống SI (hoặc hệ thống số liệu) dựa trên sức mạnh của mười, được liệt kê dưới đây (lưu ý rằng đây là bảng không đầy đủ):

femto(f) pico(p) nano(n) micro(μ) milli(m) centi(c) (base unit) hecto(h) kilo(k) mega(M) giga(G) tera(T) peta(P)
10^-15   10^-12  10^-9   10^-6    10^-3    10^-2    10^0        10^2     10^3    10^6    10^9    10^12   10^15

Công việc của bạn sẽ là thực hiện một trong những biện pháp này và chuyển đổi nó thành một biện pháp khác.

Đầu vào

Đầu vào sẽ là một số thập phân 10^-16 < x < 2^31 - 1, một tiền tố SI, một chữ cái đại diện cho một số lượng, một tiền tố SI khác để chuyển đổi và cùng một chữ số lượng. Đầu vào sẽ ở định dạng 1234.56 mC to TCvà sẽ luôn khớp với biểu thức chính quy ^\d+(\.\d+)? [fpnμmchkMGTP](?'letter'[a-zA-Z]) to [fpnμmchkMGTP](?P=letter)$. Bạn sẽ không bao giờ phải chuyển đổi sang / từ đơn vị cơ sở ( 10^0)

Đầu ra

Đầu ra sẽ có cùng số với đầu vào, chỉ cần chuyển đổi thành tiền tố SI mới. Cụ thể, chương trình nên chuyển đổi số từ SI prefix 1sang SI prefix 2trong đầu vào. Ví dụ:

Input: 1 nm to μm
Output: 0.001

Input: 82 kC to cC
Output: 8200000

Input: 6.54 MK to hK
Output: 65400

Input: 2000 MB to GB
Output: 2

Đây là , vì vậy mã ngắn nhất tính bằng byte sẽ thắng!


1
Một điều nữa, khi tạo một số lớn / nhỏ theo cách này, đầu ra phải là gì? ví dụ1 PB to fB
FryAmTheEggman

@FryAmTheEggman bạn có thể cho rằng đầu vào sẽ không bao giờ tạo ra đầu ra lớn hơn / nhỏ hơn phạm vi chữ số mà ngôn ngữ của bạn có thể xử lý (tôi nghĩ đó là những gì bạn đang hỏi).
GamrCorps

Chúng ta nên sử dụng U+00B5 MICRO SIGNhay U+03BC GREEK SMALL LETTER MU? Chúng ta có thể chọn một hoặc chúng ta phải hỗ trợ một hoặc cả hai?
PurkkaKoodari

@ Pietu1998 một trong hai là tốt.
GamrCorps

Chúng ta có được phép xuất số dấu phẩy động ngay cả khi kết quả là số nguyên không?
PurkkaKoodari

Câu trả lời:


1

Bình thường, 46 44 byte

Chương trình giả định rằng ký tự µ( U+00B5 MICRO SIGN) được sử dụng cho dấu hiệu vi mô. Trên Windows, đây là những gì bạn nhận được bằng cách nhấn Alt Gr+ M.

Mã nguồn chứa một số không thể in được, vì vậy đây là một xxdkết xuất hex có thể đảo ngược .

0000000: 2a76 684a 637a 645e 542d 466d 406a 4322  *vhJczd^T-Fm@jC"
0000010: 5c72 575d d623 8b9e 53bb 4c09 b275 2233  \rW].#..S.L..u"3
0000020: 3125 7443 6864 3137 2532 744a            1%tChd17%2tJ

Đây là phiên bản thân thiện với bản sao:

*vhJczd^T-Fm@j1057004749883241517573776978549 31%tChd17%2tJ

Bạn có thể thử bản demo hoặc sử dụng bộ thử nghiệm . Nếu các liên kết này không thành công, hãy sử dụng phiên bản thân thiện với bản sao ( bản demo , bộ kiểm tra ).


4

JavaScript (ES7), 113 109 byte

s=>(p=s.split` `)[m={f:-9,p:-6,n:-3,µ:0,m:3,c:4,h:8,k:9,M:12,G:15,T:18,P:21},0]/(10**(m[p[3][0]]-m[p[1][0]]))

Chỉnh sửa: Rõ ràng chúng ta có thể sử dụng µ( U+00B5 MICRO SIGN) cho dấu hiệu vi ngay bây giờ, vì vậy thay thế bằng đó sẽ tiết kiệm một byte.

Để tương thích ES6 (10**(m[p[3][0]]-m[p[1][0]]))có thể được thay thế bằng Math.pow(10,m[p[3][0]]-m[p[1][0]])114 byte.

Giải trình

s=>                                  // s = input string
  (p=s.split` `)                     // p = input parts

    // m = dictionary of SI prefix digit powers of 10
    //     the exact values don't matter as long as they are relative to each other
    [m={f:-9,p:-6,n:-3,µ:0,m:3,c:4,h:8,k:9,M:12,G:15,T:18,P:21},

    0]                               // get the number
      /(10**(m[p[3][0]]-m[p[1][0]])) // get the factor to divide by from the difference
                                     //     between the SI prefix powers of 10

Kiểm tra

Thử nghiệm này sử dụng Math.powthay vì **để các trình duyệt thông thường có thể kiểm tra nó.


3

Ruby (2.2.1), 126 123 byte

r={f:-9,p:-6,n:-3,µ:0,m:3,c:4,h:8,k:9,M:12,G:15,T:18,P:21};p ($*[0].to_r/10**(r[$*[3][0].to_sym]-r[$*[1][0].to_sym])).to_f

Đã lưu 3 byte nhờ user81655

Giải trình

# Hash of prefixes to relative powers
r={f:-9,p:-6,n:-3,µ:0,m:3,c:4,h:8,k:9,M:12,G:15,T:18,P:21};
p (                      # print (inspect)
  $*[0].to_r             # input value
  / 10 ** (              # divided by 10^...
    r[$*[3][0].to_sym]   # first prefix symbol
    -
    r[$*[1][0].to_sym]   # second prefix symbol
  )
).to_f                   # convert to float for proper format on output

Lấy đầu vào từ dòng lệnh, vd ruby si.rb 1 nm to μm

Đây là sân golf đầu tiên của tôi!


1
Bạn có thể lưu 3 byte nếu bạn sử dụng các giá trị {f:-9,p:-6,n:-3,µ:0,m:3,c:4,h:8,k:9,M:12,G:15,T:18,P:21}cho bảng băm. Cũng thay thế μbằng µ( U+00B5) được cho phép và sẽ lưu một byte khác.
dùng81655

@ user81655 lời khuyên tốt, cảm ơn! Hai biểu tượng mu / micro dường như cho cùng một số byte khi tôi wc -c tệp của mình, có ý tưởng nào tại sao không?
Chris

Không vấn đề gì. Tệp của bạn có thể được mã hóa bằng cách sử dụng cái gì đó như UTF-8, phân tách các ký tự trên 127 thành hai byte. Nếu bạn chuyển sang mã hóa một byte như ANSI, nó sẽ xóa byte bổ sung khỏi tệp.
dùng81655

2

Haskell, 143 byte

Gọi s.

import Data.List
s=i.words
i(n:f:_:[t])=read n*10**(x f-x t)
x=j.flip elemIndex"f  p  n  µ  mc   hk  M  G  T  P".head
j(Just n)=fromIntegral n

Tôi thích "f p n µ mc hk M G T P"thủ thuật của bạn rất nhiều. +1
Lynn

Tôi cũng thích thủ thuật này. Mẹo: bạn có thể kết hợp xjvới một mẫu bảo vệ để : x y|Just n<-elemIndex(y!!0)"f p n µ mc hk M G T P"=fromIntegral n.
nimi

2

CJam, 67 byte

lS%:I0=dA"fpnµmchkMGTP"[-7 -4WY5 6ABEHK23]+:AAI3=c#C+=AAI1=c#C+=-#/

Hãy thử trực tuyến!

Sử dụng µ( U+00B5) cho dấu hiệu vi mô, vì vậy hãy đảm bảo bạn sử dụng dấu này trong đầu vào của bạn thay vì μ( U+03BC) trong câu hỏi.

Nỗ lực đầu tiên của tôi trong việc sử dụng CJam. Vui lòng đề xuất cải tiến vì tôi chắc chắn có nhiều!

Giải trình

Phương pháp tương tự như câu trả lời JavaScript của tôi.

lS%:P                    e# P = input parts separated by space
0=d                      e# get number as double
  A
  "fpnµmchkMGTP"
    [-7 -4WY5 6ABEHK23]+
      :A                 e# A = array of SI prefixes followed by their (relative) values
   AP3=c                 e# desired SI prefix
     #C+=                e# get SI value of prefix
   AAP1=c                e# current SI prefix
     #C+=-               e# subtract value of prefix
   #                     e# get power of SI prefix difference
/                        e# divide value by 10 ^ SI prefix difference

1

Haskell, 121 byte

(e:l:i)!d|e==d=fromEnum l|0<1=i!d
b#i="f`pcnfµimlcmhqkrMuGxT{P~"!(b!!i)
g[(a,b)]=10**fromIntegral(b#1-b#7)*read a
f=g.lex

Xác định một hàm f :: String -> Double. Ví dụ:

*Main> f "6.54 MK to hK"
65400.0

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.