数を増やす


58

1年生または2年生では、拡張形式を使用して、数値の場所の値について学ぶことができます。例で説明する方が簡単なので、数値を検討してください123。展開された形式では100 + 20 + 3、として表され、若い心が場所の価値を視覚化するのに役立ちます。それはあなたがそれを言う方法を連想させます:100(プラス)20(プラス)3。

これを、小数点以下の単位の位置を超えて拡張できます。 2.718 => 2 + 0.7 + 0.01 + 0.008

あなたの挑戦は、正の浮動小数点数またはゼロ(あなたの言語が扱えるほど大きいか正確であると想定します;科学表記法ではない)または文字列を展開し、それを印刷/返すプログラムまたは関数を書くことです上で説明したように。

の間にスペース+もゼロも必要ないため、上記の例はのようになります2+.7+.01+.008101.01 => 100 + 1 + 0.01入力がゼロでない限り、ゼロに等しい値は省略()する必要があります(以下を参照)。

値がそれ以上後、小数点の前にゼロをリードする一つまたは任意の末尾のゼロを持つべきではない(ノーノー者:0060, 0000.2, 30., 30.000, .0400)。入力もこれに適合します。

1年生のアテンションスパンは短いため、コードはできるだけ短くする必要があります。

テストケース

0 => 0
6 => 6
0.99 => 0.9 + 0.09
24601 => 20000 + 4000 + 600 + 1
6.283 => 6 + 0.2 + 0.08 + 0.003
9000000.0000009 => 9000000 + 0.0000009

22
「1年生のアテンションスパンが短いため、コードはできるだけ短くする必要があります。」
ダウンゴート

2
@Doᴡɴɢᴏᴀᴛ はミームがまだ動いているのを見うれしいです。

4
それは^^人は97(4 * 20 + 10 + 7)の場合とstrugle見るために、私たち(フランス語)のカウントと同じ方法でそれを行うには面白いことだろう
Katenkyo

2
@ jimmy23013はい、理論上機能する限り。
NinjaBearMonkey

1
@Ogaday私は知りません、それはほんのいくつかのエッジケースです。多分NBZの方法が良いだろうが、それでも、それは本当に興味深いものになるだろうしていない場合
Katenkyo

回答:


6

CJam、33 26バイト

r_ee\'0fe<f{\~t~}{},'+*0e|

これはJavaインタープリターでは機能しません。フロートの印刷方法が異なります。CJamインタープリターで試してください。

最後のテストケースが出力されます9000000+9e-7これは@NinjaBearMonkeyによって有効と判断されています

7バイトのゴルフをしてくれた@ jimmy23013に感謝します!

使い方

r_                           Read a token from STDIN and push a copy.
  ee                         Enumerate its characters, i.e., push the array of all
                             [index character] pairs.
    \                        Swap the original input on top of the stack.
     '0fe<                   Perform vectorized minimum with the character '0'.
                             This replaces all digits with '0', but leaves '.'
                             untouched, since `.' < '0'.
          f{    }            For each [index character] pair, push the pair and the
                             string of zeroes and (possibly) a dot; then:
            \                    Swap the pair on top of the stack.
             ~                   Dump index and character on the stack.
              t                  Replace the string's element at that index with
                                 that character.
               ~                 Evaluate the resulting string.
                 {},         Filter the array to remove zeroes.
                    '+*      Join, using '+' as separator.
                       0e|   If the result is empty, replace it with 0.

同じ考えに基づきますr_ee\'0fe<f{\~t~}{},'+*0e|
jimmy23013

@ jimmy23013うわー、それは短いです!ありがとうございました!
デニス

5

JavaScript(ES7)、102バイト

n=>+n&&[...n.replace(/^\.0*|\./,"")].map(f=d=>10**p--*d,p=Math.floor(Math.log10(n))).filter(f).join`+`

説明

数字が先行ゼロなしの文字列として入力されることを要求します(もちろん数字 ない限り0)。

注:浮動小数点の奇妙さのために、いくつかの数字(など.3)が間違っていますが、理論的にはこれはどの数字でも機能します。

n=>                             // n = input number as string
  +n&&                          // return 0 if n = 0
  [...n.replace(/^\.0*|\./,"")] // remove leading zeroes after the decimal place
  .map(f=d=>                    // for each digit d in n
      10**p--*d,                // raise the digit to the correct power of 10
    p=Math.floor(Math.log10(n)) // p = power of 10 for the first digit, floor needs to be
  )                             //     used instead of |0 due to negative powers of 10 :(
  .filter(f)                    // remove zeroes, the map function is reused
  .join`+`                      // return the output numbers joined with +

テスト

テストでは、ブラウザの互換性のMath.pow代わりに使用し**ます。


Math.floor=> 0|...?
ETHproductions

@ETHproductions入力数が負の数を返し、フローリングの代わりにゼロに丸められる1ため、入力数が壊れるよりも少ない場合。Math.log10(n)|0
user81655

0|Math.log10(n),p-=p<0代わりに使用できますMath.floor(Math.log10(n))か?
ドムヘイスティングス

1
@DomHastingsほとんど。との両方で等しくなるn<1ため、失敗します。私が考えることができる最短の方法は、を使用するのと同じ長さです。:(0|p00.1-0.1p=Math.log10(n),p=p-(p<0)|0Math.floor
user81655

とにかく@DomHastingsはまだ動作しませn=0.1ん。
ニール

5

網膜86 77 75バイト

バイトカウントは、ソースがISO 8859-1としてエンコードされていることを前提としています。

S_`.(?<=(\.\d+))|(?=(\d*)).
Tm`d`0`\..+\B|(?<=^\d).+
¶([.0]+¶)*
+
^0.|\+0$

後続の改行は重要です。

オンラインでお試しください。

説明

S_`.(?<=(\.\d+))|(?=(\d*)).

