Trova la catena cinematica!


29

Il vincitore (abbastanza ovviamente) è Dennis ♦, che ha usato Jelly con 10 byte!

Questa sfida sarà ancora qui, tuttavia i risultati non saranno più presi.


La catena cinematica di un numero è un concetto di John Conway (che è anche noto per aver realizzato Conway's Game of Life, ma non è questo il punto). Si definisce così:

Per qualsiasi numero inserisci qui la descrizione dell'immagine..., la catena cinematica del numero è inserisci qui la descrizione dell'immagine... (cioè ogni seconda cifra, da sinistra a destra, è una potenza della cifra prima di quella). Questo processo viene ripetuto fino a quando il risultato è una singola cifra.

ESEMPI:

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

La tua sfida è, per qualsiasi numero nnell'input, tornare powertrain(n)(cioè ndopo che la decomposizione del gruppo propulsore è terminata) come output.

Questo è il golf del codice, quindi vince il minor numero di byte.

DISCLAIMER-COSE:

  • Puoi avere un numero dispari di cifre nell'input, l'ultima cifra non avrà potenza.
  • 0 ^ 0 è 1, perché se fosse 0, molti numeri collasserebbero immediatamente su 0 o 1.
  • Se il numero è indistruttibile in qualsiasi parte del processo di calcolo (ad es. Se finisce con 2592), allora puoi semplicemente generare il numero.
  • Se l'ingresso è < 10(cioè tutti i numeri a cifra singola e negativi), emettere l'ingresso.

Probabilmente annuncerò un vincitore dopo qualche ora .

Classifica attuale:

  1. Gelatina ( 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. Mathematica ( murphy ): 74
  8. Mathematica ( LegionMammal978 ) e Haskell ( Renzeee ): 77
  9. Python 2 ( mathmandan ): 111
  10. Python 3 ( Erwan ): 161
  11. Java 8 ( Blu ): 229
  12. Oracle SQL 11.2 ( Jeto ): 456
  13. Befunge '93 ( Lex ): 490

Alcuni altri casi di test sarebbero apprezzati.
Mego

Quindi l'ingresso avrà un massimo di 4 cifre?
Denker

7
Cosa succede se viene raggiunto un ciclo, ma il periodo del ciclo non è 1 o il numero di input non fa parte del ciclo?
feersum

1
"Sono certo che non ce ne sono nel regno della fattibilità". Possiamo presumere che non accadrà mai? Vale a dire che il ciclo può continuare all'infinito se viene raggiunto un ciclo del periodo> 1?
Stewie Griffin

6
Casi di prova proposti: 1100ed -42è facile perdere le regole sui casi limite se non vengono visualizzati nei casi di prova.
Dennis

Risposte:


4

Gelatina, 15 14 12 10 byte

Ds2*/€Pµ³¡

Provalo online!

Come funziona

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.

Questo potrebbe essere abbreviato semplicemente ripetendo i ntempi, ma non ho la prova che funzioni per tutti i possibili input.
Dennis

1
Dovresti essere a posto per qualsiasi numero ragionevole. In effetti stai quasi certamente bene per QUALUNQUE numero usando 16 iterazioni: oeis.org/A133503
Ton Hospel

@Dennis Hm, è quello che faccio nella mia risposta
Luis Mendo l'

1
@DonMuesli E ora che ci ho pensato, probabilmente funziona. Le probabilità di ottenere uno 0 e un indice dispari sono schiaccianti ...
Dennis

Nella moderna Jelly, questo potrebbe essere fatto in 7 byte:D*2/Pµ¡
Dennis

5

Haskell, 67 64 byte

(>> = (==)) >> = fino a quando $ p.show è una funzione senza nome che accetta un numero intero come input e restituisce il suo gruppo propulsore.

Salvato 3 byte grazie a Zgarb

p(x:y:r)=p[x]^p[y]*p r;p[]=1;p x=read x
(>>=(==))>>=until$p.show

1
((==)=<<g)salva due byte sopra (\n->g n==n).
Zgarb

Wow, non ho familiarità con l'istanza ((->) r) di Monad. Grazie per il trucco.
Damien,

Questa raffica di segni di punteggiatura (>>=(==))>>=sembra davvero un treno!
Andreï Kostyrka,

4

Perl, 42 48 byte

Includi +2 per -lp(puoi rilasciare -lanche quello ma mi piacciono le newline)

Esegui con input su STDIN, ad es

perl -lp powertrain.pl <<< 1234

powertrain.pl:

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

(su perls più vecchi puoi anche far cadere lo spazio tra la regex e fino a)

Questo non sarà in grado di gestire il punto fisso 24547284284866560000000000ma un valore così grande non funzionerà comunque perché a quel punto il perl passò alla notazione esponenziale.

In effetti, la versione precedente funzionerà velocemente (nella maggior parte dei 2592cicli) per tutti i numeri che il perl può rappresentare senza usare la notazione esponenziale poiché è dimostrato che non ci sono punti fissi tra 2592e 24547284284866560000000000( https://oeis.org/A135385 )

Ciò tuttavia presuppone qualcosa di non ancora dimostrato. In linea di principio potrebbe esserci una riduzione che richiede più di X=10^7passaggi (si ipotizza che nessun punto non fisso comporti più di 16 passaggi, https://oeis.org/A133503 ) il cui valore scende sotto X(ma sopra 10^7) e poi sale ancora. In tal caso, devo tornare a:

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

Spiegazione

Il codice funziona inserendo **e *(alternando) tra le cifre

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

così 2592diventa 2**5*9**2e 12345diventa 1**2*3**4*5. Queste sono espressioni perl valide che possono essere valutate con

$_ = eval

( 0**0è 1in perl). Quindi basta fare un giro attorno a quello con un contatore che lo fa scadere. Poiché, tranne per i punti fissi, i valori scendono molto rapidamente, la serie powertrain converge prima che il contatore abbia la possibilità di iniziare davvero


3

Pyth, 25 18 11 16 byte

?<Q0Qu*F^McjGT2Q

Provalo qui!

7 14 byte salvati con l'aiuto di @Jakube

Spiegazione

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

? <Q0Q # Se l'ingresso è un ritorno negativo Q
     u Q # applica la seguente funzione fino a quando non raggiungiamo un ciclo               
                   # il valore iniziale è Q e il valore corrente è in G
           jGT # suddivide l'input in un elenco di cifre
          c 2 # diviso in coppie di 2
        ^ M # calcola la potenza per ogni coppia
      * F # calcola il prodotto di tutti i poteri


1
Pyth è fondamentalmente solo una versione giocata a golf di Python, tranne che con piccole modifiche?
clismique l'

1
@Jakube Grazie per i suggerimenti! :) Ancora la mattina presto per me ...
Denker

@DerpfacePython Sì, un po '. Dai un'occhiata ai documenti se vuoi saperne di più.
Denker

Nessun problema. ;-)
Jakube

4
@DerpfacePython Pyth è iniziato come "abbreviato Python", ma chiamarlo che ora sarebbe disonesto. Pyth si è notevolmente discostato da Python.
Mego

3

Python 2, 111 byte

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'idea è quella di creare una stringa in cui le cifre di nsono separate da operazioni che si alternano tra *e **e quindi evalquella stringa. (Altre soluzioni usano questa stessa idea; vedi ad esempio la risposta Perl di Ton Hospel .)

Quindi, l'operazione passa avanti e indietro tra '**'[0:], che è **e '**'[-1:]che è giusto *.

Tuttavia, entro la fine di for-loop, la stringa termina con un'operazione (l'una o l'altra), quindi o dobbiamo eliminare l'ultima operazione, oppure aggiungere un'altra cifra, affinché la stringa abbia un senso.

Fortunatamente, aggiungere un 1alla fine funzionerà indipendentemente dall'ultima operazione. (Se ti piace, 1è un'identità unilaterale da destra, sia per la moltiplicazione che per l'espiazione. Un altro modo di dire questo è quello powertrain(n) == powertrain(10*n + 1)per tutti n>0.)

Infine, se il risultato dell'operazione evalè lo stesso dell'input (come in un 1ciclo di lunghezza ), la funzione termina. Altrimenti, la funzione si chiama sul risultato. (Rimarrà per sempre su qualsiasi ciclo di lunghezza > 1, ma secondo i commenti del PO sono autorizzato a supporre che non ci siano tali cicli.)

(Nota: la spiegazione sopra funziona per numeri interi positivi a una cifra, poiché nverrà completato un input a una cifra n**1che comporterà un 1ciclo. Tuttavia, dobbiamo anche accettare input non positivi, quindi c'è una condizione al iniziando i cortocircuiti se l'ingresso è inferiore a 1. Potremmo eliminare quella linea e salvare 17 byte, se l'ingresso fosse garantito non negativo.)


Sembra distorto, ma ... votato per essere Python 2. E ha una spiegazione.
clismique

@DerpfacePython Grazie! (Immagino che funzionerebbe altrettanto bene in Python 3 ...)
mathmandan

3

Java 8, 265 244 229 byte

Questa è la mia prima risposta, ma sto leggendo questo sito da un po 'e penso di sapere cosa sto facendo. Almeno batte befunge e SQL ...

Sfortunatamente, come altre risposte, questo non funziona per 24547284284866560000000000 a causa di java'a restrizioni incorporate su come numeri interi di grandi dimensioni possono ottenere.

36 byte salvati grazie a @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);}

Spiegazione Ungolfed

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

Nel tuo primo if ... else if(n<10)return n;else{...}il resto è inutile dal momento che logicamente tutto in quell'altro blocco funzionerebbe comunque solo quando n <10 è falso. La rimozione dell'altro e delle 2 parentesi graffe corrispondenti ti farà risparmiare 6 byte. C'è una situazione simile con l'ultimo se ... altrimenti if(n==t)return n;else return p(t);rimuovi l'altro e lo spazio dopo di esso per salvare altri 5 byte. In effetti puoi accorciarlo ulteriormente se usi l'operatore triadico invece dell'if ... altrimenti in questo modoreturn n==t?n:p(t);
Jack Ammo

puoi salvare qualche altro byte (17 credo) dichiarando insieme t, s, r e il ciclo for iint t=i=1,s=(int)Math.log10(n)+1,r[]=new int[s];for(;i<=s;){...}for(i=0;...)...
Jack Ammo

@JackAmmo Non sapevo che le variabili potessero essere dichiarate in quel modo, dovrò provarlo. Grazie per l'aiuto!
Blue

sì, devi solo stare attento all'ordine di dichiararli se ne usi uno per inizializzarne un altro (come il modo in cui r usa s per definirne la lunghezza)
Jack Ammo

per numeri arbitrari di grandi dimensioni, dovresti consultare la classe BigInteger
Jack Ammo

2

JavaScript (ES6) 71

Una funzione ricorsiva, che si interrompe quando viene rilevata una ripetizione. Questo potrebbe non funzionare per loop più lunghi (ripetizione di 2 o più valori) ma sembra che ciò non possa accadere, almeno nell'intervallo limitato di precisione dei numeri javascript (17 cifre)

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>


Bello di quello +'1'per uccidere due uccelli con una fava!
Neil,

Non so se lo avresti già investigato, ma il meglio che potevo fare replaceera di 1 byte in più:f=n=>`${n}1`.replace(/../g,([x,y])=>r*=Math.pow(x,y),r=1)&&n-r?f(r):n
Neil

@Neil Ci ho provato anche io, ma quella stringa di template è una nuova idea ...
edc65

1

Mathematica, 77 byte

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

Funzione anonima. Non troppo complicato.


Anche così, posso ancora avere una spiegazione?
clismique,

1

Befunge 720 490 byte

Non ho potuto resistere a fare un altro dopo la cosa di Never dirmi le probabilità . Quindi, ho ottimizzato il "ASCII-fier" del precedente. In questo caso non ho visto la necessità di far scorrere il puntatore delle istruzioni sulle cifre per leggerle, quindi non mi sono sforzato di renderle leggibili. Quindi ora è più un digitalizzatore.

Ancora una volta, se volete una spiegazione, fatemi sapere nei commenti, proverò a creare alcune descrizioni utili. È possibile copiare incollare il codice nell'interprete . Ho scoperto che l'esempio 24547284284866560000000000 restituisce 0, ma questo sembra essere un problema con l'ottenimento di un valore così grande da un punto della griglia, poiché puoi vedere chiaramente che il valore corretto viene memorizzato nei passaggi finali.

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

Questa versione supporta anche input negativi. È un grande miglioramento rispetto alla versione precedente, se lo dico io stesso. È stato corretto almeno 1 bug e le dimensioni sono state notevolmente ridotte.


Quanti byte in più ci vorranno per inserire numeri negativi?
clismique,

Non sono sicuro di essere onesto. Ho avuto dei problemi con i numeri negativi e scrivendoli da qualche parte nella griglia. Ci proverò di nuovo.
rael_kid,

Ho appena trovato anche un altro bug. Sono riuscito ad aggiungere il supporto per i numeri negativi. Pubblicherò presto un aggiornamento! Probabilmente sarà la stessa quantità di byte, dal momento che conto l'intera griglia.
rael_kid,

1

Haskell, 100 79 77 byte

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 giocato a 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

Questa funzione divide l'input in cifre e fa il trucco tramite i.

EDIT: Grazie a Nimi per alcuni suggerimenti.


Alcuni consigli: a) i(a:[])=aè i[a]=a, b) non è necessario max 1, perché 0^0 = 1in Haskell, c) sostituisci (:[])con pure, d) sposta l' letinterno gin una funzione separata e sostituisci if ... then ... elsecon le protezioni:h=i.map(read.pure).show ; g x|x==h x=x|1<2=h x
nimi

