Mở rộng số lượng


58

Bạn có thể nhớ ở lớp một hoặc lớp hai bằng cách sử dụng biểu mẫu mở rộng để tìm hiểu về giá trị vị trí của các số. Thật dễ dàng để giải thích với một ví dụ, vì vậy hãy xem xét số lượng 123. Ở dạng mở rộng, nó được biểu diễn dưới dạng 100 + 20 + 3, giúp tâm trí trẻ hình dung giá trị địa điểm. Nó gợi nhớ đến cách bạn nói: một trăm (cộng) hai mươi (cộng) ba.

Chúng tôi có thể mở rộng điều này qua các đơn vị với số thập phân: 2.718 => 2 + 0.7 + 0.01 + 0.008

Thách thức của bạn là viết một chương trình hoặc hàm có số dấu phẩy động dương hoặc bằng 0 (giả sử nó lớn hoặc chính xác như ngôn ngữ của bạn có thể xử lý; nó sẽ không ở dạng ký hiệu khoa học) hoặc chuỗi và in / trả về nó ở dạng mở rộng Như đã giải thích ở trên.

Bạn không cần khoảng trắng giữa dấu +và số 0 trước dấu thập phân, vì vậy ví dụ trên có thể là 2+.7+.01+.008. Các giá trị bằng 0 phải được bỏ qua ( 101.01 => 100 + 1 + 0.01) trừ khi đầu vào bằng 0 (xem bên dưới).

