効率的な科学表記法


12

先日、化学の先生が科学表記法について説明していました(小さい数字を使用し、10の累乗を掛けて大きい数字をより簡単に表現できるようにしました)。基本を学んだ後、いくつかの典型的な数学の質問をしました。そのうちのいくつかは次のようなものでした:

科学表記法で次を表します:
a)50000000
b)120000000000000
c)90000000000000000000000000000000000000
d)pi ^ e ^ i ^ j ^ k ^ std :: vector
...
z)200
...

そして、「何?科学的な表記法を使用して、大量の文章をより効率的に作成できると言われましたが、まったく効率的でない場合もあります!」

数を考える

300

および科学表記法での表現:

3x10^2

科学的に表記されたバージョンは実際にはより多くのスペースを占有しますか?今はできませんか?(画面スペースは貴重です。)
科学表記法で数字を書く方がよりスペース効率が良いかどうかを判断できます。または...

仕事

プログラムまたは関数は、入力としてn、任意のサイズの単一の正の数(言語がサポートするものまで)を受け取り、その数の科学的に表記されたバージョンを出力する必要があります。
ただし、n末尾のゼロと小数点以下の桁を削除した後、元の数値が表示される文字数が科学的に表記されたバージョンより少ないか同じ場合、n代わりにその元の数値を出力する必要があります。

出力もできるだけ短くする必要があるため、コードはできるだけ短くする必要があります。

仕様書

効率的な科学表記法は次のように定義されています。

bx10^e

bは、適切に10の累乗で除算された入力数です1 <= b < 10。この数値では、すべての末尾のゼロ(および必要に応じて小数点)を削除する必要がありますが、元の数値の精度(もちろん、言語の小数点の制限まで)が必要です。すなわち90000なり913.500なり1.350.000675なると6.75、あなたの言語が処理できる以上の小数点以下を含むアップこの数が終了した場合などは、小数点以下の桁数の最大数に四捨五入されなければなりません。

eは、10が累乗される指数ですn = b x 10^en1より小さい場合、この数値は負である必要があることに注意してください)。この数値には、末尾のゼロや小数点以下の桁があってはなりません(主に整数でない場合、何かが間違っているためです...)。

文字がx10^ なければなりませんの間の文字列であるとして残るbe

テストケース

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

得点

これはなので、バイト単位の最短コードが優先されます。

その他の規則と説明

  • 末尾のゼロ(および/または末尾の小数点)は、元の入力番号の文字カウントにはカウントされませんn。テストケース6などの場合は、このことに留意してください
  • 入力番号が1未満の場合、1桁の数字は常に0で始まると想定できます(テストケース5〜8のように)。
  • 入力番号が負になることはありません
  • この挑戦を些細で標準的な抜け穴にするビルトインは許可されていません
  • 出力の末尾の改行は問題ありません

編集
テストケース7および8の10のべき乗が間違っていたことを指摘してくれたuser81655に感謝します。これらを修正したので、コードがそれらを正しく評価するようにしてください。


7
だから、ええと、私は入力のための出力pi^e^i^j^k^std::vectorがどうなるかを尋ねるべきですか?
ジオビット

@Geobitsうーん、もし、数値をstd :: vectorに割り当てることができれば、多分...いいえ、入力には数値のみが表示されます(浮動小数点入力の小数点以下は除きます)。
MCΔT16年

これははるかに簡単で、使用すると「貴重な画面スペース」が少なくなりますe:(9000 -> 9e3ほぼ9,000を超える!)
Cyoce

1
@Cyoce私はそれについて考えましたが、私はこの挑戦を、実際に書かれているように一般的に書かれている方法に基づいていましたx10^。そして、それは質問の手直しのかなりの部分であるでしょう、私はそれが掲示されるので今それが適切であるとは思わない
MCΔT16年

1
@ghosts_in_the_code彼女はそうではなかったので、「数年前に[数学の授業で]初めて学んだときまで戻してくれた」
MCΔT16年

回答:


4

ES6、83の 81バイト

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

toString指数形式を要求するいくつかのエッジケースではおそらく失敗します。

編集:@ user81655のおかげで2バイトを保存しました。


良いアイデア。ちなみに、/正規表現の最後を忘れてしまったようです。
user81655

また、これをわずかに再配置して2バイトを節約できますx=>(e=s=>s.replace(/e\+?/,'x10^'),z=e(x.toExponential()),y=e(''+x))[z.length]?z:y
。– user81655

@ user81655ああ、そこで起こったのは、間違って新しい行がそこに忍び込んだと思ったような方法で長い行を折り返すことで、ブラウザが私を混乱させたことです。
ニール

2

Python 3、346 342 319 302バイト

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

たぶん恐ろしくゴルフをしましたが、ねえ、これはこのようなことで私の最初の試みです。読むのが難しいので、良いに違いありません。

私が知っている限りでは、どんなしきい値でも過去の数値を科学表記法に自動的に変換するPythonの傾向があっても、すべてのケースで動作するはずです(そのクールで派手な 'e'を除く)。標準のフォーム番号を返すことができるようにした方法を正確には覚えていませんが、それは実現しています。


2

Perl 6の、96の 90バイト

これはもっと短くなると思うが、今のところこれが最善だ

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

使用法:これを変数に割り当てます

ここでは、いくつかの悪いコメントがあります:

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

スワップ$_ <11>$_1 <=* <1010>*>=1
ブラッド・ギルバートはb2gills

私は実際に昨夜それをするつもりでしたが、私は忘れていました。帰宅したら更新します
Hotkeys

2

TI BASIC(nspire):112バイト

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

説明

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

小さい小数は自動的に変換されるため、入力がその形式にない場合は、format関数を使用して入力を科学表記に変換します。

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

指数を表す派手なEの位置を見つけ、それを「x10 ^」に置き換えます。

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

どの出力が大きいかをチェックし、最適な出力を返します。デフォルトでより小さい小数の場合を除きます。


0

Python(3.5)177バイト

正規表現を使用したソリューション

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

説明

正規表現モジュールのインポート

import re

置換eするラムダ関数の定義x10^

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

科学表記法での文字列の変換

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

元の文字列の0パディングを削除します

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

長さを比較

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

結果

>>> [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']
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.