purenon è in Preludio, ma il resto dei suggerimenti funziona, grazie. Stavo cercando di farlo con le guardie, ma alla fine ho usato ;prima la guardia e non ha funzionato, ma ora so come dovrebbe funzionare.
Renzeee,

pureè nel Preludio fornito con base-4.8.2.0. Non so quando è stato introdotto. Non hai bisogno di ( )dentro i([a])=a.
nimi,

1

Mathematica, 74 byte

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

Spiegazione

Questa soluzione utilizza una funzione di supporto f, che prende le cifre del numero come argomenti e applica una ripetizione dell'operazione della motopropulsore. L'ultima riga è una funzione pura creata per sfruttare la ReplaceRepeatedfunzione (o //.in breve), che applica una regola a un'espressione (in questo caso l'argomento #della funzione pura) fino a quando non cambia più. La regola i_/;i>0:>f@@IntegerDigits@isostituisce qualsiasi cosa non negativa con la funzione fapplicata alle sue cifre decimali.


La linea 2 non funziona (uso :=)
CalculatorFeline

Spiegazione, per favore?
clismique,

@CatsAreFluffy Non vedo il tuo problema con la linea 2. Funziona bene per me!
Murphy

SetDelayed::write: Tag Times in n f[a_,b_,c___] is Protected. >>, Set::write: Tag Times in 1 f[n_] is Protected. >>Il secondo errore scompare quando uso :=vs =.
Calcolatrice

Spiacenti, impossibile riprodurre quell'errore. Ma l'output indica che le interruzioni di riga fanno parte del problema. Prova la versione con ;s invece delle interruzioni di riga: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 byte

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

Potrebbero essere necessari alcuni secondi per produrre l'output.

EDIT (30 lug 2016): le sostituisce codice legato 9Lda 1Ladattare ai recenti cambiamenti nel linguaggio.

Provalo online!

Questo utilizza i seguenti due trucchi per ridurre il conteggio dei byte a scapito dell'efficienza del codice:

  • Iterate nvolte invece di attendere fino a quando non viene trovato un ciclo. Questo è accettabile secondo i commenti di OP.
  • Per un numero dispari di cifre 1, è necessario aggiungere un finale per completare l'operazione di alimentazione finale. Invece, il numero di aggiunte 1è il numero di cifre. Ciò garantisce un numero pari, quindi è possibile eseguire tutte le operazioni di alimentazione (anche se le ultime sono 1^1operazioni non necessarie ).

Codice:

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

Uh ... heh heh heh ... quando ho detto "cicli di numeri", intendevo numeri che andavano così - a, b, a, ball'infinito (più di un termine). Se un termine viene ripetuto, è necessario generare quel numero. Scusa se non è stato molto chiaro.
clismique,

Se un termine viene ripetuto, sto inviando quel numero. Ho prodotto il risultato dopo molte iterazioni
Luis Mendo del

Oh, capisco ora ... sto solo chiedendo, quante iterazioni sarebbe (circa)? Perché quando scrivo 2592nell'input, non sembra emettere nulla per un bel po '.
clismique,

Il numero di iterazioni è il numero di input, quindi 2592 in quel caso. Sì, ci vuole un po '
Luis Mendo il

0

Python 3, 169 161 byte

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]

