Finde den Antriebsstrang!

29

Der Gewinner (ziemlich offensichtlich) ist Dennis ♦, der Jelly mit 10 Bytes verwendet hat!

Diese Herausforderung wird es hier weiterhin geben, die Ergebnisse werden jedoch nicht mehr berücksichtigt.


Der Antriebsstrang einer Zahl ist ein Konzept von John Conway (der auch für Conways Game of Life bekannt ist, aber darum geht es nicht). Es ist wie folgt definiert:

Für jede Zahl enter image description here... ist der Antriebsstrang der Zahl enter image description here... (dh jede zweite Ziffer von links nach rechts ist eine Potenz der vorhergehenden Ziffer). Dieser Vorgang wird wiederholt, bis das Ergebnis eine einzelne Ziffer ist.

BEISPIELE

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

Ihre Herausforderung besteht darin, für eine beliebige Zahl nin der Eingabe powertrain(n)(dh nnachdem die Zerlegung des Antriebsstrangs abgeschlossen ist) als Ausgabe zurückzugeben.

Dies ist Codegolf, daher gewinnt die kürzeste Anzahl an Bytes.

HAFTUNGSAUSSCHLUSS:

  • Sie können eine ungerade Anzahl von Ziffern in der Eingabe haben, die letzte Ziffer hat einfach keine Potenz.
  • 0 ^ 0 ist 1, denn wenn es 0 wäre, würden viele Zahlen sofort zu 0 oder 1 zusammenfallen.
  • Wenn die Zahl in irgendeinem Teil des Berechnungsprozesses unzerstörbar ist (z. B. wenn sie damit endet 2592), können Sie die Zahl einfach ausgeben.
  • Wenn die Eingabe < 10(dh alle einstelligen Zahlen und Negative) ist, geben Sie die Eingabe aus.

Ich werde wahrscheinlich nach ein paar Stunden einen Gewinner bekannt geben .

Aktuelle Rangliste:

  1. Jelly ( Dennis ♦ ): 10
  2. Pyth ( DenkerAffe ): 16
  3. MATL ( Don Müsli ): 21
  4. Perl ( Ton Hospel ): 42
  5. Haskell ( Damien ): 64
  6. Javascript ES6 ( edc65 ): 71
  7. Mathematica ( Murphy ): 74
  8. Mathematica ( LegionMammal978 ) und Haskell ( Renzeee ): 77
  9. Python 2 ( Mathematiker ): 111
  10. Python 3 ( Erwan ): 161
  11. Java 8 ( blau ): 229
  12. Oracle SQL 11.2 ( Jeto ): 456
  13. Befunge '93 ( Lex ): 490
Clismique
quelle
Einige weitere Testfälle wären willkommen.
Mego
Der Eingang hat also maximal 4 Stellen?
Denker
7
Was passiert, wenn ein Zyklus erreicht ist, die Periode des Zyklus jedoch nicht 1 ist oder die Eingangsnummer nicht Teil des Zyklus ist?
Feersum
1
"Ich bin sicher, dass es im Bereich der Machbarkeit keine gibt". Können wir davon ausgehen, dass es niemals passieren wird? Dh die Schleife für immer weiterlaufen lassen, wenn ein Zyklus von Periode> 1 erreicht ist?
Stewie Griffin
6
Vorgeschlagene Testfälle: 1100und -42Es ist leicht, Regeln für Randfälle zu übersehen, wenn sie in den Testfällen nicht angezeigt werden.
Dennis

Antworten:

4

Jelly, 15 14 12 10 Bytes

Ds2*/€Pµ³¡

Probieren Sie es online!

Wie es funktioniert

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
quelle
Dies könnte durch einfaches Wiederholen der nZeiten verkürzt werden , aber ich habe keinen Beweis, dass es für alle möglichen Eingaben funktioniert.
Dennis
1
Sie sollten für jede vernünftige Anzahl in Ordnung sein. Tatsächlich sind Sie für JEDE Nummer mit 16 Iterationen mit ziemlicher Sicherheit in Ordnung
Ton Hospel
@Dennis Hm, das ist, was ich in meiner Antwort tun
Luis Mendo
1
@DonMuesli Und jetzt, wo ich darüber nachgedacht habe, funktioniert es wahrscheinlich. Die Chancen auf eine 0 und einen ungeraden Index sind überwältigend ...
Dennis
Im modernen Gelee könnte dies in 7 Bytes erfolgen:D*2/Pµ¡
Dennis
5

Haskell, 67 64 Bytes

(>> = (==)) >> = bis $ p.show eine unbenannte Funktion ist, die eine Ganzzahl als Eingabe verwendet und ihren Antriebsstrang zurückgibt .

