15
\$\begingroup\$

For a given list of number \$[x_1, x_2, x_3, ..., x_n]\$ find the last digit of \$x_1 ^{x_2 ^ {x_3 ^ {\dots ^ {x_n}}}}\$ Example:

[3, 4, 2] == 1
[4, 3, 2] == 4
[4, 3, 1] == 4
[5, 3, 2] == 5   

Because \$3 ^ {(4 ^ 2)} = 3 ^ {16} = 43046721\$.

Because \$4 ^ {(3 ^ 2)} = 4 ^ {9} = 262144\$.

Because \$4 ^ {(3 ^ 1)} = 4 ^ {3} = 64\$.

Because \$5 ^ {(3 ^ 2)} = 5 ^ {9} = 1953125\$.

Rules:

This is code golf, so the answer with the fewest bytes wins.

If your language has limits on integer size (ex. \$2^{32}-1\$) n will be small enough that the sum will fit in the integer.

Input can be any reasonable form (stdin, file, command line parameter, integer, string, etc).

Output can be any reasonable form (stdout, file, graphical user element that displays the number, etc).

Saw on code wars.

\$\endgroup\$
13
  • 2
    \$\begingroup\$ One question I have: In your post you only talk about numbers. Do you mean positive integers exclusively? That is I feel how it was interpreted. \$\endgroup\$ Jul 9, 2018 at 17:30
  • 1
    \$\begingroup\$ Is taking the input in reverse reasonable? Can the input be zero? \$\endgroup\$
    – Maya
    Jul 10, 2018 at 20:46
  • 2
    \$\begingroup\$ @NieDzejkob: 2**3 % 10 == 2**7 % 10 == 2**11 % 10. Other last digits have different patterns. This knowledge is necessary to complete the puzzle and cope with arrays of numbers that would otherwise be too large to process. As far as I can tell, none of the answers here actually cope with the original problem as posed on Code Wars. \$\endgroup\$ Jul 11, 2018 at 12:56
  • 2
    \$\begingroup\$ Dear OP, we need more test cases. \$\endgroup\$
    – Maya
    Jul 11, 2018 at 12:58
  • 2
    \$\begingroup\$ In fact the solution for [999999,213412499,34532599,4125159,53539,54256439,353259,4314319,5325329,1242149,142219,1243219,14149,1242149,124419,999999999] is straightforward, base ends with 9, so last digit is 9 when first exponent is odd, 1 when exponent is even. I would really like a codegolf that limits inputs to the available integer range, and not the full exponential. \$\endgroup\$
    – rewritten
    Jul 11, 2018 at 14:39

44 Answers 44

15
\$\begingroup\$

JavaScript (ES7), 22 bytes

Limited to \$2^{53}-1\$.

a=>eval(a.join`**`)%10

Try it online!

\$\endgroup\$
8
  • 2
    \$\begingroup\$ What on earth, why does this work?! \$\endgroup\$
    – Caleb Jay
    Jul 9, 2018 at 18:06
  • \$\begingroup\$ @komali_2: ** is JavaScript's exponentiation operator. The rest is pretty straightforward. \$\endgroup\$
    – Shaggy
    Jul 9, 2018 at 18:31
  • 3
    \$\begingroup\$ @komali_2 a.join`**` is equivalent to a.join(['**']) and ['**'] is coerced to '**' by the join method. \$\endgroup\$
    – Arnauld
    Jul 9, 2018 at 18:59
  • 1
    \$\begingroup\$ I think that OP intends that the limit is on the sum of values, in which case this does not solve the problems as posed. \$\endgroup\$ Jul 11, 2018 at 9:35
  • 1
    \$\begingroup\$ @AJFaraday the %10 at the end. When dividing any number by 10, the remainder (the modulus) will always be the last digit, so n % 10 will return the last digit of n \$\endgroup\$
    – Mayube
    Jul 11, 2018 at 15:54
