Erweitern Sie die Nummer


58

Sie können sich in der ersten oder zweiten Klasse daran erinnern, wie Sie in erweiterter Form den Stellenwert von Zahlen gelernt haben. Es ist einfacher, mit einem Beispiel zu erklären, also überlegen Sie sich die Zahl 123. In erweiterter Form wird es als dargestellt 100 + 20 + 3, was einem jungen Geist hilft, den Wert eines Ortes zu visualisieren. Es erinnert daran, wie Sie es sagen: einhundert (plus) zwanzig (plus) drei.

Wir können dies über die Einheitsstelle hinaus mit Dezimalstellen erweitern: 2.718 => 2 + 0.7 + 0.01 + 0.008

Ihre Herausforderung besteht darin, ein Programm oder eine Funktion zu schreiben, das / die eine positive Gleitkommazahl oder Null annimmt (vorausgesetzt, es ist so groß oder genau, wie Ihre Sprache es verarbeiten kann; es wird nicht in wissenschaftlicher Notation geschrieben) oder eine Zeichenfolge und es in erweiterter Form auszudrucken / zurückzugeben wie oben erklärt.

Sie brauchen weder ein Leerzeichen zwischen dem +'s noch der Null vor dem Dezimalpunkt, also könnte das obige Beispiel sein 2+.7+.01+.008. Werte, die gleich Null wären, müssen weggelassen werden ( 101.01 => 100 + 1 + 0.01), es sei denn, die Eingabe ist Null (siehe unten).

