Numarayı genişlet


58

Sayıların yer değerini öğrenmek için genişletilmiş formu kullanarak birinci veya ikinci sınıfta hatırlayabilirsiniz . Bir örnekle açıklamak daha kolaydır, bu yüzden sayıyı düşünün 123. Genişletilmiş biçimde 100 + 20 + 3, genç bir zihnin yer değerini görselleştirmesine yardımcı olan olarak temsil edilir . Nasıl söylediğini hatırlatan: yüz (artı) yirmi (artı) üç.

Birimleri yer ile bunu geçmişe genişletebiliriz: 2.718 => 2 + 0.7 + 0.01 + 0.008

Buradaki zorluk, pozitif bir kayan nokta sayısı veya sıfır alan bir dilekçe veya program yazmaktır (dilinizin idare edebileceği kadar büyük veya kesin olduğunu varsayalım; bilimsel gösterime girmeyecektir) veya string ve genişletilmiş biçimde yazdırır / döndürür. yukarıda açıklandığı gibi.

+Ondalık noktadan önceki ya da sıfır arasındaki boşluklara ihtiyacınız yoktur , bu nedenle yukarıdaki örnek olabilir 2+.7+.01+.008. Sıfıra eşit olacak olan değerler 101.01 => 100 + 1 + 0.01, giriş sıfır olmadıkça ( ) aşağıya () bakınız.

Değerler, ondalık noktadan önce birden fazla baştaki sıfıra veya ondan sonraki son sıfırlara sahip olmamalıdır (no-no::) 0060, 0000.2, 30., 30.000, .0400. Giriş de buna uygun olacaktır.

Birinci sınıf öğrencilerinin kısa ilgi alanları olduğu için, kodunuzun mümkün olduğu kadar kısa olması gerekir.

Test durumları

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
"Birinci sınıf öğrencilerinin kısa bir ilgi alanı olduğu için kodunuz mümkün olduğunca kısa olmalıdır."
Düşüş

2
@ Meme hala çalıştığını görmek sevindim .
kedi

4
İnsanları 97 (4 * 20 + 10 + 7) davasıyla boğuşurken görmek için (fransızca) yaptığımız gibi yapmak komik olurdu. ^^
Katenkyo

2
@ jimmy23013 Evet, teoride çalıştığı sürece.
NinjaBearMonkey

1
@ Bugün bilemiyorum, sadece bazı kenar durumlarda. Belki NBZ yolu daha iyi olurdu, ama yine de, eğer gerçekten ilginç olsaydı, yapma
Katenkyo

Yanıtlar:


6

CJam, 33 26 bayt

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

Bu, Java tercümanı ile çalışmayacak; baskı farklı yüzüyor. CJam tercümanı ile deneyin .

Geçen test durumu baskılar 9000000+9e-7olmuştur, @NinjaBearMonkey tarafından geçerli hüküm .

7 byte kapalı golf için @ jimmy23013 için teşekkürler!

Nasıl çalışır

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.

Aynı fikrine dayanmaktadır: r_ee\'0fe<f{\~t~}{},'+*0e|.
jimmy23013

@ jimmy23013 Vay, bu kısa! Teşekkür ederim!
Dennis,

5

JavaScript (ES7), 102 bayt

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

açıklama

(Sayı sürece sıfır yol açmadan bir dizi olarak girilmesi için sayı gerektirir olan 0 tabii).

Not: Kayan nokta tuhaflığından dolayı bazı sayılar (gibi .3) yanlış çıkıyor, ancak teorik olarak bu herhangi bir sayı için işe yarıyor.

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 +

Ölçek

Tarayıcı uyumluluğu Math.powyerine test kullanımları **.


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

@ETHproductions giriş numarası küçükse 1bunun nedeni kıracak Math.log10(n)negatif bir sayı ve dönecekti |0yerine döşeme sıfıra doğru mermi.
user81655

Eğer kullanabilir miyim 0|Math.log10(n),p-=p<0yerine Math.floor(Math.log10(n))?
Dom Hastings

