Développer le nombre

58

Vous vous souviendrez peut-être en première ou en deuxième année en utilisant une forme développée pour en savoir plus sur la valeur de position des nombres. C'est plus facile à expliquer avec un exemple, alors considérez le nombre 123. Sous forme développée, il est représenté comme 100 + 20 + 3ce qui aide un jeune esprit à visualiser la valeur de position. Cela rappelle comment vous le dites: cent (plus) vingt (plus) trois.

Nous pouvons prolonger ce passé la place des unités avec des décimales: 2.718 => 2 + 0.7 + 0.01 + 0.008

Votre défi consiste à écrire un programme ou une fonction prenant un nombre à virgule flottante positif ou zéro (supposons qu'il soit aussi grand ou précis que votre langage peut le gérer; il ne s'agira pas de notation scientifique) ou chaîne et l'affiche / le renvoie sous forme développée. comme expliqué ci-dessus.

Vous n'avez besoin ni d'espaces entre le +'s ni du zéro avant le point décimal, ainsi l'exemple ci-dessus pourrait l'être 2+.7+.01+.008. Les valeurs qui seraient égales à zéro doivent être omises ( 101.01 => 100 + 1 + 0.01) sauf si l'entrée est zéro (voir ci-dessous).

Les valeurs ne doivent pas avoir plus d'un zéro avant le point décimal, ni de zéros à la fin (non-non:) 0060, 0000.2, 30., 30.000, .0400. L'entrée sera conforme à cela aussi.

Étant donné que les élèves de première année ont une capacité d'attention limitée, votre code devra être aussi court que possible.

Cas de test

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
NinjaBearMonkey
la source
22
+1 pour "Puisque les élèves de première année ont une capacité d'attention limitée, votre code devra être aussi court que possible."
Downgoat
2
@ Doᴡɴɢᴏᴀᴛ content de voir que le meme est toujours en cours d'exécution.
chat le
4
Il aurait été amusant de le faire de la même manière que nous le comptons, de voir des gens se débattre avec le cas de 97 (4 * 20 + 10 + 7) ^^
Katenkyo le
2
@ jimmy23013 Oui, tant que cela fonctionne en théorie.
NinjaBearMonkey le
1
@Ogaday Je ne sais pas, ce ne sont que quelques cas de bord. Peut-être que NBZ serait mieux, mais ne le faites pas si ce serait vraiment intéressant
Katenkyo

Réponses:

6

CJam, 33 26 octets

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

Cela ne fonctionnera pas avec l'interpréteur Java. elle imprime différemment. Essayez-le avec l' interprète CJam .

Le dernier cas de test est imprimé 9000000+9e-7et validé par @NinjaBearMonkey .

Merci à @ jimmy23013 pour le golf de 7 octets!

Comment ça fonctionne

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.
Dennis
la source
Basé sur la même idée: r_ee\'0fe<f{\~t~}{},'+*0e|.
Jimmy23013
@ jimmy23013 Wow, c'est court! Je vous remercie!
Dennis
5

JavaScript (ES7), 102 octets

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

Explication

Requiert que le nombre soit saisi sous forme de chaîne sans zéros non majuscules (sauf s’il s’agit 0 bien entendu du nombre ).

Remarque: en raison de l'étrangeté en virgule flottante, certains nombres (comme .3) ne sont pas corrects, mais théoriquement, cela fonctionne pour n'importe quel nombre.

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 +

Tester

Testez utilise Math.powau lieu de **pour la compatibilité du navigateur.