Các giá trị không được có nhiều hơn một số 0 đứng trước dấu thập phân hoặc bất kỳ số 0 nào sau nó (no-no's 0060, 0000.2, 30., 30.000, .0400:). Đầu vào cũng sẽ phù hợp với điều này.

Vì học sinh lớp một có khoảng chú ý ngắn, mã của bạn sẽ phải càng ngắn càng tốt.

Các trường hợp thử nghiệm

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 cho "Vì học sinh lớp một có khoảng chú ý ngắn, mã của bạn sẽ phải càng ngắn càng tốt."
Hạ cấp

2
@ Doᴡɴɢᴏᴀᴛ vui mừng khi thấy meme vẫn đang chạy.
mèo

4
Sẽ rất buồn cười khi làm điều đó giống như cách chúng ta (người Pháp) đếm, để thấy mọi người chiến đấu với trường hợp 97 (4 * 20 + 10 + 7) ^^
Katenkyo

2
@ jimmy23013 Có, miễn là nó hoạt động trên lý thuyết.
NinjaBearMonkey

1
@Ogaday Tôi không biết, đó chỉ là một số trường hợp cạnh. Có lẽ cách của NBZ sẽ tốt hơn, nhưng vẫn vậy, đừng nếu nó thực sự thú vị
Katenkyo

Câu trả lời:


6

CJam, 33 26 byte

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

Điều này sẽ không hoạt động với trình thông dịch Java; nó in nổi khác nhau. Hãy thử nó với trình thông dịch CJam .

Bản in trường hợp thử nghiệm cuối cùng 9000000+9e-7, đã được @NinjaBearMonkey cai trị .

Cảm ơn @ jimmy23013 vì đã chơi golf 7 byte!

Làm thế nào nó hoạt động

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.

Dựa trên cùng một ý tưởng : r_ee\'0fe<f{\~t~}{},'+*0e|.
jimmy23013

@ jimmy23013 Wow, thật ngắn! Cảm ơn bạn!
Dennis

5

JavaScript (ES7), 102 byte

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

Giải trình

Yêu cầu số phải là đầu vào dưới dạng chuỗi mà không có số 0 đứng đầu (trừ khi số đó 0 tất nhiên).

Lưu ý: Vì sự kỳ lạ của dấu phẩy động, một số số (như .3) xuất hiện sai, nhưng về mặt lý thuyết thì điều này có hiệu quả đối với bất kỳ số nào.

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 +

Kiểm tra

Kiểm tra sử dụng Math.powthay vì **tương thích trình duyệt.


Math.floor=> 0|...?
Sản phẩm ETH

@ETHproductions Nếu số đầu vào nhỏ hơn số 1đó sẽ bị phá vỡ vì Math.log10(n)sẽ trả về số âm và làm |0tròn về 0 thay vì sàn.
dùng81655

Bạn có thể sử dụng 0|Math.log10(n),p-=p<0thay vì Math.floor(Math.log10(n))?
Dom Hastings

1
@DomHastings Hầu như. Nó không cho n<10|sẽ làm cho pbình đẳng 0cho cả hai 0.1-0.1. Cách ngắn nhất tôi có thể nghĩ là p=Math.log10(n),p=p-(p<0)|0có cùng độ dài với việc sử dụng Math.floor. :(
user81655

@DomHastings Vẫn không hoạt động n=0.1.
Neil

5

Võng mạc , 86 77 75 byte

Số lượng byte giả định rằng nguồn được mã hóa theo ISO 8859-1.

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

Các linefeed trailing là đáng kể.

Hãy thử trực tuyến.

Giải trình

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

Chúng tôi bắt đầu bằng cách biến đầu vào thành một danh sách các thành phần riêng biệt của dòng cấp dữ liệu, mặc dù chỉ có chữ số hàng đầu (hoặc dấu) là chính xác. Điều này được thực hiện bằng cách lạm dụng một giai đoạn phân chia. Thay vì chia đầu vào, chúng ta khớp tất cả các đầu vào, vì vậy các phân đoạn còn lại đều trống. Chúng tôi loại bỏ những phân đoạn trống với _tùy chọn. Điều hấp dẫn là các giai đoạn phân chia cũng trả về giá trị của tất cả các nhóm bắt giữ. Vì vậy, chúng tôi sử dụng một cái nhìn ở mỗi trận đấu để nắm bắt phần chính xác của chuỗi: đầu tiên chúng tôi cố gắng tìm một .bên trái của trận đấu. Nếu đó là trường hợp, chúng tôi nắm bắt mọi thứ từ.lên đến và bao gồm cả chữ số chúng tôi hiện đang khớp. Mặt khác, chúng ta phải ở trong phần nguyên của đầu vào, vì vậy chúng tôi nắm bắt tất cả các số sau khi khớp (bao gồm cả khớp). Chúng ta cũng phải loại bỏ dấu thập phân, vì vậy việc chụp thứ hai là tùy chọn. Nếu không có \dđể chụp, điều này sẽ chỉ loại bỏ kết quả khớp với đầu vào.

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

Bây giờ chúng tôi sử dụng một giai đoạn chuyển ngữ để biến tất cả trừ các chữ số hàng đầu / dấu thành số không. Chúng ta có thể khớp một thành phần nhỏ hơn 1 với \..+\Bviệc \Bđảm bảo rằng chúng ta dừng khớp một chữ số trước khi kết thúc hoặc chúng ta khớp một phần nguyên với (?<=^\d).+nơi mà giao diện đảm bảo rằng chúng ta bắt đầu một chữ số thành số. Giai đoạn chuyển ngữ sau đó sẽ thay thế bất kỳ chữ số ( d) nào bằng các số 0 bên trong các kết quả khớp.

¶([.0]+¶)*
+

Bây giờ định dạng đầu ra thực tế không nên sử dụng nguồn cấp dữ liệu +làm dấu phân cách. Các trận đấu một linefeed làm thay đó. Trong khi chúng tôi ở đó, chúng tôi cũng xóa các dòng chỉ chứa 0s và .s.

^0.|\+0$

Giai đoạn trước không loại bỏ một hàng đầu hoặc dấu 0(vì những cái đó không có nguồn cấp dữ liệu trước và sau chúng), vì vậy chúng tôi loại bỏ những thứ đó một cách rõ ràng.


4

Python 2, 216 210 196 175 byte

Đây là một số mã golf hơi mà tôi sẽ chơi gôn hơn khi tôi có thời gian. Nó sử dụng phân tích chuỗi.

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

Giải trình

Vì vậy, đầu vào được phân tách thành một phần nguyên và phần thập phân. Sau đó, có một sự hiểu biết danh sách vòng lặp. Trên phần nguyên, độ dài của chuỗi sau một ký tự trong số thập phân được nhân với "0" để có được nhiều số không ở cuối nếu ký tự đó.

Đối với phần thập phân, chỉ số của ký tự hiện tại là số không trước nó và vì vậy phần đó là đơn giản.

Thử và ngoại trừ được sử dụng để xác định xem nó có phần thập phân hay không (sử dụng lỗi).

Kết quả cuối cùng được nối với dấu cộng.

Hãy thử nó ở đây!


2
Tôi nghĩ rằng o if o else ["0"]có thể o or["0"].
lirtosiast

Bạn có một khoảng trắng ở dòng bốn làm tăng thêm số byte của bạn. Trên dòng bốn bạn chỉ cần một dấu hai chấm. Bạn có thể xóa các khoảng trống trong các đoạn sau: o=[(...)] for, e(I) if, e(i[1]) if, print "+", và ngoặc ngoài trong o=[(...)là tốt, thực sự. Cuối cùng, bạn có thể lấy điều kiện cuối cùng ra khỏi hàm nối như thế này: print"+".join(o)or"0"bởi vì phép nối sẽ trả về một danh sách trống nếu otrống nên điều kiện sẽ đánh giá giống như cách giúp bạn tiết kiệm một byte.
Ogaday

3

Bình thường, 30 byte

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

Bộ kiểm tra

Giải pháp cơ bản ở đây là thay thế tất cả các chữ số trong đầu vào bằng 0, sau đó chèn từng chữ số vào vị trí thích hợp, eval, lọc ra các số không và tham gia vào các điểm cộng. Thật không may, chức năng eval của Pyth hiện không chấp nhận số không hàng đầu. Tôi sẽ làm việc để sửa lỗi này.

Để vượt qua vấn đề này, tôi đã thêm một hàm trợ giúp y, nó đệ quy lại eval cho đến khi không có lỗi nào được đưa ra, loại bỏ chữ số đầu tiên mỗi lần. Lưu ý rằng chức năng này sẽ lặp vô hạn trên đầu vào không hợp lệ.

Ngoài ra, một trường hợp đặc biệt là cần thiết cho đầu vào 0.

Nói chung, tôi nghĩ rằng mã này khá tốt, nhưng các phương tiện ngôn ngữ có thể tốt hơn. Ai muốn sai sót?


3

Trăn 3, 138

Điều này dựa trên cách tiếp cận đọc số của TanMath / Ogaday một cách lỏng lẻo và phân tích nó theo cách đó. Tôi phải sử dụng phép gán sao iđể nó xử lý chính xác các số nguyên.

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 byte

Điều này vẫn còn tương đối dễ đọc. Chuyển đổi thành chuỗi và xử lý các >1chữ số riêng biệt với các <1chữ số. Chúng tôi cũng có một trường hợp đặc biệt cho số không. Tôi có thể loại bỏ hai không gian bên dưới, nhưng tôi thích giữ cho nó đẹp.

Nhược điểm là nó sẽ bị hỏng đối với các phao có hơn 9 chữ số thập phân.

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)

Dưới đây là bản gốc. Chỉnh sửa đầu tiên là rút ngắn trường hợp đặc biệt bằng 0, chỉnh sửa thứ hai là xóa 0 trước số thập phân, thứ ba là xóa một số dấu ngoặc đơn và dấu cách.

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

Giải trình:

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

Bạn không cần bao gồm mọi sửa đổi mã của mình; nếu chúng tôi muốn xem tiến trình chơi gôn của bạn, chúng tôi có thể xem lịch sử sửa đổi. Nhân tiện, chào mừng bạn đến với PPCG!
lirtosiast

1
Chỉ cần phát hiện ra nó ... Tôi sẽ phải cố gắng không dành quá nhiều thời gian cho trang web này!
bay tốc độ

2

Toán học, 81 byte

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

Trường hợp thử nghiệm:

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

3
Tôi không nghĩ rằng có dấu thập phân trên các phần nguyên được cho phép.
Martin Ender

2

CJam, 44 byte

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

Hãy thử nó ở đây.

Nó không thành công trong trường hợp thử nghiệm cuối cùng và đưa ra kết quả như sau:

9000000+9e-7

Nhưng hãy nói rằng quá chính xác rằng CJam không thể xử lý nó.

Giải trình

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 byte

Quản lý để chơi golf giảm 19 byte nhờ vào các đề xuất của @Thomas Kwa ở trên result or['0'], cộng với sắp xếp lại một số đại số ( 154 byte ):

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

Nỗ lực tốt nhất của tôi cho đến nay ( 173 byte ). Dựa trên cách tiếp cận mới, xem dưới cùng của bài viết:

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]

đánh gôn ban đầu của tôi xuống tới 180 byte :

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]

