text:
Randomizing until 0
Challenge
Sandbox post
Given a positive integer (K) Output a uniformly-random integer (Y) between [0, K).
If Y > 0 Assume K = Y and repeat the process until Y = 0.
Rules

Input must be printed at first
Output format as you wish
Your program must finish.
0 must be the final output, Optionally an empty line instead 0

If the submission is a function, may it return 0 in addition to printing it?

@Adám yes, you can return in addition

Do I need to seed my RNG?

May we print without delimiters?

I got curious. It's quite easy to prove that the average number of steps this program takes before it terminates is H(K-1) + 1 where H(K) is the K'th harmonic number. For n=1000, that's 8.484 steps on average.

Pyth, 6 5 4 bytes
.uOW

Try it here!
How it works

.uOW    Full program. Takes an integer from  STDIN and outputs a list to STDOUT.
.u      Cumulative fixed-point. Apply the given function with a given initial value,
        which is implicitly assigned to the input, until a result that has occurred
        before is found. Returns the list of intermediate results.
   W    Conditional application. If the argument (the current value) is truthy, then
        apply the function below, otherwise leave it unchanged.
  O     Random integer in the range [0, N).
        IOW: at each iteration of .u, assign a variable N to the current value, starting
        with the input. If N is not 0, then choose a random integer in [0, N), else
        return N unchanged. Whenever we encounter a 0, the next iteration must also
        result in a 0, and therefore the loop stops there.

I saw a way to do this in Pyth but I am a beginner. Respect. Language of the month in August maybe?

C (gcc), 42 bytes
f(_){printf("%d\n",_);(_=rand()%_)&&f(_);}

Try it online!
Uses short-circuited logical and.
f(_){                 // f(int _) {
    printf("%d\n",_); // print argument and a newline
    (_=rand()%_)      // set _ to rand()%_
    &&f(_);}          // short-circuit AND to recursively call f if _ not zero

C (gcc), 40 bytes (w/o printing initial value)
f(_){printf("%d\n",_=rand()%_);_&&f(_);}

Try it online!
Uses short-circuited logical and.
f(_){              // f(int _) {
    printf("%d\n", // print an integer and a newline
    _=             // The integer is _ which we set to...
    rand()%_);     // a random value modulo the input _
    _&&f(_);}      // short-circuit AND to recursively call f if _ not zero

rand()%_ is not uniform

(if you are not convinced, try using a 6-sided dice to generate a [1,5] value using this method.)

I'm fully aware that rand() is almost always biased (due to truncation), but the standard doesn't guarantee it (RAND_MAX could in theory be a multiple of all our numbers, just by luck :P though usually it's ~65k). In practice for the ranges we're dealing with it will appear sufficiently random to not stand out against similar submissions in this challenge.

that's from the challenge "Output a uniformly-random integer", so, strictly speaking, this is not valid

Strictly speaking all languages here use prng's. None of them will give a true uniform random number (which would require a perfect source of entropy). While many are more uniform than this, that isn't noticeable in log(k) iterations.

Strictly speaking, Linux supports random number generation. Refer to man 4 random. "The random number generator gathers environmental noise from device drivers and other sources into an entropy pool."

ya can take "\n" -> " " and save a byte

@Geo that sort of depends on your definition of randomness, you could take the view that computers can't generate random numbers anyway. (Besides, the entropy is an estimation anyway and so it's misleading regardless.)

@GeorgeV.Williams why not?

@Ruslan why?

R, 66 60 56 43 41 bytes
function(n)while(print(n))n=sample(n,1)-1

Try it online!

I don't think you need >0 and cat(n,"") (empty string) will also work.

But I think print is more efficient here, as it returns its argument: 56 bytes

Also 56 bytes: k=scan();while(x<-sample(1:k-1,1))k=c(x,k);cat(rev(k),0)

Sorry, am I missing something or this is valid ? Try it online!

I forgot to remove the curly brackets, so you can save 2 more bytes ;) Try it online!

btw, congrats on 1K! :-)

Just back from vacation... same bytecount, recursive tio

39 bytes: n=scan();while(print(n))n=sample(n,1)-1

MATL, 6 bytes
`tYrqt

Try it online!
Explanation
`        % Do...while
  t      %   Duplicate. Takes input (implicit) the first time
  Yr     %   Uniform random integer from 1 to n, included
  q      %   Subtract 1
  t      %   Duplicate. This will be used as loop condition
         % End (implicit). Proceeds with next iteration if non-zero
         % Display stack (implicit)

Pepe, 25 bytes
Pepe is a programming language made by user Soaku.
REeErEErReEEreeEREEeEEree

Try it online!
Explanation:
REeErEErReEEreeEREEeEEree # full program

REeE                      # input as num, in stack 1
    rEE                   # create loop in stack 2 with name 0
       rReEE              # - output and preserve the number in stack 1
            reeE          # - output a newline "\n"
                REEeEE    # - random number by 0 to input
                      ree # goto loop with name 0 if stack 1 is not equal
                            to stack 2

Perl 6, 18 bytes
{$_,(^*).pick...0}

Try it online!
Anonymous code block that returns a list of values. If you don't mind the numbers being ranges, you can do:
{^$_,^*.pick...0}

for 17 bytes. Funnily enough, another builtin random function, roll, has the same behaviour in this instance for the same amount of bytes.

Perl 5.10.0 -pl, 26 bytes
say;say while$_=int rand$_

Try it online!

Nice! Came up with a very similar approach for 22: Try it online!

Аnother similar: 20 + 2 bytes.

Jelly,  4  3 bytes
XƬ0

This is a monadic link (function) that prints an array and returns 0.
Try it online!
How it works
XƬ0  Monadic link. Argument: n

XƬ   Pseudo-randomly pick (X) an integer k in [1, ..., n], set n = k, and repeat.
     Do this 'til (Ƭ) the results are no longer unique and return the array of
     unique results, including the initial value of n.
     This stops once X returns k with argument k. The second k will be omitted
     from the return value.
  0  Print the resulting array and set the return value to 0.

Very nice strikethrough of the 4!

We wouldn't like crossed out 4 to look like regular 4, would we?

05AB1E, 8 7 bytes
Δ=L<Ω0M

Try it online!
Explanation
Δ         # loop until value doesn't change
 =        # print current value
  L<Ω     # push a random number in ([1 ... X] - 1)
          # will return -1 when X=0
     0M   # push max of that and 0

Δ=Ý¨Ω0M is equivalent.

JavaScript (ES6), 38 37 bytes
-1 byte thanks to @Arnauld
f=n=>[n,...n?f(Math.random()*n|0):[]]

f=n=>[n,...n?f(Math.random()*n|0):[]]
<input type=number id=a><button onclick="console.log(f(+a.value))">Test</button>

Can you reduce the math.random at all? e.g. with https://codegolf.stackexchange.com/a/35648/67066

@Marie using new Date%n doesn't really work here, since it doesn't change fast enough to be useful for generating multiple random numbers

Brachylog, 8 bytes
ẉ?ℕ₁-₁ṙ↰

Try it online!
Explanation
ẉ          Write the input followed by a linebreak
 ?ℕ₁       The input must be in [1, …, +∞)
    -₁ṙ    Generate an integer in [0, …, input - 1] uniformly at random
       ↰   Recursive call with that random integer as the new input

The recursion will stop once ?ℕ₁ fails, that is, when the input is 0.

J, 13 bytes
[:}:? ::]^:a:

On the subway, so apologies for lack of TIO (hopefully there isn’t a lack of correctness).
Outputs a list of values.
Presumably the APL approach will be shorter, but this is what I thought of.
How it works
^:a: apply repeatedly until convergence, storing intermediate results in an array.
? random integer in range [0, K) for K greater than 0. For 0, it gives a random integer in range (0,1). For a floating point number, it errors.
::] catch an error for an input to ? and instead of erroring, output the input that caused the error.
}: get rid of the last value in the array (this is so that a floating point number isn’t output).
Try it online!

It is just me or the code returns the same output?

@LuisfelipeDejesusMunoz someone who knows J better than I might be able to explain but I think that RNG always starts with the same seed. There is also the fixed seed ?., but I don’t think I’m using that.

@cole you are correct.

C, 38 bytes
f(k){printf("%d ",k);k?f(rand()%k):0;}

Try it online
Ungolfed
void f(int k){
    printf("%d ",k);
    if(k)
        f(rand()%k);
}

You can save a byte by replacing the ternary operator with a &&; also, you may want to consider seeding the RNG in your main function: Try it online!

You can also get rid of the ternary altogether and terminate in an error. 34 bytes

Pyth, 4 bytes
W
~O

