22
\$\begingroup\$

The challenge

Quite simple, given an input x, calculate it's infinite power tower!

x^x^x^x^x^x...

For you math-lovers out there, this is x's infinite tetration.

Keep in mind the following:

x^x^x^x^x^x... = x^(x^(x^(x^(x...)))) != (((((x)^x)^x)^x)^x...)

Surprised we haven't had a "simple" math challenge involving this!*

Assumptions

  • x will always converge.
  • Negative and complex numbers should be able to be handled
  • This is , so lowest bytes wins!
  • Your answers should be correct to at least 5 decimal places

Examples

Input >> Output

1.4 >> 1.8866633062463325
1.414 >> 1.9980364085457847
[Square root of 2] >> 2
-1 >> -1
i >> 0.4382829367270323 + 0.3605924718713857i
1 >> 1
0.5 >> 0.641185744504986
0.333... >> 0.5478086216540975
1 + i >> 0.6410264788204891 + 0.5236284612571633i
-i >> 0.4382829367270323 -0.3605924718713857i
[4th root of 2] >> 1.239627729522762

*(Other than a more complicated challenge here)

\$\endgroup\$
7
  • 2
    \$\begingroup\$ I don’t think this tower converges at x = −2 or x = −0.5. \$\endgroup\$ Jul 25, 2017 at 7:37
  • \$\begingroup\$ @AndersKaseorg I agree, though all programs seem to have the same converging answer. Why don't they converge? \$\endgroup\$
    – Graviton
    Jul 25, 2017 at 7:38
  • 2
    \$\begingroup\$ x = −2 gets attracted to a 8-cycle and x = −0.5 gets attracted to a 6-cycle. (My program still gives an answer in these cases, but it’s one of the points in the cycle and not a fixed point; this doesn’t indicate convergence.) \$\endgroup\$ Jul 25, 2017 at 7:44
  • \$\begingroup\$ @AndersKaseorg Aha very interesting. You wouldn't happen to know why '8' for -2 and '6' for -0.5? Just out of curiosity of course. \$\endgroup\$
    – Graviton
    Jul 25, 2017 at 7:47
  • 2
    \$\begingroup\$ You can run the iterations just as easily as I can, but here’s a picture: commons.wikimedia.org/wiki/File:Tetration_period.png \$\endgroup\$ Jul 25, 2017 at 7:50

17 Answers 17

16
\$\begingroup\$

APL (Dyalog), 4 bytes

*⍣≡⍨

Try it online!

* power

 until

 stable

 selfie

\$\endgroup\$
11
\$\begingroup\$

Pyth,  4  3 bytes

crossed out 4 is still regular 4 ;(

u^Q

Try it online

How it works

u       first repeated value under repeated application of G ↦
 ^QG        input ** G
    Q   starting at input
\$\endgroup\$
2
  • 2
    \$\begingroup\$ You don't need the last G, it will get auto-filled. \$\endgroup\$ Jul 25, 2017 at 13:10
  • \$\begingroup\$ @FryAmTheEggman Right, thanks! \$\endgroup\$ Jul 25, 2017 at 20:14
7
\$\begingroup\$

Haskell, 100 63 bytes

For inputs that don't converge (eg. -2) this won't terminate:

import Data.Complex
f x=until(\a->magnitude(a-x**a)<1e-6)(x**)x

Thanks a lot @ØrjanJohansen for teaching me about until and saving me 37 bytes!

Try it online!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ You can shorten this a lot with the until function. Try it online! \$\endgroup\$ Jul 25, 2017 at 8:10
  • \$\begingroup\$ Neat! Did not know until, thanks a lot. \$\endgroup\$ Jul 25, 2017 at 8:16
7
\$\begingroup\$

Python 3, 40 39 35 bytes

  • Thanks @Ørjan Johansen for a byte: d>99 instead of d==99: 1 more iteration for a lesser byte-count
  • Thanks @Uriel for 4 bytes: wise utilization of the fact that x**True evaluates to x in x**(d>99or g(x,d+1)). The expression in the term evaluates to True for depth greater than 99 and thus returns the passed value.

Recursive lambda with a max-depth 100 i.e. for a depth 100 returns the same value. Actually is convergency-agnostic, so expect the unexpected for numbers with non-converging values for the function.

g=lambda x,d=0:x**(d>99or g(x,d+1))

Try it online!

\$\endgroup\$
4
  • 1
    \$\begingroup\$ In the tio link, you can replace complex('j') with 1j \$\endgroup\$
    – Mr. Xcoder
    Jul 25, 2017 at 8:26
  • 1
    \$\begingroup\$ d>99 does one more iteration and is shorter. \$\endgroup\$ Jul 25, 2017 at 8:43
  • 1
    \$\begingroup\$ save 4 bytes with g=lambda x,d=0:x**(d>99or g(x,d+1)), x**True evaluates to x \$\endgroup\$
    – Uriel
    Jul 25, 2017 at 12:57
  • \$\begingroup\$ @Uriel, That is really smart..... Thanks!!! \$\endgroup\$ Jul 25, 2017 at 13:09
6
\$\begingroup\$

Python 3, 37 30 27 bytes

-7 bytes from @FelipeNardiBatista.
-3 bytes from from @xnor

I don't remember much of Python anymore, but I managed to port my Ruby answer and beat the other Python 3 answer :D

lambda x:eval('x**'*99+'1')

Try it online!

\$\endgroup\$
5
  • 1
    \$\begingroup\$ FYI, it appears that f-strings were first introduced in Python 3.6: see python.org/dev/peps/pep-0498 . (This would explain why your code didn't work for me in 3.5.2.) Just thought I'd mention this in case anyone else was confused. \$\endgroup\$
    – mathmandan
    Jul 25, 2017 at 16:01
  • 1
    \$\begingroup\$ You don't need to substitute in the value of x, eval('x**'*99+'1') works \$\endgroup\$
    – xnor
    Jul 25, 2017 at 18:51
  • \$\begingroup\$ @xnor doh, of course it does :) thanks \$\endgroup\$
    – daniero
    Jul 25, 2017 at 19:08
  • \$\begingroup\$ @xnor Neat -- I applied the same thing in my Ruby answer and it somehow fixed it :) \$\endgroup\$
    – daniero
    Jul 25, 2017 at 19:17
  • 1
    \$\begingroup\$ +1, I am slapping myself for forgetting the existence of eval.... :D \$\endgroup\$ Jul 26, 2017 at 5:29
