28
\$\begingroup\$

The winner (pretty obviously) is Dennis ♦, who used Jelly with 10 bytes!

This challenge will still be up here, however results won't be taken anymore.


The powertrain of a number is a concept by John Conway (who is also notable for making Conway's Game of Life, but that's not the point). It is defined as so:

For any number enter image description here..., the powertrain of the number is enter image description here... (i.e. every 2nd digit, from left to right, is a power of the digit before that). This process is repeated until the result is a single digit.

EXAMPLES:

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

Your challenge is, for any number n in the input, return powertrain(n) (i.e. n after the powertrain decomposition is finished) as output.

This is code golf, so shortest amount of bytes wins.

DISCLAIMER-THINGS:

  • You can have an odd number of digits in the input, the last digit just won't have a power.
  • 0^0 is 1, because if it was 0, then a lot of numbers would instantly collapse to 0 or 1.
  • If the number is indestructible in any part of the computation process (e.g. if it ends up with 2592), then you can just output the number.
  • If the input is < 10 (i.e. all single digit numbers and negatives), output the input.

I'll probably announce a winner after a few hours days.

Current leaderboard:

  1. Jelly (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) and Haskell (Renzeee): 77
  9. Python 2 (mathmandan): 111
  10. Python 3 (Erwan): 161
  11. Java 8 (Blue): 229
  12. Oracle SQL 11.2 (Jeto): 456
  13. Befunge '93 (Lex): 490
\$\endgroup\$
12
  • \$\begingroup\$ Some more test cases would be appreciated. \$\endgroup\$
    – user45941
    Mar 8, 2016 at 7:34
  • \$\begingroup\$ So the input will have 4 digits max? \$\endgroup\$
    – Denker
    Mar 8, 2016 at 7:42
  • 7
    \$\begingroup\$ What if a cycle is reached, but the period of the cycle is not 1, or the input number is not part of the cycle? \$\endgroup\$
    – feersum
    Mar 8, 2016 at 7:44
  • 1
    \$\begingroup\$ "I'm certain there aren't any within the realms of feasibility". Can we assume it will never happen? I.e. allowing the loop to go on forever if a cycle of period > 1 is reached? \$\endgroup\$ Mar 8, 2016 at 8:01
  • 6
    \$\begingroup\$ Proposed test cases: 1100 and -42 It's easy to miss rules about edge cases if the do not show up in the test cases. \$\endgroup\$
    – Dennis
    Mar 8, 2016 at 13:24

16 Answers 16

5
\$\begingroup\$

Haskell, 67 64 bytes

(>>=(==))>>=until$p.show is an unnamed function taking an integer as input and returning its powertrain.

Saved 3 bytes thanks to Zgarb

p(x:y:r)=p[x]^p[y]*p r;p[]=1;p x=read x
(>>=(==))>>=until$p.show
\$\endgroup\$
3
  • 1
    \$\begingroup\$ ((==)=<<g) saves two bytes over (\n->g n==n). \$\endgroup\$
    – Zgarb
    Mar 8, 2016 at 15:58
  • \$\begingroup\$ Wow, I'm not familiar with the ((->) r) instance of Monad. Thanks for the trick. \$\endgroup\$
    – Damien
    Mar 8, 2016 at 16:36
  • \$\begingroup\$ This barrage of punctuation marks (>>=(==))>>= really looks like a train! \$\endgroup\$ Aug 31, 2016 at 10:06
4
\$\begingroup\$

Jelly, 15 14 12 10 bytes

Ds2*/€Pµ³¡

Try it online!

How it works

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.
\$\endgroup\$
5
  • \$\begingroup\$ This could be made shorter by simply iterating n times, but I don't have a proof that it works for all possible inputs. \$\endgroup\$
    – Dennis
    Mar 8, 2016 at 13:55
  • 1
    \$\begingroup\$ You should be ok for any reasonable number. In fact you are almost certainly ok for ANY number using 16 iterations: oeis.org/A133503 \$\endgroup\$
    – Ton Hospel
    Mar 8, 2016 at 14:22
  • \$\begingroup\$ @Dennis Hm, that's what I do in my answer \$\endgroup\$
    – Luis Mendo
    Mar 8, 2016 at 14:50
  • 1
    \$\begingroup\$ @DonMuesli And now that I've thought about it, it probably works. The odds of getting a 0 and an odd index are overwhelming... \$\endgroup\$
    – Dennis
    Mar 8, 2016 at 16:22
  • \$\begingroup\$ In modern Jelly, this could be done in 7 bytes: D*2/Pµ¡ \$\endgroup\$
    – Dennis
    Mar 31, 2017 at 1:29
4
\$\begingroup\$

Perl, 42 48 bytes

Include +2 for -lp (you can drop the -l too but I like newlines)

Run with input on STDIN, e.g.

perl -lp powertrain.pl <<< 1234

powertrain.pl:

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

(on older perls you can also drop the space between the regex and until)

