Zwischen SI-Präfixen konvertieren

8

Einführung

Das Internationale Einheitensystem ist ein Messsystem auf der ganzen Welt, mit Ausnahme einiger weniger Länder, einschließlich der USA . Das SI-System (oder metrische System) basiert auf den unten aufgeführten Zehnerpotenzen (beachten Sie, dass dies eine unvollständige Tabelle ist):

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

Ihre Aufgabe wird es sein, eine dieser Maßnahmen zu ergreifen und in eine andere umzuwandeln.

Eingang

Die Eingabe erfolgt durch eine Dezimalzahl 10^-16 < x < 2^31 - 1, ein SI-Präfix, einen Buchstaben, der eine Menge darstellt, ein weiteres SI-Präfix, in das konvertiert werden soll, und denselben Mengenbuchstaben. Die Eingabe hat das Format 1234.56 mC to TCund stimmt immer mit dem regulären Ausdruck überein ^\d+(\.\d+)? [fpnμmchkMGTP](?'letter'[a-zA-Z]) to [fpnμmchkMGTP](?P=letter)$. Sie müssen niemals zur / von der Basiseinheit konvertieren ( 10^0)

Ausgabe

Die Ausgabe hat dieselbe Nummer wie die Eingabe und wurde gerade in ein neues SI-Präfix konvertiert. Insbesondere sollte das Programm die Zahl von SI prefix 1in SI prefix 2in die Eingabe konvertieren . Beispiele:

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

Dies ist , also gewinnt der kürzeste Code in Bytes!

GamrCorps
quelle
1
Eine andere Sache, wenn auf diese Weise eine große / kleine Zahl erzeugt wird, wie sollte die Ausgabe sein? zB1 PB to fB
FryAmTheEggman
@FryAmTheEggman Sie können davon ausgehen, dass die Eingabe niemals eine Ausgabe erzeugt, die größer / kleiner ist als der Ziffernbereich, den Ihre Sprache nativ verarbeiten kann (ich denke, das ist es, was Sie fragen).
GamrCorps
Sollen wir verwenden U+00B5 MICRO SIGNoder U+03BC GREEK SMALL LETTER MU? Können wir entweder eine auswählen oder müssen wir eine oder beide unterstützen?
PurkkaKoodari
@ Pietu1998 entweder ist alles in Ordnung.
GamrCorps
Dürfen wir eine Gleitkommazahl ausgeben, auch wenn das Ergebnis eine ganze Zahl ist?
PurkkaKoodari

Antworten:

1

Pyth, 46 44 Bytes

Das Programm geht davon aus, dass das Zeichen µ( U+00B5 MICRO SIGN) für das Mikrozeichen verwendet wird. Unter Windows erhalten Sie dies durch Drücken von Alt Gr+ M.

Der Quellcode enthält einige nicht druckbare Dateien. Hier ist also ein umkehrbarer xxdHex-Dump.

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

Hier ist eine kopierfreundliche Version:

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

Sie können die Demo ausprobieren oder die verwenden Testsuite verwenden . Wenn diese Links fehlschlagen, verwenden Sie die kopierfreundliche Version ( Demo , Testsuite ).

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

Bearbeiten: Anscheinend können wir jetzt µ( U+00B5 MICRO SIGN) für das Mikrozeichen verwenden, so dass das Ersetzen durch dieses ein Byte spart.

Aus Gründen der ES6-Kompatibilität (10**(m[p[3][0]]-m[p[1][0]])) kann die durch Math.pow(10,m[p[3][0]]-m[p[1][0]])114 Bytes ersetzt werden.

Erläuterung

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

Prüfung

Dieser Test wird Math.powanstelle von verwendet, **damit gängige Browser ihn testen können.

user81655
quelle
3

Ruby (2.2.1), 126 123 Bytes

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

3 Benutzer dank user81655 gespeichert

Erläuterung

# 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

Übernimmt Eingaben über die Befehlszeile, z ruby si.rb 1 nm to μm

Dies ist mein erster Golf!

Chris
quelle
1
Sie können 3 Bytes speichern, wenn Sie die Werte {f:-9,p:-6,n:-3,µ:0,m:3,c:4,h:8,k:9,M:12,G:15,T:18,P:21}für die Hash-Tabelle verwenden. Auch das Ersetzen μdurch µ( U+00B5) ist zulässig und speichert ein weiteres Byte.
user81655
@ user81655 guter rat, danke! Die beiden mu / micro-Symbole scheinen die gleiche Byteanzahl zu geben, wenn ich meine Datei wc -c, eine Idee, warum das so ist?
Chris
Kein Problem. Ihre Datei wird wahrscheinlich mit UTF-8 codiert, bei dem Zeichen über 127 in zwei Bytes aufgeteilt werden. Wenn Sie zu einer Ein-Byte-Codierung wie ANSI wechseln, sollte das zusätzliche Byte aus der Datei entfernt werden.
user81655
2

Haskell, 143 Bytes

Rufen Sie an 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
quelle
Ich mag deinen "f p n µ mc hk M G T P"Trick sehr. +1
Lynn
Ich mag diesen Trick auch. Ein Tipp: Sie können kombinieren xund jmit einem Musterschutz : x y|Just n<-elemIndex(y!!0)"f p n µ mc hk M G T P"=fromIntegral n.
Nimi
2

CJam, 67 Bytes

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

Probieren Sie es online aus!

Verwendet µ( U+00B5) für das Mikrozeichen, stellen Sie also sicher, dass Sie dies in Ihrer Eingabe anstelle von μ( U+03BC) in der Frage verwenden.

Mein erster Versuch, CJam zu verwenden. Sie können gerne Verbesserungen vorschlagen, da ich sicher bin, dass es viele gibt!

Erläuterung

Gleiche Methode wie meine JavaScript-Antwort.

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
user81655
quelle
1

Haskell, 121 Bytes

(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

Definiert eine Funktion f :: String -> Double. Zum Beispiel:

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

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

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

Probieren Sie es online aus!

Xcali
quelle