utilisateur81655
la source
Math.floor=> 0|...?
ETHproductions
@ETHproductions Si le nombre saisi est inférieur au nombre indiqué, 1il Math.log10(n)renverrait un nombre négatif et |0arrondit à zéro au lieu du revêtement de sol.
user81655
Pouvez-vous utiliser 0|Math.log10(n),p-=p<0au lieu de Math.floor(Math.log10(n))?
Dom Hastings le
1
@DomHastings Presque. Il échoue pour n<1parce que le 0|fera pégale 0pour les deux 0.1et -0.1. Le moyen le plus court p=Math.log10(n),p=p-(p<0)|0auquel je puisse penser est celui qui a la même longueur que l’utilisation Math.floor. :(
user81655
@DomHastings Cela ne fonctionnerait toujours pas n=0.1.
Neil
5

Retina , 86 77 75 octets

Le nombre d'octets suppose que la source est codée en tant qu'ISO 8859-1.

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

Le retour à la ligne est important.

Essayez-le en ligne.

Explication

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

Nous commençons par transformer l'entrée en une liste de composants séparée par saut de ligne, bien que seul le premier chiffre (ou le dernier chiffre) soit correct. Cela se fait en abusant d'une étape fractionnée. Au lieu de scinder l’entrée, nous faisons correspondre toutes les entrées, les segments restants sont donc tous vides. Nous supprimons ces segments vides avec l' _option. Le problème est que les étapes fractionnées renvoient également les valeurs de tous les groupes de capture. Nous utilisons donc un lookahead à chaque correspondance pour capturer la partie correcte de la chaîne: nous essayons d’abord de trouver une partie .gauche de la correspondance. Si tel est le cas, nous capturons tout de la.jusqu'à et y compris le chiffre que nous correspondons actuellement. Sinon, nous devons être dans la partie entière de l’entrée, nous allons donc capturer tous les nombres après la correspondance (y compris la correspondance). Nous devons également supprimer le point décimal lui-même, la deuxième capture est donc facultative. S'il n'y a aucune \dcapture à faire, cela supprimera simplement la correspondance de l'entrée.

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

Nous utilisons maintenant une étape de translittération pour convertir tous les chiffres sauf les premiers / derniers en zéros. Nous correspondre soit à un composant qui est inférieur à 1 avec \..+\Blequel les \Bassure que nous nous arrêtons le match un chiffre avant la fin, ou nous correspond à une partie entière avec (?<=^\d).+laquelle les assure que nous arrières , commencent un chiffre dans le numéro. L'étape de translittération remplacera alors les chiffres ( d) par des zéros à l'intérieur des correspondances.

¶([.0]+¶)*
+

Maintenant, le format de sortie actuel ne devrait +pas utiliser de sauts de ligne comme séparateurs. Le correspond à un saut de ligne pour faire la substitution. Pendant que nous y sommes, nous supprimons également les lignes qui ne contiennent que 0s et .s.

^0.|\+0$

L'étape précédente ne supprime pas les caractères d'avance ou de fin 0(car ceux-ci n'ont pas de saut de ligne avant et après eux), nous les supprimons donc explicitement.

Martin Ender
la source
4

Python 2, 216 210 196 175 octets

Voici quelques codes légèrement golfés que je jouerai plus loin quand j'aurai le temps. Il utilise une analyse de chaîne.

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

Explication

Ainsi, l’entrée est séparée en une partie entière et décimale. Ensuite, il y a une compréhension pour la liste de boucle. Sur la partie entière, la longueur de la chaîne après un caractère dans la décimale est multipliée par "0" pour obtenir autant de zéros à la fin de ce caractère.

Pour la partie décimale, l'index du caractère en cours est le nombre de zéros qui le précède et cette partie est donc simple.

L'essai et l'exception est utilisé pour déterminer s'il a une partie décimale ou non (en utilisant une erreur).

Le résultat final est associé à des signes plus.

Essayez-le ici!

TanMath
la source
2
Je pense o if o else ["0"]peut être o or["0"].
lirtosiast
Vous avez un espace de fin sur la ligne quatre qui ajoute à votre nombre d'octets. Sur la ligne quatre, vous n'avez besoin que d'un colon. Vous pouvez supprimer les espaces dans les extraits suivants: o=[(...)] for, e(I) if, e(i[1]) if, print "+"et la parenthèse extérieure dans o=[(...)aussi bien, en fait. Enfin, vous pouvez supprimer la condition finale de la fonction de jointure de la manière suivante: print"+".join(o)or"0"parce que join retournera une liste vide si oest vide, la conditionnelle sera évaluée de la même manière, ce qui vous permettra d'économiser un octet.
Ogaday
3

Pyth, 30 octets

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

Suite de tests

La solution de base consiste à remplacer tous les chiffres de l’entrée par 0, à insérer chaque chiffre à l’emplacement approprié, à évaluer, à filtrer les zéros et à se joindre au plus. Malheureusement, la fonction eval de Pyth n'accepte pas les zéros non significatifs pour le moment. Je vais travailler pour résoudre ce problème.

Pour résoudre ce problème, j'ai ajouté une fonction d'assistance y, qui relance récursivement l'évaluation jusqu'à ce qu'aucune erreur ne soit générée, en supprimant le premier chiffre à chaque fois. Notez que cette fonction sera bouclée indéfiniment sur une entrée invalide.

En outre, un cas spécial était nécessaire pour la saisie 0.

Globalement, je pense que le code est plutôt bon, mais les installations linguistiques pourraient être meilleures. Qui veut des erreurs?

isaacg
la source
3

Python 3, 138

Ceci est vaguement basé sur l’approche de TanMath / Ogaday consistant à lire le nombre sous forme de chaîne et à l’analyser de cette façon. Je dois utiliser l’affectation des étoiles ipour qu’elle gère correctement les entiers.

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))
Morgan Thrapp
la source
3

