12
\$\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\$
  • 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\$ – Jonathan Frech Jul 9 '18 at 17:30
  • 1
    \$\begingroup\$ Is taking the input in reverse reasonable? Can the input be zero? \$\endgroup\$ – NieDzejkob Jul 10 '18 at 20:46
  • 1
    \$\begingroup\$ I think you intend for the limit to be on sum of terms, and thus routines that calculate the actual sum then mod it should fail. E.g. the input [999999,213412499,34532599,4125159,53539,54256439,353259,4314319,5325329,1242149,142219,1243219,14149,1242149,124419,999999999] is valid and the result should be 1 If so, this needs to be made clearer in the question as you have upvoted answers that do not solve this (hint - move the mod inside the loop). Perhaps add some examples that make this clear. \$\endgroup\$ – Neil Slater Jul 11 '18 at 9:37
  • 1
    \$\begingroup\$ Actually the result from my example is 9. The digit reduction scheme necessary to implement this is a lot more interesting than the actual answers this problem has garnered. \$\endgroup\$ – Neil Slater Jul 11 '18 at 10:01
  • 2
    \$\begingroup\$ Dear OP, we need more test cases. \$\endgroup\$ – NieDzejkob Jul 11 '18 at 12:58

39 Answers 39

15
\$\begingroup\$

JavaScript (ES7), 22 bytes

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

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

Try it online!

\$\endgroup\$
  • 2
    \$\begingroup\$ What on earth, why does this work?! \$\endgroup\$ – Caleb Jay Jul 9 '18 at 18:06
  • \$\begingroup\$ @komali_2: ** is JavaScript's exponentiation operator. The rest is pretty straightforward. \$\endgroup\$ – Shaggy Jul 9 '18 at 18:31
  • 2
    \$\begingroup\$ @komali_2 a.join`**` is equivalent to a.join(['**']) and ['**'] is coerced to '**' by the join method. \$\endgroup\$ – Arnauld Jul 9 '18 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\$ – Neil Slater Jul 11 '18 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\$ – Skidsdev Jul 11 '18 at 15:54
13
\$\begingroup\$

R, 25 bytes

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

Try it online!

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

Haskell, 19 bytes

(`mod`10).foldr1(^)

Try it online!

\$\endgroup\$
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\$
  • 1
    \$\begingroup\$ Hey, could you explain how the bytecount is calculated? Just curious how that language uses nibbles. \$\endgroup\$ – JungHwan Min Jul 9 '18 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 '18 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 '18 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\$
  • 2
    \$\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 '18 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\$ – Sophia Lechner Jul 9 '18 at 18:12
  • 1
    \$\begingroup\$ @SophiaLechner This trick works for all input bases: codegolf.stackexchange.com/a/77728/11259 \$\endgroup\$ – Digital Trauma Jul 9 '18 at 20:23
6
\$\begingroup\$

J, 5 bytes

-3 bytes thanks to cole!

10|^/

Try it online!

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

05AB1E, 4 bytes

.«mθ

Try it online!

Explanation

.«     # fold
  m    # power
   θ   # take the last digit
\$\endgroup\$
  • 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 '18 at 20:26
  • \$\begingroup\$ Relevant Meta. \$\endgroup\$ – Mr. Xcoder Jul 9 '18 at 20:28
  • 1
    \$\begingroup\$ I have fixed this issue in the latest commit for future use. \$\endgroup\$ – Adnan Jul 9 '18 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 '18 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\$ – Erik the Outgolfer Jul 10 '18 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
    \$\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\$ – Sophia Lechner Jul 9 '18 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\$ – Digital Trauma Jul 9 '18 at 22:06
5
\$\begingroup\$

Wolfram Language (Mathematica), 16 bytes

Power@##~Mod~10&

Try it online!

\$\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\$

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\$
  • \$\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 '18 at 17:36
  • 1
    \$\begingroup\$ There is an issue if the sequence has 0s \$\endgroup\$ – rewritten Jul 11 '18 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\$ – Neil Slater Jul 11 '18 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 '18 at 8:01
3
\$\begingroup\$

05AB1E, 8 bytes

`.gGm}T%

Try it online!

\$\endgroup\$
  • \$\begingroup\$ I think you mean ...gGm}10% (or something golfier). \$\endgroup\$ – Jonathan Allan Jul 9 '18 at 18:00
3
\$\begingroup\$

Perl 6, 14 bytes

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

Try it online!

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

\$\endgroup\$
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\$
  • \$\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 '18 at 11:56
  • \$\begingroup\$ @raznagul: sorry, I'm pretty new to code-golf in C#, is it ok now ? \$\endgroup\$ – digEmAll Jul 10 '18 at 12:06
  • \$\begingroup\$ No problem. Yes this is fine now. \$\endgroup\$ – raznagul Jul 10 '18 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 '18 at 12:11
  • \$\begingroup\$ @raznagul: great ! \$\endgroup\$ – digEmAll Jul 10 '18 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
    \$\begingroup\$ ) r( -> )r(. \$\endgroup\$ – Jonathan Frech Jul 9 '18 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\$ – Jonathan Frech Jul 10 '18 at 11:30
3
\$\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\$
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\$
  • \$\begingroup\$ Weird, that wouldn't work for me. \$\endgroup\$ – Shaggy Jul 10 '18 at 19:28
  • \$\begingroup\$ 6 bytes \$\endgroup\$ – Shaggy Mar 24 at 23:55
  • \$\begingroup\$ @Shaggy :P \$\endgroup\$ – Oliver Mar 25 at 14:12
  • \$\begingroup\$ Ah, for Jaysis' sake! :\ That's happening more & more often! \$\endgroup\$ – Shaggy Mar 25 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\$
  • \$\begingroup\$ I got the exact same answer without the flag so this looks like the optimal way for now. \$\endgroup\$ – Nit Jul 9 '18 at 18:41
  • \$\begingroup\$ @Nit: until it's confirmed we can take input in reverse :) \$\endgroup\$ – Shaggy Jul 9 '18 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\$ – Nit Jul 10 '18 at 20:35
  • \$\begingroup\$ @Nit Shouldn't a flag add 3 bytes by meta consensus? \$\endgroup\$ – LegionMammal978 Jul 11 '18 at 15:51
  • \$\begingroup\$ @LegionMammal978, not any more. \$\endgroup\$ – Shaggy Jul 11 '18 at 16:01
2
\$\begingroup\$

Jelly, 6 bytes

U*@/DṪ

Try it online!

\$\endgroup\$
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\$
  • \$\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 '18 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\$
2
\$\begingroup\$

Ruby, 24 20 bytes

->a{eval(a*'**')%10}

Try it online!

\$\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.