Розгорніть число


58

Ви можете запам'ятати в першому чи другому класі, використовуючи розгорнуту форму, щоб дізнатися про значення місця чисел. Простіше пояснити на прикладі, тому врахуйте число 123. У розгорнутому вигляді вона представлена ​​як100 + 20 + 3 , що допомагає молодому розуму уявити значення місця. Це нагадує, як ви це говорите: сто (плюс) двадцять (плюс) три.

Ми можемо розширити це місце одиницями десяткових знаків: 2.718 => 2 + 0.7 + 0.01 + 0.008

Ваша задача полягає в тому, щоб написати програму або функцію, яка приймає позитивне число з плаваючою комою або нуль (припустимо, вона така велика або точна, як може обробити ваша мова; вона не буде в науковій нотації) або рядок і друкує / повертає її в розширеному вигляді як пояснено вище.

Вам не потрібні пробіли між +«s» або «нулем» перед десятковою точкою, тому приклад вище може бути 2+.7+.01+.008. Значення, які б дорівнювали нулю, повинні бути пропущені ( 101.01 => 100 + 1 + 0.01), якщо вхід не дорівнює нулю (див. Нижче).

У значень не повинно бути більше одного провідного нуля перед десятковою точкою або будь-яких проміжних нулів після нього (ні-ні:) 0060, 0000.2, 30., 30.000, .0400. Цьому теж буде відповідати вхід.

Оскільки у першокласників є короткі проміжки уваги, ваш код повинен бути якомога коротшим.

Тестові кейси

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
@ Доᴡɴɢᴏᴀᴛ рада, що мем все ще працює.
кіт

4
Було б смішно робити це так само, як ми (французький) розраховуємо, щоб люди бачились із випадком 97 (4 * 20 + 10 + 7) ^^
Катенкьо

2
@ jimmy23013 Так, поки це працює в теорії.
NinjaBearMonkey

1
@Ogaday Я не знаю, це лише деякі крайні випадки. Можливо, спосіб NBZ буде кращим, але все-таки, не варто, якщо це буде справді цікаво
Katenkyo

Відповіді:


6

CJam, 33 26 байт

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

Це не працюватиме з інтерпретатором Java; друк плаває по-різному. Спробуйте це з перекладачем CJam .

Друкується останній тестовий випадок 9000000+9e-7, який визнав дійсним @NinjaBearMonkey .

Дякуємо @ jimmy23013 за те, що ти граєш на 7 байт!

Як це працює

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округлятиметься до нуля замість підлоги.
користувач81655

Можна використовувати 0|Math.log10(n),p-=p<0замість Math.floor(Math.log10(n))?
Дом Гастінгс

1
@DomHastings Майже. Це не вдається, n<1тому що 0|воля pзрівняється 0як для, так 0.1і для -0.1. Найкоротший спосіб, який я можу придумати, - p=Math.log10(n),p=p-(p<0)|0це така ж довжина, як і використання Math.floor. :(
користувач81655

@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*)).

Почнемо з перетворення введення в окремий список компонентів, що передається в рядку, хоча правильним є лише провідна (або кінцева) цифра. Це робиться шляхом зловживання розділеним етапом. Замість того, щоб ділити вхід, ми співставляємо його всі, тому решта сегментів всі порожні. Видаляємо ці порожні сегменти з _опцією. Проблема полягає в тому, що розділені стадії також повертають значення всіх груп захоплення. Тому ми використовуємо підказку під час кожного матчу, щоб захопити правильну частину рядка: спочатку ми намагаємося знайти .ліворуч від збігу. Якщо це так, ми захоплюємо все з. до та включити цифру, яку ми зараз співставляємо. В іншому випадку ми повинні знаходитись у цілій частині введення, тому ми фіксуємо всі числа після відповідності (включаючи відповідність). Ми також повинні позбутися і десяткової крапки, тому друге захоплення необов’язково. Якщо їх немає\d захоплення, це просто видалить збіг із вхідних даних.

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