Python, 141 132 128 octets

Celui-ci est encore relativement lisible. Convertissez en chaîne et gérez les >1chiffres séparément des <1chiffres. Nous avons également un cas particulier pour zéro. Je pourrais supprimer deux autres espaces en-dessous, mais j'aime bien le garder.

L'inconvénient est qu'il sera ventilé pour les flotteurs avec plus de 9 décimales.

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)

Ci-dessous est l'original. La première modification consistait à raccourcir le cas spécial zéro, la deuxième à supprimer le 0 avant la virgule, la troisième à supprimer certaines parenthèses et espaces.

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

Explication:

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
avion rapide
la source
Vous n'avez pas besoin d'inclure chaque révision de votre code; Si nous voulons voir vos progrès en matière de golf, nous pouvons consulter l'historique des révisions. Au fait, bienvenue à PPCG!
lirtosiast
1
Je viens de le découvrir ... Je vais devoir essayer de ne pas passer trop de temps sur ce site!
avion rapide le
2

Mathematica, 81 octets

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

Cas de test:

%[101.01]
(* 100. + 1. + 0.01 *)
njpipeorgan
la source
3
Je ne pense pas qu'il soit permis d'avoir le point décimal sur les parties entières.
Martin Ender
2

CJam, 44 octets

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

Essayez ici.

Il échoue le dernier cas de test et génère les éléments suivants:

9000000+9e-7

Mais disons que c'est trop précis que CJam ne peut pas le gérer.

Explication

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.
jimmy23013
la source
2

Python 3, 187 180 173 154 octets

Géré au golf à un bon 19 octets grâce aux suggestions de @Thomas Kwa à propos de la result or['0']réorganisation de l'algèbre ( 154 octets ):

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

Ma meilleure tentative jusqu'ici ( 173 octets ). Basé sur une nouvelle approche, voir le bas de l'article:

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]

J'ai joué mon original à 180 octets :

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]

J'ai appris une nouvelle fonctionnalité de langue aujourd'hui en faisant cela! Conditions conditionnelles via indexation booléenne. J'ai peut-être un peu exagéré.

J'ai essayé de résumer les compréhensions, mais je ne pouvais pas la raccourcir ( 196 octets ):

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

(Inverser les séquences coûte cher!)