入力を行送りの個別のコンポーネントリストに変換することから始めますが、先頭(または末尾)の数字のみが正しいです。これは、分割ステージを乱用することによって行われます。入力を分割する代わりに、すべてを一致させるため、残りのセグメントはすべて空です。_オプションでこれらの空のセグメントを削除します。キャッチは、分割ステージもすべてのキャプチャグループの値を返すことです。そのため、各一致で先読みを使用して、文字列の正しい部分をキャプチャします。最初.に、一致の左を見つけようとします。その場合、すべてをキャプチャします.現在一致している数字までです。それ以外の場合は、入力の整数部分にいる必要があるため、一致後のすべての数値(一致を含む)をキャプチャします。小数点自体も削除する必要があるため、2番目のキャプチャはオプションです。\dキャプチャするものがない場合、これは単に入力から一致を削除します。

Tm`d`0`\..+\B|(?<!=\d).+

ここで、音訳段階を使用して、先頭/末尾の数字以外をすべてゼロに変換します。私たちは、いずれかで1未満のコンポーネントと一致する\..+\Bところ\B、我々は一桁終了前に試合を停止、または私たちが持つ整数部分一致性を保証(?<=^\d).+後読みは、我々は数に1桁を開始することを保証どこに。音訳段階ではd、一致する数字()がゼロに置き換えられます。

¶([.0]+¶)*
+

これで、実際の出力形式では+、区切り文字としてラインフィードを使用しないでください。一致していること置換を行うには改行。その間、0sと.s のみを含む行も削除します。

^0.|\+0$

前の段階では、先頭または末尾は削除されません0(それらの前後には改行がないため)ので、それらを明示的に削除します。


4

パイソン2、216の 210 196 175バイト

ここに、少しゴルフをしたコードを示します。時間があるときにさらにゴルフをします。文字列分析を使用します。

i=input().split(".")
I=i[0]
e=enumerate
o=[(k+len(I[j+1::])*"0") for j,k in e(I) if k!="0"] 
try:o+=["."+l*"0"+m for l,m in e(i[1]) if m!="0"]
except:0
print "+".join(o or"0")

説明

したがって、入力は整数部と小数部に分けられます。次に、forループリストの理解があります。整数部分では、10進数の文字の後の文字列の長さに「0」を掛けて、その文字の末尾にその数のゼロを取得します。

小数部分の場合、現在の文字のインデックスはその前のゼロの数であるため、その部分は単純です。

try and exceptは、小数部分があるかどうかを判断するために使用されます(エラーを使用)。

最終結果はプラス記号で結合されます。

ここで試してみてください!


2
o if o else ["0"]できると思いますo or["0"]
-lirtosiast

4行目に末尾のスペースがあり、バイトカウントが増えます。4行目では、コロンが1つだけ必要です。:あなたは、次のスニペットにスペースを削除することができo=[(...)] fore(I) ife(i[1]) ifprint "+"、および外カッコo=[(...)実際、同様。最後に、次のように結合関数から最終条件を取り出すことができます。print"+".join(o)or"0"結合oは空の場合空のリストを返すため、条件は1バイトを節約するのと同じ方法で評価されます。
-Ogaday

3

Pyth、30バイト

L.xvbytb|j\+fT.eyXXzjkUT\0kbzz

テストスイート

ここでの基本的な解決策は、入力内のすべての数字をに置き換えてから、0各数字を適切な位置に挿入し、評価し、ゼロをフィルターで取り除き、プラスで結合することです。残念ながら、Pythのeval関数は現在、先行ゼロを受け入れません。これを修正するために作業します。

この問題を解決するためにy、エラーがスローされるまでevalを再帰的に再試行するヘルパー関数を追加し、毎回最初の数字を削除しました。この関数は無効な入力で無限ループすることに注意してください。

また、入力には特別なケースが必要でした0

全体として、コードはかなり良いと思いますが、言語機能はもっと良いかもしれません。エラーが必要なのは誰ですか?


3

Python 3、138

これは、数値を文字列として読み取り、そのように解析するTanMath / Ogadayのアプローチに大まかに基づいています。i整数を正しく処理するために、スター割り当てを使用する必要があります。

j,*i=input().split(".")
e=enumerate
z="0"
print("+".join([(x+len(j[y+1:])*z)for y,x in e(j)if x>z]+["."+o*z+p for o,p in e(i)if p>z]or z))

3

パイソン、141の 132 128バイト

これはまだ比較的読みやすいです。文字列に変換し、>1数字とは別に数字を処理し<1ます。ゼロの特別なケースもあります。下のスペースをさらに2つ削除できますが、きれいに保つのが好きです。

マイナス面は、小数点以下9桁以上の浮動小数点数ではブレークダウンすることです。

x=str(int(a*1e9))
l=len(x)-10
z="0"
print"+".join([(j+z*(l-i))if l>=i
 else"."+z*(i-l-1)+j
 for i,j in enumerate(x)if j!=z]or z)

以下はオリジナルです。最初の編集はゼロの特殊なケースを短くすることで、2番目の編集は小数点の前の0を削除すること、3番目は余分な括弧とスペースを削除することでした。

x=str(int(a*1e9))
l=len(x)-10
z="0"
print "+".join([(j+z*(l-i)) if l>=i
 else ("0."+z*(i-l-1)+j)
 for i,j in enumerate(x) if j!=z]) if a else z

説明:

x=str(int(a*1e9)) # Convert into a string with nine decimals
l=len(x)-10
z="0"
print "+".join([
 (j+z*(l-i)) if l>=i       # Print numbers greater than 1
 else ("0."+z*(i-l-1)+j)   # Print less than one
 for i,j in enumerate(x) if j!=z
]) if a else z             # Special case zero

コードのすべてのリビジョンを含める必要はありません。ゴルフの進捗を確認したい場合は、改訂履歴をご覧ください。ところで、PPCGへようこそ!
リルトシアスト

1
ちょうどそれを発見した...私はこのサイトにあまり時間を費やさないようにしようとする必要があります!
スピードプレーン

2

Mathematica、81バイト

Inactive@Plus@@(10.^Range[#2-1,#2-Length@#,-1]#/.{0.->Nothing[]})&@@RealDigits@#&

テストケース:

%[101.01]
(* 100. + 1. + 0.01 *)

3
整数部分に小数点があることは許されないと思います。
マーティンエンダー

2

CJam、44バイト

r:TdLT'.-{'0f+IaaI~g*+}fI:dATW%'.##m]f/'+*e&

ここで試してみてください。

最後のテストケースに失敗し、次を出力します。

9000000+9e-7

しかし、CJamが処理できないほど正確すぎるとしましょう。

説明

r:Td
LT'.-         e# Remove the period if any.
{             e# For each character I:
  '0f+        e# Append 0 to each previous string.
  IaaI~g*+    e# Append I as a string if I isn't '0.
}fI
:d            e# Convert each string to float.
ATW%'.##      e# 10 to the kth power where k is the position of the period from the end.
m]            e# Round up, so it becomes 1 if no periods are found.
f/            e# Divide each float by this number.
'+*e&         e# Format and the 0 special case.

2

Pythonの3、187の 180 173 154バイト

上記の@Thomas Kwaの提案のおかげで、19バイトの良いゴルフをすることができましたresult or['0']。さらに、代数(154バイト)を再配置しました。

def f(n):
 *m,=n;o='0'
 try:p=m.index('.');m.pop(p)
 except:p=len(m)
 return'+'.join([['.'+o*(i-p)+d,d+o*(p-i-1)][p>i]for i,d in enumerate(m)if d!=o])or o

これまでの私の最善の試み173バイト)。新しいアプローチに基づいて、投稿の下部を参照してください:

def f(n):
 *m,=n;o='0'
 try:p=m.index('.');m.pop(p)
 except:p=len(m)
 return(o,'+'.join([['.'+o*(-1*(p-i))+d,d+o*(p-i-1)][p-i>0]for i,d in enumerate(m)if d!=o]))[eval(n)!=0]

私のオリジナルを180バイトまでゴルフした:

def f(n):x=n.split('.');a,b=(x+[''],x)[len(x)-1];e=enumerate;return('0',"+".join([d+'0'*i for i,d in e(a[::-1])if d!='0'][::-1]+['.'+'0'*i+d for i,d in e(b)if d!='0']))[eval(n)!=0]

今日、これを行うことで新しい言語機能を学びました!ブールインデックスによる条件付き。少しやり過ぎたかもしれません。

内包表記を抽象化しようとしましたが、短くすることができませんでした(196バイト):

e=lambda s:[d+'0'*(len(s)-i-1) for i,d in enumerate(s) if eval(d)]
def f(n):x=n.split('.');a,b=(x+[''],x)[len(x)-1];return['0',"+".join(e(a)+['.'+d[::-1]for d in e(b[::-1])][::-1])][bool(eval(n))]

(シーケンスの反転は高価です!)

使い方:鉱山は今の短いであるが、私はTanMathはゴルフの彼のダウン鉱山を一致させることができると思いe=enumerate、交換pass0、そして使用して'0'の代わりに['0']return文では4 + 3 + 2 = 9バイトを保存する必要があります!187まで減らします。別の数バイトをどこかで削ることができると確信しています...

編集新しいアプローチ(156バイト)。ただし、@ jimmy23013のCJamエントリと同様に最大6dpの精度しか処理できないため、最終テストに失敗します。もっと多くの0を印刷するように強制することはできませんでした。他の誰かができるかもしれません。代わりに、これを私の最善の試みの基礎として使用しました。topを参照してください(また、このアプローチは小数点の前に0を出力しますが、それも有効なようです)。トックtry:... except:...TanMathからのアプローチを:

def f(n):
 *m,=n
 try:p=m.index('.');m.pop(p)
 except:p=len(m)
 return('0','+'.join([str(eval(d)*10**(p-i-1))for i,d in enumerate(m)if d!='0']))[eval(n)!=0] 

あなたが私にゴルフの助けを与えようとしているなら、あなたの答えではなく、私の答えへのコメントとしてそれらを含めてください。私はいつもあなたの答えを見るとは限らないので、コメントを書くことで通知を受け取り、間違いなくそれを見るでしょう。
TanMath

2
こんにちは@TanMath。私はそうしますが、他の人の投稿にコメントするのに十分な担当者がまだいません。さらにアップボートを入手したら、コメントにフィードバックを残すようにします。
Ogaday

2

純粋なbash、210

o= a=${1%.*} b=${1#$a};while [ "$a" ];do c=${a:1};((${a%$c}>0))&&o+=${a%$c}${c//?/0}+;a=$c;done;[ "$b" ]&&{ b=${b#.} a=;while [ "$b" ];do c=${b:0:1};((c>0))&&o+=.$a$c+;b=${b:1};a+=0;done;};o=${o%+};echo ${o:-0}

または

o= a=${1%.*} b=${1#$a};while [ "$a" ];do c=${a:1};((${a%$c}>0))&&
o+=${a%$c}${c//?/0}+;a=$c;done;[ "$b" ]&&{ b=${b#.} a=;while [ "$b" ]
do c=${b:0:1};((c>0))&&o+=.$a$c+;b=${b:1};a+=0;done;};o=${o%+};echo ${o:-0}

テスト:

exp() {
    o= a=${1%.*} b=${1#$a};while [ "$a" ];do c=${a:1};((${a%$c}>0))&&
    o+=${a%$c}${c//?/0}+;a=$c;done;[ "$b" ]&&{ b=${b#.} a=;while [ "$b" ]
    do c=${b:0:1};((c>0))&&o+=.$a$c+;b=${b:1};a+=0;done;};o=${o%+};echo ${o:-0}
}
while read num;do
    printf "%-12s => " $num
    exp $num
done <<<$'0\n6\n0.99\n24601\n6.283\n9000000.0000009\n3.1415\n.99'
0            => 0
6            => 6
0.99         => .9+.09
24601        => 20000+4000+600+1
6.283        => 6+.2+.08+.003
9000000.0000009 => 9000000+.0000009
3.1415       => 3+.1+.04+.001+.0005
.99          => .9+.09

2

Python、131バイト

f=lambda s,k=0,i=0,o="",z="0":s and f(s[1:],(s<z)+k,i+k,o+(s>="1")*([s[0]+~-(s+".").find(".")*z,"."+z*i+s[0]][k]+"+"))or o[:-1]or z

本当に、非常に乱雑な再帰関数、おそらくこれを行うための最良の方法ではありません。のように入力しf("10.0203")ます。


これもPythonですか?大好きです。
-Ogaday

2

C、155の 153 161バイト

+2で数学ライブラリにリンクします(ソース自体は159です)。

main(d,v,p,q)char**v,*p,*q;{for(p=strchr(q=v[1],46),d=p?p-q:strlen(q);*q;++q)*q^46?printf(*q^48|q==v[1]?"%.*f%c":"",d<0?-d:0,(*q-48)*pow(10,--d),q[1]?43:0):0;}

非ゴルフ

int main(int d, char **v, char *p, char *q)
{
    for(q = v[1], /* Cache the input string */
        p = strchr(q,'.'), /* find the decimal */
        d = p ? p-q : strlen(q); /* calculate number of digits before decimal */
        *q; /* loop while still input data */
        ++q) /* iterate to next character */
    {
        *q^46 /* if not at the decimal point... */
            ? printf(*q^48 || q == v[1] /* if not a zero, or if the string itself is zero... */
                ? "%.f%c" /* print the digit */
                : "", /* else print nothing */
                d<0 ? -d : 0, /* Calculate number of places after decimal to print */
                (*q-48)*pow(10,--d), /* Calculate the digit at the desired power of 10 */
                q[1]?43:0) /* If the next character is still valid input, print the '+' */
            : 0 /* else, do nothing */
    }
}

2

Dyalog APL、47バイト

{×⍎⍵:1↓∊'+',¨0~⍨(⍎¨w)×10*(⍵⍳'.')-1+⍳≢w←⍵~'.'⋄0} 

たとえば、文字ベクトル形式の数値を取ります'123'

例:

      f←{×⍎⍵:1↓∊'+',¨0~⍨(⍎¨w)×10*(⍵⍳'.')-1+⍳≢w←⍵~'.'⋄0} 
      ↑⍕¨f¨,¨'0' '6' '0.99' '24601' '6.283' '900000.000009'
0                     
6                     
0.9 + 0.09            
20000 + 4000 + 600 + 1
6 + 0.2 + 0.08 + 0.003
900000 + 0.000009     

注:
○変更された最後の例の理由は、APLは、他の提出物の一部と同様に、そのような極端な数値についてはデフォルトで科学表記法に切り替えるからです。
○このフレーズ↑⍕¨f¨,¨は、すべての例を一度に処理するためにのみ必要です。



1

perl、132バイト

-pスイッチの場合は131 +1 。

これは以前のsed回答に基づいています

1while s/^([1-9]\d*)([1-9])(0*)([+.].*|)$/${1}0$3+$2$3$4/||s/([1-9]0*)\.([0-9])/$1+.$2/||s/\.(0*)([1-9])(\d*[1-9])$/.$1$2+.${1}0$3/

テストスイート:

perl -pe'1while s/^([1-9]\d*)([1-9])(0*)([+.].*|)$/${1}0$3+$2$3$4/||
    s/([1-9]0*)\.([0-9])/$1+.$2/||s/\.(0*)([1-9])(\d*[1-9])$/.$1$2+.${1}0$3/
' <<<$'0\n6\n0.99\n24601\n6.283\n9000000.0000009\n3.1415'
0
6
0.9+.09
20000+4000+600+1
6+.2+.08+.003
9000000+.0000009
3+.1+.04+.001+.0005

1

Powershell- 172 166 193バイト

すべて1行で:

$z=([string]$args[0])-split"\.";$y=$z[0].length-1+0.6;($z|%{$x=[char[]]$_;if($y-gt0){($x|%{$_+"0"*(-1+$y--)})}else{($x|%{"0."+"0"*[math]::abs($y--)+$_})}}|?{-not($_-match'^[0.]+$')})-join' + '

ゴルフをしていない:

$z=([string]$args[0]) -split "\."
$y=$z[0].length-1+0.6
($z | %{
    $x=[char[]]$_
    if($y -gt 0) {
        ($x | %{$_+"0"*(-1+$y--)})
    } else {
        ($x | %{"0."+"0"*[math]::abs($y--)+$_})
    }
} | ?{ -not($_ -match '^[0.]+$')}) -join ' + '

テストケース、さらに1つ:

PS> (0, 6, 0.99, 24601, 6.283, 9000000.0000009, [math]::pi) | %{.\expand.ps1 $_}

6
0.9 + 0.09
20000 + 4000 + 600 + 1
6 + 0.2 + 0.08 + 0.003
9000000 + 0.0000009
3 + 0.1 + 0.04 + 0.001 + 0.0005 + 0.00009 + 0.000002 + 0.0000006 + 0.00000005 + 0.000000003 + 0.0000000005 + 0.00 000000008 + 0.000000000009 + 0.0000000000007 + 0.00000000000009    
PS>

正規表現は除外され$args = 0ます。3バイトを節約する簡単なバグ修正を
次に示し


1

Perl、248バイト

ええと、私はPerlのゴルフに慣れていません。

@a=split/\./,<>;
@b=split``,$a[1];
@c=split``,$a[0];
for($i=0;$i<length$a[0];$i++){
   $_.=($c[$i]!=0)?$c[$i]."0"x((length$a[0])-$i-2)."+":"";
}
for($i=1;$i<=length$a[1];$i++){
   $_.=($b[$i-1]!=0)?"0."."0"x($i-1).$b[$i-1]."+":"";
}
chop;
($_=="")?print"0 ":print;

ここで試してみてください。


これは整数では機能しないようです。
F.ハウリ

間違ったIdeoneリンクを配置しました。編集モードで行われた変更は考慮されません。:(それが機能するようになりました。
ポール・ピカード

どこかにエラーがあります:入力する5とreturnになり50ます。
F.ハウリ

奇妙なことに、最初のコメントを書いた後、昨日提供したリンクで5をテストしたので。今試してみてください?(リンクを再度変更しました)
ポールピカール

私はちょうど私のperlインタプリタ(v5.20.2)上でスクリプトをテスト
F. HAURI

1

Java、 284 244 243バイト

String x(String s){int b=s.length(),d=(d=s.indexOf(46))<0?b:d,i=-1,k=0;String o="";for(char c;++i<b;)o+=(c=s.charAt(i))>48?(k++>0?" + ":"")+(d-i>0?c:"0.")+new String(new char[Math.abs(d-i)-1]).replace('\0','0')+(d-i>0?"":c):"";return b<2?s:o;}

残念ながら、繰り返し文字列を作成するより短い方法を見つけることができませんでした:

  • char[]必要な長さのビルド
  • Arrays.fill文字を設定するために使用します
  • new String連結できるように使用する

@Khaled A Khunaiferからインスピレーションを得て、40バイトを削減できました。

編集:indexOfint型を取るので、私は置き換えることができ'.'46。残念ながら、これはで可能とは思えませんreplace


私はそれをなんとか250まで縮小することができました。ideone.com/ HqLnMo
Khaled.K

@Khaled A Khunaiferあなたのソリューションには、1桁のテストケースに問題があるようです。しかし、ゼロを生成する方法が気に入っています。
ECS

この.replace('\0','0')関数を修正して、期待してStringいないcharと置き換えます.replace("\0","0")
-Khaled.K

@Khaled A Khunaifer私のテストケースでも機能し、docs.oracle.com / javase / 8 / docs / api / java / lang /
ECS

1

Python、125バイト

マシンのイプシロンの問題のために小さな数字を処理できなかった最初の回答(sry!)を削除した後、別の解決策を見つけました。整数と同様にフロートと後続ゼロ(!)を処理し、関数として記述されます。

@ogadayに役立つヒントとコンパクトな '0'修正をありがとう!

ゴルフ:

def f(x):x+='.';i=x.find('.');z=list(x);del z[i];return'+'.join([str(int(o)*10**(i-j-1))for j,o in enumerate(z)if'0'<o])or'0'

ゴルフをしていない:

def f(x):
  x+='.'
  i=x.find('.')
  z=list(x)
  del z[i]   
  return '+'.join([str(int(o)*10**(i-j-1)) for j,o in enumerate(z) if '0'<o]) or '0'

使用法:

>>> f("0")
'0'

>>> f("32.005")
'30+2+0.005'

>>> f("100020003000009000000.0007")
'100000000000000000000+20000000000000000+3000000000000+9000000+0.0007'

>>> f("1000000000009000000.0007000000000000000002")
'1000000000000000000+9000000+0.0007+2e-22'

>>> f("0001.99")
'1+0.9+0.09'

1
いいね f('0')しかし、テストケースに失敗し、コピーしてインタープリターに直接貼り付けると、科学表記法が得られます(これは問題ないと思います)。また、list(c)短いです。'.'リストに変換する前にを連結する場合、[]どちらも追加する必要はありません。findリストに変換する前に文字列をインデックスの代わりに使用すると、追加後に'.'バイトも節約されます。不等式をdef f(x):x+='.';i=x.find('.');z=list(x);del z[i];return"+".join([str(int(o)*10**(i-j-1))for j,o in enumerate(z)if"0"<o])or'0'
並べ替えると

1

CoffeeScript、144バイト

簡単なソリューション:

X=(n)->[m,k]="#{n}".split '.';(c+Array(m.length-i).join 0for i,c of m when+c).concat(".#{Array(++i).join 0}"+c for i,c of k when+c).join('+')||0

実行可能ファイル:


1

スタックス、18 バイト

ºî≤FlφLfÜG→\ΦUq╜♥←

実行してデバッグする

開梱されていない、コメントされていない、これはこのように見えます。

c           copy input
!C          terminate if input is falsy
y{          for each character in the string input...
  y.\d'0R   replace each digit in the input with "0"
  ia&       then replace the nth character back to its original value
  e         eval as float
m           map using block to produce array
{f          filter out zeroes
'+*         join with "+"

これを実行する

投稿された他の多くのソリューションと同様9000000+9e-7に、最後のテストケース用に作成されます。確立された先例によると、テストケースは言語に対して正確すぎるため、これは許可されています。


0

Lua、350バイト

さらにゴルフをする2つの方法があると思う:

  • 私はmacro.defineいくつかのコモンズ式を置き換えるために利用することができます(今はテストできません。

  • 文字列全体を繰り返すのではなく、ドットでsplitを使用します。繰り返しますが、luaで文字列を操作するのは非常に苦痛なので、この関数のサイズが小さくなるかどうかはわかりません。

function f(s)v,r=s:find("%.")or#s+1,""if #s==1 then return s end for i=1,#s do a=""(v>i and s:sub(i,v-1)or s:sub(v,i)):gsub(".",function(c)a=a..(not a:find(c)and(c==s:sub(i,i)or c==".")and c or 0)end)s,r=v<i and s:sub(0,i-1).."0"..s:sub(i+1,#s)or s,r..((#a==a:find("%.")or tonumber(a)==0)and""or a:gsub("%.","0.")..(i~=#s and"+"or""))end return r end

説明

function f(s)
  v=s:find("%.")or #s+1               -- v=index of the dot in a decimal number
  r=""                                -- v=#s+1 when s is an integer(v=0 would screw sub())
  if #s==1 then return s end          -- exit if s is a single digit
  for i=1,#s                          -- iterate over s
  do
    a=""

    (v>i and s:sub(i,v-1)or s:sub(v,i)-- only send the integer OR decimal part to gsub
      ):gsub(".",function(c)          -- iterate over each character of s:sub()

    -- a contains the next number to be concatenated to the string r(the one to be returned)
      a=a..(not a:find(c)             -- we concatenate a with c if a doen't contains
        and(c==s:sub(i,i)or c==".")   -- c, and c is either a dot, or the next number
             and c or 0)              -- to be add, we put a 0 otherwise
    end)
    -- we concatenate the new a with the string already formed
    r=r..((#a==a:find("%.")           -- if a=="." or a's value is 0
            or tonumber(a)==0)and""   -- we concatenate an empty string
      or a:gsub("%.","0.")            -- else, we replace the (possible) leading dot by "0."
      ..(i~=#s and"+"or""))           -- and concatenate a "+" if it isn't the last number to be added

    s=v<i and s:sub(0,i-1)            -- We then replace the digit we have worked with
      .."0"..s:sub(i+1,#s)or s        -- to prevent duplicates
  end
  return r
end

luaをオンラインでテストし、次のソースコードを使用していくつかのテストケースで実行できます。

function f(s)v,r=s:find("%.")or#s+1,""if #s==1 then return s end for i=1,#s do a=""(v>i and s:sub(i,v-1)or s:sub(v,i)):gsub(".",function(c)a=a..(not a:find(c)and(c==s:sub(i,i)or c==".")and c or 0)end)s,r=v<i and s:sub(0,i-1).."0"..s:sub(i+1,#s)or s,r..((#a==a:find("%.")or tonumber(a)==0)and""or a:gsub("%.","0.")..(i~=#s and"+"or""))end return r end

print(f("3123.12333"))
print(f("9545"))
print(f("9000000.0000009"))
print(f("6"))

0

C、253バイト

m(char*i){int k,j=0,s=0,d=0;while(i[s])s++;while(i[d]!=46)d++;while(j<d){if(i[j]!=48){for(k=0;k<(d-j);k++)putchar(k?48:i[j]);putchar(43);}j++;}while(++j<s)if(i[j]!=48){putchar(46);for(k=0;k<(j-d);k++)putchar(k==(j-d-1)?i[j]:48);putchar(43);}putchar(8);}

注:putchar(8)バックスペースを実行する必要があります。

 Input: 1230.0456
Output: 1000+200+30+.04+.005+.0006

詳細こちらをお試しください

while(i[s]) s++;
while(i[d]!=46) d++;

while (j<d)
{
    if (i[j]!='0')
    {
        for(k=0;k<(d-j);k++) putchar(k? '0': i[j]);
        putchar(43);
    }
    j++;
}

while (++j<s)
if (i[j]!='0')
{
    putchar(46);
    for(k=0; k<(j-d); k++) putchar(k==(j-d-1)? i[j]: '0');
    putchar(43);
}

putchar(8);

0

sed、136 128バイト

スペースを削除し、役に立たないことにより8文字削減されました0

:;s/^([1-9][0-9]*)([1-9])(0*)([+.].*|)$/\10\3+\2\3\4/;s/([1-9]0*)\.([0-9])/\1+.\2/;s/\.(0*)([1-9])([0-9]*[1-9])$/.\1\2+.\10\3/;t

テストケース:

sed -r ':;
    s/^([1-9][0-9]*)([1-9])(0*)([+.].*|)$/\10\3+\2\3\4/;
    s/([1-9]0*)\.([0-9])/\1+.\2/;
    s/\.(0*)([1-9])([0-9]*[1-9])$/.\1\2+.\10\3/;
    t' <<<$'0\n6\n0.99\n24601\n6.283\n9000000.0000009\n3.1415'
0
6
0.9+.09
20000+4000+600+1
6+.2+.08+.003
9000000+.0000009
3+.1+.04+.001+.0005

0

JavaScript(ES7)、114バイト

s=>(p=s.search(/.\b/),i=-1,[for(c of s)if((i++,c>0))(z=s.substring(i,p).replace(/d/g,0),i<p?c+z:z+c)].join`+`||s

全体で文字列操作を使用するため、任意の長さの数値で動作します。

配列内包表記なし(122バイト):

s=>[...s].map((c,i)=>c<'1'?'':(z=s.substring(i,p).replace(/\d/g,0),i<p?c+z:z+c),p=s.search(/.\b/)).filter(x=>x).join`+`||s

ゴルフをしていない:

function expand(s) {
    zeros = s.replace(/\d/g, "0");
    point = s.indexOf(".");
    if (point < 0) point = s.length;
    result = [];
    for (i = 0; i < s.length; i++) {
        if (s[i] > "0") {
            if (i < point) result.push(s[i] + zeros.slice(i, point - 1));
            else result.push(zeros.slice(point - 1, i) + s[i]);
         }
     }
     return result.length ? result.join("+") : s;
}

私の知る限りでは、この新しい配列内包構文はECMAScriptのから7です
manatwork

@manatworkありがたいことに、私は未ゴルフバージョンを追加している間に更新しました。
ニール

0

R-133バイト

堅牢で、マシンイプシロンを無視し、末尾のゼロでも機能します。

a)ゴルフ:

f=function(x)if(x=='0')x else{z=strsplit(x,'')[[1]];i=which(z=='.');n=as.numeric(z[-i])*10^(i-seq(z)[-1]);paste(n[n>0],collapse='+')}

ゴルフをしていない:

f=function(x)
  if(x=='0') 
    x 
  else {
    z=strsplit(x,'')[[1]]
    i=which(z=='.')   
    n=as.numeric(z[-i])*10^(i-seq(z)[-1])  
    paste(n[n>0],collapse='+')
  }

使用法:

f("900.008")
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.