Etkili Bilimsel Gösterim


12

Geçen gün kimya öğretmenim bize bilimsel notasyonu açıkladı (az sayı kullanarak ve çok sayıları daha kolay ifade etmek için on güçle çarparak), bu da beni ilk öğrendiğim zamana geri götürdü. Temel bilgileri öğrendikten sonra, bazıları aşağıdaki gibi olan bir dizi tipik matematik sorusu yaptık:

Bilimsel gösterimde aşağıdakileri temsil edin:
a) 50000000
b) 120000000000000
c) 90000000000000000000000000000000000000
d) pi ^ e ^ i ^ j ^ k ^ std :: vektör
...
z) 200
...

Ve düşündüm ki, "Ne? Bilimsel gösterimin çok sayıda yazmayı daha verimli hale getirmek için kullanıldığı söylendi, ancak bazı vakalar hiç daha verimli değil!"

Numarayı düşünün

300

ve bilimsel gösterimde temsili:

3x10^2

Ne, bilimsel olarak not edilmiş versiyon aslında daha fazla yer kaplıyor? Şimdi sahip olamayız değil mi? (Ekran alanı değerlidir.)
Bilimsel gösterimde bir sayı yazmanın daha verimli olup olmadığını kendimiz belirleyebiliriz, ya da ...

Görev

Programınız veya işleviniz tek bir pozitif nrasgele boyut (dilinizin desteklediği şeye kadar) girdi olarak almalı ve numaranın bilimsel olarak not edilmiş versiyonunu çıkarmalıdır.
Bununla birlikte, orijinal sayı n, izleyen sıfırların ve sondaki ondalık basamağın kaldırılmasından sonra, gösterilmesi bilimsel olarak not edilmiş versiyonundan daha az veya aynı miktarda karakter alırsa, nbunun yerine orijinal numarayı çıkarmalısınız.

Çıktınızın da mümkün olduğunca kısa olması gerektiğinden kodunuzun olabildiğince kısa olması gerekir.

Özellikler

Etkili Bilimsel Gösterim aşağıdaki gibi tanımlanır:

bx10^e

bgirdi sayısı, 10'lu güçlere uygun şekilde bölünür 1 <= b < 10. Bu sayı, tüm sıfırları (ve gerekirse ondalık noktasını) kaldırmış olmalı, ancak orijinal sayının hassasiyetine sahip olmalıdır (elbette kendi dilinizde ondalık nokta sınırına kadar). Yani 90000olur 9, 13.500olur 1.35, 0.000675olur 6.75vs. Bu sayı, dilinizin işleyebileceğinden daha fazla ondalık basamak içeriyorsa, bu maksimum ondalık basamağa yuvarlanmalıdır.

eonun yükseltildiği üssü n = b x 10^e( n1'den küçükse bu sayının negatif olması gerektiğini unutmayın ). Bu sayının sonunda sıfır veya ondalık bir yer olmamalıdır (esas olarak bir tamsayı değilse bir şey yanlıştır ...).

Karakter x10^ olmalıdır arasındaki dizede olduğu gibi kalır bve e.

Test senaryoları

Input -> output
1 -> 1
20 -> 20
3000000 -> 3x10^6
400000 -> 400000
0.008093 -> 0.008093
0.007835000000000 -> 0.007835
0.000003000000 -> 3x10^-6
0.00000065 -> 6.5x10^-7
0 -> 0

puanlama

Bu , bayt en kısa kod kazanır.

Diğer kurallar ve açıklama

  • Sondaki sıfırlar (ve / veya sondaki ondalık basamak), orijinal giriş numarasının karakter sayısına göre sayılmaz n. Test örneği 6 gibi durumlar için bunu aklınızda bulundurun
  • Giriş numarası 1'den küçükse, her zaman rakamlar için 0 ile başlayacağını varsayabilirsiniz (test durumları 5-8'de olduğu gibi).
  • Giriş numarası asla negatif olmayacak
  • Bu meydan okumayı önemsiz kılan ve standart boşlukların kullanılmasına izin verilmeyen yerleşikler
  • Çıktının sonundaki yeni satır tamam

EDIT
Test durumları 7 ve 8'i işaret ettiği için user81655 sayesinde on gücünde yanlış güçler vardı. Şimdi bu düzeltildi bu yüzden kodunuzu doğru değerlendirir emin olun.


7
Öyleyse, uh, girdi çıktısının ne pi^e^i^j^k^std::vectorolacağını sormalıyım ?
Geobits

@Geobits Hmm, eğer std :: vector'a sayısal bir değer atayabiliyorsanız, o zaman belki ... Hayır, girişte sadece sayılar bulunur (kayan nokta girişi için ondalık bir yer hariç).
MC ΔT

Bu çok daha kolay olurdu ve eğer kullanılmışsa "değerli ekran alanınızdan" daha az yer e9000 -> 9e3
kaplardık

1
@Cyoce bunu düşündüm, ama bu zorluğu gerçekten yazıldığına (fiziksel olarak yazıldığı gibi) dayandırdım, ki öyle görünüyor x10^. Ve bu soru üzerinde oldukça fazla yeniden çalışma olurdu, ki bu şimdi yayınlandığına göre uygun olduğunu düşünmüyorum
MC ΔT

1
@ghosts_in_the_code O değildi, bu yüzden "beni [matematik dersinde] ilk öğrendiğim zamana geri getirdi birkaç yıl"
MC ΔT

Yanıtlar:


4

ES6, 83 81 bayt

x=>(e=s=>s.replace(/e\+?/,'x10^'),z=e(x.toExponential()),y=e(''+x))[z.length]?z:y