3 Bytes dank Zgarb gespart

p(x:y:r)=p[x]^p[y]*p r;p[]=1;p x=read x
(>>=(==))>>=until$p.show
Damien
quelle
1
((==)=<<g)spart zwei Bytes über (\n->g n==n).
Zgarb
Wow, ich kenne die ((->) r) -Instanz von Monad nicht. Danke für den Trick.
Damien
Diese Flut von Satzzeichen (>>=(==))>>=sieht wirklich aus wie ein Zug!
Andreï Kostyrka
4

Perl, 42 48 Bytes

Enthalten Sie +2 für -lp(Sie können das auch fallen lassen, -laber ich mag Zeilenumbrüche)

Mit Eingabe auf STDIN ausführen, z

perl -lp powertrain.pl <<< 1234

powertrain.pl:

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

(Bei älteren Perls können Sie auch den Abstand zwischen dem regulären Ausdruck und bis löschen.)

Dies wird den Fixpunkt nicht verarbeiten können, 24547284284866560000000000aber ein so großer Wert wird sowieso nicht funktionieren, da zu diesem Zeitpunkt Perl auf Exponentialschreibweise umgestellt wurde.

Die obige Version funktioniert in der Tat schnell (höchstens 2592Schleifen) für alle Zahlen, die Perl ohne Exponentialschreibweise darstellen kann, da nachgewiesen ist, dass es keine festen Punkte zwischen 2592und gibt 24547284284866560000000000( https://oeis.org/A135385 ).

Dies setzt jedoch etwas Unbewiesenes voraus. Im Prinzip könnte es eine Reduzierung geben, die mehr als X=10^7Schritte dauert (es wird vermutet, dass kein nicht festgelegter Punkt mehr als 16 Schritte dauert, https://oeis.org/A133503 ), deren Wert unter X(aber über 10^7) sinkt und dann steigt nochmal. In diesem Fall muss ich auf Folgendes zurückgreifen:

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

Erläuterung

Der Code setzt **und *(abwechselnd) zwischen den Ziffern

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

so 2592wird 2**5*9**2und 12345wird 1**2*3**4*5. Dies sind gültige Perl-Ausdrücke, mit denen ausgewertet werden kann

$_ = eval

( 0**0ist 1in Perl). Dann legen Sie einfach eine Schleife um das mit einem Zähler, der es abläuft. Da die Werte mit Ausnahme der Fixpunkte extrem schnell sinken, konvergiert die Antriebsstrangreihe, bevor der Zähler die Chance erhält, wirklich in Gang zu kommen

Tonne Hospel
quelle
3

Pyth, 25 18 11 16 Bytes

?<Q0Qu*F^McjGT2Q

Probieren Sie es hier aus!

7 14 Bytes mit Hilfe von @Jakube gespeichert

Erläuterung

? <Q0Qu * F ^ McjGT2Q # Q = eval (Eingabe)

? <Q0Q # Wenn der Eingang negativ ist, geben Sie Q zurück
     u Wenden Sie Q # die folgende Funktion an, bis wir einen Zyklus erreichen               
                   # Startwert ist Q und der aktuelle Wert ist in G
           jGT # teilt die Eingabe in eine Liste von Ziffern auf
          c 2 # in 2er-Paare aufgeteilt
        ^ M # berechnet die Leistung für jedes Paar
      * F # berechnet das Produkt aller Kräfte

Denker
quelle
1
Is Pyth basically just a golfed version of Python, except with minor changes?
clismique
1
@Jakube Thanks for the hints! :) Still early in the morning for me...
Denker
@DerpfacePython Yea, kinda. Have a look at the docs if you wanna learn about it.
Denker
No problem. ;-)
Jakube
4
@DerpfacePython Pyth begann als "verkürztes Python", aber es so zu nennen, wäre jetzt unaufrichtig. Pyth hat sich deutlich von Python unterschieden.
Mego
3

Python 2, 111 Bytes

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

Die Idee ist, eine Zeichenfolge zu erstellen, bei der die Ziffern ndurch abwechselnde Operationen zwischen *und **und dann evaldiese Zeichenfolge getrennt werden. (Andere Lösungen verwenden dieselbe Idee. Siehe beispielsweise die Perl-Antwort von Ton Hospel .)

Die Operation wechselt also zwischen '**'[0:], was ist **und '**'[-1:]was ist gerecht *.

Am Ende der for-Schleife endet die Zeichenfolge jedoch mit einer Operation (der einen oder anderen). Daher müssen wir entweder die letzte Operation löschen oder eine weitere Ziffer hinzufügen, damit die Zeichenfolge einen Sinn ergibt.