13
\$\begingroup\$

R, 25 bytes

Reduce(`^`,scan(),,T)%%10

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ Not sure what people liked so much about this answer. \$\endgroup\$
    – ngm
    Jul 10, 2018 at 20:32
  • 1
    \$\begingroup\$ I personally like to see Reduce being used. \$\endgroup\$
    – JayCe
    Jul 11, 2018 at 16:04
10
\$\begingroup\$

Haskell, 19 bytes

(`mod`10).foldr1(^)

Try it online!

\$\endgroup\$
0
9
\$\begingroup\$

HP 49G RPL, 36.5 bytes

Run it in APPROX mode (but enter the program in EXACT mode). Takes input on the stack with the first element deepest in the stack, as integers or reals.

WHILE DEPTH 1 - REPEAT ^ END 10 MOD

It straightforwardly exponentiates on the stack as in Sophia's solution until there is one value left, then takes it mod 10 to get the last digit.

The reason I use APPROX for computation is because 0.0^0.0 = 1 (when they are both reals), but 0^0 = ? (when they are both integers). APPROX coerces all integers to reals, so the input is fine with either. However, I use EXACT to enter the program because 10 (integer) is stored digit-by-digit, and is 6.5 bytes, but 10.0 (real) is stored as a full real number, and is 10.5 bytes. I also avoid using RPL's reduce (called STREAM) because it introduces an extra program object, which is 10 bytes of overhead. I already have one and don't want another.

Limited to the precision of an HP 49G real (12 decimal digits)

-10 bytes after empty list -> 1 requirement was removed.

-2 bytes by taking input on stack.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Hey, could you explain how the bytecount is calculated? Just curious how that language uses nibbles. \$\endgroup\$ Jul 9, 2018 at 16:52
  • 1
    \$\begingroup\$ @JungHwanMin The HP 49G uses a 4-bit processor and BCD arithmetic, since it's a calculator. Internally most commands are transformed into 2.5 byte pointers to the routines they represent, to save space. Small numbers (0-9) are also transformed in this way. \$\endgroup\$
    – Jason
    Jul 9, 2018 at 17:07
  • 1
    \$\begingroup\$ The Saturn processor is actually pretty fun to work with. A long time ago, I wrote this port of BurgerTime (in assembly) for the HP 48G(X). It was later ported to the 49G. Good memories! \$\endgroup\$
    – Arnauld
    Jul 9, 2018 at 19:15
7
\$\begingroup\$

dc, 17 15 bytes

1[^z1<M]dsMxzA%

Try it online!

Takes input from the stack, outputs to the stack. Very straightforward implementation - exponentiates until only one value is left on the stack and mod for the last digit.

Thanks to brhfl for saving two bytes!

\$\endgroup\$
3
  • 3
    \$\begingroup\$ You can golf one byte by changing 10% to A%, and one more byte by not checking stack depth twice - just put a 1 atop the stack before executing since n^1==n: 1[^z1<M]dsMxA% \$\endgroup\$
    – brhfl
    Jul 9, 2018 at 17:45
  • \$\begingroup\$ Good ideas! I had no idea dc would let me use A as a literal while set to decimal input. Thank you @brhfl! \$\endgroup\$ Jul 9, 2018 at 18:12
  • 2
    \$\begingroup\$ @SophiaLechner This trick works for all input bases: codegolf.stackexchange.com/a/77728/11259 \$\endgroup\$ Jul 9, 2018 at 20:23
6
\$\begingroup\$

J, 5 bytes

-3 bytes thanks to cole!

10|^/

Try it online!

\$\endgroup\$
3
  • \$\begingroup\$ Does 10|^/ not work? \$\endgroup\$
    – cole
    Jul 9, 2018 at 23:41
  • \$\begingroup\$ @cole Of course it works, thanks! \$\endgroup\$ Jul 10, 2018 at 3:15
  • 1
    \$\begingroup\$ Finally, a challenge where J beats Jelly! \$\endgroup\$
    – Jonah
    Jul 10, 2018 at 15:11
