Trouvez le groupe motopropulseur!

29

Le gagnant (assez évidemment) est Dennis ♦, qui a utilisé Jelly avec 10 octets!

Ce défi sera toujours là, mais les résultats ne seront plus pris.


Le groupe motopropulseur d'un numéro est un concept de John Conway (qui est également connu pour avoir créé Game of Life de Conway, mais ce n'est pas le but). Il est défini comme suit:

Pour tout nombre entrez la description de l'image ici..., le groupe motopropulseur du nombre est entrez la description de l'image ici... (c'est-à-dire que chaque deuxième chiffre, de gauche à droite, est une puissance du chiffre avant cela). Ce processus est répété jusqu'à ce que le résultat soit un seul chiffre.

EXEMPLES:

2592 => (2^5)(9^2) = 2592 <= Cannot be further decomposed 135 => (1^3)5 = 5 1234 => (1^2)(3^4) = 81 => (8^1) = 8 1100 => (1^1)(0^0) = 1 # (0^0) = 1 -42 => -42 # Negative numbers output the input

Votre défi est, pour n'importe quel nombre ndans l'entrée, de retourner powertrain(n)(c'est- nà- dire une fois la décomposition du groupe motopropulseur terminée) en sortie.

C'est le golf de code, donc le plus petit nombre d'octets gagne.

AVIS DE NON-RESPONSABILITÉ:

  • Vous pouvez avoir un nombre impair de chiffres dans l'entrée, le dernier chiffre n'aura tout simplement pas de puissance.
  • 0 ^ 0 est 1, car s'il était égal à 0, alors beaucoup de nombres s'effondreraient instantanément à 0 ou 1.
  • Si le nombre est indestructible dans n'importe quelle partie du processus de calcul (par exemple s'il se termine par 2592), alors vous pouvez simplement sortir le nombre.
  • Si l'entrée est < 10(c'est-à-dire tous les nombres à un chiffre et les négatifs), sortez l'entrée.

J'annoncerai probablement un gagnant au bout de quelques heures .

Classement actuel:

  1. Gelée ( Dennis ♦ ): 10
  2. Pyth ( DenkerAffe ): 16
  3. MATL ( Don Muesli ): 21
  4. Perl ( Ton Hospel ): 42
  5. Haskell ( Damien ): 64
  6. Javascript ES6 ( edc65 ): 71
  7. Mathématiques ( murphy ): 74
  8. Mathematica ( LegionMammal978 ) et Haskell ( Renzeee ): 77
  9. Python 2 ( mathmandan ): 111
  10. Python 3 ( Erwan ): 161
  11. Java 8 ( bleu ): 229
  12. Oracle SQL 11.2 ( Jeto ): 456
  13. Befunge '93 ( Lex ): 490
clismique
la source
Quelques cas de test supplémentaires seraient appréciés.
Mego
L'entrée aura donc 4 chiffres maximum?
Denker
7
Que se passe-t-il si un cycle est atteint, mais la période du cycle n'est pas 1, ou le numéro d'entrée ne fait pas partie du cycle?
feersum
1
"Je suis certain qu'il n'y en a pas dans les domaines de la faisabilité". Pouvons-nous supposer que cela n'arrivera jamais? C'est-à-dire permettre à la boucle de continuer indéfiniment si un cycle de période> 1 est atteint?
Stewie Griffin
6
Cas de test proposés: 1100et -42Il est facile d'ignorer les règles concernant les cas de bord s'ils n'apparaissent pas dans les cas de test.
Dennis

Réponses:

4

Gelée, 15 14 12 10 octets

Ds2*/€Pµ³¡

Essayez-le en ligne!

Comment ça marche

Ds2*/€Pµ³¡  Main link. Argument: n

D           Convert n into the array of its decimal digits.
 s2         Split into pairs of digits.
   */€      Reduce each pair by exponentiation.
      P     Take the product of the resulting powers.
       µ    Push the preceding chain as a link, and start a new one.
        ³¡  Execute the link n times and return the last result.