Tôi đã học được một tính năng ngôn ngữ mới ngày hôm nay để làm điều này! Điều kiện thông qua lập chỉ mục boolean. Tôi có thể đã hơi quá liều nó.

Tôi đã cố gắng trừu tượng hóa những hiểu biết, nhưng tôi không thể làm cho nó ngắn hơn ( 196 byte ):

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

(Đảo ngược trình tự là tốn kém!)

Trong khi tôi là ngắn hơn bây giờ, tôi nghĩ rằng TanMath có thể chơi golf của mình xuống để phù hợp với tôi: Sử dụng e=enumerate, thay thế passvới 0, và sử dụng '0'ở vị trí của ['0']trong báo cáo lợi nhuận nên tiết kiệm 4 + 3 + 2 = 9 byte! Giảm xuống còn 187. Tôi chắc chắn một vài byte khác có thể bị xóa ở đâu đó ...

chỉnh sửa Cách tiếp cận mới ( 156 byte ). Tuy nhiên, nó chỉ có thể xử lý với độ chính xác lên đến 6dp tương tự như mục nhập CJam của @ jimmy23013, vì vậy nó đã thất bại trong bài kiểm tra cuối cùng. Tôi không thể ép buộc nó in thêm 0, có thể người khác có thể. Thay vào đó, tôi đã sử dụng nó làm cơ sở cho nỗ lực tốt nhất của mình, xem trên cùng (Ngoài ra, cách tiếp cận này in 0 trước vị trí thập phân, nhưng điều đó cũng có vẻ hợp lệ.). Lấy try:... except:...cách tiếp cận từ 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] 