This won't be able to handle the fixed point 24547284284866560000000000 but that large a value won't work anyways because by that time perl switched to exponential notation.

The above version is will in fact work fast (at most 2592 loops) for all numbers that perl can represent without using exponential notation since it is proven that there are no fixed points between 2592 and 24547284284866560000000000 (https://oeis.org/A135385)

This does however assume something as yet unproven. In principle there could be a reduction that takes more than X=10^7 steps (it is conjectured that no non-fixed point takes more than 16 steps, https://oeis.org/A133503) whose value dips below X (but above 10^7) and then goes up again. If that is the case I must fall back to:

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

Explanation

The code works by putting ** and * (alternating) between the digits

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

so 2592 becomes 2**5*9**2 and 12345 becomes 1**2*3**4*5. These are valid perl expressions that can be evaluated with

$_ = eval

(0**0 is 1 in perl). Then just put a loop around that with a counter that makes it expire. Since except for the fixed points the values go down extremely quickly the powertrain series converges before the counter gets a chance to really get going

\$\endgroup\$
0
3
\$\begingroup\$

Pyth, 25 18 11 16 bytes

?<Q0Qu*F^McjGT2Q

Try it here!

7 14 bytes saved with help from @Jakube

Explanation

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

?<Q0Q              # If input is negative return Q
     u         Q   # apply the following function until we reach a cycle               
                   # starting value is Q and the current value is in G
           jGT     # split input into a list of digits
          c   2    # split into pairs of 2
        ^M         # compute the power for every pair
      *F           # compute the product of all powers

\$\endgroup\$
7
  • 1
    \$\begingroup\$ Is Pyth basically just a golfed version of Python, except with minor changes? \$\endgroup\$
    – clismique
    Mar 8, 2016 at 9:09
  • 1
    \$\begingroup\$ @Jakube Thanks for the hints! :) Still early in the morning for me... \$\endgroup\$
    – Denker
    Mar 8, 2016 at 9:20
  • \$\begingroup\$ @DerpfacePython Yea, kinda. Have a look at the docs if you wanna learn about it. \$\endgroup\$
    – Denker
    Mar 8, 2016 at 9:21
  • \$\begingroup\$ No problem. ;-) \$\endgroup\$
    – Jakube
    Mar 8, 2016 at 9:35
  • 4
    \$\begingroup\$ @DerpfacePython Pyth started out as just "shortened Python", but to call it that now would be disingenuous. Pyth has significantly diverged from Python. \$\endgroup\$
    – user45941
    Mar 8, 2016 at 17:33
3
\$\begingroup\$

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

The idea is to make a string where the digits of n are separated by operations which alternate between * and **, and then eval that string. (Other solutions use this same idea; see for example Ton Hospel's Perl answer.)

So, the operation switches back and forth between '**'[0:], which is **, and '**'[-1:], which is just *.

However, by the end of the for-loop, the string ends with an operation (one or the other), so we either need to drop the last operation, or else add another digit, in order for the string to make sense.

Fortunately, appending a 1 on the end will work no matter which operation is last. (If you like, 1 is a one-sided identity from the right, for both multiplication and exponentiation. Another way of saying this is that powertrain(n) == powertrain(10*n + 1) for all n>0.)

Finally, if the result of the eval happens to be the same as the input (as in a length-1 cycle), the function terminates. Otherwise, the function calls itself on the result. (It will hang forever on any cycle of length > 1, but according to the OP's comments I am allowed to assume there are no such cycles.)

(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.)

\$\endgroup\$
2
  • \$\begingroup\$ This sounds biased, but... upvote for being Python 2. And it has an explanation. \$\endgroup\$
    – clismique
    Mar 9, 2016 at 1:52
  • \$\begingroup\$ @DerpfacePython Thanks! (I guess this would work just as well in Python 3...) \$\endgroup\$
    – mathmandan
    Mar 9, 2016 at 2:18
3
\$\begingroup\$

Java 8, 265 244 229 bytes

This is my first answer, but I have been reading this site for a while and think I know what I'm doing. At least it beats befunge and SQL...

Unfortunately, like other answers, this one does not work for 24547284284866560000000000 due to java'a built in restrictions on how large integers can get.

Saved 36 bytes thanks to @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);}

Ungolfed Explanation

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);
}
\$\endgroup\$
6
  • \$\begingroup\$ 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); \$\endgroup\$
    – Jack Ammo
    Mar 13, 2016 at 0:27
  • \$\begingroup\$ 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;...)... \$\endgroup\$
    – Jack Ammo
    Mar 13, 2016 at 0:46
  • \$\begingroup\$ @JackAmmo I wasn't aware variables could be declared like that, I'll have to try it. Thanks for your help! \$\endgroup\$
    – Blue
    Mar 13, 2016 at 0:59
  • \$\begingroup\$ yeah, you just have to be careful with the order of declaring them if you're using one to initialize another (like how r uses s to define it's length) \$\endgroup\$
    – Jack Ammo
    Mar 13, 2016 at 1:07
  • \$\begingroup\$ for arbitrary large numbers, you should look into java's BigInteger class docs.oracle.com/javase/8/docs/api/java/math/BigInteger.html \$\endgroup\$
    – Jack Ammo
    Mar 13, 2016 at 2:05