Try it online!
This basically implements the algorithm:
\$ \begin{align} % Unknown environment algorithm :(
&Q \gets \text{input} \\
&\mathbf{Repeat} \\
&\begin{array}{cl}
1. & temp \gets Q \\
2. & Q \gets \text{unif}\{ 0, Q - 1 \} \\
3. & \mathtt{Print}(temp)
\end{array} \\
&\mathbf{Until} \quad temp = 0
\end{align} \$
To translate the Pyth into the algorithm, we can mostly just examine what each character means. Since Pyth is written in prefix notation (i.e. * + 1 2 3 is (1 + 2) * 3) we can start from the left and fill in the arguments as we go.
W begins a traditional while loop. The first statement after it is the loop condition and the second statement after it is the loop body. If the second statement is empty it becomes a no-op. This while works exactly like the Python while, so it will evaluate non-zero integers as True and zero as false.
The first statement after the while begins with the newline character. This corresponds to Pyth's "print and return with a newline" function. This takes one argument, which is then printed and also returned unmodified. This allows us to print the intermediate steps while also performing the needed operations.
The argument passed to this print function begins with ~ which is a bit special. If the character immediately after ~ is a variable it takes two arguments, otherwise it takes one. Since O is not a variable ~ will consume only one argument. ~ functions a bit like += does in many conventional languages, though the closest operator would be the post-increment operator ++ from C. You may know that x++ will be like using x as the current value, but thereafter x will be x+1. ~ is the same idea, but generalised to whatever the result of the first argument is. How it picks what variable to assign to will be addressed later.
The argument of ~ is O which is very simple. When its one argument is an integer O returns a value from 0 to one less than that integer uniformly at random.
Now you may have noticed O does not have an argument. Here the Pyth interpreter kindly fills in a guess, which here is the variable Q. Q has a special meaning in Pyth: whenever it is present in a program the Pyth program begins with assigning Q to the input of the program. Since this is the first variable occurring in ~'s argument Q is also now the variable that ~ will assign a value to.
Summed up our "readable" program might look like:
while print_and_return( assign_variable( Q, unif(0, Q-1) ) ):
    pass

And one sample "run-through" might look like:

Q = 5
O returns 3, ~ returns 5, \n returns and prints 5 which is true
Q = 3
O returns 0, ~ returns 3, \n returns and prints 3 which is true
Q=0
O returns something irrelevant, ~ returns 0, \n returns and prints 0 which is false
Q = something irrelevant
Terminate

Factor, 21 bytes
[ [ random ] follow ]

Try it online!
Basically, collects the values after each iteration (including zeroth iteration) stopping when the value is f, where each iteration converts the value n to a random integer between 0 and n-1 inclusive. Calling random on zero yields f, conveniently terminating the loop.
Interestingly, the doc page for follow has an example code that solves almost the same task, but it is actually longer since it tries to exclude zero at the end.

Python 2, 64 62 60 bytes
from random import*
k=input()
while k:print k;k=randrange(k)

Try it online!

Saved

-2 bytes, thanks to Jonathan Allan

"Input must be printed at first"... while 1:print k;k=randint(0,~-k) should work (with an error at the end)

...and then while 1:print k;k=randrange(k) saves two.

@JonathanAllan Thanks :), The questions says I can use an empty line instead of 0, so no error.

APL (Dyalog Unicode), 12 9 bytes
Anonymous tacit prefix function. Assumes ⎕IO (Index Origin) to be 0, which is default on many systems. Returns the final value (0) in addition to printing while run.
{⌊?⎕←⍵}⍣=

Try it online!
{…}⍣= apply the following function until stable:
 ⎕←⍵ output the argument
 ? return a uniformly distributed random number in the range 0 through that–1
 ⌊ round down (because ?0 gives a (0,1) float)

C++ (gcc), 98 bytes
#import<cstdio>
#import<cstdlib>
#define d printf("%i ",x
int p(int x){d);while(x>0)d=rand()%x);}

Try it here!
Usage
int main() {
    p(100);
}

This is my first code golf attempt. Any feedback or remarks are welcome.
Edit:
Removed the main function as suggested to make it valid.

