Konversi di antara awalan SI

8

pengantar

Sistem Satuan Internasional adalah sistem pengukuran di seluruh dunia, kecuali untuk beberapa negara termasuk AS . Sistem SI (atau sistem metrik) didasarkan pada kekuatan sepuluh, tercantum di bawah (perhatikan bahwa ini adalah tabel yang tidak lengkap):

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

Tugas Anda adalah mengambil salah satu dari tindakan ini dan mengubahnya menjadi tindakan lain.

Memasukkan

Input akan berupa angka desimal 10^-16 < x < 2^31 - 1, awalan SI, huruf yang mewakili kuantitas, awalan SI lain untuk dikonversi, dan huruf kuantitas yang sama. Input akan berada dalam format 1234.56 mC to TC, dan akan selalu cocok dengan regex ^\d+(\.\d+)? [fpnμmchkMGTP](?'letter'[a-zA-Z]) to [fpnμmchkMGTP](?P=letter)$. Anda tidak perlu mengonversi ke / dari unit dasar ( 10^0)

Keluaran

Output akan menjadi nomor yang sama dengan input, baru saja dikonversi ke awalan SI baru. Secara khusus, program harus mengonversi angka dari SI prefix 1menjadi SI prefix 2dalam input. Contoh:

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

Ini adalah , jadi kode terpendek dalam byte menang!

GamrCorps
sumber
1
Hal lain, ketika menghasilkan sejumlah besar / kecil dengan cara ini, seperti apa outputnya? misalnya1 PB to fB
FryAmTheEggman
@FryAmTheEggman Anda mungkin berasumsi bahwa input tidak akan pernah menghasilkan output yang lebih besar / lebih kecil dari rentang digit yang dapat ditangani oleh bahasa Anda (saya pikir itulah yang Anda tanyakan).
GamrCorps
Haruskah kita menggunakan U+00B5 MICRO SIGNatau U+03BC GREEK SMALL LETTER MU? Bisakah kita memilih salah satu atau kita harus mendukung satu atau keduanya?
PurkkaKoodari
@ Pietu1998 keduanya baik-baik saja.
GamrCorps
Apakah kita diizinkan untuk mengeluarkan angka floating point walaupun hasilnya bilangan bulat?
PurkkaKoodari

Jawaban:

1

Pyth, 46 44 byte

Program mengasumsikan bahwa karakter µ( U+00B5 MICRO SIGN) digunakan untuk tanda mikro. Di Windows, inilah yang Anda dapatkan dengan menekan Alt Gr+ M.

Kode sumber mengandung beberapa unsintables, jadi di sini adalah xxddump hex reversibel .

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

Ini versi ramah-salinan:

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

Anda dapat mencoba demo atau menggunakan test suite . Jika tautan ini gagal, gunakan versi ramah-salin ( demo , test suite )

PurkkaKoodari
sumber
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]]))

Sunting: Rupanya kita bisa menggunakan µ( U+00B5 MICRO SIGN) untuk tanda mikro sekarang, jadi ganti dengan yang menghemat satu byte.

Untuk kompatibilitas ES6 (10**(m[p[3][0]]-m[p[1][0]]))dapat diganti dengan Math.pow(10,m[p[3][0]]-m[p[1][0]])untuk 114 byte.

Penjelasan

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

Uji

Tes ini digunakan Math.powalih-alih **agar browser umum dapat mengujinya.

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

Disimpan 3 byte berkat pengguna81655

Penjelasan

# 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

Mengambil input dari command line misalnya ruby si.rb 1 nm to μm

Ini golf pertama saya!

Chris
sumber
1
Anda bisa menyimpan 3 byte jika Anda menggunakan nilai {f:-9,p:-6,n:-3,µ:0,m:3,c:4,h:8,k:9,M:12,G:15,T:18,P:21}untuk tabel hash. Juga mengganti μdengan µ( U+00B5) diperbolehkan dan akan menghemat byte lain.
user81655
@ user81655 saran bagus, terima kasih! Dua simbol mu / mikro tampaknya memberikan jumlah byte yang sama ketika saya wc -c file saya, ada ide mengapa itu?
Chris
Tidak masalah. File Anda mungkin dikodekan menggunakan sesuatu seperti UTF-8 yang membagi karakter di atas 127 menjadi dua byte. Jika Anda beralih ke pengkodean satu byte seperti ANSI, ia harus menghapus byte tambahan dari file.
user81655
2

Haskell, 143 byte

Panggil 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
Leif Willerts
sumber
Saya suka "f p n µ mc hk M G T P"trik Anda . +1
Lynn
Saya suka trik ini juga. Tip: Anda dapat menggabungkan xdan jdengan penjaga pola: 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+=-#/

Cobalah online!

Menggunakan µ( U+00B5) untuk tanda mikro jadi pastikan Anda menggunakan ini pada input Anda alih-alih μ( U+03BC) dalam pertanyaan.

Upaya pertama saya menggunakan CJam. Jangan ragu untuk menyarankan perbaikan karena saya yakin ada banyak!

Penjelasan

Metode yang sama dengan jawaban JavaScript saya.

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

Menentukan fungsi f :: String -> Double. Sebagai contoh:

*Main> f "6.54 MK to hK"
65400.0
Lynn
sumber
0

Perl 5 , 113 + 8 (-p -Mutf8) = 121 byte

%c=(f,-15,p,-12,n,-9,µ,-6,'m',-3,c,-2,h,2,k,3,M,6,G,9,T,12,P,15);/([0-9.]+) (.).*(.)./;$_=$1*10**($c{$2}-$c{$3})

Cobalah online!

Xcali
sumber