Nếu bạn đang cố gắng giúp tôi chơi golf, vui lòng đưa chúng vào làm nhận xét cho câu trả lời của tôi chứ không phải trong câu trả lời của bạn. Không phải lúc nào tôi cũng thấy câu trả lời của bạn, vì vậy bằng cách viết bình luận, tôi sẽ nhận được thông báo và chắc chắn sẽ thấy nó.
TanMath

2
Xin chào @TanMath. Tôi sẽ, nhưng tôi chưa có đủ đại diện để bình luận về bài viết của người khác. Khi tôi nhận được thêm một vài chiếc thuyền, tôi chắc chắn sẽ để lại phản hồi trong các bình luận.
Ogaday

2

bash tinh khiết, 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}

hoặc là

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}

Kiểm tra:

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 byte

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

Một hàm đệ quy thực sự, thực sự lộn xộn, có lẽ không phải là cách tốt nhất để làm điều này. Đầu vào như thế nào f("10.0203").


Đây có phải là Python không? Yêu nó.
Ogaday

2

C, 155 153 161 byte

+2 để liên kết trong thư viện toán học (nguồn chính là 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;}

Ung dung

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

APL Dyalog , 47 byte

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

Lấy số ở dạng vector ký tự, vd '123'.

Ví dụ:

      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     

Lưu ý:
Lý do cho ví dụ cuối cùng được sửa đổi là APL, giống như một số bài nộp khác, theo mặc định sẽ chuyển sang ký hiệu khoa học cho các số cực đoan như vậy.
Cụm từ ↑⍕¨f¨,¨chỉ cần thiết để xử lý tất cả các ví dụ cùng một lúc.



1

perl, 132 byte

131 +1 cho -pcông tắc.

Điều này dựa trên câu trả lời trước của tôised :

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/

Bộ kiểm tra:

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 byte

Tất cả trên một dòng duy nhất:

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

Ung dung:

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

Các trường hợp thử nghiệm, cộng thêm một:

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 byte

Ew, tôi không thích chơi golf 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;

Hãy thử nó ở đây.


Điều này dường như không hoạt động với số nguyên.
F. Hauri