Werte sollten nicht mehr als eine führende Null vor dem Dezimalpunkt oder nachfolgende Nullen (no-no's:) enthalten 0060, 0000.2, 30., 30.000, .0400. Der Eingang wird auch diesem entsprechen.

Da Erstklässler nur eine kurze Aufmerksamkeitsspanne haben, muss Ihr Code so kurz wie möglich sein.

Testfälle

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 für "Da Erstklässler nur eine kurze Aufmerksamkeitsspanne haben, muss Ihr Code so kurz wie möglich sein."
Downgoat

2
@ Freut mich zu sehen, dass das Mem noch läuft.
Katze

4
Es wäre lustig, wenn wir es genauso machen würden, wie wir (Franzosen) zählen, um zu sehen, wie die Leute mit dem Fall 97 (4 * 20 + 10 + 7)
kämpfen.

2
@ jimmy23013 Ja, solange es theoretisch funktioniert.
NinjaBearMonkey

1
@Ogaday Ich weiß nicht, es sind nur einige Randfälle. Vielleicht wäre der NBZ-Weg besser, aber nicht, wenn es wirklich interessant wäre
Katenkyo

Antworten:


6

CJam, 33 26 Bytes

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

Dies funktioniert mit dem Java-Interpreter nicht. es druckt schwebt anders. Probieren Sie es mit dem CJam-Interpreter aus .

Der letzte Testfall wird gedruckt 9000000+9e-7, der von @NinjaBearMonkey als gültig eingestuft wurde .

Danke an @ jimmy23013 für das Golfen mit 7 Bytes!

Wie es funktioniert

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.

Basierend auf der gleichen Idee: r_ee\'0fe<f{\~t~}{},'+*0e|.
Jimmy23013

@ jimmy23013 Wow, das ist kurz! Danke!
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`+`

Erläuterung

Erfordert die Eingabe der Nummer als Zeichenfolge ohne führende Nullen (es sei denn, die Nummer ist 0 natürlich).

Hinweis: Aufgrund der Fließkomma-Verrücktheit kommen einige Zahlen (wie .3) falsch heraus, aber theoretisch funktioniert dies für jede Zahl.

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 +

Prüfung

Testverwendung Math.powstatt aus **Gründen der Browserkompatibilität.


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

@ETHproductions Wenn die eingegebene Zahl kleiner ist als 1sie unterbrochen wird, wird Math.log10(n)eine negative Zahl zurückgegeben und |0anstelle von Flooring auf Null gerundet.
user81655

Können Sie 0|Math.log10(n),p-=p<0anstelle von verwenden Math.floor(Math.log10(n))?
Dom Hastings

1
@ DomHastings Fast. Es schlägt fehl , für , n<1weil die 0|machen pgleich 0für beide 0.1und -0.1. Der kürzeste Weg, den ich mir vorstellen kann, ist p=Math.log10(n),p=p-(p<0)|0der, der genauso lang ist wie die Verwendung Math.floor. :(
user81655

@DomHastings Würde trotzdem nicht funktionieren n=0.1.
Neil

5

Retina , 86 77 75 Bytes

Die Byteanzahl setzt voraus, dass die Quelle als ISO 8859-1 codiert ist.

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

Der Zeilenvorschub am Ende ist signifikant.

Probieren Sie es online aus.

Erläuterung

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

Wir beginnen damit, die Eingabe in eine separate Zeilenvorschubliste von Komponenten umzuwandeln, obwohl nur die führende (oder nachfolgende) Ziffer korrekt ist. Dies geschieht durch den Missbrauch einer geteilten Stufe. Anstatt die Eingabe zu teilen, passen wir sie alle an, sodass die verbleibenden Segmente alle leer sind. Wir entfernen diese leeren Segmente mit der _Option. Der Haken ist, dass geteilte Stufen auch die Werte aller einfangenden Gruppen zurückgeben. Daher verwenden wir bei jedem Match einen Lookahead, um den richtigen Teil des Strings zu erfassen: Zuerst versuchen wir, einen .linken Teil des Matches zu finden. In diesem Fall erfassen wir alles aus dem.Bis einschließlich der Ziffer, die wir gerade abgleichen. Andernfalls müssen wir uns im ganzzahligen Teil der Eingabe befinden, damit wir alle Zahlen nach der Übereinstimmung erfassen (einschließlich der Übereinstimmung). Wir müssen auch den Dezimalpunkt selbst loswerden, sodass die zweite Erfassung optional ist. Wenn keine \dzu erfassenden Elemente vorhanden sind , wird die Übereinstimmung einfach aus der Eingabe entfernt.

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

Jetzt verwenden wir eine Transliterationsstufe, um alle bis auf die führenden / nachfolgenden Ziffern in Nullen umzuwandeln. Wir passen entweder eine Komponente an, die kleiner als 1 ist, mit \..+\Bder \Bsichergestellt wird, dass die Übereinstimmung um eine Ziffer vor dem Ende (?<=^\d).+abgebrochen wird , oder wir passen einen ganzzahligen Teil an, mit der der LookBehind sichergestellt wird, dass eine Ziffer in der Zahl beginnt. Die Transliterationsstufe ersetzt dann alle Ziffern ( d) durch Nullen innerhalb der Übereinstimmungen.

¶([.0]+¶)*
+

Jetzt sollte das eigentliche Ausgabeformat +keine Zeilenvorschübe als Trennzeichen verwenden. Das entspricht einem Zeilenvorschub, um diese Ersetzung durchzuführen. Während wir gerade dabei sind, entfernen wir auch Zeilen, die nur 0s und .s enthalten.

^0.|\+0$

In der vorherigen Phase wird weder ein führendes 0noch ein nachfolgendes Element entfernt (da davor und danach kein Zeilenvorschub vorhanden ist). Daher werden diese explizit entfernt.


4

Python 2, 216 210 196 175 Bytes

Hier ist ein leicht golfener Code, den ich weiter spielen werde, wenn ich Zeit habe. Es wird eine String-Analyse verwendet.

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

Erläuterung

Die Eingabe ist also in einen ganzzahligen und einen dezimalen Teil unterteilt. Dann gibt es ein Verständnis für for-Schleifenlisten. Im ganzzahligen Teil wird die Länge des Strings nach einem Zeichen in der Dezimalzahl mit "0" multipliziert, um am Ende dieses Zeichens so viele Nullen zu erhalten.

Für den Dezimalteil ist der Index des aktuellen Zeichens die Anzahl der vorangestellten Nullen, sodass dieser Teil einfach ist.

Das try und except wird verwendet, um zu bestimmen, ob es einen Dezimalteil hat oder nicht (unter Verwendung eines Fehlers).

Das Endergebnis wird mit Pluszeichen verbunden.

Probieren Sie es hier aus!


2
Ich denke o if o else ["0"]kann sein o or["0"].
Lirtosiast

Sie haben ein Leerzeichen in Zeile vier, das Ihre Byteanzahl erhöht. In Zeile 4 benötigen Sie nur einen Doppelpunkt. : Sie können die Räume in den folgenden Schnipsel löschen o=[(...)] for, e(I) if, e(i[1]) if, print "+", und die äußere Klammer in o=[(...)als auch, eigentlich. Schließlich können Sie die endgültige Bedingung wie print"+".join(o)or"0"folgt aus der Join-Funktion entfernen: Da der Join eine leere Liste zurückgibt, wenn diese oleer ist, wird die Bedingung auf die gleiche Weise ausgewertet, mit der Sie ein Byte sparen.
Ogaday

3

Pyth, 30 Bytes

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

Testsuite

Die grundlegende Lösung besteht darin, alle Ziffern in der Eingabe durch zu ersetzen 0, dann jede Ziffer an der richtigen Stelle einzufügen, auszuwerten, die Nullen herauszufiltern und Pluszeichen zu setzen. Leider akzeptiert Pyths Eval-Funktion derzeit keine führenden Nullen. Ich werde daran arbeiten, dies zu beheben.

Um dieses Problem zu umgehen, habe ich eine Hilfsfunktion hinzugefügt y, die die Auswertung rekursiv wiederholt, bis kein Fehler mehr auftritt. Dabei wird jedes Mal die erste Ziffer entfernt. Beachten Sie, dass diese Funktion bei ungültiger Eingabe eine Endlosschleife ausführt.

Auch für die Eingabe wurde ein Sonderfall benötigt 0.

Alles in allem finde ich den Code ziemlich gut, aber die Sprachausstattung könnte besser sein. Wer will Fehler?


3

Python 3, 138

Dies basiert lose auf TanMath / Ogadays Ansatz, die Zahl als Zeichenfolge zu lesen und auf diese Weise zu analysieren. Ich muss die Sternzuweisung verwenden i, damit Ganzzahlen korrekt verarbeitet werden.

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 Bytes

Dieser ist noch relativ gut lesbar. In Zeichenfolge konvertieren und die >1Ziffern getrennt von den <1Ziffern behandeln. Wir haben auch einen Sonderfall für Null. Ich könnte zwei Leerzeichen weiter unten entfernen, aber ich mag es, es hübsch zu halten.

Der Nachteil ist, dass es für Floats mit mehr als 9 Dezimalstellen aufschlüsselt.

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)

Unten ist das Original. Die erste Änderung bestand darin, den Sonderfall Null zu verkürzen, die zweite Änderung bestand darin, die 0 vor der Dezimalstelle zu entfernen, und die dritte darin, zusätzliche Klammern und Leerzeichen zu entfernen.

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

Erläuterung:

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

Sie müssen nicht jede Revision Ihres Codes einbeziehen. Wenn wir Ihren Golffortschritt sehen möchten, können wir die Revisionshistorie einsehen. Übrigens, willkommen bei PPCG!
Lirtosiast

1
Habe es gerade entdeckt ... Ich werde versuchen müssen, nicht zu viel Zeit auf dieser Seite zu verbringen!
Speedplane

2

Mathematica, 81 Bytes

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

Testfall:

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

3
Ich denke nicht, dass es erlaubt ist, den Dezimalpunkt über den Ganzzahlteilen zu haben.
Martin Ender

2

CJam, 44 Bytes

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

Probieren Sie es hier aus.

Es schlägt den letzten Testfall fehl und gibt Folgendes aus:

9000000+9e-7

Aber sagen wir, es ist zu genau, dass CJam nicht damit umgehen kann.

Erläuterung

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 Bytes

Dank der obigen Vorschläge von @Thomas Kwa und der result or['0']Neuordnung einiger Algebra- Elemente ( 154 Bytes ) konnten gut 19 Bytes weniger golfen werden :

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

Mein bisher bester Versuch ( 173 Bytes ). Basierend auf einem neuen Ansatz, siehe unten im Beitrag:

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]

hat mein Original auf 180 Bytes abgespielt :

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]