4
\$\begingroup\$

Mathematica, 12 bytes

#//.x_:>#^x&

Takes a floating‐point number as input.

\$\endgroup\$
4
\$\begingroup\$

J, 5 bytes

^^:_~

Try it online!

Explanation

First, I'll show what command is being executed after parsing the ~ at the end, and the walk-through will be for the new verb.

(^^:_~) x = ((x&^)^:_) x

((x&^)^:_) x  |  Input: x
      ^:_     |  Execute starting with y = x until the result converges
  x&^         |    Compute y = x^y
\$\endgroup\$
2
  • \$\begingroup\$ The J solution is really nice here. To break down your first line in finer grain, is it correct to say that the following happens: (^^:_) creates a new dyadic verb via the power conj, then self adverb ~ makes that verb monadic, so that when given an argument x it's expanded to x (^^:_) x. the left x subsequently "sticks", giving ((x&^)^:_) x per your note, and only the right argument changes during iteration? \$\endgroup\$
    – Jonah
    Jul 25, 2017 at 14:30
  • 1
    \$\begingroup\$ @Jonah Sure, when giving two arguments to a dyad with power, x u^:n y, the left argument is bonded with the dyad to form a monad that is nested n times on y. x u^:n y -> (x&u)^:n y -> (x&u) ... n times ... (x&u) y \$\endgroup\$
    – miles
    Jul 25, 2017 at 14:36
4
\$\begingroup\$

C# (.NET Core), 79 78 bytes

x=>{var a=x;for(int i=0;i++<999;)a=System.Numerics.Complex.Pow(x,a);return a;}

Try it online!

I chose to iterate until i=999 because if I iterated until 99 some examples did not reach the required precision. Example:

Input:                      (0, 1)
Expected output:            (0.4382829367270323, 0.3605924718713857)
Output after 99 iterations: (0.438288569331222,  0.360588154553794)
Output after 999 iter.:     (0.438282936727032,  0.360592471871385)

As you can see, after 99 iterations the imaginary part failed in the 5th decimal place.

Input:                      (1, 1)
Expected output:            (0.6410264788204891, 0.5236284612571633)
Output after 99 iterations: (0.64102647882049,   0.523628461257164)
Output after 999 iter.:     (0.641026478820489,  0.523628461257163)

In this case after 99 iterations we get the expected precision. In fact, I could iterate until i=1e9 with the same byte count, but that would make the code considerably slower

  • 1 byte saved thanks to an anonymous user.
\$\endgroup\$
2
  • 1
    \$\begingroup\$ +1 For the complex class I didn't even know that existed. \$\endgroup\$ Jul 25, 2017 at 11:29
  • 1
    \$\begingroup\$ @TheLethalCoder neither did I until I googled it. :-) \$\endgroup\$
    – Charlie
    Jul 25, 2017 at 11:30
3
\$\begingroup\$

Jelly, 5 bytes

³*$ÐL

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Ruby, 21 20 bytes

->n{eval'n**'*99+?1}

Disclaimer: It seems that Ruby returns some weird values when raising a complex number to a power. I assume it's out of scope for this challenge to fix Ruby's entire math module, but otherwise the results of this function should be correct. Edit: Applied the latest changes from my Python 3 answer and suddenly it somehow gives the same, expected results :)

Try it online!