Bien que le mien soit plus court pour l’instant, je pense que TanMath peut jouer comme il le souhaite: utiliser e=enumerate, remplacer passpar0 et utiliser '0'à la place de ['0']la déclaration doit faire économiser 4 + 3 + 2 = 9 octets! Je suis sûr que quelques octets supplémentaires peuvent être supprimés quelque part ...

edit Nouvelle approche ( 156 octets ). Cependant, il ne peut gérer qu'une précision allant jusqu'à 6dp, similaire à l'entrée CJam de @ jimmy23013, de sorte qu'il échoue au test final. Je ne pouvais pas le contraindre à imprimer plus de 0, peut-être que quelqu'un d'autre peut le faire. Au lieu de cela, je l'ai utilisé comme base de ma meilleure tentative pour le moment, voir ci-dessus (De plus, cette approche affiche le 0 avant la décimale, mais cela semble également valable.). A pris l' try:... except:...approche de 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] 
Ogaday
la source
Si vous essayez de m'aider à jouer au golf, incluez-les dans vos commentaires, pas dans votre réponse. Je ne vois pas toujours vos réponses, alors en écrivant un commentaire, je vais recevoir un avis et le voir.
TanMath
2
Bonjour @ Tanath. Je le ferais, mais je n'ai pas assez de représentant pour commenter les messages d'autres personnes. Une fois que j'aurai quelques bateaux supplémentaires, je veillerai à laisser des commentaires dans les commentaires.
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}

ou

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}

Tester:

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
F. Hauri
la source
2

Python, 131 octets

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

Une fonction récursive vraiment très compliquée, probablement pas la meilleure façon de procéder. Entrée comme f("10.0203").

Sp3000
la source
Est-ce même Python? Aimer.
Ogaday
2

C, 155 153 161 octets

+2 à lier dans la bibliothèque mathématique (la source elle-même est 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 */
    }
}
Cole Cameron
la source
2

Dyalog APL , 47 octets

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

Prend nombre sous forme de vecteur de caractères, par exemple '123'.

Exemples:

      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     

Remarques:
○ La raison du dernier exemple modifié est que APL, comme certaines des autres soumissions, passera par défaut à la notation scientifique pour des nombres aussi extrêmes.
○ La phrase ↑⍕¨f¨,¨n'est nécessaire que pour traiter tous les exemples à la fois.

Adam
la source
1

Rétine, 113 octets

Actuellement beaucoup plus long que la solution de Martin mais utilise une méthode différente, j'ai donc décidé de l'afficher.

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

¶\..*¶.*

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

Essayez-le en ligne ici.

randomra
la source
1

perl, 132 octets

131 +1 pour le -pcommutateur.

Ceci est basé sur ma sedréponse précédente :

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/

Suite de tests:

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
F. Hauri
la source
1

Powershell - 172 166 193 octets

Tous sur une seule ligne:

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

Cas de test, plus un supplémentaire:

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>
Chris J
la source
1

Perl, 248 octets

Eh bien, je suis noobish au 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;

Essayez ici.