6
\$\begingroup\$

05AB1E, 4 bytes

.«mθ

Try it online!

Explanation

.«     # fold
  m    # power
   θ   # take the last digit
\$\endgroup\$
6
  • 1
    \$\begingroup\$ As far as I am aware, stack-based languages can assume the input is present on the stack instead of STDIN or alternatives, so something like this should work for 4 bytes (alternatively, just place E in the header). \$\endgroup\$
    – Mr. Xcoder
    Jul 9, 2018 at 20:26
  • \$\begingroup\$ Relevant Meta. \$\endgroup\$
    – Mr. Xcoder
    Jul 9, 2018 at 20:28
  • 1
    \$\begingroup\$ I have fixed this issue in the latest commit for future use. \$\endgroup\$
    – Adnan
    Jul 9, 2018 at 20:44
  • \$\begingroup\$ @Mr.Xcoder: Right! I should have remembered that. So rarely need to though with implicit input. Thanks :) \$\endgroup\$
    – Emigna
    Jul 10, 2018 at 6:04
  • \$\begingroup\$ @Mr.Xcoder Uh, I'm not sure if that's what the meta really means. What is a "function" in 05AB1E? I think it should simply be a string, since you can assign it to a variable, and can be eval-ed with .V. .«mθ looks more like a snippet, since, by itself, you can't assign it to a variable for later reuse. Well, Adnan now fixed the issue, but eh. \$\endgroup\$ Jul 10, 2018 at 10:32
5
\$\begingroup\$

Pure Bash (builtins only - no external utilities), 21