Tôi đặt liên kết Ideone sai. Nó không tính đến các thay đổi được thực hiện trong chế độ Chỉnh sửa. :( Nó sẽ hoạt động ngay bây giờ.
Paul Picard

Bạn có một lỗi ở đâu đó: khi tôi nhập 5nó trở lại 50.
F. Hauri

Thật kỳ lạ, vì tôi đã thử nghiệm 5 với liên kết tôi đã cung cấp ngày hôm qua sau khi bạn đưa ra nhận xét đầu tiên của mình. Tâm cố gắng bây giờ? (Tôi đã thay đổi liên kết một lần nữa)
Paul Picard

Tôi vừa kiểm tra tập lệnh của bạn trên trình thông dịch perl của tôi (v5.20.2)
F. Hauri

1

Java, 284 244 243 byte

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

Thật không may, tôi không thể tìm thấy cách tạo chuỗi lặp lại ngắn hơn:

  • xây dựng một char[]chiều dài cần thiết
  • sử dụng Arrays.fillđể thiết lập các ký tự
  • sử dụng new Stringđể nó có thể được nối

Với cảm hứng từ @Khaled A Khunaifer, tôi có thể cạo sạch 40 Byte.

Chỉnh sửa: indexOfmất một int, vì vậy tôi có thể thay thế '.'bằng 46. Thật không may, điều này dường như không thể với replace.


Tôi đã thu nhỏ nó xuống còn 250, kiểm tra ideone.com/HqLnMo
Khaled.K

@Khaled A Khunaifer Giải pháp của bạn dường như có vấn đề với các trường hợp kiểm tra một chữ số. Nhưng tôi thích cách bạn tạo ra số không.
ECS

.replace('\0','0')Stringchar.replace("\0","0")
Sửa

@Khaled A Khunaifer Nó hoạt động trong các trường hợp thử nghiệm của tôi, cũng là docs.oracle.com/javase/8/docs/api/java/lang/iêu
ECS

1

Python, 125 byte

Sau khi xóa câu trả lời đầu tiên của tôi (sry!) Không thể xử lý số lượng nhỏ do các vấn đề về máy epsilon, tôi đã tìm thấy một giải pháp khác. Nó xử lý float cũng như các số nguyên, các số 0 ở cuối (!) Và được viết dưới dạng hàm.

Cảm ơn @ogaday về các gợi ý hữu ích và bản sửa lỗi '0' nhỏ gọn!

Chơi gôn

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'

Ung dung:

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ử dụng:

>>> 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
Đẹp. f('0')Tuy nhiên, thất bại trong trường hợp thử nghiệm và khi tôi sao chép và dán thẳng vào trình thông dịch của mình, tôi nhận được ký hiệu khoa học (mà tôi nghĩ là ổn). Ngoài ra, list(c)là ngắn hơn. Nếu bạn ghép nối '.'trước khi biến nó thành một danh sách bạn không cần thêm []. Sử dụng findthay cho chỉ mục trên chuỗi trước khi biến nó thành một danh sách, sau khi thêm '.'cũng giúp bạn tiết kiệm một byte. Sắp xếp lại bất bình đẳng cho phép bạn cũng xóa một khoảng 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'
trắng

1

CoffeeScript, 144 byte

Giải pháp thẳng về phía trước:

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

Thực thi:


1

Stax , 18 byte

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

Chạy và gỡ lỗi nó

Giải nén, không được chỉnh sửa và nhận xét, nó trông như thế này.

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

Chạy cái này

Giống như nhiều giải pháp khác được đăng, nó tạo ra 9000000+9e-7cho trường hợp thử nghiệm cuối cùng. Theo tiền lệ được thiết lập, điều này được cho phép vì trường hợp thử nghiệm quá chính xác đối với ngôn ngữ.


0

Lua, 350 byte

Tôi nghĩ có hai cách để chơi golf hơn nữa:

  • Tôi có thể sử dụng macro.defineđể thay thế một số biểu thức commons (không thể kiểm tra ngay bây giờ và không chắc chắn rằng nó sẽ khiến tôi có được một số byte)

  • Sử dụng chia trên dấu chấm thay vì lặp trên toàn bộ chuỗi. Một lần nữa, tôi không chắc nó sẽ làm giảm kích thước của hàm này, vì thao tác chuỗi trong lua khá đau đớn.

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

Giải thích

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

Bạn có thể kiểm tra lua trực tuyến và sử dụng mã nguồn sau để chạy nó với một số trường hợp thử nghiệm

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 byte

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

Lưu ý: putchar(8)nên thực hiện một backspace.

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

Chi tiết , thử tại đây

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 byte

Giảm 8 ký tự bằng cách bỏ không gian và vô dụng 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

Các trường hợp thử nghiệm:

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 byte

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

Hoạt động với các số độ dài tùy ý vì nó sử dụng thao tác chuỗi trong suốt.

Không có mảng hiểu (122 byte):

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

Ung dung:

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

Theo như tôi biết, cú pháp hiểu mảng mới này là từ ECMAScript 7.
manatwork

@manatwork Cảm ơn, tôi đã cập nhật nó trong khi tôi đang thêm phiên bản chưa được chỉnh sửa.
Neil

0

R - 133 byte

Mạnh mẽ, bỏ qua Máy Epsilon và cũng hoạt động với các số 0 ở cuối.

a) Chơi gôn:

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

Ung dung:

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

Sử dụng:

f("900.008")
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.