Paul picard
la source
Cela ne semble pas fonctionner avec des nombres entiers.
F. Hauri
Je mets le mauvais lien Ideone. Il ne prend pas en compte les modifications apportées en mode édition. :( Cela devrait fonctionner maintenant.
Paul Picard
Vous avez une part d'erreur: quand je rentre dans 5ce retour 50.
F. Hauri
Étrange, depuis que j'ai testé 5 avec le lien que j'ai fourni hier après avoir mis votre premier commentaire. Tu veux essayer maintenant? (J'ai de nouveau changé le lien)
Paul Picard
Je viens de tester votre script sur mon interprète Perl (v5.20.2)
F. Hauri
1

Java, 284 244 243 octets

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

Malheureusement, je ne pouvais pas trouver un moyen plus court de créer des chaînes répétitives que:

  • construire un char[]de la longueur requise
  • utiliser Arrays.fillpour définir les caractères
  • utiliser new Stringafin qu'il puisse être concaténé

Inspiré par @Khaled A Khunaifer, je pouvais me débarrasser de 40 octets.

Edit: indexOfprend un int, je pourrais donc le remplacer '.'par 46. Malheureusement, cela ne semble pas être possible avec replace.

ECS
la source
J'ai réussi à le réduire à 250, consultez ideone.com/HqLnMo
Khaled.K
@Khaled A Khunaifer Votre solution semble avoir des problèmes avec les cas de test à un chiffre. Mais j'aime votre façon de générer les zéros.
ECS
corriger cette .replace('\0','0')fonction remplacer Stringne chardevrait pas , il devrait être.replace("\0","0")
Khaled.K
@Khaled A Khunaifer Cela fonctionne dans mes cas de test, également docs.oracle.com/javase/8/docs/api/java/lang/…
ECS le
1

Python, 125 octets

Après avoir supprimé ma première réponse (sry!) Qui ne pouvait pas gérer de petits nombres en raison de problèmes de machine epsilon, j'ai trouvé une solution différente. Il gère les flottants ainsi que les entiers, les zéros de fin (!) Et est écrit en tant que fonction.

Merci à @ogaday pour les astuces utiles et pour le compact '0'-fix!

Golfé:

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'

Usage:

>>> 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'
LambruscoAcido
la source
1
Agréable. f('0')Cela échoue cependant, et quand je copie / colle directement dans mon interprète, je reçois la notation scientifique (ce qui me semble bien). Aussi, list(c)est plus courte. Si vous concaténez le '.'avant de le transformer en une liste, vous n'avez pas besoin de l'ajouter []non plus. Utiliser findau lieu d'index sur la chaîne avant de la transformer en liste, après l'ajout '.'vous enregistre également un octet. Réordonner l'inégalité vous permet également de supprimer un espace supplémentaire: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'
Ogaday
1

CoffeeScript, 144 octets

Solution simple:

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

Exécutable:

métalim
la source
1

Stax , 18 octets

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

Exécuter et déboguer

Déballé, non golfé et commenté, cela ressemble à ceci.

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

Exécuter celui-ci

Comme beaucoup d'autres solutions publiées, il produit 9000000+9e-7pour le dernier cas de test. Selon les précédents établis, cela est autorisé car le test élémentaire est trop précis pour la langue.

récursif
la source
0

Lua, 350 octets

Je pense qu'il y a deux façons de jouer plus bas:

  • Je pourrais utiliser macro.definepour remplacer certaines expressions communes ( je ne peux pas tester pour le moment, et je ne suis pas sûr que cela me ferait gagner des octets)

  • Utilisez split sur le point au lieu d'itérer sur toute la chaîne. Encore une fois, je ne suis pas sûr que cela réduirait la taille de cette fonction, car la manipulation de ficelle dans Lua est assez pénible.

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

Des explications

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

Vous pouvez tester lua en ligne et utiliser le code source suivant pour l'exécuter avec certains cas de test.

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"))
Katenkyo
la source
0

C, 253 octets

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

Remarque: putchar(8)devrait effectuer un retour arrière.

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

Détaillé , essayez ici

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);
Khaled.K
la source
0

sed, 136 128 octets

Réduit de 8 caractères en laissant tomber des espaces et inutile 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

Cas de test:

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
F. Hauri
la source
0

JavaScript (ES7), 114 octets

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

Fonctionne avec des nombres de longueur arbitraires car il utilise une manipulation de chaîne.

Sans la compréhension du tableau (122 octets):

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;
}
Neil
la source
Pour autant que je sache, cette nouvelle syntaxe de compréhension de tableau provient de ECMAScript 7.
manatwork
@manatwork Merci, je l'ai mis à jour pendant que j'ajoutais la version sans golf.
Neil
0

R - 133 octets

Robuste, ignore Machine Epsilon et fonctionne également avec des zéros à la fin.

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

Usage:

f("900.008")
LambruscoAcido
la source