\$\endgroup\$
5
  • \$\begingroup\$ Take out the space after the eval. \$\endgroup\$
    – Value Ink
    Jul 25, 2017 at 21:41
  • \$\begingroup\$ Your original version failed on the complex test case because it evaled the string "0+1i**0+1i**0+1i**...", which parses in the wrong way since ** has higher precedence than +. \$\endgroup\$ Jul 26, 2017 at 0:39
  • \$\begingroup\$ @ØrjanJohansen huh, you're right. I guess I was fooled by the fact that #inspect and #to_s return different values. Before submitting the initial answer I did some testing in irb and saw that e.g entering Complex(1,2) in the REPL would give (1+2i), including the parentheses. When stringifying the value however the parentheses are not included, so the precedence, as you point out, messed it up. \$\endgroup\$
    – daniero
    Jul 26, 2017 at 2:37
  • \$\begingroup\$ I thought eval use was forbidden. \$\endgroup\$ Jul 26, 2017 at 9:07
  • \$\begingroup\$ @V.Courtois Ok. But it's not. \$\endgroup\$
    – daniero
    Jul 26, 2017 at 10:10
2
\$\begingroup\$

TI-BASIC, 16 bytes

The input and output are stored in Ans.

Ans→X
While Ans≠X^Ans
X^Ans
End
\$\endgroup\$
1
\$\begingroup\$

R, 36 33 bytes

-3 bytes thanks to Jarko Dubbeldam

Reduce(`^`,rep(scan(,1i),999),,T)

Reads from stdin. Reduces from the right to get the exponents applied in the correct order.

Try it (function)

Try it (stdin)

\$\endgroup\$
2
  • 1
    \$\begingroup\$ scan(,1i) works. Similar to how scan(,'') works. \$\endgroup\$
    – JAD
    Jul 25, 2017 at 19:20
  • \$\begingroup\$ @JarkoDubbeldam of course! sometimes my brain doesn't work. \$\endgroup\$
    – Giuseppe
    Jul 25, 2017 at 19:24
1
\$\begingroup\$

Javascript, 33 bytes

f=(x,y=x)=>(x**y===y)?y:f(x,x**y)
\$\endgroup\$
1
  • \$\begingroup\$ JavaScript doesn't handle imaginary numbers. \$\endgroup\$
    – kamoroso94
    Jul 25, 2017 at 22:24
1
\$\begingroup\$

MATL, 20 10 bytes

cut down to half thanks to @LuisMendo

t^`Gw^t5M-

Try it online!

This is my first and my first time using MATL so i'm sure it could be easily outgolfed.

\$\endgroup\$
4
  • \$\begingroup\$ Welcome to the site, and nice first answer! A few suggestions: XII is equivalent to t. You can also get rid of XH and H using the automatic clipboard M, that is, ttt^`yw^t5M-]bb-x. And in the last part, instead of deleting the unwanted values you can use &, which tells the implicit display function to only show the top. So, you can use ttt^`yw^t5M-]& and save a few bytes. \$\endgroup\$
    – Luis Mendo
    Jul 27, 2017 at 15:01
  • \$\begingroup\$ Also, the first t is not needed, and using G instead of another t you can avoid & and thus leave ] implicit: t^`Gw^t5M-. Hey, we've reduced byte count by a half! \$\endgroup\$
    – Luis Mendo
    Jul 27, 2017 at 15:09
  • \$\begingroup\$ @LuisMendo Thanks for the great tips! I have a lot to learn about MATL, but I really like it. \$\endgroup\$
    – Cinaski
    Jul 28, 2017 at 9:11
  • \$\begingroup\$ Glad to hear that! \$\endgroup\$
    – Luis Mendo
    Jul 28, 2017 at 9:11
1
\$\begingroup\$

Vyxal r, 4 bytes

‡?eẊ

Try it Online!

\$\endgroup\$
1
\$\begingroup\$

PowerShell Core, 165 140 bytes

param($a)$u=1;for($r=$a;$u-join'+'|iex){$r=[Numerics.Complex]::Pow($a,($p=$r))
$u=($p.Real,($p|% I*),-$r.Real,-($r|% I*))|% *g '.0000000'}$r

Try it online!

-7 bytes thanks to mazzy!

55 bytes without complex numbers

\$\endgroup\$
2
  • 1
    \$\begingroup\$ [Numerics.Complex] instead [System.Numerics.Complex]? \$\endgroup\$
    – mazzy
    Aug 29, 2021 at 14:52
  • 1
    \$\begingroup\$ Thanks @mazzy ! I followed your advice :) \$\endgroup\$
    – Julian
    Aug 29, 2021 at 21:19
0
\$\begingroup\$

Perl 6, 17 bytes

{[R**] $_ xx 999}

Try it online!

R** is the reverse-exponentiation operator; x R** y is equal to y ** x. [R**] reduces a list of 999 copies of the input argument with reverse exponentiation.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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