echo $[${1//,/**}%10]

Input is given on the command line as a comma-separated list.

Bash integers are subject to normal signed integer limits for 64- and 32-bit versions.

Try it online!

\$\endgroup\$
2
  • 2
    \$\begingroup\$ ^ is bitwise XOR, which is why you're getting 5 out of the test case instead of the correct 1. You'll need to add a byte to switch to ** \$\endgroup\$ Jul 9, 2018 at 21:58
  • \$\begingroup\$ @SophiaLechner Yes - of course - good catch! Not sure how that ^ crept in - I had ** in previous iterations of my dev cycle. \$\endgroup\$ Jul 9, 2018 at 22:06
5
\$\begingroup\$

Wolfram Language (Mathematica), 16 bytes

Power@##~Mod~10&

Try it online!

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

Perl 6, 14 bytes

{([**] $_)%10}

Try it online!

Uses the reduction meta square brackets with the operator **, modulo 10.

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

Python 2 and Python 3, 30 bytes

lambda N:eval('**'.join(N))%10

Try it online!

The input N is expected to be an iterable object over string representations of number literals.

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

Julia 0.6, 30 bytes

first∘digits∘x->foldl(^,x)

Try it online!

This is an anon function
∘ is the composition operator.
It is multiple bytes

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

Ruby, 41 47 bytes

Size increase due to handling of any 0 in the input array, which needs extra consideration. Thanks to rewritten

->a{a.reverse.inject{|t,n|n<2?n:n**(t%4+4)}%10}

This is solved as I believe the original source intended, i.e. for very large exponentiations that will not fit into language native integers - the restriction is that the array will sum into 2**32-1, not that the interim calculations are also guaranteed to fit. In fact that would seem to be the point of the challenge on Code Wars. Although Ruby's native integers can get pretty big, they cannot cope with the example below processed naively with a %10 at the end

E.g.

Input: [999999,213412499,34532597,4125159,53539,54256439,353259,4314319,5325329,1242149,142219,1243219,14149,1242149,124419,999999999]

Output: 9

\$\endgroup\$
4
  • \$\begingroup\$ Impressive. By spending a 4 more bytes, you can also cope with much higher towers: replace n**(t%4+4) with n**((t-1)%4+1) so you get n**1 instead of n**5 etc. Kudos for the observation that at any stage 4 would be a good cycle. \$\endgroup\$
    – rewritten
    Jul 11, 2018 at 17:36
  • 1
    \$\begingroup\$ There is an issue if the sequence has 0s \$\endgroup\$
    – rewritten
    Jul 11, 2018 at 17:48
  • \$\begingroup\$ @rewritten: Good spot! I'll have to think about that. In theory the sequence should be forced to terminate 2 steps before the first zero. \$\endgroup\$ Jul 11, 2018 at 18:16
  • \$\begingroup\$ Indeed, but that will require a lot more code, exactly 6 more bytes: n<2?n: before n**. \$\endgroup\$
    – rewritten
    Jul 12, 2018 at 8:01
3
\$\begingroup\$

05AB1E, 8 bytes

`.gGm}T%

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ I think you mean ...gGm}10% (or something golfier). \$\endgroup\$ Jul 9, 2018 at 18:00
3
\$\begingroup\$

APL (Dyalog Unicode), 5 bytes

10|*⌿

Try it online!

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

C# (.NET Core), 84 bytes

a=>{int i=a.Length-1,j=a[i];for(;i-->0;)j=(int)System.Math.Pow(a[i],j);return j%10;}

Try it online!

  • -7 bytes thanks to @raznagul
\$\endgroup\$
5
  • \$\begingroup\$ You can save some bytes by removing the brackers around a and by combining the loop condition with the decrement (for(var i=a.Lengt-1;i-->0;)). But using-statement must be included in he byte count. \$\endgroup\$
    – raznagul
    Jul 10, 2018 at 11:56
  • \$\begingroup\$ @raznagul: sorry, I'm pretty new to code-golf in C#, is it ok now ? \$\endgroup\$
    – digEmAll
    Jul 10, 2018 at 12:06
  • \$\begingroup\$ No problem. Yes this is fine now. \$\endgroup\$
    – raznagul
    Jul 10, 2018 at 12:08
  • 1
    \$\begingroup\$ You can save 3 more bytes by using a new variable to hold the result and remove most of the index access to the array: Try it online! \$\endgroup\$
    – raznagul
    Jul 10, 2018 at 12:11
  • \$\begingroup\$ @raznagul: great ! \$\endgroup\$
    – digEmAll
    Jul 10, 2018 at 13:53
3
\$\begingroup\$

C (gcc), 56

  • Saved 4 bytes thanks to @JonathanFrech

Recursive function r() called from macro f - normal stack limits apply.

R;r(int*n){R=pow(*n,n[1]?r(n+1):1);}
#define f(n)r(n)%10

Input given as a zero-terminated int array. This is under the assumption that none of the xn are zero.

Try it online!

\$\endgroup\$
2
  • 2
    \$\begingroup\$ ) r( -> )r(. \$\endgroup\$ Jul 9, 2018 at 21:49
  • 1
    \$\begingroup\$ Also, if you want to use UB, you could golf r(int*n){return pow to R;r(int*n){R=pow. \$\endgroup\$ Jul 10, 2018 at 11:30
3
\$\begingroup\$

PHP, 50 44 bytes

-6 bytes from @Shaggy

<?=eval("return ".join('**',$argv).";")%10?>

Try it online!

\$\endgroup\$
4
  • \$\begingroup\$ btw, you can use join() to shave off 3 bytes because it's an alias of implode(), but I don't agree with how you're passing in input, you're just setting an array before your script is called. I think you should parse $argv or $argn. \$\endgroup\$
    – Ethan
    Jul 10, 2018 at 4:00
  • \$\begingroup\$ You're supposed to return the last digit, not the whole thing. \$\endgroup\$
    – Maya
    Jul 11, 2018 at 8:02
  • \$\begingroup\$ 44 bytes \$\endgroup\$
    – Shaggy
    Jul 11, 2018 at 12:02
  • \$\begingroup\$ Well, if this kind of input is valid, then it can be even shorter: 40 bytes \$\endgroup\$
    – Night2
    Jul 15, 2018 at 12:41
3
\$\begingroup\$

Japt -h, 7 bytes

OvUqp)ì

Try it online!

Explanation:

OvUqp)ì
Ov   )    // Japt eval:
   q      //   Join
  U       //   Input with
    p     //   Power method
      ì   // Split into an array of numbers
-h        // Return the last number
\$\endgroup\$
4
  • \$\begingroup\$ Weird, that wouldn't work for me. \$\endgroup\$
    – Shaggy
    Jul 10, 2018 at 19:28
  • \$\begingroup\$ 6 bytes \$\endgroup\$
    – Shaggy
    Mar 24, 2019 at 23:55
  • \$\begingroup\$ @Shaggy :P \$\endgroup\$
    – Oliver
    Mar 25, 2019 at 14:12
  • \$\begingroup\$ Ah, for Jaysis' sake! :\ That's happening more & more often! \$\endgroup\$
    – Shaggy
    Mar 25, 2019 at 15:40
3
\$\begingroup\$

Japt -h, 7 6 bytes

If input can be taken in reverse order then the first character can be removed.

Limited to 2**53-1.

Ôr!p ì

Try it


Explanation

Ô          :Reverse the array
 r         :Reduce by
  !p       :  Raising the current element to the power of the current total, initially the first element
     ì     :Split to an array of digits
           :Implicitly output the last element
\$\endgroup\$
6
  • \$\begingroup\$ I got the exact same answer without the flag so this looks like the optimal way for now. \$\endgroup\$
    – Etheryte
    Jul 9, 2018 at 18:41
  • \$\begingroup\$ @Nit: until it's confirmed we can take input in reverse :) \$\endgroup\$
    – Shaggy
    Jul 9, 2018 at 18:46
  • \$\begingroup\$ @Oliver Yeah, but you're still using a flag. Personally I think the byte count without flags is the most accurate scoring result. \$\endgroup\$
    – Etheryte
    Jul 10, 2018 at 20:35
  • \$\begingroup\$ @Nit Shouldn't a flag add 3 bytes by meta consensus? \$\endgroup\$ Jul 11, 2018 at 15:51
  • \$\begingroup\$ @LegionMammal978, not any more. \$\endgroup\$
    – Shaggy
    Jul 11, 2018 at 16:01
2
\$\begingroup\$

Jelly, 6 bytes

U*@/DṪ

Try it online!

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

Python 2, 45 43 bytes

lambda x:reduce(lambda b,a:a**b,x[::-1])%10

Try it online!

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

Excel VBA, 60 bytes

An anonymous VBE immediate window function that takes input from range [A1:XFD1]

s=1:For i=-[Count(1:1)]To-1:s=Cells(1,-i)^s:Next:?Right(s,1)
\$\endgroup\$
2
\$\begingroup\$

Stax, 7 bytes

üT(Çó╖⌐

Run and debug it

Algorithm like in my Python answer

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

CJam, 14 bytes

q~_,({~#]}*~A%

Should work for any input, since CJam isn't limited to 64 bit integers

Try it online!

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

Python 3, 55 bytes

p=lambda l,i=-1:not l or f'{l[0]**int(p(l[1:],0))}'[i:] 

Older versions

p=lambda l,i=-1:len(l)and f'{l[0]**int(p(l[1:],0))}'[i:]or 1    (60 bytes)

\$\endgroup\$
1
  • \$\begingroup\$ Wouldn't that have to be p=lambda...? Python can't handle recursive anonymous lambdas, so if you need your function to be named, it needs to be part of your solution, and the naming counts towards your byte count for code-golf challenges. \$\endgroup\$
    – mypetlion
    Jul 9, 2018 at 20:20
2
\$\begingroup\$

Python 3, 47 bytes

f=lambda x,y=1:f(x[:-1],x[-1]**y)if x else y%10

Try it online!

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

Brain-Flak, 161 bytes

Includes +1 for -r

([][()]){({}[()]<({}<(({}))>[()]){({}<(({})<({}<>)({<({}[()])><>({})<>}{}<><{}>)>)>[()])}{}{}>)}{}({}((()()()()()){})(<>))<>{(({})){({}[()])<>}{}}{}<>([{}()]{})

Try it online!

The example [3, 4, 2] takes longer than 60 seconds, so the TIO link uses [4, 3, 2].

The -r can be removed if input can be taken in reverse order for a byte count of 160.

# Push stack size -1
([][()])

# While there are 2 numbers on the stack
{({}[()]<

    # Duplicate the second number on the stack (we're multiplying this number by itself)
    ({}<(({}))>[()])

    # For 0 .. TOS
    {({}<

        # Copy TOS
        (({})<

        # Multiple Top 2 numbers
        ({}<>)({<({}[()])><>({})<>}{}<><{}>)

        # Paste the old TOS
        >)

    # End for (and clean up a little)
    >[()])}{}{}

# End While (and clean up)
>)}{}

# Mod 10
({}((()()()()()){})(<>))<>{(({})){({}[()])<>}{}}{}<>([{}()]{})
\$\endgroup\$
2
\$\begingroup\$

Pari/GP, 32 bytes

a->fold((x,y)->y^x,Vecrev(a))%10

Try it online!

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

Z80Golf, 36 bytes

00000000: cd03 80f5 30fa f1f1 57f1 280d 4f41 15af  ....0...W.(.OA..
00000010: 8110 fd47 1520 f818 ef7a d60a 30fc c60a  ...G. ...z..0...
00000020: cd00 8076                                ...v

Try it online!

Brute-force test harness

Takes input as raw bytes. Limited to 2**8-1.

Explanation

input:
    call $8003    ;      the input bytes
    push af       ; push                 on the stack
    jr nc, input  ;                                   until EOF
    pop af        ; the last byte is going to be pushed twice
    pop af
outer:
    ld d, a       ; d = exponentiation loop counter, aka the exponent
    pop af        ; pop the new base off the stack
    jr z, output  ; The flags are being pushed and popped together with the
                  ; accumulator. Since the Z flag starts as unset and no
                  ; instruction in the input loop modifies it, the Z flag is
                  ; going to be unset as long as there is input, so the jump
                  ; won't be taken. After input is depleted, a controlled stack
                  ; underflow will occur. Since SP starts at 0, the flags
                  ; register will be set to the $cd byte from the very beginning
                  ; of the program. The bit corresponding to the Z flag happens
                  ; to be set in that byte, so the main loop will stop executing
    ld c, a       ; C = current base
    ld b, c       ; B = partial product of the exponentiation loop
    dec d         ; if the exponent is 2, the loop should only execute once, so
                  ; decrement it to adjust that
pow:
    xor a         ; the multiplication loop sets A to B*C and zeroes B in the
mul:              ; process, since it's used as the loop counter
    add c         ; it's definitely not the fastest multiplication algorithm,
    djnz mul      ; but it is the smallest
    ld b, a       ; save the multiplication result as the partial product
    dec d         ; jump back to make the next iteration of either
    jr nz, pow    ; the exponentiation loop or the main loop, adjusting the
    jr outer      ; loop counter in the process
output:           ; after all input is processed, we jump here. We've prepared
    ld a, d       ; to use the result as the next exponent, so copy it back to A
mod:              ; simple modulo algorithm:
    sub 10        ;            subtract ten
    jr nc, mod    ; repeatedly              until you underflow,
    add 10        ; then undo the last subtraction by adding ten
    call $8000    ; output the result
    halt          ; and exit
\$\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.