Ich habe heute ein neues Sprachfeature dazu gelernt! Bedingungen über Boolesche Indizierung. Ich habe es vielleicht etwas übertrieben.

Ich habe versucht, das Verständnis zu abstrahieren, aber ich konnte es nicht kürzer machen ( 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))]

(Das Umkehren von Sequenzen ist teuer!)

Während meine für den Moment kürzer ist, denke ich, dass TanMath seine Daunen so spielen kann, dass sie meiner entsprechen: Durch Verwenden e=enumerate, Ersetzen passdurch 0und Verwenden '0'anstelle ['0']der return-Anweisung sollten 4 + 3 + 2 = 9 Bytes gespart werden! Ich bin sicher, dass noch ein paar Bytes irgendwo abgeschabt werden können ...

edit Neuer Ansatz ( 156 Bytes ). Es kann jedoch nur mit einer Genauigkeit von bis zu 6 dpi umgehen, die dem CJam-Eintrag von @ jimmy23013 ähnelt, sodass der endgültige Test fehlschlägt. Ich konnte es nicht erzwingen, mehr Nullen zu drucken, vielleicht kann es jemand anderes. Stattdessen habe ich es als Grundlage für meinen bislang besten Versuch verwendet (siehe oben). (Dieser Ansatz gibt auch die 0 vor der Dezimalstelle aus, aber das scheint auch gültig zu sein.) Nahm den try:... except:...Ansatz von 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] 