1
@DomHastings Neredeyse. Bu başarısız n<1çünkü 0|yapacak peşit 0ikisi için 0.1ve -0.1. Düşünebildiğim en kısa yol p=Math.log10(n),p=p-(p<0)|0, kullanmakla aynı uzunlukta Math.floor. :(
user81655 19:16

@DomHastings Hala n=0.1yine de işe yaramazdı .
Neil

5

Retina , 86 77 75 bayt

Bayt sayısı, kaynağın ISO 8859-1 olarak kodlandığını varsayar.

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

Sondaki satır besleme kayda değerdir.

Çevrimiçi deneyin.

açıklama

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

Girişi sadece satır aralığı (veya sondaki) basamağı doğru olmasına rağmen satırları ayrı bir bileşen listesine çevirerek başlıyoruz. Bu bölünmüş bir aşamayı suistimal ederek yapılır. Girdiyi bölmek yerine hepsini eşleştiriyoruz, böylece kalan bölümlerin hepsi boş. Bu boş segmentleri _seçeneği ile kaldırıyoruz . Yakalama, bölünmüş aşamaların da tüm yakalama gruplarının değerlerini döndürdüğüdür. Bu yüzden dizgenin doğru kısmını yakalamak için her maçta bir gözetleme kullanıyoruz: ilk önce .eşleşmenin solunu bulmaya çalışıyoruz . Eğer durum buysa, her şeyi ....şu anda eşleştirdiğimiz rakam dahil. Aksi takdirde, girişin tamsayı kısmında olmalıyız, bu yüzden maçtan sonra tüm sayıları yakalarız (maç dahil). Ondalık noktadan da kurtulmalıyız, bu yüzden ikinci yakalama isteğe bağlıdır. Eğer \dyakalanacak bir şey yoksa , bu eşleşmeyi girdiden kaldıracaktır.

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

Şimdi baştaki / sondaki rakamlardan başkalarını sıfıra çevirmek için bir harf çevirisi aşaması kullanıyoruz. Ya birlikte 1'den az olan bir bileşen maç \..+\Bnerede \Bbiz bir basamak bitmeden maçı durdurmak, ya da biz bir tam sayı kısmını maç olmasını sağlar (?<=^\d).+Geriye dönük biz sayıya bir rakam başlangıç olmasını sağlar nerede. Harf çevirisi aşaması daha sonra herhangi bir rakamı ( d) eşleşmelerde sıfırla değiştirir .

¶([.0]+¶)*
+

Şimdi asıl çıktı formatı +ayırıcılar olarak satır beslemelerini kullanmamalıdır . Maçları bir satır besleme ikamesinin yapmak. Biz buna devam ederken sadece 0s ve .s içeren satırları da kaldırıyoruz .

^0.|\+0$

Önceki aşamada 0bir satır veya iz kaldırılmaz (çünkü onlardan önce ve sonra satır beslemesi olmadığından), bu nedenle açıkça kaldırılır.


4

Python 2, 216 210 196 175 bayt

İşte zamanım olduğunda daha fazla golf oynayacağım bazı golf kodları. String analizi kullanır.

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

açıklama

Böylece giriş bir tamsayı ve ondalık bölüme ayrılmıştır. Sonra, bir döngü listesi kavrama var. Tamsayı bölümünde, ondalık içindeki bir karakterden sonraki dizginin uzunluğu "0" ile çarpılır ve bu karakterin sonunda o kadar sıfır elde edilir.

Ondalık kısım için, geçerli karakterin dizini ondan önceki sıfırların sayısıdır ve bu nedenle bu kısım basittir.

Deneme ve hariç, ondalık bölüm olup olmadığını belirlemek için kullanılır (bir hata kullanarak).

Nihai sonuç artı işaretleriyle birleştirilir.

Burada dene!


2
Bence o if o else ["0"]olabilir o or["0"].
lirtosiast,

Dördüncü satırda bayt sayınıza katkıda bulunan bir sonda boşluk var. Dördüncü satırda sadece bir kolona ihtiyacınız var. : Aşağıdaki snippet'lerdeki alanlarını silebilirler o=[(...)] for, e(I) if, e(i[1]) if, print "+", ve dış parantez o=[(...)aslında yanı. Son olarak, bu gibi birleştirme işlevinin son koşullu koşulunu çıkarabilirsiniz: print"+".join(o)or"0"çünkü birleşme boşsa boş bir liste döndürür o, bu nedenle koşullu bir bayttan tasarruf sağlayan aynı şekilde değerlendirilir.
Ogaday

3

Pyth, 30 bayt

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

Test odası

Buradaki temel çözüm, girdideki tüm basamakları değiştirmek 0, ardından her basamağı uygun yere yerleştirmek, değerlendirmek, sıfırları filtrelemek ve artılara katılmaktır. Ne yazık ki, Pyth'in değerlendirme işlevi şu anda önde gelen sıfırları kabul etmiyor. Bunu düzeltmek için çalışacağım.

Bu sorunu yaşmak için, her seferinde ilk haneyi kaldırarak hiçbir hata atılmadan değerlendirmeyi tekrarlı olarak yeniden deneyen bir yardımcı işlev ekledim . Bu işlevin geçersiz girişte sonsuz döngü yapacağına dikkat edin.

Ayrıca, giriş için özel bir durum gerekliydi 0.

Sonuçta, kodun oldukça iyi olduğunu düşünüyorum, ancak dil olanakları daha iyi olabilirdi. Kim hata istiyor?


3

Python 3, 138

Bu, TanMath / Ogaday'ın sayıyı bir dize olarak okuma ve bu şekilde ayrıştırma yaklaşımına gevşek bir şekilde dayanmaktadır. iTamsayıları doğru şekilde ele alması için yıldız atamasını kullanmalıyım .

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

Python, 141 132 128 bayt

Bu hala nispeten okunaklı. Dizeye dönüştür ve >1basamakları basamaklardan ayrı <1tut. Ayrıca sıfır için özel bir durumumuz var. Aşağıdaki iki boşluğu daha kaldırabilirim ama güzel kalmasını seviyorum.

Dezavantajı 9'dan fazla ondalık basamağa sahip yüzdürmeler için parçalanacak olmasıdır.

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)