Dennis
la source
Cela pourrait être raccourci simplement en itérant les ntemps, mais je n'ai pas de preuve que cela fonctionne pour toutes les entrées possibles.
Dennis
1
Vous devriez être d'accord pour tout nombre raisonnable. En fait, vous êtes presque certainement d'accord pour TOUT nombre en utilisant 16 itérations: oeis.org/A133503
Ton Hospel
@Dennis Hm, c'est ce que je fais dans ma réponse
Luis Mendo
1
@DonMuesli Et maintenant que j'y ai pensé, cela fonctionne probablement. Les chances d'obtenir un 0 et un indice impair sont écrasantes ...
Dennis
Dans Jelly moderne, cela pourrait être fait en 7 octets:D*2/Pµ¡
Dennis
5

Haskell, 67 64 octets

(>> = (==)) >> = jusqu'à ce que $ p.show soit une fonction sans nom prenant un entier en entrée et renvoyant son groupe motopropulseur.

Enregistré 3 octets grâce à Zgarb

p(x:y:r)=p[x]^p[y]*p r;p[]=1;p x=read x
(>>=(==))>>=until$p.show
Damien
la source
1
((==)=<<g)enregistre deux octets de plus (\n->g n==n).
Zgarb
Wow, je ne connais pas l'instance ((->) r) de Monad. Merci pour l'astuce.
Damien
Ce barrage de signes de ponctuation (>>=(==))>>=ressemble vraiment à un train!
Andreï Kostyrka
4

Perl, 42 48 octets

Inclure +2 pour -lp(vous pouvez aussi laisser tomber -lmais j'aime les nouvelles lignes)

Exécuter avec entrée sur STDIN, par exemple

perl -lp powertrain.pl <<< 1234

powertrain.pl:

s/\B/1&pos?"**":"*"/eg until++$.>($_=eval)

(sur les anciennes perles, vous pouvez également supprimer l'espace entre l'expression régulière et jusqu'à)

Cela ne sera pas en mesure de gérer le point fixe 24547284284866560000000000mais cette grande valeur ne fonctionnera pas de toute façon car à ce moment-là, perl est passé à la notation exponentielle.

La version ci-dessus fonctionnera en fait rapidement (au plus les 2592boucles) pour tous les nombres que perl peut représenter sans utiliser de notation exponentielle car il est prouvé qu'il n'y a pas de points fixes entre 2592et 24547284284866560000000000( https://oeis.org/A135385 )

Cela suppose cependant quelque chose qui n'a pas encore été prouvé. En principe, il pourrait y avoir une réduction qui prend plus de X=10^7pas (on suppose qu'aucun point non fixe ne prend plus de 16 pas, https://oeis.org/A133503 ) dont la valeur descend en dessous X(mais au-dessus 10^7) puis monte encore. Si tel est le cas, je dois me rabattre sur:

s/\B/1&pos?"**":"*"/eg until$s{$_=eval}++||/-/

Explication

Le code fonctionne en mettant **et *(en alternance) entre les chiffres

s/\B/1&pos?"**":"*"/eg

2592devient ainsi 2**5*9**2et 12345devient 1**2*3**4*5. Ce sont des expressions perl valides qui peuvent être évaluées avec

$_ = eval

( 0**0est 1en perl). Ensuite, mettez simplement une boucle autour de cela avec un compteur qui le fait expirer. Étant donné que, sauf pour les points fixes, les valeurs diminuent extrêmement rapidement, la série de groupes motopropulseurs converge avant que le compteur n'ait vraiment la possibilité de démarrer.

Ton Hospel
la source
3

Pyth, 25 18 11 16 octets

?<Q0Qu*F^McjGT2Q

Essayez-le ici!

7 14 octets enregistrés avec l'aide de @Jakube

Explication

? <Q0Qu * F ^ McjGT2Q # Q = eval (entrée)

? <Q0Q # Si l'entrée est négative, retournez Q
     u Q # appliquer la fonction suivante jusqu'à ce que nous atteignions un cycle               
                   # la valeur de départ est Q et la valeur actuelle est en G
           jGT # divise l'entrée en une liste de chiffres
          c 2 # divisé en paires de 2
        ^ M # calcule la puissance de chaque paire
      * F # calcule le produit de tous les pouvoirs

Denker
la source
1
Python est-il simplement une version golfée de Python, sauf avec des modifications mineures?
clismique
1
@Jakube Merci pour les conseils! :) Encore tôt le matin pour moi ...
Denker
@DerpfacePython Oui, un peu. Jetez un œil aux documents si vous voulez en savoir plus.
Denker
Aucun problème. ;-)
Jakube
4
@DerpfacePython Pyth a commencé comme un simple "Python raccourci", mais l'appeler comme ça serait malhonnête. Pyth a considérablement divergé de Python.
Mego
3

Python 2, 111 octets

def p(n,b=0,o=''):
 if n<1:return n
 for c in str(n):o+=c+'**'[b:];b=~b
 j=eval(o+'1');return p(j)if j-n else j

L'idée est de faire une chaîne où les chiffres de nsont séparés par des opérations qui alternent entre *et **, puis evalcette chaîne. (D'autres solutions utilisent cette même idée; voir par exemple la réponse Perl de Ton Hospel .)