Hi, and welcome to PPCG :) You do not need to include the sample call in your byte count (i.e. you don't need to write the main function) since we accept functions as valid submissions. Otherwise, your submission is technically not valid since if the input was some two or more digit number the output could be ambiguous. If you just add a space at the end of the format string in your macro you should be fine. Happy golfing!

Adding the compiler flag -Dd='printf("%i,",x' instead of the #define would save you some bytes (-4), and is allowed as long as you count the bytes towards your result (because it is a non-standard preprocessor directive. You can also leave out the imports (at least with -std=c++98 and -w, which don't count for bytes), and the variable types. So, you'd have p(x){d);while(x>0)d=rand()%x;} and -Dd='printf("%i,",x'.

Also, you should probably check out the Standard Loopholes and Tips for golfing in C, if you haven't already :)

C (gcc), 40 42 bytes
Some idiot™ forgot to print the initial value first.
f(K){while(K)printf("%d\n",K,K=rand()%K);}

Don't panic.

You tied me, the question also requires that you print the initial K. Without it I also got 40. You can also get the 42 fully compliant version in a similar way: f(K){while(K)printf("%d\n",K),K=rand()%K;}. Still you got my +1 for an equal solution!

Even better: f(K){while(K)printf("%d\n",K,K=rand()%K);}

x86 + rdrand, 19 bytes
Straightforward implementation. Takes input K in ecx and outputs to a buffer in ebx.
0000000a <start>:
   a:   0f c7 f0                rdrand %eax
   d:   31 d2                   xor    %edx,%edx
   f:   f7 f1                   div    %ecx
  11:   89 13                   mov    %edx,(%ebx)
  13:   83 c3 04                add    $0x4,%ebx
  16:   89 d1                   mov    %edx,%ecx
  18:   85 c9                   test   %ecx,%ecx
  1a:   75 ee                   jne    a <start>
  1c:   c3                      ret

MATLAB (49 46 bytes)
@(k)eval('while k;disp(k);k=randi(k)-1;end;0')

Sample output:
>> @(k)eval('while k;disp(k);k=randi(k)-1;end;0')
ans(5)

ans =

    @(k)eval('while k;disp(k);k=randi(k)-1;end;0')

     5
     3
     2
     1

ans =
     0

I suppose you can do k=randi(k)-1 for a few bytes less.

TI-Basic (TI-84 Plus CE), 17 13 bytes
While Ans
Disp Ans
int(randAns
End
Ans

-4 bytes from Misha Lavrov
Takes input in Ans as 50:prgmNAME.
TI-Basic is a tokenized language. All tokens used here are one byte.
Explanation:
While Ans    # 3 bytes, While the number we hold is not zero:
Disp Ans     # 3 bytes,   Display it on its own line
int(randAns  # 4 bytes,   and replace it with a number randomly
                        # chosen from 0 to one less than it (inclusive)
End          # 2 bytes, end While loop
Ans          # 1 byte,  Display (and return) zero

An 11-byte solution suggested by Misha Lavrov that requires pressing enter after each line following the first.
Ans
While Ans
Pause int(randAns
End

int(Ansrand is shorter. Also, using Pause instead of Disp, you can make the only statement in the loop be Pause int(Ansrand, which also updates Ans.

Python 3, 39 bytes
f=lambda k:print(k)or f(hash('.'*k)%k)

Probably not the most cryptographically secure random number generator but to the human eye it looks random enough...
Try it online!

Notes: 1) the entry gives (usually) different results every time it's run in a new interpreter but may give the same result if run within the same python session. 2) I assume that terminating through an error without explicitly checking for k=0 is acceptable.

Sorry, but functions must be reusable arbitrarily often in the same environment. Terminating in an error is acceptable though

The task requires a uniform random number from the given range. hash() tries to maintain but doesn't guarantee this property. For that task you should use the random module.

With only 57 bytes you can amend your solution to use uniformly random numbers from random.randrange(): from random import*;f=lambda k:print(k)or f(randrange(k))

><>, 92+2 Bytes
:nao:0=?;0_1>:{:}(?\\
}(?!\$2*1>x~\$+1$*2/\~00:{{:@}
8+1.\~:{:}\+>$1+f
~~@~~47*0.\(a2*1@@?!.

+2B for -v flag
Try it online!
><>'s only source of randomness comes from the 'x' instruction, which sets the instruction pointer's direction to a random value. As such, generating a random number from 0 to n isn't trivial.
I first calculate how many bits are required to represent a number in the range [0,n), then generate random bits to generate a random number. This leaves the possibility that it'll generate a number slightly larger than n, in which case we just discard it and try again.
Explanation:
:nao                              Print the current number followed by a newline
    :0=?;                         If the current n is 0, terminate

Calculate how many random bits we need to be generating:
         0 1                      Initialise the variables for this loop:
                                      numberOfBits = 0, maxValue = 1
             :{:}(?\              If maxValue >= n, break out of the loop
                 *2               maxValue *= 2
             $+1$                 numberOfBits += 1

Generate the random number:
                     ~            Delete maxValue
                      00          Initialise randomNumber = 0, i = 0
}(?!\                   :{{:@}    If i >= numberOfBits, break out of the (inner) loop
     $2*                          randomNumber *= 2
          _
        1>x~\                     The random bit: If the IP goes up or
          \+>                     left, it'll be redirected back onto the 'x',
                                  if it goes down, it adds one to randomNumber
                                  If it goes right, it does nothing to randomNumber

             $1+                  increment i
8+1.            f                 Jump back to the start of the inner loop

After we've generated our number, check that it's actually below n
     ~                            Delete i
      :{:} (      ?               Test that the number is less than n
            a2*1    .             If it's not, jump back to the start
                                  of the number generation section
  @~~                             Otherwise delete the old value of n, and numberOfBits
     47*0.                        Then jump back to the start of the program

Very nice! I came up with the same idea independently; without whitespace, my solution uses several characters fewer than yours, but you've managed to make a much more compact block of code.

The current meta consensus is that you don't have to count the bytes used on flags

Retina, 21 bytes
.+
*
L$`.
$.`
+¶<)G?`

Try it online! Explanation:
+

Repeat until the value stops changing (i.e. 0).
¶<)

Print the value before each pass through the loop.
.+
*

Convert to unary.
L$`.
$.`

Create the range and convert to decimal.
G?`

Pick a random element.

PHP, 43 42 bytes
<?while($a=$a?rand(0,$a-1):$argn)echo$a?>0

To run it:
echo '<input>' | php -nF <filename>

Or Try it online!
Example output:
10019128410

-1 byte thanks to Titus's suggestion.

rand(0,$a) get a number between 0 and $a included. As $a should not be a possible value, the max argument for rand must be $a-1

Right you are @Med! Thanks for letting me know, I've updated my answer.

Why don´t you just append 0 instad of two newlines?

Thanks @Titus! That's very helpful, I've updated my solution (-1 byte).

Pyth, 6 7 bytes
QWQ=OQQ

Try it online!
+1 to print the initial input value.
While Q is truthy, set Q to be a random integer between 0 and Q and print Q.
Not the shortest Pyth answer but I'm just learning and only posting because of the recent discussion about no-one using Pyth any more :)

I managed to tie using cumulative reduce but keeping it as a procedural program. Thanks for the motivation to work on a golf :)

That's cool. Still trying to work out how (why) it works.

By default, both = and ~ use the first variable of an expression as the variable that will be assigned if one isn't specified. For example ~hT will set T to 11 while returning 10. The only other fancy trick is that the newline character prints its input and then returns that value unmodified, so we can have an empty loop body. Let me know if something else is confusing :)

The whole lot is confusing with golfing languages. I'm used to Python and Java every day. Thanks for the explanation though. Much appreciated.  I'll keep learning :)

@FryAmTheEggman That's beautiful.

@isaacg Thanks! I originally meant for it to just be edited in here, but I decided to write something up since I wanted to try MathJax. These kinds of Pyth answers were always my favourite since they feel both intentional but also abusive :)

Haskell, 74 71 bytes
-3 bytes by actually doing what the specs say it should do.
import System.Random
f 0=pure[0]
f x=randomRIO(0::Int,x-1)>>=fmap(x:).f

Try it online!

Java, 56 bytes
Object f(int n){return n<1?0:n+","+f(n*=Math.random());}

Try It Online
Acknowledgments

-6 bytes thanks to Kevin Cruijssen

(int)(Math.random()*n) can be golfed to n*=Math.random()

IBM/Lotus Notes Formula, 48 bytes
o:=i;@While(i>0;i:=@Integer(i*@Random);o:=o:i);o

Field formula that takes input from another field i.
There's no TIO for formula so here's a screenshot of a sample output:

Powershell, 36 32 bytes
-4 bytes thanks AdmBorkBork
filter f{$_;if($_){Random $_|f}}

Testscript:
filter f{$_;if($_){Random $_|f}}

100 |f

Output:
100
61
20
8
6
3
0

The Get- is implied, so you can remove it for -4 bytes Try it online!

PowerShell, 35 bytes
for($a="$args";$a;$a=Random $a){$a}

Try it online!
Full program. Takes input $args, stores it into $a, and enters a for loop. Each iteration we're checking whether $a is still positive (as 0 is falsey in PowerShell). Then we leave $a on the pipeline and move to the next iteration, where we set $a to be the result of Get-Random $a, which returns an integer in the range 0..($a-1).
(Ab)uses the fact that PowerShell outputs an additional trailing newline in lieu of outputting the final zero (allowed by the rules as currently written).

"$args" - nice. I was stuck on $args[0] in this case

Lua, 58 bytes
p,r=print,...+0 p(r)while r>0 do r=math.random(0,r)p(r)end

Try it online!
For some more Lua love here :)

Hey, you can remove the +0 on the r declaration and move it to the r on the while statement, by doing so you'll use 1 less byte for the space (p,r=print,...p(r)while).

C# (Visual C# Interactive Compiler), 84 82 bytes
var k=int.Parse(ReadLine());for(Write(k);k>0;)Write($",{k=new Random().Next(k)}");

Try it online!
-2 Bytes thanks to charliefox2
Explenation:
var k = int.Parse(ReadLine());   //1. Read a line from STDIN and convert it to int
for(Write(k);                    //2. Write the original value of k to STDOUT
        k>0;)                    //3. Loop while k > 0
    Write($",{                   //6. Write the separator and the new value to STDOUT
        k =                      //5. Assign it to k
        new Random().Next(k)}"); //4. Get a random int between 0 (inclusive) and k (exclusive)

I think you could save a couple of bytes by using Write() instead of WriteLine() and using string formatting to add a separator, e.g. Write($",{k=new Random().Next(k)}" since OP said output format doesn't matter

@charliefox2: No, that would be 2 bytes longer.

How can you use WriteLine and ReadLine without the Console Prefix?

@raznagul not if you do it for WriteLine(k) as well. var k=int.Parse(ReadLine());for(Write(k);k>0;)Write($",{k=new Random().Next(k)}"); should save you 2 bytes

@charliefox2: Thanks, I totally missed that.

@Snowfire: Try it Online automatically includes using static System.Console for C# Interactive Compiler.

CJam, 7 9 bytes
ri{_pmr}h

Try it online!
Annotated
r       e# read input token
i       e# convert to int
{       e# do {
    _   e# duplicate topOfStack
    p   e# pop topOfStack and print it
    mr  e# rand(0, topOfStack)
}h      e# } while(topOfStack != 0)
        e# implicitly convert stack to string and print it

Bash, 65 58 56 50 bytes
f()(echo ${a=$1};for((;a;)){ echo $[a=RANDOM%a];})

Try it online!
(Improved thanks to manatwork)
Recursive approach
 50  28
f()(echo $1&&f $[RANDOM%$1])

Try

“Input must be printed at first”. Try with more Bash specific syntax.

Welcome to PPCG! :)

Grr! I always forget the {..} enclosed for block which can reduce it to 50 characters.

Thanks for your welcome. I've discovered a few cool bash tricks which i didn't know before. :)

If you reverse the logic, you not need if and exit: f()(echo $1;(($1))&&f $[RANDOM%$1]). Or with an error message even f()(echo $1&&f $[RANDOM%$1]).

Yeah right. I've seen this in post with tips,but for some reason I still thought && is
logical AND like in some other languages.

Atari 400/800 6502 Assembler – 16 bytes
K set initially to #$FF (but can set to any byte value), then calls the POKEY PRNG at $D20A, if greater than or equal, try again, else save as the new upper limit. Keep going until it reaches zero.
define K $FF
* = $600
    LDA #K
.1: STA $80
    BEQ .3
.2: LDA $D20A
    CMP $80
    BCC .1
    BCS .2
.3: BRK       ; if you assume memory is cleared, can omit for 15 bytes

Which, when assembled, is:
a9 ff 85 80 f0 09 ad 0a d2 c5 80 90 f5 b0 f7 00

Output is by running a monitor, single stepping, and spying on $80! The rules indicated “output format as you wish”!

Most likely you need to print or write to buffer. Leaving a value in memory is unreasonable unless it is not possible to print or do any kind of I/O. See https://codegolf.meta.stackexchange.com/questions/2447/default-for-code-golf-input-output-methods

C# (.NET Core), 71 bytes
Using recursion.
static int f(int k){Console.WriteLine(k);return k==0?k:f(r.Next(0,k));}

Try it online!
Output:
100
9
3
0

><>, 147 + 2 bytes
 :0=?\:0&:0=?\:2%-2,&1+&80.
   ;n/       \r:r&:0=?\1-&2*\
          /oan:{/?(}:~/44+\ v
<         \:0=?;>{~00.\*1.^0x
                          \1/

Try it online!
The idea is the same as @Sasha's—generate random bits, making sure not to exceed the original number—but just in a different layout. My solution uses the register to record the number of bits of n.
There is unfortunately a certain amount of wasted space, particularly on the last line.
How it works:
 :0=?\:0&                      n = 0?   No: duplicate n; let reg = 0
   ;n/                                  Yes: print then end

         :0=?\:2%-2,&1+&80.    n = 0?   No: n = floor(n / 2); increment reg; loop to (8,0)
             \                          Yes: enter loop to construct random number r

              r:r&:0=?\1-&2*\  reg = 0? No: r = 2 * r + (0 or 1); loop to (16, 1)
                      /44+\ v           Yes: check if r <= n
<                     \*1.^0x
                          \1/

          /oan:{/?(}:~         r > n?   No: print r and newline;
          \:0=?;>

                 {~00.         Go back to (0,0), using either r or n

You could do something like this to get rid of that last line

Or reversing the whole thing (91 bytes)

J, 8 bytes
?^:*^:a:

Try it online!
How it works
f^:g^:_ is a J idiom for "do while", which means to repeatedly apply f to the input while g gives true. g should always give 0 or 1. Change the last _ (infinity) to a: (boxed empty), and the resulting verb gives the list of intermediate values.
Monadic ? is "roll", i.e. given N, generates a random integer between 0 and N-1 inclusive. Monadic * is "signum", i.e. gives 1 for positive, 0 for zero, -1 for negative input.

Kotlin, 60 bytes
fun f(k:Int){println(k);if(k>0)f((Math.random()*k).toInt())}

Try it online!
Solution with recursion.

random is function from java.lang.Math, isn't it? java.lang.Math module is required explicit import or Math.random() code

Vyxal M, 4 bytes
{℅…|

Try it Online!
the M flag generates a range 0-n implicitly
{         # while true
 ℅        # random in range 0-n
  …|      # print w/o popping

K4, 13 12 11 bytes
Solution:
(*1?)\[0<;]

Examples:
q)k)(*1?)\[0<;] 100
100 77 30 17 12 2 0
q)k)(*1?)\[0<;] 100
100 37 28 20 2 0
q)k)(*1?)\[0<;] 100
100 77 61 55 53 6 2 0
q)k)(*1?)\[0<;] 100
100 12 1 0

Explanation:
Iterate over expression while x is greater than zero.
(*1?)\[0<;] / the solution
(   )\[0<;] / iterate over brackets whilst 0< evaluates true
  1?        / 1 choose (returns a 1-item list)
 *          / take the first

Bonus:
A 14 byte solution that also works in K (oK); this one is an if/else version of the same theme:
{$[x;*1?x;x]}\

Try it online!

Charcoal, 11 bytes
ＩθＷ⊟θＩ⊞Ｏθ‽ι

Try it online! Link is to verbose version of code. Slightly unusual input format. Explanation:
Ｉθ

Cast the input to string and print it.
Ｗ⊟θ

While the input is non-zero...
⊞Ｏθ‽ι

... replace it with a random number in the implicit range...
Ｉ

... and cast the result to string and print it.
13-byte version with more standard input format:
θＮθＷθ«≔‽θθ⸿Ｉθ

Try it online! Link is to verbose version of code.

Jelly, 6 bytes
X’$¹Ð¿

Try it online!

XƬ;0 saves two since it'll stop when the randrange(1,x+1) returns x at which point we have our 0 :) EDIT: Oh, I just scrolled and saw Dennis's answer.

@JonathanAllan Dennis's previous revision? Bah.

JavaScript, 34 bytes
Outputs a space-delimited string of integers.
f=n=>n&&n+" "+f(Math.random()*n|0)

Try it online

Ruby, 31 29 bytes
->n{n=rand p n until 1>n;p 0}

Try it online!

Red, 41 bytes
func[n][print n if 0 < n[f random n - 1]]

Try it online!

Batch, 54 bytes
@echo %1&if %1 gtr 0 set/an=%random%%%%1&call %0 %%n%%

Four %s in a row... just a typical day for Batch. Only works up to 32768 (and not terribly uniform at that) due to limitations of Batch's random number generator. See my Batch answer to Pick a random number between 0 and n using a constant source of randomness for large uniform randomness.

Japt, 10 bytes
Outputs an array of integers.
_Ì}f@NpU=ö

Try it

Explanation
               :Implicit input of integer U
  }f           :Loop until left function returns falsey and return final value of right function
    @          :Right function
         ö     :  Random integer in the range [0,U)
       U=      :  Reassign to U
      p        :  Push
     N         :   To the array of inputs
_              :Left function
 Ì             :Get the last element of N. If it's 0, which is falsey, then the loop will be broken

Alternative, 8 bytes
A direct port of my JavaScript solution.
©U+S+ßUö

Try it

Excel VBA, 42 bytes
An anonymous function that takes input from range [A1] and outputs to the console.
k=[A1]:?k:While k:y=Int(k*Rnd):?y:k=y:Wend

Python 2.7, 112 bytes
from random import randint
k=int(raw_input())
def r(k):
    y=randint(0, k-1)
    print y
    if y!=0:
        r(y)
r(k)

This does not quite meet the spec, as it does not print the first number. Consider modifying your code to something like this

Also, you can save bytes by removing whitespace and submitting as a function instead of a full program

I see that you've been posting mostly Python answers. Have you had a look at Tips for golfing in Python?

F#, 70 bytes
let r=System.Random()
let rec x K=printfn"%i"K;if K>0 then r.Next K|>x

Try it online!

The rules say "Input must be printed at first".

I do apologise... no idea how I missed that, having already looked at half a dozen answers.

Julia 0.6, 33 bytes
~n=(println(n);n>0&&~rand(0:n-1))

Try it online!
Defines the function as an operator ~ (to save bytes). Print the given number, and if we haven't reached 0, call itself recursively with a new uniformly random number from range 0:n-1.
(Could've used @show instead of println since OP says "output format as you wish" (@show prints the variable name before the value every time, eg. n = 8 instead of 8), but the 2 byte saving doesn't seem worth it relative to total bytecount, and I like this neater output.)

AWK, 56 bytes
{print($0);k=$0;for(srand();k>0;)print(k=int(k*rand()))}

Try it online!

Pascal (FPC), 89 bytes
var K:word;begin Randomize;read(K);repeat writeln(K);K:=Random(K)until K<1;writeln(K)end.

Try it online!
Not only Pascal code is as long as usual, you also need to Randomize; beforehand...
Instead of writing of the initial value before the loop, 0 is written after the loop. This approach saves a byte because 1end. isn't valid; instead od separating this into 2 tokens, it tries to find a meaningful scientific notation.

Ruby, 23 bytes
f=->k{k<1||f[rand p k]}

Try it online!
Non-recursive, 25 bytes
->k{k=rand p k while k>0}

Try it online!
->k{(k=rand p k)>0&&redo}

Try it online!

MATLAB, 36 bytes
K
Y=1;while Y>0,Y=randi(K)-1;K=Y,end

Sample output:
For K = 25
K =

    25

K =

    15

K =

    11

K =

     6

K =

     4

K =

     1

K =

     0

Racket, 52 bytes
(define(f n)(println n)(unless(= n 0)(f(random n))))

Try it online!

Julia 0.6, 49 bytes
~x=(println(x);x-1)
!x=(y=rand(0:~x))>0 ? !y : ~0

Try it online!
If one were willing to accept outputting all output except the last to STDOUT, and the last 0 as returning false,
then it can be
~x=(println(x);x-1)
!x=(y=rand(0:~x))>0&&!y

Which is a bit short. But I think mixing outputs like that is not really in spirit.

Elixir, 157 148 bytes
-9 bytes from Okx
defmodule N do def f(0,k)do IO.puts 0 end;def f(n,k)do IO.puts n;f Enum.random(0..k),k end end;k=String.to_integer IO.gets"";N.f Enum.random(0..k),k

Try it online!
Formatted:
defmodule N do
    def f(0,k) do
      IO.puts n
    end

    def f(n,k) do
      IO.puts n
      f Enum.random(0..k), k
    end
end
{k,_} = Integer.parse IO.gets""
N.f Enum.random(0..k),k

We define a module with 2 functions - one is recursive, the other is the base case with a guard so it only executes when our random is 0 (Elixir doesn't necessarily assign anything, it does pattern matching for e.g. arguments- and thus f(0,k) only matches when n=0, otherwise f(n,k) matches). After defining that module (since functions can't be defined outside a module), we parse an integer from input and start our recursive looping.
Notably, k=String.to_integer IO.gets"" is the same length as the other method I've found to parse integers from input, {k,_}=Integer.parse IO.gets"", which is kinda neat.

def f(n,k) when n <= 0 can be shortened to def f(0,k)

Common Lisp - 52 Bytes
(loop while (/= a 0) do (print (setf a (random a))))

Assumes a is already defined.
Test case:
(setf a 5000000)
(loop while (/= a 0) do (print (setf a (random a))))

PHP, 44 bytes
<?=$a=$argn;while($a--)echo _,$a=rand(0,$a);

or
<?for(;$a=&$argn;$a=rand(0,$a))echo$a--,_?>0

print integers delimited by underscore. Save to file, run as pipe with -nF.

Noether, 9 bytes
I~n0(nRP)

Try it online!
Output is given in the form
735920

Explanation:
I~n        - Store input in the variable n
   0(   ) - Loop until the top of the stack equals zero
     nR    - Push a random integer between 0 and n
       P   - Print the top of the stack

Swift 4, 30 bytes
while n>0{n=rand()%n;print(n)}

Try it online!
n is the value of input

Elixir, 87 bytes
fn n->[n]++Enum.take_while(Stream.repeatedly(fn->Enum.random(0..n)end),&(&1>1))++[0]end

Try it online!

This isn't actually valid as an answer - it doesn't uniformly randomize, the sequence is strictly decreasing due to how you recurse (if your first iteration is 50>25, it can never generate numbers 26-50 again).

@Delioth fixed.

Forth (gforth), 57 bytes
include random.fs
: f begin dup . random dup 0= until . ;

Try it online!
Explanation
Get Random integer in range, loop until result is 0.
Code Explanation
include random.fs     \ import the file that implements the "random" word
:f                    \ start a word defintion
  begin               \ start an indefinite loop
    dup .             \ duplicate the top of the stack and print it
    random            \ get random int between 0 and n - 1
    dup 0=            \ duplicate the top of the stack and then check if it's 0
  until               \ if it's zero end the loop
  .                   \ output the top of the stack (always 0)
;                     \ end the word definition

Julia 1.0, 53 bytes
function q(N)println(N);if N>0;q(rand(0:N-1));end;end

Try it online!

Pyt, 5 bytes
`0⇹ɾł

Try it online!
Explanation:
         Implicit input
`   ł    Do ... while top of stack is not 0:
 0          Push 0
  ⇹         Swap top two elements on stack
   ɾ        Get random number in [0,top of stack)
         Implicit print

At the TIO link, this always just outputs 0. Am I missing something?

Fortran 90, 56 bytes
read(*,*)i
do while(i>0)
i=rand(i)*i
print*,i
enddo
end

Trying to golf Fortran is always fun.
Also, because seeding the RNG in Fortran is a pain and costs a lot of bytes (and RAND() uses a particularly poor algorithm but has a nice short name), the output is pretty much deterministic - but I'm hoping to get away with it.
Example
Input:
10000000

Output:
 2636923
 1681125
  264113
   17707
    2453
      47
       0

PHP 5.6
$k = $y = 5;
do {
    echo $k. "\n";
    $k = rand(0, $y-1);
} while($k > 0)

Please specify the name (and if relevant the version) of the used language in a Header at top of your answer, together with the code length measured in bytes. And please use Code and Preformatted Text markup for the code block to make it readable. Then please read the code-golf tag wiki about what is the goal in these challenges.

To help getting into golfing, there is a collection of Tips for golfing in PHP. And also a generic Tips for golfing in .

MathGolf, 4 bytes
orw∟

Try it online.
Explanation:
   ∟  # Do-while true without popping:
o     #  Print the current integer with trailing newline (without popping)
      #  (which will be the implicit input-integer in the first iteration)
 r    #  Pop and push a list in the range [0,K)
  w   #  Pop and push a random integer from this list

Note: builtin w of itself works with an integer argument as well, but it'll output a random integer in the range \$[0,K]\$ instead of \$[0,K)\$, hence the need for the explicit r.

Thunno 2, 5 bytes
(ß;Lɼ

Attempt This Online!
Explanation
(ß;Lɼ  # Implicit input
( ;    # While loop
 ß     # (condition)  Print TOS without popping
   Lɼ  # (body)       Choose a random integer in the range [0..TOS)


text:
A Lazy Bag of Bread
I work at a bakery that serves Wheat, Rye, Barley, Grain, and French bread, but the baker's a little weird - he stacks the loaves in random order, and sometimes just leaves some shelves at the end empty.
Each day, the same customer comes in and asks for one of each loaf of bread, but the tricky thing is, he's a germophobe, so when I fill his bag, I can't take loaves from two adjacent shelves in consecutive selections.
It takes one second to walk between adjacent shelves. It's a busy store; for any random configuration of loaves, I'd like to minimize the time it takes to get one of each unique loaf. I can start and end at any shelf.
If today's ordering is W B W G F R W, a possible path is 0, 3, 5, 1, 4, for a total of 12 seconds: abs(3-0) + abs(5-3) + abs(1-5) + abs(4-1) = 12
(1, 2, 3, 4, 5 doesn't work, because bread is picked consecutively from adjacent shelves.)
If it's B W B G B F B R B W B F, a possible path is 1, 3, 5, 7, 10, for a total of 9 seconds.
The manager always makes sure there is a possible solution, so I don't need to worry about catching bad inputs. He usually sends me the order in a file, but if I want, I can type it to STDIN or read it a different way. I'd like the program to print out the indices of the best path, as well as its time, according to default I/O rules.
In short:

5 types of bread.
Loaf orders appears as strings of random order and length.
Must select one of each unique loaf.
Cannot make adjacent consecutive selections.
Minimize the distance between selection indices.
Don't need to worry about invalid inputs.
Default I/O rules apply.

This is code-golf, shortest byte count wins.

0+3+5+1+4=13 but 1+3+5+7+10=26, not 9.

@JungHwanMin Technically, it doesn't need to be formatted, but yes, it could be formatted like that.

I deleted the tag [tag:random] because it seemed that the output is not necessarily non-deterministic for each input; the input may be randomized, but the algorithm to compute the output does not necessarily contain randomness. If you intend otherwise, feel free to roll back my edit!

In that case then the first test case is wrong, not the second; the result should be 12, not 13.

"Each shelf takes one second to walk to" should probably be worded "It takes one second to walk between adjacent shelves".

[0, 1, 3, 4, 5] can be a possible output for W B W G F R W

@LuisfelipeDejesusMunoz Not quite, several of those consecutive indeces are adjacent.

Welcome to PPCG, and nice first challenge!

It's not important to the actual task, but I'm curious: why does him being a germophobe mean you can't take loaves from two adjacent shelves in consecutive selections?

Might there be any empty shelves that are not at the ends? (e.g. is 'WBWG FRW' a valid input too?

JavaScript (ES6), 114 bytes
Saved 1 byte thanks to @Oliver
Takes input as an array of characters. Outputs a comma-separated string where the first value is the total time and the next ones describe the path.
a=>(b=g=(r,s=o='',c,p)=>s[c>b|4]?o=(b=c)+r:a.map((v,i)=>s.match(v)||(d=p<i?i-p:p-i)<2||g([r,i],s+v,~~c+d,i))&&o)``

Try it online!
Commented
a => (                          // a[] = input array
  b =                           // b = best score so far (initially a non-numeric value)
  g = (                         // g = recursive function taking:
    r,                          //   r = path
    s =                         //   s = string of collected loaves of bread
    o = '',                     //   o = final output
    c,                          //   c = current cost
    p                           //   p = index of the last visited shelf
  ) =>                          //
    s[c > b                     // if the final cost is not greater than our best score
            | 4] ?              // and we've successfully collected 5 loaves of bread:
      o = (b = c) + r           //   update the current output and the best score
    :                           // else:
      a.map((v, i) =>           //   for each loaf of bread v at shelf i in a[]:
        s.match(v) ||           //     if we've already collected this kind of bread
        (d =                    //     or the distance d
          p < i ? i - p : p - i //     defined as the absolute value of p - i
        ) < 2 ||                //     is less than 2: stop recursion
        g(                      //     otherwise, do a recursive call to g() with:
          [r, i],               //       r updated with the index of the current shelf
          s + v,                //       s updated with the current loaf of bread
          ~~c + d,              //       c updated with the last distance
          i                     //       i as the index of the last shelf
        )                       //     end of recursive call
      )                         //   end of map()
      && o                      //   return the current output
  )``                           // initial call to g() with r = [""]

Python 2, 212 210 bytes
lambda s:min((sum(h(p)),p)for b in combinations(range(len(s)),5)for p in permutations(b)if(len(set(s[i]for i in p))==5)&all(d>1for d in h(p)))
h=lambda p:[abs(y-x)for x,y in zip(p,p[1:])]
from itertools import*

Try it online!
2 bytes thx to Jonathan Frech.

if len(...)==5and all(...) can be if(len(...)==5)&all(...) to save two bytes.

Python3, 244
def f(l):
 q=[(0,0,[],[])]
 L,C=0,0
 for a,r,b,c in q:
  if C and r>=C:continue
  if not{*l}-{*c}:L=b;C=r;continue
  for i,A in enumerate(l):
   if i not in b and A not in c and(c==[]or abs(b[-1]-i)!=1):q+=[(i,r+abs(a-i),b+[i],c+[A])]
 return L

Try it online!

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
Last digit large number
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.

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.

Is taking the input in reverse reasonable? Can the input be zero?

(i. e. can any input value be zero). Do we need to handle the one-value case?

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.

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.

@NeilSlater you can only do %10 on the last iteration. Consider 2**3 vs 2**13.

@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.

Dear OP, we need more test cases.

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.

@NeilSlater Because nobody requires us that the answers need to work in any time limit. Who cares about that, only short code matters.

@user202729 I did not mention any time limit. The question does in fact imply that you need to be able to cope with very large interim values - in the title. Also the Code Wars version does require it (it's the whole point of the challenge - just taking a modulus at the end is trivial and doesn't solve anything meaningful). And it is still possible to golf the code to do this, just it would be longer than the answers given. However, the question was not worded clearly, and now there are lots of solutions that don't work with that constraint. So the chance to change it here is gone.

@NeilSlater That is why initially I voted to close this as "unclear what you're asking" (not sure if I actually voted to close), because I had the same thought -- this should have time limit, but OP didn't include any. However if it does include a time limit it needs to be explicitly stated in the challenge with all the machine specification details and possible inputs, because otherwise we cannot be clear what the time limit is.

See also: What's a general algorithm/technique to find the last digit of a nested exponential?

JavaScript (ES7), 22 bytes
Limited to \$2^{53}-1\$.
a=>eval(a.join`**`)%10

Try it online!

What on earth, why does this work?!

@komali_2: ** is JavaScript's exponentiation operator. The rest is pretty straightforward.

@komali_2 a.join`**`  is equivalent to a.join(['**']) and ['**'] is coerced to '**' by the join method.

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.

Sorry for the basic question, what part of this is retrieving the last digit?

@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

@Mayube doh.jpg Of course, I should have spotted that.

(a=>eval(a.join\**`)%10)([2, 53, 53])->NaN`

R, 25 bytes
Reduce(`^`,scan(),,T)%%10

Try it online!

Not sure what people liked so much about this answer.

I personally like to see Reduce being used.

Haskell, 19 bytes
(`mod`10).foldr1(^)

Try it online!

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.

Hey, could you explain how the bytecount is calculated? Just curious how that language uses nibbles.

@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.

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!

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!

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%

Good ideas! I had no idea dc would let me use A as a literal while set to decimal input. Thank you @brhfl!

@SophiaLechner This trick works for all input bases: https://codegolf.stackexchange.com/a/77728/11259

J, 5 bytes
-3 bytes thanks to cole!
10|^/

Try it online!

Does 10|^/ not work?

@cole Of course it works, thanks!

Finally, a challenge where J beats Jelly!

05AB1E, 4 bytes
.«mθ

Try it online!
Explanation
.«     # fold
  m    # power
   θ   # take the last digit

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

Relevant Meta.

I have fixed this issue in the latest commit for future use.

@Mr.Xcoder: Right! I should have remembered that. So rarely need to though with implicit input. Thanks :)

@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.

@EriktheOutgolfer I think the Meta answer uses function as a generic term. Anyway, if you disagree I'll add an answer to Default I/Os that allows this, because it seems perfectly reasonable.

Wolfram Language (Mathematica), 16 bytes
Power@##~Mod~10&

Try it online!

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!

^ 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 **

@SophiaLechner Yes - of course - good catch!  Not sure how that ^ crept in - I had ** in previous iterations of my dev cycle.

Perl 6, 14 bytes
{([**] $_)%10}

Try it online!
Uses the reduction meta square brackets with the operator **, modulo 10.

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.

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

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

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.

There is an issue if the sequence has 0s

@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.

Indeed, but that will require a lot more code, exactly 6 more bytes: n<2?n: before n**.

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

I got the exact same answer without the flag so this looks like the optimal way for now.

@Nit: until it's confirmed we can take input in reverse :)

@Oliver Yeah, but you're still using a flag. Personally I think the byte count without flags is the most accurate scoring result.

@Nit Shouldn't a flag add 3 bytes by meta consensus?

@LegionMammal978, not any more.

Ah, okay. It's a bit tricky trying to search stuff on Meta.

PHP, 50 44 bytes
-6 bytes from @Shaggy
<?=eval("return ".join('**',$argv).";")%10?>

Try it online!

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.

You're supposed to return the last digit, not the whole thing.

44 bytes

Well, if this kind of input is valid, then it can be even shorter: 40 bytes

05AB1E, 8 bytes
`.gGm}T%

Try it online!

I think you mean ...gGm}10% (or something golfier).

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!

) r( -> )r(.

Also, if you want to use UB, you could golf r(int*n){return pow to R;r(int*n){R=pow.

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

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.

@raznagul: sorry, I'm pretty new to code-golf in C#, is it ok now ?

No problem. Yes this is fine now.

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!

@raznagul: great !

APL (Dyalog Unicode), 5 bytes
10|*⌿

Try it online!

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

Weird, that wouldn't work for me.

6 bytes

@Shaggy :P

Ah, for Jaysis' sake! :\ That's happening more & more often!

Jelly, 6 bytes
U*@/DṪ

Try it online!

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)

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.

Python 2, 45 43 bytes
lambda x:reduce(lambda b,a:a**b,x[::-1])%10

Try it online!

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)

Stax, 7 bytes
üT(Çó╖⌐

Run and debug it
Algorithm like in my Python answer

C (gcc), 76 75 bytes

Saved a byte thanks to ceilingcat; golfing o<=O to O/o.

o(int*O){O=_(O)%10;}_(O,o,Q)int*O;{for(o=Q=1;*O>=0&&_(O+1)/Q++;o*=*O);O=o;}

Try it online! Takes input as an int pointer to a -1-terminated list of integers.

Ruby, 24 20 bytes
->a{eval(a*'**')%10}

Try it online!

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

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

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

Try it online!

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
({}((()()()()()){})(<>))<>{(({})){({}[()])<>}{}}{}<>([{}()]{})

Pari/GP, 32 bytes
a->fold((x,y)->y^x,Vecrev(a))%10

Try it online!

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

Ruby, without limitation on very high exponential towers, 142 bytes
def d(b,h,*t)
h=h%b
return h if !t[0]
l=b.times.find_index{|i|h**(i+2)%b==h} unless h*h==b
l ?l==0?h:h**d(l+1,*t)%b:[1,h,0][[t[0],2].min]
end

This code operates a reduction at each step so every single exponentiation is done on very small numbers. It is able to deal with almost arbitrarily high exponential towers without using arbitrary precision, all is done within a very small integer range, the highest integer used at any point is 9**9.
The function must be called with an initial base, for the examples it would be

d(10, 3, 4, 2)

so it is able to return the "last digit" of the result in any base.

@neilslater answer is much better, based on the observation that we don't need to compute the cycle at each stage, because once we get to the first stage of the exponential, n^4 === n (mod whatever was the previous cycle, including the initial base 10). My answer is able to start say with base 13 instead of 10, where the cycles are much weirder at the first stages.

Actually n^5 === n, not n^4 === n

Pyth, 7 bytes
e.U^Zb_

Try it online!
Explanation:
e.U^Zb_   //full program
 .U       //reduce with the function
   ^Zb    //lambda b,Z:Z^b
      _   //on reversed (implicit) input
e         //return last digit

Also, if input can be taken in reverse order, the final _ can be removed for a final score of 6 bytes.

Factor, 37 bytes
[ reverse [ swap ^ ] 1reduce 10 mod ]

Attempt This Online!
Reverse the input, reduce by swapped exponentiation, take the last digit.

Arturo, 25 bytes
$=>[%do join.with:"^"&10]

Try it!
$=>[                ; a function where input is assigned to &
    join.with:"^"&  ; turn [3 4 2] into "3^4^2", for example
    do              ; eval
    %...10          ; modulo 10
]                   ; end fucntion

ES6, 44 bytes, solves all cases from the original problem
Thanks to @NeilSlater for the (mod 4) condition
a=>a.reduceRight((t,n)=>n<2?n:n**(t%4+4))%10

Tested passing an array of 2^20 elements each equal to 2^20

Perl 5, 22 + 2 (-pl flag) = 24 bytes
One-liner:
$_=(s/ +/**/g,eval)%10

Try it online.

I think you can remove the + and require the input string to be single-space separated.

PHP, 54 bytes
<?eval('echo '.str_replace(',','**',$argv[1]).'%10;');

To run it:
php -n <filename> <number,number,...>

Example:
php -n last_digit.php 5,3,2

Or Try it online!

How?
Simply creates a string with format of <number>**<number>**<number>...%10 and outputs the evaluation of that string.
For input of 5,3,2, the evaluation string will be echo 5**3**2%10;.

Java 10, 77 bytes (limited to 232-1)
a->{int i=a.length-1,j=a[i];for(;i-->0;)j=(int)Math.pow(a[i],j);return j%10;}

Input is an int[], output is an int.
Try it online.
Java 10, 82 bytes (limited to 264-1)
a->{int i=a.length-1;var j=a[i];for(;i-->0;)j=(long)Math.pow(a[i],j);return j%10;}

Input is a long[], output is a long.
Try it online.
Java 10, 177 bytes (unlimited)
a->{int i=a.length-1;var j=a[i];for(;i-->0;){var r=j.ONE;for(var t=a[i];j.signum()>0;t=t.multiply(t),j=j.shiftRight(1))if(j.testBit(0))r=r.multiply(t);j=r;}return j.mod(j.TEN);}

Input is a java.math.BigInteger[], output is a java.math.BigInteger.
Try it online.
java.math.BigInteger has a builtin pow method, but only accepts int as parameter. This last answer uses a golfed variation of this SO answer as implementation of a pow(BigInteger, BigInteger) method.

Thunno 2 t, 3 bytes
µʋ@

Try it online!
Explanation
µʋ@  # Implicit input
µʋ   # Right-reduce the list by:
  @  #  Swapped exponentiation
     # Take the last item (digit)
     # Implicit output

TI-Basic, 34 bytes
Prompt A
1
For(I,dim(lA),1,~1
lA(I)^Ans
End
10fPart(.1Ans

~ represents the negative sign.

Uiua, 6 bytes
◿10/ⁿ⇌

Try it!
     ⇌  # reverse
   /ⁿ   # reduce by power
◿10     # modulo 10

Python 3, 19 bytes
lambda N:eval(N)%10

Try it online!
The input is given as a string where each integer is separated by the characters **. I claim that the two characters ** are equally reasonable to ,  at separating digit sequences.

16: print input()%10

-1, because I think the input format is not reasonable. Where to stop? I can take the input as a string representation of a list and declare the list opening as (, the list separator as ** and the list closing as )%10. My answer is then a simple eval. Very funny.

Very similar to this standard loophole (-1)

Related meta discussion

@JungHwanMin Correct me if I am wrong, but I interpret this as such that there currently is no real consensus on allowing borderline input specification like this.

How about just joining input on **?  Adds 11 bytes, but still beats the other python answers: https://tio.run/##K6gsycjPM/6fZhvzPycxNyklUcHPKrUsMUdDSUtLSS8rPzNPw09TU9XQ4H9BUWZeiUaaRrSSsZKOgpIJiDBSitXU/A8A

@DigitalTrauma Thanks for the suggestion, though I encourage you to post it yourself.

I don't consider this to violate the loophole linked to above, but don't think this kind of answer should be permitted.

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
Black Box Trigonometry
Write a program or function that can distinguish the following 12 trigonometric functions:  sin,
cos,
tan,
asin,
acos,
atan,
sinh,
cosh,
tanh,
asinh,
acosh,
atanh.
Your program is given one of the above functions as black box and should output the function's name either as given above or the way it is named in your language.
This is code-golf, so the shortest answer in each language wins. You should show that your code works correctly by including test cases with all 12 possible inputs. If the language of your choice does not include build-ins for all of the above functions, you have to provide your own sensible implementations of the missing ones.
Further Clarifications

Using complex numbers to query the black box is allowed if the underlying build-ins can handle them.
As \$ dom\ acosh \cap dom\ atanh = \emptyset \$ when using only real numbers, queries to the black box function can give domain errors. In this case you should assume that the black box only communicates the existence of an error, but not from which function it originates.
If instead of an error some other value, e.g. NaN or null, is returned, then your submission should be able to handle them.

Thanks for the helpful sandbox feedback!

Mathematica can handle symbolic inputs so that the function output is only partially evaluated, if at all. The difference it makes is that I could use some pattern-matching instead of computations.

@JungHwanMin If that means you can access the function names from the symbolic output then I'm afraid it is not allowed.

Python 3.6.4 on Linux, 99 bytes
Bit of a silly answer, but:
lambda f:"asinh acos cos cosh atan atanh tan sin asin tanh sinh acosh".split()[hash(f(.029))%19%12]

Requires the trigonometric functions to be one out of the built-in cmath module for complex in/output.

@JungHwanMin I believe that you are confused. I most certainly take an actual function. Note that my only reference to input f is f(.029) - calling the function with a value.

You are correct. My bad, I misread your program (+1)

Did you bruteforce this?

@mbomb007 If by brute force you mean a loop that does a couple hundred iterations in the blink of an eye, yes.

This is both amazing and silly.

How comes this works only in this specific version? Does the hash function change from release to release?

@Laikoni I don't know if it only works in this specific version - I just listed the specific version I used just in case the hash function does change.

Relevant?

@mbomb007 From the docs it doesn't appear that Python randomizes hashes of complex types. I've tested the program multiple times now and it still works.

Instead of listing every function, is there a way you could use a regex? (e.g. "a?(sin|cos|tan)h?")

@OldBunny2800 No, Python has no ability to generate all possible strings that a regex recognizes sadly.

@orlp You could filter a list to get the strings like I did. Also, it does have the ability, but it's not a built-in, and it's not likely to be short.

@mbomb007 When I said it doesn't have the ability, I meant built-in. It's a turing complete language so it obviously has the ability :P The filtering of globals like you did doesn't work because I need the functions in a specific order matching the hash function.

@orlp Right. I was wondering if you could use my earlier filtering method that ended with 13 function names, and find a mapping that ignores isinf.

@orlp [x+y+z for x in["","a"]for y in["sin","cos","tan"]for z in["","h"]] is a little shorter than "...".split() but unfortunately the order is different :(

Perl 6, 75 bytes
->&f {([X~] ("","a"),<sin cos tan>,("","h")).min({abs(f(2i)-&::($_)(2i))})}

Try it online!
As it happens, all twelve of the functions to be discriminated amongst are built-in and all take complex arguments.
[X~] ("", "a"), <sin cos tan>, ("", "h") generates all twelve function names by reducing the three input lists with cross-product-concatenation.  Given those, .min(...) finds the one which the smallest difference from the input function at 2i.

59 bytes X can be used for multiple terms, and a few other tricks to golf bytes

C (gcc), 178 172 bytes
double d;_;f(double(*x)(double)){d=x(0.9247);_=*(int*)&d%12;puts((char*[]){"acosh","sinh","asinh","atanh","tan","cosh","asin","sin","cos","atan","tanh","acos"}[_<0?-_:_]);}

Try it online!
Old but cool: C (gcc), 194 bytes
double d;_;f(double(*x)(double)){char n[]="asinhacoshatanh";d=x(0.9247);_=*(int*)&d%12;_=(_<0?-_:_);n[(int[]){10,5,5,0,14,10,4,4,9,14,0,9}[_]]=0;puts(n+(int[]){5,1,0,10,11,6,0,1,6,10,11,5}[_]);}

Try it online!
The -lm switch in TIO is merely to test. If you could write a perfect
implementation of the standard trig functions you would get the right answer.
Explanation
The idea was to find some input value such that when I interpret the outputs of
each of the trig functions as integers they have different remainders modulo 12.
This will allow them to be used as array indices.
In order to find such an input value I wrote the following snippet:
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>

// Names of trig functions
char *names[12] = {"sin","cos","tan","asin","acos","atan","sinh","cosh","tanh","asinh","acosh","atanh"};

// Pre-computed values of trig functions
double data[12] = {0};

#define ABS(X) ((X) > 0 ? (X) : -(X))

// Performs the "interpret as abs int and modulo by" operation on x and i
int tmod(double x, int i) {
    return ABS((*(int*)&x)%i);
}

// Tests whether m produces unique divisors of each trig function
// If it does, it returns m, otherwise it returns -1
int test(int m) {
    int i,j;
    int h[12] = {0}; // stores the modulos

    // Load the values
    for (i = 0; i < 12; ++i)
        h[i] = tmod(data[i],m);

    // Check for duplicates
    for (i = 0; i < 12; ++i)
        for (j = 0; j < i; ++j)
            if (h[i] == h[j])
                return -1;

    return m;
}

// Prints a nicely formatted table of results
#define TEST(val,i) printf("Value: %9f\n\tsin      \tcos      \ttan      \n  \t%9f\t%9f\t%9f\na \t%9f\t%9f\t%9f\n h\t%9f\t%9f\t%9f\nah\t%9f\t%9f\t%9f\n\n\tsin      \tcos      \ttan      \n  \t%9d\t%9d\t%9d\na \t%9d\t%9d\t%9d\n h\t%9d\t%9d\t%9d\nah\t%9d\t%9d\t%9d\n\n",\
        val,\
        sin(val), cos(val), tan(val), \
        asin(val), acos(val), atan(val),\
        sinh(val), cosh(val), tanh(val),\
        asinh(val), acosh(val), atanh(val),\
        tmod(sin(val),i), tmod(cos(val),i), tmod(tan(val),i), \
        tmod(asin(val),i), tmod(acos(val),i), tmod(atan(val),i),\
        tmod(sinh(val),i), tmod(cosh(val),i), tmod(tanh(val),i),\
        tmod(asinh(val),i), tmod(acosh(val),i), tmod(atanh(val),i))

// Initializes the data array to the trig functions evaluated at val
void initdata(double val) {
    data[0] = sin(val);
    data[1] = cos(val);
    data[2] = tan(val);
    data[3] = asin(val);
    data[4] = acos(val);
    data[5] = atan(val);
    data[6] = sinh(val);
    data[7] = cosh(val);
    data[8] = tanh(val);
    data[9] = asinh(val);
    data[10] = acosh(val);
    data[11] = atanh(val);
}

int main(int argc, char *argv[]) {
    srand(time(0));

    // Loop until we only get 0->11
    for (;;) {
        // Generate a random double near 1.0 but less than it
        // (experimentally this produced good results)
        double val = 1.0 - ((double)(((rand()%1000)+1)))/10000.0;
        initdata(val);
        int i = 0;
        int m;

        // Find the smallest m that works
        do {
            m = test(++i);
        } while (m < 0 && i < 15);

        // We got there!
        if (m == 12) {
            TEST(val,m);
            break;
        }
    }

    return 0;
}

If you run that (which needs to be compiled with -lm) it will spit out that with
a value of 0.9247 you get unique values.
Next I reinterpeted as integers, applied modulo by 12, and took the absolute
value. This gave each function an index. They were (from 0 -> 11): acosh, sinh,
asinh, atanh, tan, cosh, asin, sin, cos, atan, tanh, acos.
Now I could just index into an array of strings, but the names are very long and
very similar, so instead I take them out of slices of a string.
To do this I construct the string "asinhacoshatanh" and two arrays. The first
array indicates which character in the string to set to the null terminator,
while the second indicates which character in the string should be the first
one. These arrays contain: 10,5,5,0,14,10,4,4,9,14,0,9 and
5,1,0,10,11,6,0,1,6,10,11,5 respectively.
Finally it was just a matter of implementing the reinterpretation algorithm
efficiently in C. Sadly I had to use the double type, and with exactly 3 uses,
it was quicker to just use double three times then to use #define D double\nDDD
by just 2 characters. The result is above, a description is below:
double d;_;                                 // declare d as a double and _ as an int
f(double(*x)(double)){                      // f takes a function from double to double
    char n[]="asinhacoshatanh";             // n is the string we will manipulate
    int a[]={10,5,5,0,14,10,4,4,9,14,0,9};  // a is the truncation index
    int b[]={5,1,0,10,11,6,0,1,6,10,11,5};  // b is the start index
    d=x(0.9247);                            // d is the value of x at 0.9247
    _=*(int*)&d%12;                         // _ is the remainder of reinterpreting d as an int and dividing by 12
    _=(_<0?-_:_);                           // make _ non-negative
    n[a[_]]=0;                              // truncate the string
    puts(n+b[_]);}                          // print the string starting from the correct location

Edit: Unfortunately just using a raw array is actually shorter, so the code becomes much simpler. Nonetheless the string slicing was fun. In theory an appropriate argument might actually come up with the right slices on its own with some math.

You can save 20 bytes by replacing puts(...) with printf("%.5s","acoshsinh asinhatanhtan  cosh asin sin  cos  atan tanh acos "+5*(_<0?-_:_))

You can save 5 bytes by compiling with -DD=double and replacing all doubles in your code with D. Note that the flag needs to be counted for total bytes.

An additional three bytes can be shed by replacing char*[] with int*[], and by changing the ternary operator (?:) to an abs(_)

159 bytes

Python 3.6.5 on Linux, 90 85 bytes
h=hash;lambda f:h(f(.0869))%3%2*"a"+"tscaionns"[h(f(.14864))%3::3]+h(f(.511))%5%2*"h"

This builds upon orlp's answer; but instead of finding 1 magic number, we find 3! This basically just saves bytes by avoiding putting the string literals for "sin", "cos", and "tan" multiple times, instead building the answer one part at a time.
The first magic number is used to determine whether it's one of the "arc" trigonometric functions, prepending an "a" accordingly, the second for whether it's one of the "sin", "cos", or "tan" based functions, selecting the appropriate string, and the third for whether it's one of the hyperbolic functions, appending a "h" accordingly.
Like orlp's answer, it uses the functions from Python's built-in cmath module as input.
Saved 5 bytes by using slice indexing into the middle string
Finding the Magic Numbers
For completeness, here's (more or less) the script I used to find these magic numbers. I mostly just worked straight in a python terminal, so the code is messy, but it gets the job done.
import cmath
fns = [(fn, getattr(cmath, fn)) for fn in ["sin","cos","tan","asin","acos","atan","sinh","cosh","tanh","asinh","acosh","atanh"]]

count_length = lambda num, modulus, base_modulus : len(str(num).rstrip('0').lstrip('0')) + (1 + len(str(modulus)) if modulus != base_modulus else 0)

min_length = float("inf")
min_choice = None
for modulus in range(2,10):
   for i in range(1,100000):
      num = i/100000.
      is_valid = True
      for fn in fns:
         val = hash(fn[1](num))%modulus%2
         if (val == 0 and fn[0][0]=="a") or (val == 1 and fn[0][0]!="a"):
            is_valid = False
      if is_valid:
         length = count_length(num, modulus, 2)
         if length < min_length:
            min_length = length
            min_choice = (modulus,num)
print(min_choice)

min_length = float("inf")
min_choice = None
for modulus in range(3,10):
   for i in range(100000):
      num = i/100000.
      mapping = {}
      is_valid = True
      for fn in fns:
         fn_type = "sin" if "sin" in fn[0] else "cos" if "cos" in fn[0] else "tan"
         val = hash(fn[1](num))%modulus%3
         if val in mapping and mapping[val] != fn_type:
            is_valid = False
            break
         mapping[val] = fn_type
      if is_valid:
         length = count_length(num, modulus, 3)
         if length < min_length:
            min_length = length
            min_choice = (modulus, num, mapping)
print(min_choice)

min_length = float("inf")
min_choice = None
for modulus in range(2,10):
   for i in range(1,100000):
      num = i/100000.
      is_valid = True
      for fn in fns:
         val = hash(fn[1](num))%modulus%2
         if (val == 0 and fn[0][-1]=="a") or (val == 1 and fn[0][-1]!="a"):
            is_valid = False
      if is_valid:
         length = count_length(num, modulus, 2)
         if length < min_length:
            min_length = length
            min_choice = (modulus,num)
print(min_choice)

Great second answer! Would you mind sharing the program you used to find the magic numbers?

Thanks! I just added code to find the magic numbers to the answer, although it isn't terribly pretty.

Python, 108 94 90 bytes
Compares the result of the input function to the results of all of the functions for the value .2.
from cmath import*
lambda f:[w for w in globals()if w[-1]in'shn'and eval(w)(.2)==f(.2)][0]

Try it online
-14 bytes by Jonathan Allen
-4 bytes by Rod

No need for re, just get the ones needed with slicing: lambda f,d=dir(cmath):[s for s in d[4:12]+d[22:]if eval("cmath."+s)(.2)==f(.2)][0] (rewritten to work on TIO as the import must happen before d=dir(cmath) yet F= must be in the header to not be counted).

...or better yet lambda f:[s for s in dir(cmath)if s[-1]in'shn'and eval("cmath."+s)(.2)==f(.2)][0]

Dyalog APL, 25 21 19 bytes
(8-(2○⍨8-⍳15)⍳⎕2)∘○

Try it online!
-3 thanks to H.PWiz
-2 thanks to ngn
Goes trough all the required trig functions (which in APL are 1 2 3 5 6 7 ¯1 ¯2 ¯3 ¯5 ¯6 ¯7○2) plus some more things (this goes trough -7..7), finds which one matches input○2, and outputs that "with" ○, which outputs as num∘○

JavaScript, 76 67 66 bytes
Not pretty but I went far too far down the rabbit hole with this over a few beers to not post it. Derived independently from Nit's solution.
b=>Object.getOwnPropertyNames(M=Math).find(x=>M[x](.8)+M==b(.8)+M)

Try it online

Saved 6 bytes thanks to Neil
Saved 1 bye thanks to l4m2

b=>Object.getOwnPropertyNames(M=Math).find(x=>M[x](.8)+M==b(.8)+M)? (though I don't quite know why convert to String to compare)

Don't know why I didn't think of that. Thanks, @l4m2.

@l4m2 We need NaN to compare equal to NaN, so it's either that or Object.is.

C (gcc) with -lm, 374 346 324 310 bytes
Thanks to Giacomo Garabello and ceilingcat for the suggestions.
I was able to save a bit more space by having a helper macro do token-pasting in addition to my original macro which does stringizing.
In the tests, I used a couple of non-library trig functions to confirm the validity of the results. As the results between the library and non-library functions weren't exactly the same floating-point value, I compared the difference of the results against a small value ε instead of using equality.
#import<math.h>
#define q(f)f,#f,
#define _(f,g)q(f##sin##g)q(f##cos##g)q(f##tan##g)
#define p for(i=0;i<24;i+=2)!j[i]
typedef double(*z)(double);*y[]={_(,)_(a,)_(,h)_(a,h)};i,x;*f(z g){int j[24]={x=0};char*c;for(double w;x++<9;)p&isnan(w=((z)y[i])(x))-isnan(g(x))|fabs(w-g(x))>1E-9?j[i]=1:0;p?c=y[i+1]:0;g=c;}

Try it online!

I managed to remove 14 bytes. In the TIO you can find the details. Try it online!

+1 from me, but I did find a sub 200 solution using a different strategy :)

Perl 6, 39 bytes
{i.^methods.first({try $^a.(i)==.(i)})}

Try it online!
By the looks of things, one of the few to use introspection. i here is the complex number, whose value is unique for each trig function, so by iterating through all the methods we can find the matching method and implicitly spit out its name. The try is needed as some (unwanted) methods have the a different signature.

JavaScript, 108 70 bytes
I haven't tried golfing in pure Javascript in ages, so I'm sure there's stuff to improve here.
t=>Object.getOwnPropertyNames(m=Math).find(f=>m[f](.9,0)+''==t(.9)+'')

Pretty straightforward, checks every function on the Math prototype against an arbitrary value (0.9, many other values probably work) and compares with the result of the black box function.
Tested in Google Chrome, will break if the input black box function is not one of the trigs.
Cut off a ton of bytes thanks to Shaggy and Neil.

const answer = t=>Object.getOwnPropertyNames(m=Math).find(f=>m[f](.9,0)+''==t(.9)+'');
const tests = [Math.sin, Math.cos, Math.tan, Math.asin, Math.acos, Math.atan, Math.sinh, Math.cosh, Math.tanh, Math.asinh, Math.acosh, Math.atanh];

tests.forEach(test => console.log(test + ' yields ' + answer(test)));

Very similar to the solution I was working on over a few beers but couldn't quite figure out. 2 quick savings I can spot: 0.3 -> .3 and assign Math to m within getOwnPropertyNames().

I managed to get this down to 71 bytes: t=>Object.getOwnPropertyNames(m=Math).find(f=>m[f](.9,0)+''==t(.9)+'');. I noticed @Shaggy used find as well. The +'' does a string compare, meaning we only have to check one point. The ,0 makes us skip Math.atan2.

@Neil, it doesn't looks like the ,0  is needed: https://tio.run/##Lc6xDoMgEMbxvU/RMEFq2TvgG1jdjYknomLkzghp7dPTqEz/@5LfcDN8wOvNruGJ1Js4qNipvOxmo4McTSi/WG20mi383uCM54UqIExCDhZ7vqu8qPeGy5d4MKZUly4RNaGnxciFRl4z0ORZdmY66i2mnDMAphzzsoleMsHLnay5SQcrdyof@PFQ7Roh5EwW2@zeivgH

@Shaggy I guess it's implementation-dependent; in Firefox, atan2 precedes acosh in the array returned by Object.getOwnPropertyNames.

If anyone was wondering, this solution works because the first non-function from getOwnPropertyNames is Math.E, and all trig functions enumerate before that.

@MattH Yeah, I had a check for the type at first, but then I realized I didn't need it.

Don't meet something like E?

@l4m2 Nope, see MattH's comment.

Wolfram Language (Mathematica), 86 bytes
#&@@Nearest[a=Join[a={Sin,Cos,Tan,Sinh,Cosh,Tanh},InverseFunction/@a];#@2&/@a->a,#@2]&

Try it online!

Ruby, 71 67 bytes
->g{Math.methods.find{|h|g[0.5]==Math.send(h,0.5)rescue p}||:acosh}

Try it online!

R, 73 bytes
function(b)Find(function(x)get(x)(1i)==b(1i),apropos('(sin|cos|tan)h?$'))

Try it online!
For the moment (R v3.5) it works.
If in a future R version it will be added a function matching this regex, then who knows :P

-4 bytes thanks to @Giuseppe
-9 bytes thanks to @JayCe
-2 bytes using Find instead of for

wow. Very nice! I think 1i works as well as -1i for -2 bytes.

@Giuseppe: I was sure I had tested it and it wasn't working... but probably it was only my imagination :D

very Nice! Works on TIO, depends on your config probably in the general case: tio

@JayCe: getting the environment through position is risky...for example it doesn't work in RStudio...fortunately I found another function searching for the objects everywhere, with the same bytecount :)

finally...GET is shorter (77)

@JayCe : save 2 more bytes ! :D

Sweet! I have never used Find...

73 bytes by tweaking your regex.

@Giuseppe: thanks! P.S. long time no see... I've been really busy this year and I couldn't golf anymore... how are you?

Not too bad. Crazy year for all of us, I think. Shame you missed R as the language of the month!

@Giuseppe: yeah, crazy year for sure... oh, R finally succeeded in being language of the month! You and the others golfeRs surely did a good job!

HP 49G RPL, 88.0 bytes excluding 10 byte program header
Another solution using complex numbers! Enter and execute it in COMPLEX, APPROX mode. Takes the function on the stack.
2. SWAP EVAL { SIN COS TAN ASIN ACOS ATAN SINH COSH TANH ASINH ACOSH ATANH }
DUP 1. << 2. SWAP EVAL >> DOLIST ROT - ABS 0. POS GET

(the newlines don't matter)
For the constant 2.0, all twelve trig functions are defined in the complex plane, so we just evaluate all twelve and see which one matches. This time, the iterative solution is longer (111.5 bytes) because of the stack shuffling needed to get it. RPL, as far as I know, doesn't let you break out of a loop early.

In case they are returned as upper-case, that's fine now as I edited the challenge.

@JungHwanMin They are upper-case. Thanks for the catch! It can be modified to lower-case with ->STR DUP SIZE 3 - "    " "   " IFTE XOR, 34.5 bytes. (those are supposed to be 4 and 3 spaces, respectively)

JavaScript (Node.js), 72 bytes
f=>eval('for(s=i=0;!s||s(.8)+s!=f(.8)+s;i++)s=Math[t=i.toString(30)];t')

Try it online!