Glücklicherweise 1funktioniert das Anhängen eines am Ende, unabhängig davon, welche Operation zuletzt ausgeführt wurde. (Wenn Sie möchten, 1ist dies eine einseitige Identität von rechts, sowohl für die Multiplikation als auch für die Potenzierung. Eine andere Art, dies zu sagen, ist die powertrain(n) == powertrain(10*n + 1)für alle n>0.)

evalEntspricht das Ergebnis von zufällig der Eingabe (wie in einem Längenzyklus 1), wird die Funktion beendet. Andernfalls ruft die Funktion das Ergebnis auf. (Es wird für immer an jedem Zyklus der Länge hängen > 1, aber nach den Kommentaren des OP darf ich davon ausgehen, dass es keine solchen Zyklen gibt.)

(Note: the above explanation works for single-digit positive integers, since a single-digit input n will be completed to n**1 which will result in a 1-cycle. However, we also need to accept non-positive input, so there's a condition at the beginning that short-circuits if the input is less than 1. We could eliminate that line, and save 17 bytes, if the input were guaranteed to be non-negative.)

mathmandan
quelle
This sounds biased, but... upvote for being Python 2. And it has an explanation.
clismique
@DerpfacePython Danke! (Ich denke, das würde in Python 3 genauso gut funktionieren ...)
mathmandan
3

Java 8, 265 244 229 Bytes

Dies ist meine erste Antwort, aber ich habe diese Seite eine Weile gelesen und denke, ich weiß, was ich tue. Zumindest schlägt es befunge und SQL ...

Wie andere Antworten auch, funktioniert dies leider nicht für 24547284284866560000000000, da in Java Einschränkungen für die Größe von ganzen Zahlen eingebaut sind.

36 Bytes dank @JackAmmo gespeichert

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

Ungolfed Erklärung

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);
}
Blau
quelle
In your first if...else if(n<10)return n;else{...} the else is unneccessary since logically everything in that else block would only run anyway when n<10 is false. Removing the else and the 2 matching braces will save you 6 bytes. There's a similar situation with your last if...else if(n==t)return n;else return p(t); remove the else and the space after it to save another 5 bytes. In fact you can shorten it even further if you use the triadic operator instead of the if...else like so return n==t?n:p(t);
Jack Ammo
you can save a few more bytes (17 i think) by declaring t,s,r, and the for loop's i together int t=i=1,s=(int)Math.log10(n)+1,r[]=new int[s];for(;i<=s;){...}for(i=0;...)...
Jack Ammo
@JackAmmo Mir war nicht bewusst, dass Variablen so deklariert werden können. Ich muss es versuchen. Danke für Ihre Hilfe!
Blue
Ja, Sie müssen nur vorsichtig mit der Reihenfolge sein, in der Sie sie deklarieren, wenn Sie eine verwenden, um eine andere zu initialisieren (wie zum Beispiel, wenn Sie s verwenden, um die Länge zu definieren)
Jack Ammo
Für willkürlich große Zahlen sollten Sie die Java-Klasse BigInteger unter docs.oracle.com/javase/8/docs/api/java/math/BigInteger.html
Jack Ammo
2

JavaScript (ES6) 71

A recursive function, stopping when a repetition is found. This could not work for longer loops (2 or more value repeating) but it seems this could not happen, at least in the limited range of javascript number precision (17 digits)

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

Test

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
quelle
Nice of that +'1' to kill two birds with one stone!
Neil
I don't know whether you'd investigated it already but the best I could do with replace was 1 byte longer: f=n=>`${n}1`.replace(/../g,([x,y])=>r*=Math.pow(x,y),r=1)&&n-r?f(r):n
Neil
@Neil I tried hard too, but that template string is a new idea ...
edc65
1

Mathematica, 77 bytes

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

Anonymous function. Not too complicated.

LegionMammal978
quelle
Even so, can I still have an explanation?
clismique
1

Befunge 720 490 bytes

Couldn't resist to do one more after the Never tell me the odds thing. So, I've optimized the "ASCII-fier" of the previous one. In this case I saw no need to let the instruction pointer run over the digits to read them, so I haven't taken the effort to make them human readable. So it's more of a digitifier, now.

Again, if you guys want an explanation, let me know in the comments, I'll try to create some helpful descriptions. You can copy paste the code into the interpreter. I've found that the example 24547284284866560000000000 outputs 0, but that seems to be a problem with getting such a large value from a point on the grid, as you can clearly see the correct value being stored in the final steps.

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

This version also supports negative input. It's a great improvement on the previous version, if I say so myself. At least 1 bug was fixed and the size was reduced greatly.