Тепер ми використовуємо етап транслітерації, щоб перетворити всі нулі, окрім провідних / кінцевих цифр, у нулі. Ми або збігаємо компонент, менший за 1, \..+\Bі \Bгарантує, що ми зупинимо відповідність на одну цифру до кінця, або ми співставимо цілу частину з тим, (?<=^\d).+де погляд за спиною гарантує, що ми починаємо одну цифру в число. Потім етап транслітерації замінить будь-які цифри ( 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")

Пояснення

Отже, вхід відокремлюється на цілу і десяткову частину. Потім є розуміння списку циклу. У цілій частині довжина рядка після символу в десятковій частині множиться на "0", щоб отримати стільки нулів в кінці, якщо цей символ.

Для десяткової частини індекс поточного символу - це число нулів перед ним, і така частина проста.

Спробуйте і виняток використовується для визначення того, має десяткову частину чи ні (використовуючи помилку).

Остаточний результат поєднується зі знаками плюс.

Спробуйте тут!


2
Я думаю, що o if o else ["0"]може бути o or["0"].
ліртосіаст

У чотирьох рядках є пробіл, який додається до вашого числа байтів. На четвертій лінії вам потрібно лише одна двокрапка. Ви можете видалити пробіли в наступних фрагментах: o=[(...)] for, e(I) if, e(i[1]) if, print "+"і зовнішньої дужкою в o=[(...)а, на самому ділі. Нарешті, ви можете взяти остаточне умовне з функції приєднання так: print"+".join(o)or"0"тому що приєднання поверне порожній список, якщо oвін порожній, тож умовний буде оцінювати так само, як заощадить вам один байт.
Огадай

3

Pyth, 30 байт

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

Тестовий набір

Основне рішення тут - замінити всі цифри на вході на 0, а потім вставити кожну цифру в потрібному місці, eval, відфільтрувати нулі та приєднатись до плюсів. На жаль, функція eval Pyth наразі не приймає провідні нулі. Я буду працювати над тим, щоб це виправити.

Щоб подолати цю проблему, я додав функцію помічника y, яка рекурсивно повторює eval, поки не буде видано жодної помилки, видаляючи першу цифру кожного разу. Зауважте, що ця функція буде нескінченно циклічна на недійсному введенні.

Також для введення знадобився окремий випадок 0.

Загалом, я вважаю, що код досить гарний, але мовні засоби можуть бути і кращими. Хто хоче помилок?


3

Пітон 3, 138

Це грунтується на підході TanMath / Огадая до читання числа як рядка та аналізує його таким чином. Мені потрібно використовувати призначення зірки, 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цифр. У нас також є спеціальний випадок нуля. Я міг би видалити ще два пробіли внизу, але мені подобається зберігати його досить.

Мінус полягає в тому, що він розбивається на поплавці з більш ніж 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)

Нижче - оригінал. Перша редакція полягала в скороченні нульового спеціального випадку, у другому редагуванні було видалення 0 перед десятковою, третє - у видаленні додаткових дужок та пробілів.

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!
lirtosiast

1
Щойно виявив це ... Мені доведеться намагатися не витрачати занадто багато часу на цьому сайті!
швидкісний літак

2

Математика, 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 вище про 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 може гольфи His вниз , щоб відповідати моїм: Використанню e=enumerate, заміна passз 0, і використовуючи'0' замість ['0']в заяві-відповіді слід зберегти 4 + 3 + 2 = 9 байт! Знімаючи це до 187. Я впевнений, що ще кілька байт можна десь поголити ...

редагувати Новий підхід ( 156 байт ). Однак він може мати справу лише з точністю до 6dp, подібною до запису CJam @ jimmy23013, тому він не дає остаточного тесту. Я не міг примусити його надрукувати більше 0-х, можливо, хтось ще може. Натомість я використав це як основу моєї найкращої спроби досі, дивіться вгорі (Крім того, цей підхід друкує 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 Я б хотів, але у мене ще недостатньо респондентів, щоб коментувати пости інших людей. Як тільки я отримаю ще кілька оновлень, я обов’язково залиште відгуки в коментарях.
Огадай

2

чистий баш, 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

Пітон, 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? Любіть це.
Огадай

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

Діалог 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 байти

131 +1 для -pвимикача.

Це ґрунтується на моїй попередній 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 байт

Усі в одному рядку:

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

Тестові приклади плюс один додатковий:

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 байт

Ев, я нобіш в гольф на 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;

Спробуйте тут.


Це, здається, не працює з цілими числами.
Ф. Хаурі

Я поставив неправильне посилання Ideone. Він не враховує зміни, внесені в режимі редагування. :( Це має працювати зараз.
Пол Пікард

У вас десь є помилка: коли я входжу, 5повертаюся 50.
Ф. Хаурі

Дивно, адже я перевірив 5 за посиланням, яке я надав вчора після того, як ви поставили свій перший коментар. Розум намагається зараз? (Я знову змінив посилання)
Пол Пікард

Я щойно перевірив ваш сценарій на моєму перекладаче perl (v5.20.2)
Ф. Хаурі

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 байт.

Редагувати: indexOfбере int, щоб я міг замінити '.'на 46. На жаль, це, здається, неможливо replace.


Мені вдалося зменшити його до 250, перевірте ideone.com/HqLnMo
Khaled.K

@Khaled A Khunaifer Начебто у вашому рішенні проблеми з однозначними тестовими кейсами. Але мені подобається ваш спосіб генерації нулів.
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

Пітон, 125 байт

Після видалення моєї першої відповіді (sry!), Яка не могла впоратися з невеликими цифрами через проблеми з машинним епсілоном, я знайшов інше рішення. Він обробляє як плаваючі, так і цілі числа, виводячи нулі (!) І записується як функція.

Дякуємо @ogaday за корисні підказки та за компактний '0'-fix!

Гольф:

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

Луа, 350 байт

Я думаю, що існує два способи продовжити гольф:

  • Я міг би використати macro.defineдля заміни деяких виразів Commons (не можу перевірити зараз, і не впевнений, що це змусить мене набрати кілька байтів)

  • Використовуйте розділення на крапку, а не ітерацію на цілому рядку. Ще раз я не впевнений, що це зменшить розмір цієї функції, оскільки маніпулювати струною в луа досить болісно.

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 Спасибі, я оновив його, поки додавав версію, яка не використовується.
Ніл

0

R - 133 байт

Надійна, ігнорує Machine Epsilon та працює також із задніми нулями.

а) Гольф:

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")
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.