Wenn Sie versuchen, mir beim Golfen zu helfen, geben Sie diese bitte als Kommentar zu meiner Antwort an, nicht in Ihrer Antwort. Ich sehe Ihre Antworten nicht immer. Wenn ich einen Kommentar schreibe, erhalte ich eine Benachrichtigung und sehe sie auf jeden Fall.
TanMath

2
Hallo @ TanMath. Ich würde, aber ich habe noch nicht genug Repräsentanten, um die Beiträge anderer zu kommentieren. Sobald ich ein paar Upboats mehr bekomme, werde ich sichergehen, dass ich in den Kommentaren ein Feedback hinterlasse.
Ogaday

2

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

oder

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}

Prüfung:

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 Bytes

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

Eine wirklich, wirklich chaotische rekursive Funktion, wahrscheinlich nicht der beste Weg, dies zu tun. Eingabe wie f("10.0203").


Ist das überhaupt Python? Liebe es.
Ogaday

2

C 155 153 161 Bytes

+2 zum Verknüpfen in der Mathematikbibliothek (Quelle selbst ist 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 Bytes

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

Nimmt Nummer in Zeichenvektorform, z '123'.

Beispiele:

      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     

Anmerkungen:
○ Der Grund für das modifizierte letzte Beispiel ist, dass APL, wie einige der anderen Einreichungen, für solche extremen Zahlen standardmäßig auf wissenschaftliche Notation umschaltet.
○ Die Phrase ↑⍕¨f¨,¨wird nur benötigt, um alle Beispiele gleichzeitig zu verarbeiten.


1

Netzhaut, 113 Bytes

Derzeit viel länger als Martins Lösung , verwendet aber eine andere Methode, sodass ich mich entschied, sie zu posten.

^
x
S_`(?<=(.*)).(?=(.*))
x

¶\..*¶.*

$
¶
T`d`0`(?<=\d).*¶.*¶
(.*)¶(.*)¶
$2$1¶
(\..*?)0*¶
$1¶
\.?¶0*
¶
¶+
+
\+$
[empty line]

Probieren Sie es hier online aus.


1

Perl, 132 Bytes

131 +1 für -pSchalter.

Dies basiert auf meiner vorherigen sedAntwort :

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/

Testsuite:

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 Bytes

Alles in einer Zeile:

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

Testfälle plus ein weiteres:

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>

Ihr regulärer Ausdruck wird herausgefiltert $args = 0. Hier ist eine einfache Fehlerbehebung, die auch 3 Bytes spart
Veskah


1

Perl, 248 Bytes

Ew, ich bin bei Perl Golf noobish.

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

Probieren Sie es hier aus.


Dies scheint nicht mit Ganzzahlen zu funktionieren.
F. Hauri

Ich habe den falschen Ideone-Link gesetzt. Im Bearbeitungsmodus vorgenommene Änderungen werden nicht berücksichtigt. :( Es sollte jetzt funktionieren.
Paul Picard

Du hast irgendwo einen Fehler: wenn ich 5ihn eingebe, kehre ich zurück 50.
F. Hauri

Seltsam, da ich 5 mit dem Link getestet habe, den ich gestern bereitgestellt habe, nachdem Sie Ihren ersten Kommentar abgegeben haben. Versuchen Sie es jetzt? (Ich habe den Link wieder geändert)
Paul Picard

Ich habe gerade Ihr Skript auf meinem Perl-Interpreter (v5.20.2) getestet
F. Hauri

1

Java, 284 244 243 Bytes

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

Leider konnte ich keinen kürzeren Weg finden, um sich wiederholende Strings zu erstellen als:

  • baue eine char[]der benötigten länge
  • Verwenden Sie Arrays.fill, um die Zeichen einzustellen
  • Verwenden new StringSie diese Option, damit sie verkettet werden kann

Mit der Inspiration von @Khaled A Khunaifer konnte ich 40 Bytes abschneiden.

Edit: indexOfnimmt einen int, so konnte ich ersetzen '.'mit 46. Leider scheint dies mit nicht möglich zu sein replace.


Ich habe es geschafft, es auf 250 zu verkleinern, siehe ideone.com/HqLnMo
Khaled.K

@ Khaled A Khunaifer Ihre Lösung scheint Probleme mit einstelligen Testfällen zu haben. Aber ich mag deine Art, die Nullen zu generieren.
ECS

behebe diese .replace('\0','0')funktion ersetze erwarte Stringnicht char, es sollte sein.replace("\0","0")
Khaled.K

@Khaled A Khunaifer Es funktioniert auch in meinen Testfällen docs.oracle.com/javase/8/docs/api/java/lang/…
ECS

1

Python, 125 Bytes

Nachdem ich meine erste Antwort (sry!) Gelöscht hatte, die aufgrund von Maschinen-Epsilon-Problemen keine kleinen Zahlen verarbeiten konnte, fand ich eine andere Lösung. Es behandelt sowohl float als auch ganze Zahlen, folgt Nullen (!) Und wird als Funktion geschrieben.

Vielen Dank an @ogaday für die nützlichen Hinweise und für das kompakte '0'-Update!

Golf gespielt:

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'

Verwendungszweck:

>>> 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
Nett. Schlägt der f('0')Testfall jedoch fehl , und wenn ich direkt in meinen Interpreter kopiere und einfüge, erhalte ich die wissenschaftliche Notation (die ich für gut halte). Auch list(c)ist kürzer. Wenn Sie das verketten, '.'bevor Sie es in eine Liste verwandeln, müssen Sie auch nichts hinzufügen []. Wenn Sie findanstelle des Indexes den String verwenden, bevor Sie ihn in eine Liste umwandeln, '.'sparen Sie nach dem Hinzufügen auch ein Byte. Wenn Sie die Ungleichung neu 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'
anordnen,

1

CoffeeScript, 144 Bytes

Einfache Lösung:

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

Ausführbar:


1

Stax , 18 Bytes

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

Führen Sie es aus und debuggen Sie es

Ausgepackt, ungolfed und kommentiert sieht es so aus.

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

Führen Sie dieses aus

Wie die vielen anderen Lösungen, die veröffentlicht wurden, wird 9000000+9e-7für den letzten Testfall produziert. Laut etabliertem Präzedenzfall ist dies zulässig, da der Testfall für die Sprache zu genau ist.


0

Lua, 350 Bytes

Ich denke, es gibt zwei Möglichkeiten, weiter zu golfen:

  • Ich könnte es gebrauchen macro.define, um einige der allgemeinen Ausdrücke zu ersetzen (kann derzeit nicht testen und bin mir nicht sicher, ob ich dadurch einige Bytes gewinnen würde)

  • Verwenden Sie "Aufteilen auf den Punkt", anstatt die gesamte Zeichenfolge zu iterieren. Auch hier bin ich mir nicht sicher, ob es die Größe dieser Funktion verringern würde, da das Manipulieren von Strings in lua ziemlich schmerzhaft ist.

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

Erklärungen

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

Sie können lua online testen und den folgenden Quellcode verwenden, um es mit einigen Testfällen auszuführen

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 Bytes

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

Hinweis: putchar(8)Sollte eine Rücktaste ausführen.

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

Ausführlich , versuchen Sie es hier

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 bytes

Reduziert um 8 Zeichen durch Ablegen von Leerzeichen und unbrauchbar 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

Testfälle:

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

Funktioniert mit Zahlen beliebiger Länge, da durchgehend Zeichenfolgenmanipulation verwendet wird.

Ohne das Array-Verständnis (122 Bytes):

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

Soweit ich weiß, stammt diese neue Syntax für das Array-Verständnis aus ECMAScript 7.
manatwork

@manatwork Danke, ich habe es aktualisiert, als ich die ungolfed-Version hinzugefügt habe.
Neil

0

R - 133 Bytes

Robust, ignoriert Machine Epsilon und arbeitet auch mit nachgestellten Nullen.

a) Golf gespielt:

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

Verwendungszweck:

f("900.008")
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.