2
\$\begingroup\$

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>

\$\endgroup\$
3
  • \$\begingroup\$ Nice of that +'1' to kill two birds with one stone! \$\endgroup\$
    – Neil
    Mar 11, 2016 at 22:38
  • \$\begingroup\$ 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 \$\endgroup\$
    – Neil
    Mar 11, 2016 at 22:45
  • \$\begingroup\$ @Neil I tried hard too, but that template string is a new idea ... \$\endgroup\$
    – edc65
    Mar 12, 2016 at 1:12
1
\$\begingroup\$

Mathematica, 77 bytes

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

Anonymous function. Not too complicated.

\$\endgroup\$
1
  • \$\begingroup\$ Even so, can I still have an explanation? \$\endgroup\$
    – clismique
    Mar 14, 2016 at 9:05
1
\$\begingroup\$

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.

\$\endgroup\$
3
  • \$\begingroup\$ How many bytes more will it take for the thing to input negative numbers? \$\endgroup\$
    – clismique
    Mar 11, 2016 at 6:25
  • \$\begingroup\$ 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. \$\endgroup\$ Mar 11, 2016 at 8:07
  • \$\begingroup\$ 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. \$\endgroup\$ Mar 11, 2016 at 8:15
1
\$\begingroup\$

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.

\$\endgroup\$
3
  • \$\begingroup\$ 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 \$\endgroup\$
    – nimi
    Mar 9, 2016 at 18:23
  • \$\begingroup\$ 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. \$\endgroup\$
    – Renzeee
    Mar 11, 2016 at 8:49
  • \$\begingroup\$ 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. \$\endgroup\$
    – nimi
    Mar 11, 2016 at 17:02
1
\$\begingroup\$

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.

\$\endgroup\$
5
  • \$\begingroup\$ Line 2 doesn't work (use :=) \$\endgroup\$ Mar 14, 2016 at 1:00
  • \$\begingroup\$ Explanation, please? \$\endgroup\$
    – clismique
    Mar 14, 2016 at 9:04
  • \$\begingroup\$ @CatsAreFluffy I don't see your problem with line 2. It works fine for me! \$\endgroup\$
    – murphy
    Mar 14, 2016 at 9:54
  • \$\begingroup\$ 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=. \$\endgroup\$ Mar 14, 2016 at 15:07
  • \$\begingroup\$ 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& \$\endgroup\$
    – murphy
    Mar 14, 2016 at 18:54
1
\$\begingroup\$

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
\$\endgroup\$
4
  • \$\begingroup\$ 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. \$\endgroup\$
    – clismique
    Mar 11, 2016 at 23:26
  • \$\begingroup\$ If one term is repeated, I'm outputting that number. I output the result after many iterations \$\endgroup\$
    – Luis Mendo
    Mar 12, 2016 at 14:04
  • \$\begingroup\$ 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. \$\endgroup\$
    – clismique
    Mar 13, 2016 at 0:51
  • \$\begingroup\$ The number of iterations is the input number, so 2592 in that case. Yes, it takes a while \$\endgroup\$
    – Luis Mendo
    Mar 13, 2016 at 3:58
0
\$\begingroup\$

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']
\$\endgroup\$
5
  • \$\begingroup\$ @PeterTaylor Fixed! \$\endgroup\$
    – Erwan
    Mar 8, 2016 at 13:44
  • \$\begingroup\$ 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. \$\endgroup\$
    – Denker
    Mar 10, 2016 at 9:17
  • \$\begingroup\$ 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] \$\endgroup\$ Mar 10, 2016 at 17:26
  • \$\begingroup\$ @CatsAreFluffy o=[['1',s]["-"in s]] in default argument don't work for me it raise a error ` s not defined` \$\endgroup\$
    – Erwan
    Mar 11, 2016 at 6:58
  • \$\begingroup\$ Oops, move o to the next line. \$\endgroup\$ Mar 11, 2016 at 14:32
0
\$\begingroup\$

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.

\$\endgroup\$
1
  • \$\begingroup\$ Where's the explanation? \$\endgroup\$
    – clismique
    Mar 11, 2016 at 23:21
0
\$\begingroup\$

Husk, 10 bytes

ωöΠmF`^C2d

Try it online!

Explanation

ωöΠmF`^C2d
ωö         apply the following functions till a fixed point is reached:
         d get base-10 digits
       C2  split into groups of two
   mF`^    map each pair to power
  Π        multiply all the powers.
\$\endgroup\$
0
\$\begingroup\$

Japt, 13 bytes

Èì ò ®rpÃ×}gN

Try it

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.