Orijinali aşağıdadır. İlk düzenleme sıfır özel durumu kısaltmak, ikinci düzenleme ondalık basamağı 0'dan önce çıkarmak, üçüncüsü fazladan parantez ve boşluk çıkarmaktır.

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

Açıklama:

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

Kodunuzun her revizyonunu eklemeniz gerekmez; Golf ilerlemenizi görmek istiyorsak revizyon geçmişine bakabiliriz. Bu arada, PPCG'ye hoş geldiniz!
lirtosiast

1
Sadece keşfettim ... Bu sitede çok fazla zaman harcamak değil denemek zorundayım!
hız uçağı

2

Mathematica, 81 bayt

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

Test durumu:

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

3
Tamsayı bölümleri üzerinde ondalık noktaya sahip olmanın izin verildiğini sanmıyorum.
Martin Ender

2

CJam, 44 bayt

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

Burada dene.

Son sınama durumunda başarısız olur ve aşağıdakileri çıkarır:

9000000+9e-7

Ama diyelim ki CJam'ın üstesinden gelemez.

açıklama

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 bayt

@Thomas Kwa'nın önerileri result or['0']ve bazı cebirleri ( 154 byte ) yeniden düzenlemek için iyi bir 19 baytlık golf yapmayı başardı :

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

Şimdiye kadarki en iyi girişimim ( 173 bytes ). Yeni yaklaşıma dayanarak, yazının altına bakın:

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]

orjinalimi 180 bayta indirdim :

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]

Bugün bunu yaparak yeni bir dil özelliği öğrendim! Boole endekslemesi ile şartlamalar. Biraz fazla abartmış olabilirim.