rael_kid
quelle
How many bytes more will it take for the thing to input negative numbers?
clismique
I'm not sure to be honest. I had some problems with negative numbers and writing them somewhere in the grid. I'll try it again.
rael_kid
I just found another bug, too. I did manage to add support for negative numbers. I'll post an update soon! It'll probably be the same amount of bytes, since I count the entire grid.
rael_kid
1

Haskell, 100 79 77 bytes

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

Not golfed:

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

This function splits the input into digits and does the trick via i.

EDIT: Thanks to nimi for some tips.

Renzeee
quelle
A few tips: a) i(a:[])=a is i[a]=a, b) no need for max 1, because 0^0 = 1 in Haskell, c) replace (:[]) with pure, d) move the let within g into a separate function and replace the if ... then ... else with guards: h=i.map(read.pure).show ; g x|x==h x=x|1<2=h x
nimi
pure is not in Prelude, but the rest of the tips work, thanks. I was trying to do it with guards, but ended up using ; before the guard and that didn't work, but now I know how it should work.
Renzeee
pure is in the Prelude that comes with base-4.8.2.0. Don't know when it was introduced. You don't need the ( ) in i([a])=a.
nimi
1

Mathematica, 74 bytes

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

Explanation

This solution uses a helper function f, which takes the digits of the number as arguments and applies one iteration of the power train operation. The last line is a pure function that is crafted to exploit the ReplaceRepeated function (or //. for short), which applies a rule to an expression (in this case the argument # of the pure function) until it doesn't change anymore. The rule i_/;i>0:>f@@IntegerDigits@i replaces anything non-negative with the function f applied to its decimal digits.

murphy
quelle
Line 2 doesn't work (use :=)
CalculatorFeline
Explanation, please?
clismique
@CatsAreFluffy I don't see your problem with line 2. It works fine for me!
murphy
SetDelayed::write: Tag Times in n f[a_,b_,c___] is Protected. >>, Set::write: Tag Times in 1 f[n_] is Protected. >> The second error disappears when i use :=vs=.
CalculatorFeline
Sorry, can't reproduce that error. But your output indicates that the line-breaks are part of the problem. Please try the version with ;s instead of the line-breaks: 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 bytes

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

It may take a few seconds to produce the output.

EDIT (July 30, 2016): the linked code replaces 9L by 1L to adapt to recent changes in the language.

Try it online!

This uses the following two tricks to reduce byte count at the expense of code efficiency:

  • Iterate n times instead of waiting until a cycle is found. This is acceptable as per OP's comments.
  • For an odd number of digits a final 1 would have to be appended to complete the final power operation. Instead of that, the number of added 1 is the number of digits. This ensures an even number, so all power operations can be done (even if the last ones are unnecessary 1^1 operations).

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
quelle
Uh... heh heh heh... when I said "loops of numbers", I meant numbers that went like this - a, b, a, b ad infinitum (more than one term). If one term is repeated, then you should output that number. Sorry if that wasn't really clear.
clismique
If one term is repeated, I'm outputting that number. I output the result after many iterations
Luis Mendo
Oh, I understand now... just asking, how many iterations would it be (approx.)? Because when I type in 2592 into the input, it doesn't seem to output anything for quite a while.
clismique
The number of iterations is the input number, so 2592 in that case. Yes, it takes a while
Luis Mendo
0

Python 3, 169 161 bytes

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]

Results

>>> [f(i) for i in ['135', '1234', '642', '2592', '-15']]
['5', '8', '2592', '2592', '-15']
Erwan
quelle
@PeterTaylor Fixed!
Erwan
You can put multiple statements in one line if you seperate them with a ; This way you saves you the intendation whitespaces. Also you can put the body of the for loop on that same line.
Denker
Suggested golfing: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]
CalculatorFeline
@CatsAreFluffy o=[['1',s]["-"in s]] in default argument don't work for me it raise a error ` s not defined`
Erwan
Oops, move o to the next line.
CalculatorFeline
0

Oracle SQL 11.2, 456 bytes

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;

Un-golfed

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 is a recursive view, parameters are

n : number to split in 2 digits parts

c : number of 2 digits parts

i : current 2 digits part to compute

f : string concatenating the powers with * as separator

t : evaluation of f

The DECODEs switch to the next number to split and compute when all the parts of the current number are done.

XMLTABLE(f) takes an expression an evaluates it, putting the result in the pseudo column "column_value". It's the golfed version of http://tkyte.blogspot.fr/2010/04/evaluating-expression-like-calculator.html

CYCLE is the oracle build in cycle detection and is used as the exit condition.

Since the result for :1<10 is :1 and v returns no row for those cases, SUM forces a row with NULL as the value. NVL returns :1 as the result if the row is null.

Jeto
quelle
Where's the explanation?
clismique