Ainsi, l'opération bascule entre '**'[0:]ce qui est **et '**'[-1:]ce qui est juste *.

Cependant, à la fin de la forboucle, la chaîne se termine par une opération (l'une ou l'autre), nous devons donc soit supprimer la dernière opération, soit ajouter un autre chiffre, pour que la chaîne ait du sens.

Heureusement, l'ajout d'un 1à la fin fonctionnera quelle que soit la dernière opération. (Si vous voulez, 1c'est une identité unilatérale de droite, à la fois pour la multiplication et l'exponentiation. Une autre façon de le dire est celle powertrain(n) == powertrain(10*n + 1)pour tous n>0.)

Enfin, si le résultat de la evalse trouve être le même que l'entrée (comme dans un 1cycle de longueur ), la fonction se termine. Sinon, la fonction s'appelle sur le résultat. (Il restera à jamais suspendu sur n'importe quel cycle de longueur > 1, mais selon les commentaires du PO, je suis autorisé à supposer qu'il n'y a pas de tels cycles.)

(Remarque: l'explication ci-dessus fonctionne pour les entiers positifs à un chiffre, car une entrée à un chiffre nsera complétée, n**1ce qui entraînera un 1cycle. Cependant, nous devons également accepter une entrée non positive, il y a donc une condition à la en commençant ces courts-circuits si l'entrée est inférieure à 1. Nous pourrions éliminer cette ligne et économiser 17 octets si l'entrée était garantie non négative.)

mathmandan
la source
Cela semble biaisé, mais ... vote positif pour Python 2. Et il a une explication.
clismique
@DerpfacePython Merci! (Je suppose que cela fonctionnerait aussi bien en Python 3 ...)
mathmandan
3

Java 8, 265 244 229 octets

Ceci est ma première réponse, mais je lis ce site depuis un certain temps et je pense savoir ce que je fais. Au moins, il bat befunge et SQL ...

Malheureusement, comme d'autres réponses, celle-ci ne fonctionne pas pour 24547284284866560000000000 en raison des restrictions intégrées de java'a sur la taille des entiers.

36 octets enregistrés grâce à @JackAmmo

public int p(int n){if(n<10)return n;int i=1,t=1,s=(int)Math.log10(n)+1,r[]=new int[s];for(;i<=s;){int a=(int)Math.pow(10,i);r[s-i++]=n%a/(a/10);}for(i=0;i<s-1;i++)t*=Math.pow(r[i],r[++i]);if(s%2==1)t*=r[s-1];return n==t?n:p(t);}

Explication non golfée

public int powertrain(int input){
    //handles negative and 1-digit cases
    if(input<10)return input;
    //initialize output variable       
    int total=1;
    // get "length" of number. Shorter than getting length of string representation
    int size=(int)Math.log10(input)+1;
    //initialize array to store digits
    int[] array=new int[size];
    //Now, because Java doesn't have support
    // for the "**" operation, and the way of turning
    // an integer into a string takes too many bytes,
    // I decided just to put every digit into an array with
    // math and iterate from there
    for(int i=1;i<=size;){
        int place=(int)Math.pow(10,i);
        //crazy math. Saved 1 byte by incrementing i when accessed
        array[size-i++]=input%place/(place/10);
    }
    for(int i=0;i<size-1;i++)
        //This is where the train happens.
        //Saved 1 byte by incrementing while accessing 
        //again, instead of i+=2 and i+1
        total*=Math.pow(array[i],array[++i]);
    //Make sure last number isn't left out if size is odd
    if(size%2==1)
        total*=array[size-1];
    //if we end up with same number, stop.
    //otherwise, keep recurring
    return input==total?input:powertrain(total);
}
Bleu
la source
Dans votre premier if ... else if(n<10)return n;else{...}the else est inutile car logiquement tout dans ce bloc else ne fonctionnerait de toute façon que lorsque n <10 est faux. La suppression du reste et des 2 accolades correspondantes vous fera économiser 6 octets. Il y a une situation similaire avec votre dernier si ... sinon if(n==t)return n;else return p(t);supprimez le reste et l'espace après pour économiser encore 5 octets. En fait, vous pouvez le raccourcir encore plus si vous utilisez l'opérateur triadique au lieu du if ... sinon comme çareturn n==t?n:p(t);
Jack Ammo
vous pouvez économiser quelques octets de plus (17 je pense) en déclarant ensemble t, s, r et la boucle forint t=i=1,s=(int)Math.log10(n)+1,r[]=new int[s];for(;i<=s;){...}for(i=0;...)...
Jack Ammo
@JackAmmo Je ne savais pas que les variables pouvaient être déclarées comme ça, je vais devoir l'essayer. Merci de votre aide!
Blue
oui, il suffit de faire attention à l'ordre de les déclarer si vous en utilisez un pour en initialiser un autre (comme la façon dont r utilise s pour définir sa longueur)
Jack Ammo
pour de grands nombres arbitraires, vous devriez regarder dans la classe BigInteger
Jack Ammo
2

JavaScript (ES6) 71

Une fonction récursive, s'arrêtant lorsqu'une répétition est trouvée. Cela ne pourrait pas fonctionner pour des boucles plus longues (2 ou plusieurs valeurs répétées) mais il semble que cela ne puisse pas se produire, au moins dans la plage limitée de précision du nombre javascript (17 chiffres)

f=n=>[...n+'1'].map((c,i)=>i&1?r*=Math.pow(d,c):d=c,r=1)&&n-r?f(r):n

Tester

f=n=>[...n+'1'].map((c,i)=>i&1?r*=Math.pow(d,c):d=c,r=1)&&n-r?f(r):n

function go()
{
  v=+I.value
  R.textContent=f(v)
}  

go()
<input id=I value="1234"><button onclick="go()">Go</button>
<span id=R></span>

edc65
la source
Sympa de +'1'tuer deux oiseaux avec une pierre!
Neil
Je ne sais pas si vous l'avez déjà enquêté mais le mieux que j'ai pu faire replaceétait de 1 octet de plus:f=n=>`${n}1`.replace(/../g,([x,y])=>r*=Math.pow(x,y),r=1)&&n-r?f(r):n
Neil
@Neil J'ai essayé dur aussi, mais cette chaîne de modèle est une nouvelle idée ...
edc65
1

Mathematica, 77 octets

Times@@(If[#2<1,1,#^#2]&)@@@Partition[IntegerDigits@#,2,2,1,1]&~FixedPoint~#&

Fonction anonyme. Pas trop compliqué.

LegionMammal978
la source
Néanmoins, puis-je avoir une explication?
clismique
1

Befunge 720 490 octets

Je n'ai pas pu résister à en faire un de plus après la chose Never tell me the odds . J'ai donc optimisé le "ASCII-fier" du précédent. Dans ce cas, je n'ai vu aucun besoin de laisser le pointeur d'instruction parcourir les chiffres pour les lire, donc je n'ai pas pris l'effort de les rendre lisibles par l'homme. C'est donc plus un numériseur, maintenant.

Encore une fois, si vous voulez des explications, faites-le moi savoir dans les commentaires, je vais essayer de créer des descriptions utiles. Vous pouvez copier coller le code dans l'interpréteur . J'ai trouvé que l'exemple 24547284284866560000000000 génère 0, mais cela semble être un problème pour obtenir une valeur aussi élevée à partir d'un point de la grille, car vous pouvez clairement voir la valeur correcte stockée dans les étapes finales.

v                                                    //top row is used for "variables"
>&:0`#v_.@                                           //initialize the counter                          
v     <                           g01_v#-p01:  <     //on our way back to the digitifier, check if we're done
>::>210p>55+%:10g0p-55+/:v            >10g.@         //digitifier, creates a series of ASCII characters at the top line, one for each digit in the source
        ^p01+1g01    _v#:<
v1$$                  <                              //forget some remainders of the digitifier, put 1 on the stack as a base of calculation
                      v p0-1g01-1g0-1g01*g0g01<      //taking powers of each pair of digit
>10g2-!#v_10g1-!#v_  1>                10g1-0g|
^                                  p01-2g01  *<
        >10g0g*  >                             ^     //extra multiplication with last digit if the number of digits was odd

Cette version prend également en charge l'entrée négative. C'est une grande amélioration par rapport à la version précédente, si je le dis moi-même. Au moins 1 bug a été corrigé et la taille a été considérablement réduite.

rael_kid
la source
Combien d'octets de plus faudra-t-il pour que la chose entre des nombres négatifs?
clismique
Je ne suis pas sûr d'être honnête. J'ai eu des problèmes avec les nombres négatifs et les ai écrits quelque part dans la grille. Je vais réessayer.
rael_kid
Je viens de trouver un autre bug aussi. J'ai réussi à ajouter un support pour les nombres négatifs. Je publierai bientôt une mise à jour! Ce sera probablement la même quantité d'octets, car je compte toute la grille.
rael_kid
1

Haskell, 100 79 77 octets

g x|x==h x=x|1<2=g$h x;h=i.map(read.(:[])).show;i[]=1;i[a]=a;i(a:b:c)=a^b*i c

Non golfé:

g x|x==h x=x|1<2=g$h x
h=i.map(read.(:[])).show
i[]=1
i[a]=a
i(a:b:c)=a^b*i c

Cette fonction divise l'entrée en chiffres et fait l'affaire via i .

EDIT: Merci à nimi pour quelques conseils.

Renzeee
la source
Quelques conseils: a) i(a:[])=aest i[a]=a, b) inutile max 1, car 0^0 = 1dans Haskell, c) remplacez (:[])par pure, d) déplacez l' letintérieur gdans une fonction distincte et remplacez-le if ... then ... elsepar des gardes:h=i.map(read.pure).show ; g x|x==h x=x|1<2=h x
nimi
puren'est pas dans Prelude, mais le reste des conseils fonctionne, merci. J'essayais de le faire avec des gardes, mais j'ai fini par utiliser ;avant le gardien et cela n'a pas fonctionné, mais maintenant je sais comment cela devrait fonctionner.
Renzeee
pureest dans le Prélude fourni avec la base-4.8.2.0. Je ne sais pas quand il a été introduit. Vous n'avez pas besoin de l' ( )entrée i([a])=a.
nimi
1

Mathematica, 74 octets

0~f~0=f[]=1
f@n_=n
f[a_,b_,c___]:=f[c]a^b
#//.i_/;i>0:>f@@IntegerDigits@i&

Explication

Cette solution utilise une fonction d'assistance f, qui prend les chiffres du nombre comme arguments et applique une itération de l'opération du groupe motopropulseur. La dernière ligne est une fonction pure conçue pour exploiter la ReplaceRepeatedfonction (ou //.pour faire court), qui applique une règle à une expression (dans ce cas l'argument #de la fonction pure) jusqu'à ce qu'elle ne change plus. La règle i_/;i>0:>f@@IntegerDigits@iremplace tout ce qui n'est pas négatif par la fonction fappliquée à ses chiffres décimaux.

murphy
la source
La ligne 2 ne fonctionne pas (utilisation :=)
CalculatorFeline
Explication, s'il vous plaît?
clismique
@CatsAreFluffy Je ne vois pas votre problème avec la ligne 2. Cela fonctionne bien pour moi!
murphy
SetDelayed::write: Tag Times in n f[a_,b_,c___] is Protected. >>, Set::write: Tag Times in 1 f[n_] is Protected. >>La deuxième erreur disparaît quand je l' utilise :=vs =.
CalculatorFeline
Désolé, impossible de reproduire cette erreur. Mais votre sortie indique que les sauts de ligne font partie du problème. Veuillez essayer la version avec ;s au lieu des sauts de ligne:0~f~0=f[]=1;f@n_=n;f[a_,b_,c___]:=f[c]a^b;#//.i_/;i>0:>f@@IntegerDigits@i&
murphy
1

MATL , 21 octets

tt0>*:"V!UtQgv9L2#)^p

La production de la sortie peut prendre quelques secondes.

EDIT (30 juillet 2016): le code lié remplace 9Lpar 1Lpour s'adapter aux évolutions récentes de la langue.

Essayez-le en ligne!

Cela utilise les deux astuces suivantes pour réduire le nombre d'octets au détriment de l'efficacité du code:

  • Répétez les ntemps au lieu d'attendre qu'un cycle soit trouvé. Ceci est acceptable selon les commentaires du PO.
  • Pour un nombre impair de chiffres, une finale 1devrait être ajoutée pour terminer l'opération d'alimentation finale. Au lieu de cela, le nombre ajouté 1est le nombre de chiffres. Cela garantit un nombre pair, de sorte que toutes les opérations d'alimentation peuvent être effectuées (même si les dernières sont des 1^1opérations inutiles ).

Code:

t         % implicitly take input x. Duplicate
t0>*      % duplicate. Is it greater than 0? Multiply. This gives 0 if input is negative,
          % or leaves the input unchanged otherwise
:         % Generate array [1,2,...,x]
"         % for each (repeat x times)
  V       %   convert x to string
  !       %   transpose into column char array
  U       %   convert each char into number
  tQg     %   duplicate. Add 1 so that no entry is zero. Convert to logical: gives ones
  v       %   concatenate vertically
  9L2#)   %   separate odd-indexed and even-indexed entries
  ^       %   element-wise power
  p       %   product of all entries
          % implicitly end for each
          % implicitly display
Luis Mendo
la source
Euh ... heh heh heh ... quand j'ai dit "boucles de nombres", je voulais dire des nombres qui allaient comme ça - a, b, a, b infini (plus d'un terme). Si un terme est répété, vous devez sortir ce nombre. Désolé si ce n'était pas vraiment clair.
clismique
Si un terme est répété, je produis ce nombre. Je produis le résultat après plusieurs itérations
Luis Mendo
Oh, je comprends maintenant ... je demande juste, combien d'itérations serait-ce (environ)? Parce que quand je tape2592 dans l'entrée, il ne semble rien produire pendant un bon moment.
clismique
Le nombre d'itérations est le numéro d'entrée, donc 2592 dans ce cas. Oui, cela prend du temps
Luis Mendo
0

Python 3, 169 161 octets

def f(s):
 o=[['1',s]['-'in s]]
 while s not in o:
  o+=[s];s+='1'*(len(s)%2==1);r=1;
  for i,j in zip(s[::2],s[1::2]):r*=int(i)**int(j);s=str(r);
 return o[-1]

Ungoldfed

def f(s):
 o=[['1',s]['-'in s]]
 while s not in o:
  o+=[s]
  s+='1'*(len(s)%2==1)
  r=1
  for i,j in zip(s[::2],s[1::2]):
   r*=int(i)**int(j)
  s=str(r)
 return o[-1]

Résultats

>>> [f(i) for i in ['135', '1234', '642', '2592', '-15']]
['5', '8', '2592', '2592', '-15']
Erwan
la source
@PeterTaylor Fixed!
Erwan
Vous pouvez mettre plusieurs instructions sur une seule ligne si vous les séparez avec un ;Cette façon vous permet d'économiser les espaces blancs d'intention. Vous pouvez également mettre le corps de la boucle for sur cette même ligne.
Denker
Golf suggéré:def f(s,o=[['1',s]["-"in s]],n=int): while s not in o: o+=[s];s+=1*(len(s)%2<1);r=1 for i,j in zip(s[::2],s[1::2]):r*=n(i)**n(j) s=str(r) return o[-1]
CalculatriceFeline
@CatsAreFluffy o=[['1',s]["-"in s]]dans l'argument par défaut ne fonctionne pas pour moi, il déclenche une erreur `non définie`
Erwan
Oups, passez o à la ligne suivante.
CalculatorFeline
0

Oracle SQL 11.2, 456 octets

WITH v(n,c,i,f,t)AS(SELECT:1+0,CEIL(LENGTH(:1)/2),1,'1',0 FROM DUAL UNION ALL SELECT DECODE(SIGN(c-i+1),-1,t,n),DECODE(SIGN(c-i+1),-1,CEIL(LENGTH(t)/2),c),DECODE(SIGN(c-i+1),-1,1,i+1),DECODE(SIGN(c-i+1),-1,'1',RTRIM(f||'*'||NVL(POWER(SUBSTR(n,i*2-1,1),SUBSTR(n,i*2,1)),SUBSTR(n,i*2-1,1)),'*')),DECODE(SIGN(c-i+1),-1,0,TO_NUMBER(column_value))FROM v,XMLTABLE(f)WHERE i<=c+2 AND:1>9)CYCLE n,c,i,f,t SET s TO 1 DEFAULT 0SELECT NVL(SUM(n),:1) FROM v WHERE s=1;

Non golfé

WITH v(n,c,i,f,t) AS
(
  SELECT :1+0,CEIL(LENGTH(:1)/2),1,'1',0 FROM DUAL
  UNION ALL
  SELECT DECODE(SIGN(c-i+1),-1,t,n),
         DECODE(SIGN(c-i+1),-1,CEIL(LENGTH(t)/2),c),
         DECODE(SIGN(c-i+1),-1,1,i+1),
         DECODE(SIGN(c-i+1),-1,'1',RTRIM(f||'*'||NVL(POWER(SUBSTR(n,i*2-1,1),SUBSTR(n,i*2,1)),SUBSTR(n,i*2-1,1)),'*')),
         DECODE(SIGN(c-i+1),-1,0,TO_NUMBER(column_value))
  FROM v,XMLTABLE(f) WHERE i<=c+2 AND :1>9 
)  
CYCLE n,c,i,f,t SET s TO 1 DEFAULT 0
SELECT NVL(SUM(n),:1) FROM v WHERE s=1;

v est une vue récursive, les paramètres sont

n: nombre à diviser en 2 chiffres

c: nombre de parties à 2 chiffres

i: partie actuelle à 2 chiffres à calculer

f: chaîne concaténant les puissances avec * comme séparateur

t: évaluation de f

Les DECODE passent au numéro suivant pour se diviser et calculer lorsque toutes les parties du numéro actuel sont terminées.

XMLTABLE (f) prend une expression et l'évalue, en plaçant le résultat dans la pseudo-colonne "valeur_colonne". C'est la version golfée de http://tkyte.blogspot.fr/2010/04/evaluating-expression-like-calculator.html

CYCLE est la construction oracle de la détection de cycle et est utilisée comme condition de sortie.

Comme le résultat pour: 1 <10 est: 1 et v ne renvoie aucune ligne pour ces cas, SUM force une ligne avec NULL comme valeur. NVL renvoie: 1 comme résultat si la ligne est nulle.

Jeto
la source
Où est l'explication?
clismique