Kavrayışları soyutlamayı denedim, ancak daha kısa sürede yapamadım ( 196 bytes ):

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

(Tersinir dizileri pahalıdır!)

Artık benim için daha kısa iken, ben TanMath can golf onun aşağı mayın maç için düşünüyorum: kullanma e=enumerate, değiştirme passile 0ve kullanma '0'yerine ['0']4 + 3 + 2 = 9 bayt kaydetmek gerekir dönüş açıklamada! 187'e düşürüyorum. Eminim başka bir kaç bayt başka bir yerde traş olabilir ...

düzenlemek New approach ( 156 bytes ). Ancak, yalnızca @ jimmy23013'ün CJam girişine benzer 6dp'ye kadar hassasiyetle başa çıkabilir, bu nedenle son testte başarısız olur. Daha fazla 0 basmak için zorlayamadım, belki başkası yapabilir. Bunun yerine, şimdiye kadarki en iyi girişimin temeli olarak kullandım, başa bakın (Ayrıca, bu yaklaşım ondalık basamağın önünde 0 değerini yazdırır, ancak bu da geçerli görünüyor.). try:... except:...TanMath'tan yaklaşımı aldı :

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] 

Bana golf yardımı vermeye çalışıyorsanız, lütfen cevabınıza değil, cevabımı yorum olarak ekleyin. Cevaplarınızı her zaman göremiyorum, bu yüzden bir yorum yazarak bir bildirim alacağım ve kesinlikle göreceğim.
TanMath

2
Selam @TanMath. Yapardım, fakat henüz diğer kişilerin gönderileri hakkında yorum yapacak kadar bilgim yok. Birkaç tekne daha gelince yorumlarda geri bildirim bırakacağımdan emin olacağım.
Ogaday

2

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

veya

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}

Ölçek:

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 bayt

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

Gerçekten, gerçekten dağınık özyinelemeli bir işlev, muhtemelen bu konuda en iyi yol değil. Gibi giriş f("10.0203").


Bu bile Python mu? Sevdim.
Ogaday

2

C, 155 153 161 bayt

+2 matematik kütüphanesinde bağlantı kurmak için (kaynağın kendisi 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;}

Ungolfed

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 bayt

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

Örneğin karakter vektör biçiminde sayı alır '123' .

Örnekler:

      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     

Notlar:
last Değiştirilen son örneğin nedeni, APL'nin, diğer gönderilerin bazıları gibi, varsayılan olarak, bu tür aşırı sayılar için bilimsel gösterime geçeceği şeklindedir.
Phrase İfadenin ↑⍕¨f¨,¨yalnızca tüm örnekleri bir kerede işlemesi için gereklidir.



1

perl, 132 bayt

-pAnahtar için 131 +1 .

Bu önceki sedcevabımı temel alıyor :

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/

Test odası:

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 bayt

Hepsi tek bir satırda:

$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' + '

Ungolfed:

$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 ' + '

Test durumları, artı bir ek:

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>



1

Perl, 248 bayt

Ew, ben Perl golf sahasında asil değilim.

@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;

Burada dene.


Bu tamsayı sayıları ile çalışmıyor gibi görünüyor.
F. Hauri,