risultati

>>> [f(i) for i in ['135', '1234', '642', '2592', '-15']]
['5', '8', '2592', '2592', '-15']

@PeterTaylor Risolto!
Erwan,

È possibile inserire più istruzioni in una riga se le si separa con A In ;questo modo si risparmiano gli spazi bianchi di intenzione. Inoltre puoi mettere il corpo del ciclo for su quella stessa linea.
Denker,

Golf suggerito: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]
CalcolatriceFeline

@CatsAreFluffy o=[['1',s]["-"in s]]nell'argomento predefinito non funziona per me, genera un errore `s non definito`
Erwan

Spiacenti, passa a alla riga successiva.
Calcolatrice

0

Oracle SQL 11.2, 456 byte

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 è una vista ricorsiva, i parametri lo sono

n: numero da dividere in parti di 2 cifre

c: numero di parti di 2 cifre

i: parte corrente a 2 cifre da calcolare

f: stringa che concatena i poteri con * come separatore

t: valutazione di f

I DECODI passano al numero successivo per dividere e calcolare al termine di tutte le parti del numero corrente.

XMLTABLE (f) accetta un'espressione e la valuta, inserendo il risultato nella pseudo colonna "valore_colonna". È la versione golfata di http://tkyte.blogspot.fr/2010/04/evaluating-expression-like-calculator.html

CYCLE è il rilevamento del ciclo incorporato nell'oracolo e viene utilizzato come condizione di uscita.

Poiché il risultato per: 1 <10 è: 1 e v non restituisce alcuna riga per questi casi, SUM forza una riga con NULL come valore. NVL restituisce: 1 come risultato se la riga è nulla.


Dov'è la spiegazione?
clismique,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.