Muhtemelen toStringüstel formatta ısrar eden bazı kenar durumlarda başarısız olur .

Düzenleme: @ user81655 sayesinde 2 bayt kaydedildi.


İyi fikir. Bu arada, /normal ifadenin sonunda unuttun gibi görünüyor .
user81655

Ayrıca 2 bayt kaydetmek için bunu biraz yeniden düzenleyebilirsiniz:x=>(e=s=>s.replace(/e\+?/,'x10^'),z=e(x.toExponential()),y=e(''+x))[z.length]?z:y
user81655

@ user81655 Ah, orada olan şey, tarayıcımın uzun çizgiyi, yanlışlıkla orada yeni bir çizginin süzüldüğünü düşündüğüm şekilde sararak kafasını karıştırmasıydı.
Neil

2

Python 3, 346 342 319 302 bayt

L=len;N=str(float(input()))
if N.endswith('.0'):N=N[:-2]
if'e'in N:C,P=N.split('e');N=N.replace('e','x10^')
else:
 C=N.strip('.0').replace('.','');F=N.find('.')
 if L(C)>1:C=C[0]+'.'+C[1:]
 P=((L(N) if F==-1 else F)-1-N.lstrip('0').find(C[0]))
print(min([N,'{0}x10^{1}'.format(C,int(P))],key=L))

Muhtemelen korkunç golf, ama hey, bu benim ilk denemede böyle bir şey. Okuması zor, bu yüzden iyi olmalı.

Bildiğim kadarıyla, her durumda, Python'un herhangi bir eşiği aşan sayıları otomatik olarak bilimsel gösterime dönüştürme eğiliminde olsa bile (bu havalı ve süslü 'e' hariç) çalışmalıdır. Standart form numaralarını döndürmek için bunu nasıl yaptığımı tam olarak hatırlamıyorum, ama bunu yapıyor.


2

Perl 6, 9690 bayt

Bunun daha kısa olabileceğini hissediyorum, ama bu benim için en iyisi

{my \s=($_,*×(1>$_??10!!.1)…10>*>=1);min(s[*-1]~"x10^"~(1>$_??1-s!!s-1),$_,by=>&chars)}

kullanım : Bunu bir değişkene atayın

Burada bazı kötü yorumlarla dinlenmemiş:

my &f = -> $n {
    my $a = 1 > $n ?? 10 !! .1;             # If $n < 1, we will multiply by 10
                                            # in the sequence below, else by 0.1

    my @seq = ($n, * × $a ... 10 > * >= 1); # Sequence starting at $n, 
                                            # multiply the previous value by $a
                                            # until we reach a number 1 <= x < 10

    # Join the last element in @seq, "x10^", and the length of @seq,
    # with an extra subtraction for numbers less than 1.
    # this gets us our scientific notation.
    my $science = @seq[*-1] ~ "x10^" ~ @seq - (1 > $n ?? @seq*2 !! 1); 

    min($science, $n, by => &chars) # Uses the &chars function to
                                    # choose a min value and return it.
}

Takas $_ <1ile 1>$_ve 1 <=* <10ile10>*>=1
Brad Gilbert b2gills

Aslında bunu dün gece yapmak istedim ama unuttum. Eve geldiğimde güncelleyeceğim
Hotkeys

2

TI BASIC (nspire): 112 bayt

Define f(x)=
Prgm
string(x)➝a
If x≥1 Then
format(x,"s")➝a
EndIf
instring(a,"ᴇ")➝b
left(a,b-1)&"x10^"&mid(a,b+1)➝a
If dim(a)<dim(string(n)) or x<1 Then
Disp a
Else
Disp x
Endif
EndPrgm

açıklama

If x≥1 Then
format(x,"s")➝a
EndIf

Küçük ondalık sayıları otomatik olarak dönüştürüldüğünden, girdiyi zaten bu biçimde değilse, biçim işleviyle bilimsel gösterime dönüştürür.

instring(a,"ᴇ")➝b
left(a,b-1)&"x10^"&mid(a,b+1)➝a

Fantezi E'nin üsleri belirten konumunu bulur ve "x10 ^" ile değiştirir.

If dim(a)<dim(string(x)) or x<1 Then
Disp a
Else
Disp x
Endif

Hangi çıktının daha büyük olduğunu kontrol eder ve en uygun çıktıyı verir. Varsayılan olarak daha küçük olan küçük bir ondalık sayı olmadığı sürece.


0

Python (3.5) 177 bayt

Normal ifade kullanan bir çözüm

import re
g=lambda s:re.sub(r"e\+?(-?)0?","x10^\\1",s)
def f(i):
 t=g(re.sub(r"\.[0]*e","e","%e"%i))
 u=g(re.sub(r"(\..*)[0]*$","\\1",str(i)))
 return t if len(u)>len(t) else u

açıklama

Normal ifade modülünün önemi

import re

Lambda fonksiyonu tanımı yerine egörex10^

g=lambda s:re.sub("e\+?(-?)0?","x10^\\1",s)
def f(i):

Dizenin bilimsel gösterimde dönüşümü

 t=g(re.sub(r"\.[0]*e","e","%e"%i))

Orjinal dizede 0 dolguyu kaldır

 u=g(re.sub(r"(\..*)[0]*$","\\1",str(i)))

uzunluğu karşılaştır

 return t if len(u)>len(t) else u

Sonuçlar

>>> [f(i) for i in [1, 20, 3000000, 400000, 0.008093, 0.007835000000000, 0.000003000000, 0.00000065, 0]]
['1', '20', '3x10^6', '400000', '0.008093', '0.007835', '3x10^-6', '6.5x10^-7', '0']
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.