Yanlış İdeone bağlantısını koydum. Düzenleme modunda yapılan değişiklikleri dikkate almaz. :( Şimdi çalışması gerekiyor.
Paul Picard

Bir yerde bir hatam var: Girdiğimde 5geri dön 50.
F. Hauri,

Garip, çünkü ilk yorumunuzu yaptıktan sonra dün verdiğim bağlantıyı 5 test ettim. Şimdi dener misin? (Bağlantıyı tekrar değiştirdim)
Paul Picard

Senaryonuzu perl tercümanım üzerinde test ettim (v5.20.2)
F. Hauri

1

Java, 284 244 243 Bayt

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

Ne yazık ki, yinelenen karakter dizileri oluşturmanın daha kısa bir yolunu bulamadım:

  • char[]istenilen uzunlukta bir tane oluşturmak
  • Arrays.fillkarakterleri ayarlamak için kullanın
  • new Stringbirleştirin böylece kullanmak

@Khaled A Khunaifer'in ilhamıyla 40 Bayt'ı tıraş edebilirim.

Düzenleme: indexOfbir int alır, böylece '.'ile değiştirebilirim 46. Ne yazık ki, bu mümkün görünmüyor replace.



@Khaled A Khunaifer Çözümünüzün tek haneli test durumları ile ilgili problemleri var gibi görünüyor. Ama ben sıfır üretme şeklini seviyorum.
ECS

Bunu düzeltmek .replace('\0','0')beklemek yerine işlevini Stringdeğil charolması gerektiği,.replace("\0","0")
Khaled.K

@Khaled A Khunaifer Test vakalarımda da çalışıyor
ECS

1

Python, 125 bayt

Makine epsilon sorunları nedeniyle küçük sayıları kaldıramayan ilk cevabımı (sry!) Sildikten sonra farklı bir çözüm buldum. Float ve tam sayıların yanı sıra, sıfır (!) Harflerini işler ve fonksiyon olarak yazılır.

@Ogaday'a faydalı ipuçları ve kompakt '0' düzeltmesi için teşekkürler!

golfed:

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'

Ungolfed:

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'

Kullanımı:

>>> 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
Güzel. f('0')Ancak test davası başarısız olur ve tercümanıma doğrudan kopyalayıp yapıştırdığımda bilimsel gösterimi alırım (bence iyi). Ayrıca, list(c)daha kısa. '.'Bir listeye dönmeden önce birleştirmek eğer []ya da eklemeniz gerekmez . Dizgede findindeks yerine kullanmak , listeye çevirmeden önce, ekledikten sonra '.'da bir bayt kazandırır. Eşitsizliğin yeniden 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'
sıralanması

1

CoffeeScript, 144 bayt

Dümdüz ileri çözüm:

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

çalıştırılabilir:


1

Stax , 18 bayt

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

Koş ve hata ayıkla

Ambalajsız, ağzı açılmış ve yorumlanmış gibi görünüyor.

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 "+"

Bunu çalıştır

Yayınlanan diğer çözümlerin çoğu gibi, 9000000+9e-7son test durumu için de üretiyor . Oluşturulan emsallere göre buna izin verilir, çünkü test durumu dil için çok hassastır.


0

Lua, 350 Bayt

Bence daha fazla golf atmanın iki yolu var:

  • macro.defineBazı ortak kullanım ifadelerinin yerine geçmek için faydalanabilirim (şu anda test edemiyorum ve bazı baytlar kazanmamı sağlayamadığından emin değilim)

  • Tüm dizgiyi yinelemek yerine noktaya bölme kullanın. Bir kez daha, bu fonksiyonun boyutunu azaltacağından emin değilim.

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

açıklamalar

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'yı çevrimiçi olarak test edebilir ve bazı test durumlarında çalıştırmak için aşağıdaki kaynak kodu kullanabilirsiniz.

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 bayt

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

Not: putchar(8)Bir geri alma gerçekleştirmelisiniz.

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

Ayrıntılı , burada deneyin

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 bayt

Boşluk bırakarak 8 karakter azalır ve işe yaramaz 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

Test durumları:

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 bayt

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

İsteğe bağlı uzunluk sayılarıyla çalışır, çünkü karakter dizisi manipülasyonunu kullanır.

Dizi kavraması olmadan (122 bayt):

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

Ungolfed:

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

Bildiğim kadarıyla, bu yeni dizi anlama sözdizimi ECMAScript 7'den geliyor.
manatwork

@ manatwork Teşekkürler, ungolfed versiyonunu eklerken güncelledim.
Neil

0

R - 133 bayt

Sağlam, Machine Epsilon'u yok sayar ve izleyen sıfırlarla da çalışır.

a) Golf:

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='+')}

Ungolfed:

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='+')
  }

Kullanımı:

f("900.008")
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.