text:
Ordering a list
Summary
Given a list of integers, return the index each integer would end up at when sorted.
For example, if the list was [0,8,-1,5,8], you should return [1,3,0,2,4].  Note that the two 8s maintain their order relative to each other (the sort is stable).
Put another way:  For each element in the list, return the number of elements in the list that are: Smaller than the chosen element OR (equal to the element AND appears before the chosen element)
Indexes must start with 0 (not 1)EDIT: given the large pushback, I'll allow 1-based indicies.
Test cases:
0                -> 0
23               -> 0
2,3              -> 0,1
3,2              -> 1,0
2,2              -> 0,1
8,10,4,-1,-1,8   -> 3,5,2,0,1,4
0,1,2,3,4,5,6,7  -> 0,1,2,3,4,5,6,7
7,6,5,4,3,2,1,0  -> 7,6,5,4,3,2,1,0
4,4,0,1,1,2,0,1  -> 6,7,0,2,3,5,1,4
1,1,1,1,1,1,1,1  -> 0,1,2,3,4,5,6,7
1,1,1,1,1,1,1,0  -> 1,2,3,4,5,6,7,0

Despite the simpleness of this challenge, I couldn't find a duplicate of this challenge.

This is a specialisation of this question where instead of taking two arrays it takes one array and the second one is [0 1 ... n-1].

@PeterTaylor: In that challenge, the array has no repeats.

Note to solvers: that 8,10,4,-1,-1 test case is very deceptive. Try the 4,4,0,1,1,2,0,1 one first.

@Lynn I looked up what "grade up" does, and I figured out why that test case is so deceptive.  Fixed.

Related: Get the indices of an array after sorting

APL, 2 bytes
⍋⍋

The “grade up” built-in, applied twice. Works if indexing starts at 0, which isn’t the default for all flavors of APL. Try it here!
Why does this work?
⍋x returns a list of indices that would stably sort x. For example:
    x ← 4 4 0 1 1 2 0 1
    ⍋x
2 6 3 4 7 5 0 1

because if you take element 2, then 6, then 3… you get a stably sorted list:
    x[⍋x]
0 0 1 1 1 2 4 4

But the index list that answers this question is subtly different: first we want the index of the smallest element, then the second smallest, etc. — again, keeping the original order.
If we look at ⍋x, though, we see it can give us this list easily: the position of a 0 in ⍋x tells us where the smallest element would end up after sorting, and the position of a 1 in ⍋x tells us where the second smallest element would end up, etc.
But we know ⍋x contains exactly the numbers [0, 1… n−1]. If we grade it again, we’ll just get the index of 0 in ⍋x, then the index of 1 in ⍋x, etc., which is precisely what we’re interested in.
So the answer is ⍋⍋x.

wow, this must of been painstakingly golfed :P

ngn-apl only supports UTF-8, but this works in pretty much every flavor provided that the index origin is set to 0.

That makes me wonder: are there any try-it-onlines for classic APL flavors?

There's TryAPL for Dyalog, but IO defaults to 1. It's easily changeable though. permalink

1-based is allowed now.

Jelly, 2 bytes
ỤỤ

Grade up twice. 1-indexed. Try it online!

Two bytes in what encoding scheme?

Ah! In the Jelly code page. I added a link in the header. :)

JavaScript ES6, 87 82 79 74 70 bytes
(a,b={})=>a.map(l=>[...a].sort((a,b)=>a-b).indexOf(l)+(b[l]=b[l]+1|0))

Don't like using an object but it seems to be the shortest way to keep track of dupes
Explanation
(a,b={})=>          `a` is input
                    `b` stores the occurrences of each number
  a.map(l =>        Loop over the array, `l` is item
  [...a]            Copy `a`
    .sort(...)       Sort in ascending numerical order
    .indexOf(l)      Index of input in that array
  +                 Add the following to account for dupes
   (b[l]=            set and return the item `l` in hashmap `b` to...
     b[l]+1           Increase the counter by one if it exists yet
     |0               default is zero
   )

61 bytes

K, 5 2 bytes
<<

Grade up (<) twice. JohnE saved three bytes by pointing out tacit expressions exist in K! Super cool. Try it out.

The lambda wrapper is not strictly necessary- you can just write this as a tacit expression <<. Try it here.

Haskell, 50 48 bytes
import Data.List
m x=map snd$sort$zip x[0..]
m.m

Usage example: m.m $ [4,4,0,1,1,2,0,1]-> [6,7,0,2,3,5,1,4].
It's map snd.sort.zip x [0..] applied twice on the input, i.e pair each element e with it's index i ((e,i)), sort it remove the first elements.
Repeat one time.
@Lynn came up with m=map snd.sort.(`zip`[0..]) which has the same byte count.

Python 2, 67 60 bytes
def f(x):x=zip(x,range(len(x)));print map(sorted(x).index,x)

Thanks to @xnor for golfing off 7 bytes!
Test it on Ideone.

The flipped enumerate can be done shorter with a zip: l=input();x=zip(l,range(len(l))).

In that case, a function is even shorter. Thanks!

MATL, 10 9 4 bytes
4 Bytes saved thanks to @Luis
&S&S

This solution uses 1-based indexing
Try it Online

@DrGreenEggsandIronMan I search meta, and I couldn't find anything indicating either way.  That said, I've reverted the restricition.

CJam, 15 bytes
{{eeWf%$1f=}2*}

Try it online!
Explanation
{             }       Delimits an anonymous block.
 {         }2*        Run this block on the argument twice:
  ee                  Enumerate ([A B C] → [[0 A] [1 B] [2 C]])
    Wf%               Reverse each ([[A 0] [B 1] [C 2]])
       $              Sort the pairs lexicographically;
                        i.e. first by value, then by index.
        1f=           Keep the indices.

Python 2, 67 bytes
a=input()
p=[]
for x in a:print sorted(a).index(x)+p.count(x);p+=x,

xnor saved two bytes.

It's shorter to recreate the list of previously-seen elements as you go: a=input();p=[]\nfor x in a:print sorted(a).index(x)+p.count(x);p+=x,

Ah, I like that! Thank you.

PowerShell v2+, 63 bytes
param($n)$n|%{($n|sort).IndexOf($_)+($n[0..$i++]-eq$_).count-1}

Takes input $n, pipes that through a loop over every element |%{...}. Each iteration, we sort $n and get the IndexOf our current element $_. This counts how many items are smaller than the current element. We add to that a slice of $n, that expands every loop iteration, of the elements that are equal to the current element $_ and take the .Count of that. We then subtract -1 so we don't count our current element, and that number is left on the pipeline. Output at the end is implicit.
Examples
PS C:\Tools\Scripts\golfing> .\ordering-a-list.ps1 @(4,4,0,1,1,2,0,1)
6
7
0
2
3
5
1
4

PS C:\Tools\Scripts\golfing> .\ordering-a-list.ps1 @(8,10,4,-1,-1)
3
4
2
0
1

J, 5 bytes
/:^:2

Grade up (/:) twice (^:2). 0-indexed.
To try it out, type f =: /:^:2 and then f 4 4 0 1 1 2 0 1 into tryj.tk.

Or /:@/: with an equal byte-count.

05AB1E, 12 bytes
2FvyN‚}){€¦˜

Explained
2F            # 2 times do
  vyN‚})      # create list of [n, index]-pairs
        {€¦   # sort and remove first element leaving the index
           ˜  # deep flatten
              # implicit output

Try it online

Haskell, 40 bytes
f l|z<-zip l[0..]=[sum[1|y<-z,y<x]|x<-z]

Annotate each element with its index, then map each element to the count of smaller elements, tiebreaking on index. No sorting.

Pyth, 10 9 bytes
1 byte thanks to Jakube.
xLo@QNUQU

Test suite.
There must be a shorter way...

xL instead of sxR. Or am I overlooking something?

Julia, 17 bytes
~=sortperm;!x=~~x

1-indexed. Grade up (sortperm) twice. Try it here.
EDIT: Dennis saved four bytes by giving stuff operator-y names! Julia is weird.

JavaScript (ES6), 52 bytes
a=>(g=a=>[...a.keys()].sort((n,m)=>a[n]-a[m]))(g(a))

Defines g as the grade function, which returns an array of indices to which all the elements in the sorted array would have come from in the original array. Unfortunately what we want is the indices which all the elements will go to. Fortunately this turns out to be the mapping from the grade back to the original list of indices, which itself can be considered to be the result of sorting the grade, thus allowing us to take the grade of the grade to achieve the desired result.

Racket, 117 bytes
(λ(x)(build-list(length x)(λ(h)((λ(y)(+(count(λ(z)(< z y))x)(count(λ(z)(eq? z y))(take x h))))(list-ref x h)))))

I am eternally disappointed by the lack of a builtin for this.

Would it be shorter to put each element in a (number, index) pair, then sort it?

I tried that, but it gives me the inverse of the list that I'd want, and unfortunately getting the index of an object within the list in order to invert it is horribly byte-inefficient.

Ruby, 54 53 bytes
Try it online
-1 byte from upgrading to @Downgoat's approach of using a hash to store values instead of counting the duplicates each time.
->a{b={};a.map{|e|a.sort.index(e)+b[e]=(b[e]||-1)+1}}

Ruby's sort is unstable, which means that this might do the wrong thing on ties.

@NathaMerrill It doesn't because of the exact method I am using to generate the numbers. If I sorted on a list of indices, it would produce the wrong result. Try the link! It'll work 60% of the time, every time. I'll post an explanation later on it, too.

Ah, ok.  I wasn't sure what the rest of the code is doing (I don't know Ruby)

? It doesn't do the wrong thing on ties, but it does something else wrong 40% of the time?

@WGroleau it's an Anchorman quote. My code works all the time, though.

Clojure, 83 bytes
(fn[a](nth(iterate #(->> %(map-indexed(comp vec rseq vector))sort(map second))a)2))

I create an anonymous function that grades the input array up and iterate it twice on the input. The first call will return the grade. The second call operates on the grade and returns the rank.

Brachylog, 27 bytes
lL-M,?og:MjO,L~l.#d:Orz:ma?

Try it online! or verify all test cases.
Explanation
This is a straightforward implementation of the following relationship: each integer of the output corresponding to an element of the input is the index of that element in the sorted input.
Example input: [3:2]

lL               L is the length of the input (e.g L=2)
  -M,            M = L-1 (e.g. M=1)
?o               Sort the input...
  g:MjO,         ... and create a list O with L copies of the input (e.g. O=[[2:3]:[2:3]])
L~l.             Output is a list of length L (e.g. [I:J])
    #d           All elements of the output must be distinct (e.g. I≠J)
      :Orz       Zip O with the output (e.g. [[[2:3]:I]:[[2:3]:J]])
          :ma?   Apply predicate Member with that zip as input and the input as output
                 (e.g. 3 is the Ith element of [2:3] and 2 is the Jth element of [2:3])

Mathematica, 15 bytes
(o=Ordering)@*o

Mathematica, 135 bytes
Function[{list}, SortBy[MapIndexed[Join[{#1}, #2]&, Sort@MapIndexed[Join[{#1}, #2] &, list]], #[[1, 2]] &][[All, 2]] - 1]

Common Lisp, 117 bytes
(flet((i(Z)(mapcar'cdr(stable-sort(loop for e in Z for x from 0 collect(cons e x))'< :key'car))))(lambda(L)(i(i L))))

Apply a Schwartzian transform twice.
;; FIRST TIME

(0 8 -1 5 8)
;; add indexes
((0 . 0) (8 . 1) (-1 . 2) (5 . 3) (8 . 4))
;; sort by first element
((-1 . 2) (0 . 0) (5 . 3) (8 . 1) (8 . 4))
;; extract second elements
(2 0 3 1 4)

;; SECOND TIME

(2 0 3 1 4)
;; indexes
((2 . 0) (0 . 1) (3 . 2) (1 . 3) (4 . 4))
;; sort by first element
((0 . 1) (1 . 3) (2 . 0) (3 . 2) (4 . 4))
;; extract second elements
(1 3 0 2 4)

Test
(let ((fn (flet((i(Z)(mapcar'cdr(stable-sort(loop for e in Z for x from 0 collect(cons e x))'< :key'car))))(lambda(L)(i(i L))))))
  (every
   (lambda (test expected)
     (equal (funcall fn test) expected))

   '((0) (23) (2 3) (3 2) (2 2) (8 10 4 -1 -1 8) (0 1 2 3 4 5 6 7)
     (7 6 5 4 3 2 1 0) (4 4 0 1 1 2 0 1) (1 1 1 1 1 1 1 1) (1 1 1 1 1 1 1 0))

   '((0) (0) (0 1) (1 0) (0 1) (3 5 2 0 1 4) (0 1 2 3 4 5 6 7) (7 6 5 4 3 2 1 0)
     (6 7 0 2 3 5 1 4) (0 1 2 3 4 5 6 7) (1 2 3 4 5 6 7 0))))
=> T

GNU Core Utils, 39 33 bytes
nl|sort -nk2|nl|sort -nk2|cut -f1

Produces 1-based output.  Add -v0 after the second nl to get 0-based output.  (+4 bytes)
Commands we are using:

nl adds line numbers to each line of the input.
sort -n -k 2 sorts by column 2 numerically.
cut -f 1 takes the first Tab-delimited column, discarding the rest.

Additionally, the -s option can be passed to sort to request a stable sort, but we don't need it here.  If two items are identical, sort will determine their order by falling back to the other columns, which in this case is the monotonically increasing output from nl.  So the sort will be stable without needing to specify it, by virtue of the input.

JavaScript (using external library) (105 bytes)
(n)=>{var a=_.From(n).Select((v,i)=>v+""+i);return a.Select(x=>a.OrderBy(y=>(y|0)).IndexOf(x)).ToArray()}

Link to lib: https://github.com/mvegh1/Enumerable
Explanation of code: Create anonymous method that accepts a list of integers. _.From creates an instance of the library that wraps an array with special methods. Select maps each item to a new item, by taking the "v"alue, parsing it to a string, then concatenating the "i"ndex of that item (this solves duplicate value case). Thats stored in variable 'a'. Then we return the result of the following: Map each item in 'a' to the index of that item in the sorted version of a (as integers), and cast back to a native JS array

Note that negative duplicate numbers seem to print in the reverse order. I'm not sure if that invalidates this solution? Technically 8,10,4,-1,-1,8 should be 3,5,2,0,1,4 according to OP but my code is printing 3,5,2,1,0,4 which I believe is still technically valid?

Java 149 140 bytes
public int[] indexArray(int[] index){
  int[] out=new int[index.length];
  for(int i=-1;++i<index.length;){
    for(int j=-1;++i<index.length;){
      if(index[i]==Arrays.sort(index.clone())[j]){
        out[i]=j;
      }
    }
  }
  return out;
}

Golfed
int[]a(int[]b){int l=b.length;int[]o=new int[l];for(int i=-1;++i<l;)for(int j=-1;++i<l;)if(b[i]==Arrays.sort(b.clone())[j])o[i]=j;return o;}

Thanks to @Kevin Cruissjen for shaving of 9 bytes.

@Nathan Merrill I noticed that when i golfed it, but forgot it when i pasted the golfed answer in.

You can golf it some more. You don't need the spaces between int[] a and int[] b. You can take the int out of the loops. And since you use b.length twice at the start you can put it in a separate field. So in total something like this: int[]a(int[]b){int l=b.length,o[]=new int[l],i,j;for(i=-1;++i<l;)for(j=-1;++i<b.length;)if(b[i]==Arrays.sort(b.clone())[j])o[i]=j;return o;} (140 bytes) Hmm, also, it doesn't seem to work.. Arrays.sort(...) doesn't return anything (it's a void method), so how can you compare it with b[i]?..

PHP, 88 bytes
unset($argv[0]);$a=$argv;sort($a);foreach($argv as$e)echo$h[$e]+++array_search($e,$a),_;

operates on command line arguments; prints 0-indexed, underscore-separated list.
Run with -nr.
breakdown
unset($argv[0]);        // remove file name from arguments
$a=$argv;               // create copy
sort($a);               // sort copy (includes reindexing, starting with 0)
foreach($argv as$e)     // loop $e through original
    echo                    // print:
        $h[$e]++            // number of previous occurences
        +array_search($e,$a)// plus position in copy
        ,_                  // followed by underscore
    ;

MATLAB, 29 bytes
function j=f(s);[~,j]=sort(s)

Most of MATLAB's sorting built-ins will return an optional second array containing the sorted indices. The j= could be removed if printing the indices is acceptable, rather than returning them.

CJam, 19 bytes
_$:A;{A#_AWt:A;1+}%

Try it online!
Explanation:
_ duplicate array
 $ sort array
  :A store in variable A
    ; discard top item in stack
     {A#_AWt:A;1+} block that finds index of item and removes it from sorted array to prevent duplicates
      % map block onto every item in array


text:
Calculate the Super-Logarithm
This should be a simple challenge.
Given a number \$n \ge 0\$, output the super-logarithm (or the \$\log^*\$, log-star, or iterated logarithm, which are equivalent since \$n\$ is never negative for this challenge.) of \$n\$.
$$\log^*(n) = \begin{cases}
0  & \text{ if } n \le 1 \\
1 + \log^*(\log(n)) & \text{ if } n > 1
\end{cases}$$
This is one of the two inverse functions to tetration. The other is the super-root, which is in a related question.
Examples
Input       Output
0           0
1           0
2           1
3           2
4           2
...
15          2
16          3
...
3814279     3
3814280     4

Rules

You do not need to support decimals, though you may.
You need to support input of at least \$3814280 =  \left\lceil e^{e^e} \right\rceil\$.
You may not hard-code the values like 3814280. (Your program must theoretically support higher numbers.) I want an algorithm to be implemented.
Shortest code wins.

Related OEIS

Related.

Jelly, 8 bytes
ÆlÐĿĊḊi1

Try it online! or verify all test cases.
Background
We start by successively taking natural logarithms of the input and the subsequent results until the result no longer changes. This works because the extension of the natural logarithm to the complex plane has a fixed point; if z = e-W(-1) ≈ 0.318 + 1.337i – where W denotes the Lambert W function – we have log(z) = z.
For input n, after computing [n, log(n), log(log(n)), …, z], we first apply the ceiling function to each of the results. Jelly's implementation (Ċ) actually computes the imaginary part of complex number instead†, but we're not interested in these anyway.
Once the kth application of log yields a value less than or equal to 1, Ċ will return 1 for the first time. The 0-based index of that first 1 is the desired result.
The straightforward implementation (compute 1-based index, decrement) fails because of edge case 0, which does not have a 1 in its list of logarithms. In fact, for input 0, the sequence of logarithms is
[0, None]

This is because Jelly's logarithm (Æl) is overloaded; it first tries math.log (real logarithm), then cmath.log (complex logarithm), and finally "gives up" and returns None. Fortunately, Ċ is similarly overloaded and simply returns it argument if it cannot round up or take an imaginary part.
Likewise, input 1 returns
[1, 0, None]

which may create problems in other approaches that do or do not involve Ċ.
One way to fix this problem is apply Ḋ (dequeue; removes first element) to the array of logarithms. This maps
0ÆlÐĿ -> [0, None]    -> [None]
1ÆlÐĿ -> [1, 0, None] -> [0, None]

so neither list has a 1 now. This way, finding the index of the first 1 will return 0 (not found), which is the desired output for inputs 0 and 1.
How it works
ÆlÐĿĊḊi1  Main link. Argument: n (non-negative integer)

  ÐĿ      Apply the following link until the results are no longer unique.
Æl          Natural logarithm.
          Return the array of all unique results.
    Ċ     Round all resulting real numbers up to the nearest integer. This takes
          the imaginary part of complex numbers and does nothing for non-numbers.
     Ḋ    Dequeue; remove the first item (n) of the array of results.
      i1  Find the first index of 1 (0 if not found).

† This is one of the only three atoms in Jelly that are overloaded in a non-obvious manner.

Jelly, 9 bytes
Æl>1$Ð¿L’

Try it online!
Test suite. (Slightly modified.)
Explanation
Æl>1$Ð¿L’
     Ð¿    while loop, collect all intermediate results.
  >1$      condition: z>1
Æl         body: natural logarithm.
       L   length of the array containing all intermediate results,
           meaning number of iterations
        ’  minus one.

Javascript, 45 27 26 bytes
l=a=>a>1&&1+l(Math.log(a))

Here is test suite (3rd rev)
Thanks @LeakyNun for saving 1 byte with conditional and then converting function to lambda, and @Neil for pointing out false is ok return value for <=1 (changed test to be == instead of ===)

I was doing it without es6, but yeah that would be 1 byte shorter, thanks.

Why would you not use lambda?

no good reason, i just haven't used it that much, so it's not my first instinct

Apparently we're allowed to return false instead of 0 (as it auto-converts to 0 in an integer expression) in which case you can drop the |0.

That would save 1 byte, but what do you mean by "it auto-converts to 0"? What is "it"?

@CShark false is stored as zero behind the scenes.

Ok if returning false instead of 0 is fine, then sweet (type doesn't matter).

C, 38 bytes
f(double n){return n>1?1+f(log(n)):0;}

Pretty self-explanatory.
Try it on ideone.

Mathematica, 21 bytes
If[#>1,1+#0@Log@#,0]&

Recursive anonymous function. Takes an integer as input and returns its super-logarithm as output. Just uses the given definition.

I actually looked ahead of time to see if there was a built-in. I was surprised when there wasn't. :D

Pyth, 10 bytes
L&>b1hy.lb

Test suite.
This defines a function.

I don't see any output in your test suite. Just a bunch of empty lines in the output.

@mbomb007 Fixed.

Way cooler: tl.u?>N1.l ;-)

@Jakube You could post that!

Dyalog APL, 13 bytes
Direct translation of OP:
{⍵≤1:0⋄1+∇⍟⍵}

TryAPL online!

Haskell, 23 bytes
l x|x>1=1+l(log x)|1<2=0

Usage example: l 3814280 -> 4.

05AB1E, 16 13 bytes
[Dî2‹#¼žr.n]¾

Explanation
              # implicit input n
[          ]  # infinite loop
 Dî2‹#        # break if n rounded up is less than 2
      ¼       # else, increase counter
       žr.n   # set next n = log(n)
            ¾ # push counter and implicitly print

Try it online

J, 21 19 18 16 bytes
Saved 2 bytes to Leaky Nun, 1 byte to Galen Ivanov, and 2 bytes to FrownyFrog!
2#@}.(0>.^.)^:a:

Try it online!
Test cases
ls =: >:@$:@^.`0:@.(<:&1)
   ls 0
0
   ls 1
0
   ls 2
1
   ls 3
2
   ls 4
2
   ls 15
2
   ls 16
3
   ls 3814280
4

Here's my 18 bytes solution:
2#@}.^.^:(0<])^:a:
(I started sovling what turned out to be a dup of this problem.)

2#@}.(0>.^.)^:a: seems to work.

Not sure if it’s equivalent though.

Python 3, 45 bytes
import math
s=lambda x:x>1and-~s(math.log(x))

For x <= 1, this returns False (which is == 0 in Python).

Yes, False can be used for 0.

Also, you beat my naive implementation (by using and rather than if else). Grats.

MATL, 15 12 bytes
0`ZetG>~}x@q

Try it online! Or verify all test cases (slightly modified version to handle several inputs).
How it works
Starting with 0, apply iterated exponentiation until exceeding the input. The output is the number of iterations minus 1.
0       % Push 0
`       % Do...while loop
  Ze    %   Exponential
  t     %   Duplicate
  G     %   Push input
  >~    %   Is current value less than or equal to the input? If so: next iteration
}       % Finally (code executed at the end of the last iteration)
  x     %   Delete
  @q    %   Iteration index minus 1
        % Implicitly end loop
        % Implicitly display stack

Julia, 17 bytes
!x=x>1&&1+!log(x)

Try it online!

Java 7, 47 bytes
int c(double n){return n>1?1+c(Math.log(n)):0;}

Try it online.
The recursive Java 7 style method above is 2 bytes shorter than an iterative Java 8 style lambda:
n->{int c=0;for(;n>1;c++)n=Math.log(n);return c;}

Try it online.
Explanation:
int c(double n){      // Method with double parameter and integer return-type
  return n>1?         //  If the input is larger than 1:
    1+                //   Return 1 +
      c(Math.log(n))  //   A recursive call with log(input)
   :                  //  Else:
    0;                //   Return 0 instead

n->{                  // Method with double parameter and integer return-type
  int c=0;            //  Create a counter, starting at 0
  for(;n>1;           //  Loop as long as the input is still larger than 1:
    c++)              //   Increase the counter by 1
    n=Math.log(n);    //   And update the input to log(input)
  return c;}          //  After the loop: return the counter as result

You might get it shorter with a Java 8 lambda.

@mbomb007 responding three years later, haha.. (at the time I was only code-golfing in Java 7), but to still answer your question: no, unfortunately a Java 8 lambda is 2 bytes longer than the recursive method. I've added it to my answer, and I've also added an explanation.

So you can't do recursive lambdas?

@mbomb007 No, in Java unfortunately not. In Python, JavaScript, and I think C# .NET as well, recursive lambdas are possible, but in Java not for some reason..

Jelly, 8 bytes
-Ælß$Ị?‘

Straightforward implementation of the definition. Try it online! or verify all test cases.
How it works
-Ælß$Ị?‘  Main link. Argument: x

     Ị    Insignificant; test if |x| ≤ 1.
      ?   If the result is 1:
-           Return -1.
          Else:
   $        Execute the monadic chain formed by the two links to the left.
Æl            Apply natural logarithm to x.
  ß           Recursively call the main link.
       ‘  Increment the result.

R, 38 37 bytes
f=function(x)if(x>1)1+f(log(x))else 0

Thanks @user5957401 for the extra byte!
Test cases:
> f(0)
[1] 0
> f(1)
[1] 0
> f(2)
[1] 1
> f(3)
[1] 2
> f(4)
[1] 2
> f(3814279)
[1] 3
> f(3814280)
[1] 4

I think you can save a byte by using a literal if, else statement.
i.e. if(x>1)1+f(log(x))else 0 is one byte shorter.

Mathematica, 29 bytes
Simple as all hell, and works for comically large as well as negative inputs:
f[x_]:=If[x>1,1+f[Log[x]],0]

MATLAB / Octave, 44 bytes
function a=g(n);a=0;if n>1;a=1+g(log(n));end
Tried to do it all as one anonymous function, but I forgot that MATLAB/Octave continues to evaluate expressions even if they are multiplied by a boolean false (zero) value:
f=@(n)(n>1)*(1+f(log(n)))

Yes, it would be nice to have a short-circuiting product :-)

R, 34 bytes
f=pryr::f(`if`(n>1,1+f(log(n)),0))

Try it online!
A non-recursive approach is possible: 36 bytes and takes input from stdin.
n=scan()
while((n=log(n))>0)F=F+1
+F

Emacs Lisp, 38 bytes
(defun l(n)(if(> n 1)(1+(l(log n)))0))

Testcases:
(mapcar 'l '(0 1 2 3 4 15 16 3814279 3814280))
;; (0 0 1 2 2 2 3 3 4)

Perl 5, 35 bytes
Very simple, requires -M5.016 (which is free) to enable the __SUB__ keyword for anonymous recursion.
sub{$_[0]>1?1+__SUB__->(log pop):0}

Another alternative is
sub{$_[0]>1?1+__SUB__->(log pop):0}

which is 34 bytes, and gives the same output for all inputs > 1, but returns the special false value for inputs <= 1. False is numerically equal to zero, but prints as "" (empty string), so it probably doesn't qualify.

Great answer. You can win 1 byte by doing sub{($_=pop)>1?1+__SUB__->(log):0} though

CJam (16 bytes)
rd{_1>}{_ml}w],(

Online demo
Simple while loop with pre-condition. (What I really want here is a Golfscript-style unfold operation, but CJam doesn't have one, and floating point in GolfScript is messy and not at all golfy).

As an aside, this is my 80th answer in [tag:math] and earned me my second tag badge today.

PARI/GP, 24 bytes
Just the straightforward recursion.
f(n)=if(n>1,1+f(log(n)))

Racket, 61 bytes
(λ(x)(letrec([a(λ(b)(if(> b 1)(+ 1 (a(log b)))0))])(a x)))

Maple, 32,30 29 bytes
f:=x->`if`(x>1,1+f(log(x)),0)

Test cases:
> f(0.);
  0
> f(1.);
  0
> f(2.);
  1
> f(3.);
  2
> f(4.);
  2
> f(3814279.);
  3
> f(3814280.);
  4

R, 36 bytes
Slightly different approach from Plannapus
->n;a=0;while(n>1){a=a+1;n=log(n)};a

Uses a right assign to run the code -- so the desired number must precede it. i.e.
10->n;a=0;while(n>1){a=a+1;n=log(n)};a

Whispers v3, 9 bytes
>> ln*(L)

Try it online!
Note that I had to push a bug fix in order to make this work. The ln* function had already been added before September 1st 2020, but I hadn't noticed a bug in the parsing that was fixed today
This is a function, going by the standards defined here for Whispers functions. It can be called by appending the code in the Footer to the file.
Whispers v3 also has the slog, lg* (uses \$\log_2\$) and log* (uses \$\log_{10}\$) functions

Ruby, 29 bytes
l=->n{n<=1?0:1+l[Math.log n]}

-1 byte by rewriting n<=1?a:b as n>1?b:a and -1 more byte with anonymous lambda functions.

Perl 6, 21 bytes
{($_,*.log...1>=*)-1}

Try it online!
The parenthesized expression is a sequence.  $_, the argument to the function, is the first element.  *.log generates each successive element by taking the log of the previous element.  The sequence continues until the ending condition, 1 >= *, is true: 1 is greater than or equal to the current element.  Subtracting 1 from the sequence coerces it to a number: its length.

source: Stack Exchange

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

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

sort: votes


text:
Guard your can with your life!
Lets Play Kick The Can!
Although Moogie is the current winner, if anyone can take his crown they are encouraged to do so
Kick the can is a children's game. Involving one defender, and multiple attackers. Today it is no longer such a game! Your job is to write a bot that plays it, to win, king-of-the-hill style!
https://en.wikipedia.org/wiki/Kick_the_can
There are some key differences in this game. The first key difference is that the game is multiplayer (5v5). The second key difference is that both sets of bots can kill and eliminate enemy players with both mines and thrown bombs! Bots can not see any mines (regardless of distance) or players at greater than five blocks away!
The map is a maze as follows.

This maze is procedurally generated by first creating a maze using a depth first recursive backtracking algorithm. And then placing the shown holes in (as well as make the maze more "imperfect". The maze is 65x65 blocks wide, and zero indexed. Thus the blue flag (can) is at 1,1 and the red flag (can) is at 63,63. Blue team spawns at 2,2 and 3,3 4,4 etc. red team spawns at 62,62 and 61,61, 60,60 etc. The blocks in cyan are bots on the blue team, and the blocks in magenta are red bots. The game is always five versus five. Each bot on the team will use your code (but may store other instance variables (or create local files) to keep track of state and differentiate roles.

Gameplay
Mines can be placed as you can see in gray. And bombs can be thrown a maximum distance of up to four blocks. These travel for up to four blocks through walls and other players killing only the enemies which stand in your way. After each step they have a 40% chance of falling away. So they have 100% chance of 1 range 60% at 2 range 36% at 3 range and 21.6% at three range Placing a mine or throwing a bomb takes one team ammo. This starts at 0 and can be increased by collecting the orange boxes. Note that four (4) of these ammo caches will be conveniently centered. The Bots are lined up in an array of two red and two blue. I.E RRRRRBBBBB. Gaurding the flag is permitted, but beware that being near the flag(i.e less than five blocks) results in slowness, and only allows movent. every three turns. The Arena picks a random starter for each turn. I.E The order can be RBBBBBRRRRR BBBBBRRRRR BBBRRRRRBB etc..
Objective
Program your five bots (each has the same class file) to successfully navigate the maze and touch the opposing can while being careful not to accidentally knock over ones own can, or step on a mine.
Programming
The arena and bot entries are currently in Java however a stdin/out wrapper exists for other languages.
The arena code will be made available but here is the relevant details.
Bot Class
public class YourUniqueBotName extends Bot{
public YourUniqueBotName(int x , int y, int team){
super(x,y,team);
//optional code
}
public Move move(){//todo implement this method
//it should output  a Move();
//A move has two paramaters
//direction is from 0 - 3 as such
//         3
//       2-I-0
//         1
// a direction of 4 or higher means a no-op (i.e stay still)
//And a MoveType. This movetype can be
//MoveType.Throw
//MoveType.Mine
//MoveType.Defuse defuse any mine present in the direction given
//MoveType.Move
}
}

Key Methods Available
Note that using any techniques to modify or access data you should generally not have access to is not permitted and will result in disqualification.
Arena.getAmmo()[team];//returns the shared ammo cache of your team

Arena.getMap();//returns an integer[] representing the map. Be careful since all enemies more than 5 blocks away (straight line distance) and all mines are replaced with constant for spaces
//constants for each block type are provided such as Bot.space Bot.wall Bot.mine Bot.redTeam Bot.blueTeam Bot.redFlag Bot.blueFlag

Arena.getAliveBots();//returns the number of bots left

getX();//returns a zero indexed x coordinate you may directly look at (but not change X)

getY();//returns a zero indexed y coordinate (y would work to, but do not change y's value)

//Although some state variables are public please do not cheat by accessing modifying these

StdIn/Out wrapper Interface Specification
The interface consists of two modes: initialisation and running.
During initialisation mode, a single INIT frame is sent via stdout. This frame's specification is as follows:
INIT
{Team Membership Id}
{Game Map}
TINI

Where:
{Team Membership Id} is an single character: R or B. B meaning blue team, R meaning red team.
{Game Map} is a series of rows of ascii characters representing one row of the map. The following ascii characters are valid:
    F = blue flag
    G = red flag
    O = open space
    W = wall
The game will then proceed to send game frames over stdout to each bot as so:
FRAME
{Ammo}
{Alive Bot Count}
{Bot X},{Bot Y}
{Local Map}
EMARF

Where:
{Ammo} is a string of digits, value will be 0 or greater
{Alive Bot Count} is a string of digits, value will be 0 or greater
{Box X} is a string of digits representing the X co-ordinate of the bot on the game map. Value will be 0 <= X < Map Width.
{Box Y} is a string of digits representing the Y co-ordinate of the bot on the game map. Value will be 0 <= Y < Map Height.
{Local Map} is a series of rows of ascii characters representing the whole map surrounding the bot. The following ascii characters are valid:
    F = blue flag
    G = red flag
    O = open space
    W = wall
    R = red team bot
    B = blue team bot
    M = mine
    A = ammo
The Controller expects that your bot will then output (to stdout) a single line response in the format:
{Action},{Direction}

Where:
{Action} is one of:
    Move
    Defuse
    Mine
    Throw
{Direction} is a single digit between 0 and 4 inclusive. (see direction information earlier)

NOTE: all strings will be delimited by \n End of Line character.

This will be an elimination tournament. My sample bots will participate as fillers, but I will not award myself the win. In the event of a victory by one of my bots, the title goes to the second place member, and will continue until there is a bot which is not one of mine. Each match consists of 11 rounds of kick the can. If neither team has won a single match by then they both are eliminated. If there is a tie of non-zero score one tie breaker match will be played. If a tie remains both are eliminated. Later rounds may consist of more matches. The seeding of the tournament will be based on the number of upvotes as of 7/31/16 (date subject to change).
Each match lasts 4096 turns. A victory grants one point. A tie or loss grants zero points. Good luck!
Feel free to look at the code or critique it at this GitHub Repo.
https://github.com/rjhunjhunwala/BotCTF/blob/master/src/botctf/Arena.java

Note that I do not have interpreters for too many languages on my computer, and I may need volunteers to run the simulation on their computer. Or I can download the language interpreter. Please ensure that your bots.

Respond in a reasonable amount of time (say 250 ms)
Will not damage my host machine

@Moogie I have decided to release this

In the local map, what does it show for tiles beyond the vision of the bots?

It shows the map. The only thing is that you can not see the bots at a larger distance. Your bots are provided with an actual map of the arena, but they may not where there stealthy opponents are hiding. @justhalf

@Moogie, I was wondering if you could write a python bot for me so i can test the stdin/stdout wrapper

So the map beyond the bots vision will just show as empty space, right?

@justhalf so you can see walls and ammunition beyond your bots vision, but you can not see other bots. The rational being that your bot has an excellent memory and is provided a map before the game.

Yes, by "can not see other bots", in place of other bots, it will be empty space ("O"), right?

@justhalf yes in palce of other bots The arena will show an empty space "O"

@RohanJhunjhunwala I am in the process of making a bot that uses the wrapper. It is java based, however it communicates via the stdin/out wrapper. So far there has been no issues in the controller or the wrapper.

nothing to see, i mis-understood the spec

Ok let me know when you make it, I would love to see a competition between two different bots

@Moogie ^^^^^^^^^^^^^^^ ^

@RohanJhunjhunwala been busy :P work and getting ready to move house. I will try to get it up and running tonight if i get some free time. However i think there is a minor change that may be necessary for the stdin/out wrapper as some information is not available: the current game frame count. If the bot is in the slow area of the map then then a bot's internal frame count will get out of synch with the actual game frame count. I proposed that the interface be updated to include the current game frame so that all bots can be synchronised.

Ok, I can add that if you dwould like. let me know if you wish for me to push it tot the repo. @Moogie

sounds good to me

@RohanJhunjhunwala i have added a bot :) It does expect that the stdin/out interface sends the current frame as the first entry after the "FRAME" constant.

@Moogie how do i run it?

@RohanJhunjhunwala i'll upload a 'moogie' branch to the git repo later, moving house today

@Moogie all right sounds good, good luck with the move!

@RohanJhunjhunwala moogie branch added.

NavPointBot, Java 8

Bot is white/blue
This bot nominates a leader from friendly bots each frame that will then assign nav points for each bot to navigate to.
Initally, all bots are on ammo depot finding duty, then two bots are assigned as guards with the remainder looking for ammo and then attacking the enemy flag.
I have found that the game is very dependant on the starting location of depots. As such i cannot really say that this bot is better than any others.
Run with java NavPointBot
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

public final class NavPointBot implements Serializable
{
    private static final int[][] offsets = new int[][]{{-1,0},{0,-1},{1,0},{0,1}};
    private static final List<int[]> navPointsBlue = Arrays.asList(new int[][]{{1,2},{2,1}});
    private static final List<int[]> navPointsRed = Arrays.asList(new int[][]{{63,62},{62,63}});
    transient private static int mapWidth=0;
    transient private static int mapHeight=0;
    transient private char[][] map;
    transient private char team;
    transient private int ammo;
    transient private int botsAlive;
    transient private int enemyFlagX;
    transient private int enemyFlagY;
    private int frameCount;
    private int botX;
    private int botY;
    private String id;
    private int navPointX;
    private int navPointY;

    transient static Object synchObject = new Object(); // used for file read/write synchronisation if multiple instances are run in the same VM

    final static class Data implements Serializable
    {
        int frameCount;
        boolean[][] diffusedMap = new boolean[mapWidth][mapHeight];
        Map<String,NavPointBot> teamMembers = new HashMap<>();
    }

    interface DistanceWeigher
    {
        double applyWeight(NavPointBot p1Bot, PathSegment p1);
    }

    static class PathSegment
    {
        public PathSegment(int tileX, int tileY, int fscore, int gscore, PathSegment parent, int direction, int targetX, int targetY)
        {
            super();
            this.tileX = tileX;
            this.tileY = tileY;
            this.fscore = fscore;
            this.gscore = gscore;
            this.parent = parent;
            this.direction = direction;
            this.targetX = targetX;
            this.targetY = targetY;
        }
        public PathSegment(PathSegment parent)
        {
            this.parent = parent;
            this.targetX = parent.targetX;
            this.targetY = parent.targetY;
        }
        int tileX;
        int tileY;
        int fscore;
        int gscore;
        int direction;
        PathSegment parent;
        int targetX;
        int targetY;
    }

    public static void main(String[] args) throws Exception
    {
        new NavPointBot(UUID.randomUUID().toString());
    }

    private NavPointBot(String id) throws Exception
    {
        this.id = id;
        System.err.println("NavPointBot ("+id+") STARTED");

        Data data;
        while(true)
        {
            String line=readLine(System.in);

            // decode initial frame
            if ("INIT".equals(line))
            {
                // read team membership
                team = readLine(System.in).charAt(0);

                // get the map
                line = readLine(System.in);

                List<char[]> mapLines = new ArrayList<>();
                while(!"TINI".equals(line))
                {
                    mapLines.add(line.toCharArray());
                    line = readLine(System.in);
                }
                map = mapLines.toArray(new char[][]{});
                mapHeight = map.length;
                mapWidth = map[0].length;

                out:
                for (int y = 0; y<mapHeight;y++)
                {
                    for (int x=0; x<mapWidth;x++)
                    {
                        if (map[y][x]==(team=='B'?'G':'F'))
                        {
                            enemyFlagX = x;
                            enemyFlagY = y;
                            break out;
                        }
                    }
                }
                data = readSharedData();
                data.diffusedMap=new boolean[mapWidth][mapHeight];
                writeSharedData(data);

            }
            else
            {
                System.err.println("Unknown command received: "+line);
                return;
            }

            line = readLine(System.in);
            while (true)
            {
                // decode frame
                if ("FRAME".equals(line))
                {
                    frameCount = Integer.parseInt(readLine(System.in));
                    ammo = Integer.parseInt(readLine(System.in));
                    botsAlive = Integer.parseInt(readLine(System.in));
                    line = readLine(System.in);
                    String[] splits = line.split(",");
                    botX = Integer.parseInt(splits[0]);
                    botY = Integer.parseInt(splits[1]);

                    // get the map
                    line = readLine(System.in);

                    int row=0;
                    while(!"EMARF".equals(line))
                    {
                        map[row++] = line.toCharArray();
                        line = readLine(System.in);
                    }
                }
                else
                {
                    System.err.println("Unknown command received: "+line);
                    return;
                }

                data = readSharedData();

                // this bot is nomitated to be the leader for this frame
                if (data.frameCount<frameCount || (frameCount==0 && data.frameCount > 3))
                {
                    data.frameCount=frameCount;

                    List<NavPointBot> unassignedBots = new ArrayList<>(data.teamMembers.values());

                    // default nav points to be enemy flag location.
                    unassignedBots.forEach(t->{t.navPointY=enemyFlagY;t.navPointX=enemyFlagX;});

                    // after 700 frames assume dead lock so just storm the flag, otherwise...
                    if (frameCount<700)
                    {
                        // if the after the initial rush then we will assign guard(s) while we have enemies
                        if (frameCount>70 && botsAlive > data.teamMembers.size())
                        {
                            Map<NavPointBot, PathSegment> navPointDistances = assignBotShortestPaths(unassignedBots,team=='B'?navPointsBlue:navPointsRed,true, new DistanceWeigher() {

                                @Override
                                public double applyWeight( NavPointBot owner ,PathSegment target) {
                                    return target.gscore;
                                }
                            });
                            navPointDistances.keySet().forEach(s->{s.navPointX=navPointDistances.get(s).targetX;s.navPointY=navPointDistances.get(s).targetY;});
                        }

                        // the remaining bots will go to ammo depots with a preference to the middle ammo depots
                        List<int[]> ammoDepots = new ArrayList<>();
                        for (int y = 0; y<mapHeight;y++)
                        {
                            for (int x=0; x<mapWidth;x++)
                            {
                                if (map[y][x]=='A')
                                {
                                    ammoDepots.add(new int[]{x,y});
                                }
                            }
                        }

                        System.err.println("ammoDepots: "+ammoDepots.size());
                        if (ammoDepots.size()>0)
                        {
                            Map<NavPointBot, PathSegment> ammoDistances = assignBotShortestPaths(unassignedBots,ammoDepots,true, new DistanceWeigher() {

                                @Override
                                public double applyWeight( NavPointBot owner ,PathSegment target) {
                                    return target.gscore + (Math.abs(target.targetX-mapWidth/2)+Math.abs(target.targetY-mapHeight/2)*10);
                                }
                            });

                            // assign ammo depot nav points to closest bots
                            ammoDistances.keySet().forEach(s->{s.navPointX=ammoDistances.get(s).targetX;s.navPointY=ammoDistances.get(s).targetY;});
                        }
                    }

                    System.err.println("FRAME: "+frameCount+" SET");
                    data.teamMembers.values().forEach(bot->System.err.println(bot.id+" nav point ("+bot.navPointX+","+bot.navPointY+")"));
                    System.err.println();
                }

                // check to see if enemies are in range, if so attack the closest
                List<int[]> enemies = new ArrayList<>();
                for (int y = 0; y<mapHeight;y++)
                {
                    for (int x=0; x<mapWidth;x++)
                    {
                        if (map[y][x]==(team=='B'?'R':'B'))
                        {
                            int attackDir = -1;
                            int distance = -1;
                            if (x==botX && Math.abs(y-botY) < 4) { distance =  Math.abs(y-botY); attackDir = botY-y<0?1:3;}
                            if (y==botY && Math.abs(x-botX) < 4) { distance =  Math.abs(x-botX); attackDir = botX-x<0?0:2;}
                            if (attackDir>-1)
                            {
                                enemies.add(new int[]{x,y,distance,attackDir});
                            }
                        }
                    }
                }

                enemies.sort(new Comparator<int[]>() {

                    @Override
                    public int compare(int[] arg0, int[] arg1) {
                        return arg0[2]-arg1[2];
                    }
                });

                String action;

                // attack enemy if one within range...
                if (enemies.size()>0)
                {
                    action = "Throw,"+enemies.get(0)[3];
                }
                else
                {
                    // set action to move to navpoint
                    PathSegment pathSegment = pathFind(botX,botY,navPointX,navPointY,map,true);
                    action = "Move,"+pathSegment.direction;

                    // clear mines if within 5 spaces of enemy flag

                    if ((team=='B' && botX>=mapWidth-5 && botY>=mapHeight-5 ) ||
                        (team=='R' && botX<5 && botY<5 ))
                    {
                        if (!data.diffusedMap[pathSegment.parent.tileX][pathSegment.parent.tileY])
                        {
                            action = "Defuse,"+pathSegment.direction;
                            data.diffusedMap[pathSegment.parent.tileX][pathSegment.parent.tileY]=true;
                        }
                    }

                }

                writeSharedData(data);
                System.out.println(action);
                line = readLine(System.in);
            }
        }
    }

    /**
     * assigns bots to paths to the given points based on distance to the points with weights adjusted by the given weigher implementation
     */
    private Map<NavPointBot, PathSegment> assignBotShortestPaths(List<NavPointBot> bots, List<int[]> points, boolean exact, DistanceWeigher weigher) {

        Map<Integer,List<PathSegment>> pathMap = new HashMap<>();
        final Map<PathSegment,NavPointBot> pathOwnerMap = new HashMap<>();

        for (NavPointBot bot : bots)
        {
            for(int[] navPoint: points)
            {
                List<PathSegment> navPointPaths = pathMap.get((navPoint[0]<<8)+navPoint[1]);
                if (navPointPaths == null)
                {
                    navPointPaths = new ArrayList<>();
                    pathMap.put((navPoint[0]<<8)+navPoint[1],navPointPaths);
                }
                PathSegment path = pathFind(bot.botX,bot.botY,navPoint[0],navPoint[1],map,exact);
                pathOwnerMap.put(path, bot);
                navPointPaths.add(path);
            }
        }

        // assign bot nav point based on shortest distance
        Map<NavPointBot, PathSegment> results = new HashMap<>();
        for (int[] navPoint: points )
        {
            List<PathSegment> navPointPaths = pathMap.get((navPoint[0]<<8)+navPoint[1]);

            if (navPointPaths !=null)
            {
                Collections.sort(navPointPaths, new Comparator<PathSegment>() {

                    @Override
                    public int compare(PathSegment p1, PathSegment p2) {

                        NavPointBot p1Bot = pathOwnerMap.get(p1);
                        NavPointBot p2Bot = pathOwnerMap.get(p2);
                        double val = weigher.applyWeight(p1Bot, p1) - weigher.applyWeight(p2Bot, p2);
                        if (val == 0)
                        {

                            return p1Bot.id.compareTo(p2Bot.id);
                        }
                        return val<0?-1:1;
                    }
                });

                for (PathSegment shortestPath : navPointPaths)
                {
                    NavPointBot bot = pathOwnerMap.get(shortestPath);

                    if (!results.containsKey(bot) )
                    {
                        results.put(bot,shortestPath);
                        bots.remove(bot);
                        break;
                    }
                }
            }
        }
        return results;
    }

    /**
     * reads in the previous bot's view of teammates aka shared data
     */
    private Data readSharedData() throws Exception
    {
        synchronized(synchObject)
        {
            File dataFile = new File(this.getClass().getName()+"_"+team);

            Data data;
            if (dataFile.exists())
            {
                FileInputStream in = new FileInputStream(dataFile);
                try {
                    java.nio.channels.FileLock lock = in.getChannel().lock(0L, Long.MAX_VALUE, true);
                    try {
                        ObjectInputStream ois = new ObjectInputStream(in);
                        data = (Data) ois.readObject();
                    } catch(Exception e)
                    {
                        System.err.println(id+": CORRUPT shared Data... re-initialising");
                        data = new Data();
                    }
                    finally {
                        lock.release();
                    }
                } finally {
                    in.close();
                }
            }
            else
            {
                System.err.println(id+": No shared shared Data exists... initialising");
                data = new Data();
            }

            //purge any dead teammates...
            for (NavPointBot bot : new ArrayList<>(data.teamMembers.values()))
            {
                if (bot.frameCount < frameCount-3 || bot.frameCount > frameCount+3)
                {
                    data.teamMembers.remove(bot.id);
                }
            }

            // update our local goals to reflect those in the shared data
            NavPointBot dataBot = data.teamMembers.get(id);
            if (dataBot !=null)
            {
                this.navPointX=dataBot.navPointX;
                this.navPointY=dataBot.navPointY;
            }

            // ensure that we are a team member
            data.teamMembers.put(id, this);

            return data;
        }
    }

    private void writeSharedData(Data data) throws Exception
    {
        synchronized(synchObject)
        {
            File dataFile = new File(this.getClass().getName()+"_"+team);
            FileOutputStream out = new FileOutputStream(dataFile);

            try {
                java.nio.channels.FileLock lock = out.getChannel().lock(0L, Long.MAX_VALUE, false);
                try {
                    ObjectOutputStream oos = new ObjectOutputStream(out);
                    oos.writeObject(data);
                    oos.flush();
                } finally {
                    lock.release();
                }
            } finally {
                out.close();
            }
        }
    }

    /**
     * return the direction to move to travel for the shortest route to the desired target location
     */
    private PathSegment pathFind(int startX, int startY, int targetX,int targetY,char[][] map,boolean exact)
    {
        // A*
        if (startX==targetX && startY==targetY)
        {
            return new PathSegment(targetX,targetY,0, 0,null,4,targetX,targetY);//PathSegment.DEFAULT;
        }
        else
        {
            int[][] tileIsClosed = new int[mapWidth][mapHeight];

            // find an open space in the general vicinity if exact match not required
            if (!exact)
            {
                out:
                for (int y=-1;y<=1;y++)
                {
                    for (int x=-1;x<=1;x++)
                    {
                        if (startX == targetX+x && startY==targetY+y)
                        {
                            return new PathSegment(targetX,targetY,0, 0,null,4,targetX,targetY);//PathSegment.DEFAULT;
                        }
                        else if (targetY+y>=0 && targetY+y<mapHeight && targetX+x>=0 && targetX+x < mapWidth && map[targetY+y][targetX+x]=='O')
                        {
                            targetX+=x;
                            targetY+=y;
                            break out;
                        }
                    }
                }
            }

            PathSegment curSegment = new PathSegment(targetX,targetY,1,1,null,4,targetX,targetY);
            PathSegment newSegment;
            Set<PathSegment> openList = new HashSet<PathSegment>();
            openList.add(curSegment);

            do
            {
                if (openList.isEmpty())
                {
                    break;
                }
              PathSegment currentBestScoringSegment = openList.iterator().next();
              //  Look for the lowest F cost square on the open list
              for (PathSegment segment : openList)
              {
                if (segment.fscore<currentBestScoringSegment.fscore)
                {
                  currentBestScoringSegment = segment;
                }
              }
              curSegment = currentBestScoringSegment;

              // found path
              if (startX==curSegment.tileX && startY==curSegment.tileY)
              {
                break;
              }

              // if not in closed list
              if (tileIsClosed[curSegment.tileX][curSegment.tileY]==0)
              {
                    // Switch it to the closed list.
                    tileIsClosed[curSegment.tileX][curSegment.tileY]=1;
                    // remove from openlist
                    openList.remove(curSegment);

                    // add neigbours to the open list if necessary
                    for (int i=0;i<4;i++)
                    {

                        int surroundingCurrentTileX=curSegment.tileX+offsets[i][0];
                        int surroundingCurrentTileY=curSegment.tileY+offsets[i][1];
                        if (surroundingCurrentTileX>=0 && surroundingCurrentTileX<mapWidth &&
                            surroundingCurrentTileY>=0 && surroundingCurrentTileY<mapHeight )
                        {
                            newSegment = new PathSegment( curSegment);
                            newSegment.tileX = surroundingCurrentTileX;
                            newSegment.tileY = surroundingCurrentTileY;
                            newSegment.direction = i;

                            switch(map[surroundingCurrentTileY][surroundingCurrentTileX])
                            {
                                case 'W':
                                case 'F':
                                case 'G':
                                    continue;
                            }

                          int surroundingCurrentGscore=curSegment.gscore+1 + ((surroundingCurrentTileX!=startX && surroundingCurrentTileY!=startY && map[surroundingCurrentTileY][surroundingCurrentTileX]==team)?20:0);//+map[surroundingCurrentTileY][surroundingCurrentTileX]!='O'?100:0;
                          newSegment.gscore=surroundingCurrentGscore;
                          newSegment.fscore=surroundingCurrentGscore+Math.abs( surroundingCurrentTileX-startX)+Math.abs( surroundingCurrentTileY-startY);
                          openList.add(newSegment);
                        }
                    }
              }
              else
              {
                  // remove from openlist
                  openList.remove(curSegment);
              }
            } while(true);

            return curSegment;
        }
     }

    /**
     * Reads a line of text from the input stream. Blocks until a new line character is read.
     * NOTE: This method should be used in favor of BufferedReader.readLine(...) as BufferedReader buffers data before performing
     * text line tokenization. This means that BufferedReader.readLine() will block until many game frames have been received.
     * @param in a InputStream, nominally System.in
     * @return a line of text or null if end of stream.
     * @throws IOException
     */
    private static String readLine(InputStream in) throws IOException
    {
       StringBuilder sb = new StringBuilder();
       int readByte = in.read();
       while (readByte>-1 && readByte!= '\n')
       {
          sb.append((char) readByte);
          readByte = in.read();
       }
       return readByte==-1?null:sb.toString();

    }

}

beautiful animation, just out of curiosity what is the approximate win percentage of my bot?

I have not performed any real statistics but i would hazard 60% my bot vs 40% your bot? but really depends on the placement of ammo

Ok, gg on the win!

should I had more ammo, or should I configure the ammo to spawn equally?

@RohanJhunjhunwala i think it is what it is, too late to change the behaviour now. Use it as a learning experience for the next question asked :)

ok that makes sense

Optimised Pathfinder JAVA
Thanks to @Moogie for helping me optimise my messy floodfill pathfinding. Here is the source for the bot. This guy knows how important it is to defend his flag. He alocates three defenders and two attackers. The defenders hang back and defend/gather ammo, the two attackers take (a fairly straight) path to the flag (and collect the ammo at the middle). He shoots anyone he sees, and should be fierce competition. The defenders place mines around the flag and camp until there is no opposition left so they can go and kick the can.
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 * todo fight
 */
package botctf;

import botctf.Move.MoveType;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;

/**
 *
 * @author rohan
 */
public class PathFinderOptimised extends Bot {
    private static final int[][] offsets = new int[][]{{0,-1},{1,0},{0,1},{-1,0}};
    public static boolean shouldCampingTroll = true;
    private int moveCounter = -1;//dont ask
    public boolean defend;

    public PathFinderOptimised(int inX, int inY, int inTeam) {

        super(inX, inY, inTeam);
        //System.out.println("Start");
        //floodFillMap(getX(), getY());
        //System.out.println("Finish");
        defend=inX%2==0;
    }
    public static int[][] navigationMap;

    boolean upMine = false;
    boolean sideMine = false;

        int[][] myMap;

    @Override
    public Move move() {
                moveCounter++;
        myMap=getMap();
        int targetX, targetY;
        int enemyTeam=team==redTeam?blueTeam:redTeam;
        ArrayList<Coord> enemyCoordinates=new ArrayList<>();
        for(int i = 0; i<65;i++){
            for(int j = 0;j<65;j++){
                if(map[i][j]==enemyTeam){
                    enemyCoordinates.add(new Coord(i,j));
                }
            }
        }
        for(Coord enemy:enemyCoordinates){
            int enemyX=enemy.x;
            int enemyY=enemy.y;
         int dX= enemy.x-this.x;
            int dY= enemy.y-this.y;
            //System.out.println(dX+"|"+dY);
            if((dX==0||dY==0)){

                if(Arena.getAmmo()[this.team]>0){

                    if(dX>0&&dX<5){
                    return new Move(0,MoveType.Throw);
                }
                if(dX<0&&dX>-5){
                    return new Move(2,MoveType.Throw);
                }
                if (dY>0&&dY<5){
                    return new Move(1, MoveType.Throw);
                }
                if(dY<0&&dY>-5){
                    return new Move(3,MoveType.Throw);
                }
            }
        }
        }
        if(myMap[x+1][y]==ammo){
            return new Move(0,MoveType.Move);
        }
                if(myMap[x-1][y]==ammo){
            return new Move(2,MoveType.Move);
        }
                                if(myMap[x][y+1]==ammo){
            return new Move(1,MoveType.Move);
        }
                                                                if(myMap[x][y-1]==ammo){
            return new Move(3,MoveType.Move);
        }

int bestOption = 4;
        if (defend) {
if(Arena.getAliveBots()==1){
    defend=false;
}
            int bestAmmoX = -1;
            int bestAmmoY = -1;
            int bestAmmoDist = Integer.MAX_VALUE;
            for (int i = 0; i < 65; i++) {
                for (int j = 0; j < 65; j++) {
                    if (myMap[i][j] == ammo) {
                        int path = pathFind(getX(),getY(),i,j,myMap);
                        if ((path & 0xFFFFFF) < bestAmmoDist) {
                            bestAmmoX = i;
                            bestAmmoY = j;
                            bestAmmoDist = (path & 0xFFFFFF);
                            bestOption = path >> 24;
                        }
                    }
                }
            }
            if (bestAmmoDist<15||Arena.getAmmo()[this.team]==0){
                targetX = bestAmmoX;
                targetY = bestAmmoY;
            } else {
                targetX = team == redTeam ? 62 : 2;
                targetY = team == redTeam ? 62 : 2;
            }
        } else {

            if(this.x>18&this.x<42&&this.y>16&&this.y<44&&myMap[33][33]==ammo){
                targetX=33;
                targetY=33;
            }else{
            if (this.team == redTeam) {
                targetX = 1;
                targetY = 1;
            } else {
                targetX = 63;
                targetY = 63;
            }
            }
        }
        if(upMine&&sideMine){
            if(targetX==2||targetX==62){
                if(targetY==2||targetY==62){
                    targetX+=targetX==2?3:-3;
                    targetY+=targetY==2?3:-3;
                }
            }
        }else if (targetX == getX() && targetY == getY()) {
            if (!upMine) {
                upMine = true;
                if (this.team == redTeam) {
                    return new Move(0, MoveType.Mine);
                } else {
                    return new Move(2, MoveType.Mine);
                }
            }else if(!sideMine){
                sideMine=true;
                if (this.team == redTeam) {
                    return new Move(1, MoveType.Mine);
                } else {
                    return new Move(3, MoveType.Mine);
                }
            }   else {
                return new Move(5, MoveType.Move);
            }
        }

        bestOption = pathFind(getX(),getY(),targetX,targetY,myMap) >> 24;

MoveType m=MoveType.Move;
if(moveCounter%2==0){
    if(this.team==redTeam?x<25&&y<25:x>39&&y>39){
        m=MoveType.Defuse;
    }
}
//System.out.println(bestOption);
        return new Move(bestOption, m);
    }

    /**
     * returns a result that is the combination of movement direction and length of a path found from the given start position to the target
     * position. result is ((direction) << 24 + path_length)
     */
    private int pathFind(int startX, int startY, int targetX,int targetY,int[][] map)
    {
        class PathSegment
        {
            public PathSegment(int tileX, int tileY, int fscore, int gscore, PathSegment parent)
            {
                super();
                this.tileX = tileX;
                this.tileY = tileY;
                this.fscore = fscore;
                this.gscore = gscore;
                this.parent = parent;
            }
            public PathSegment(PathSegment parent)
            {
                this.parent = parent;
            }
            int tileX;
            int tileY;
            int fscore;
            int gscore;
            PathSegment parent;
        }
        // A*
        if (startX==targetX && startY==targetY)
        {
            return 4;
        }
        else
        {
            int[][] tileIsClosed = new int[64][64];

            PathSegment curSegment = new PathSegment(targetX,targetY,1,1,null);
            PathSegment newSegment;
            Set<PathSegment> openList = new HashSet<PathSegment>();
            openList.add(curSegment);

            do
            {
                if (openList.isEmpty())
                {
                    break;
                }
              PathSegment currentBestScoringSegment = openList.iterator().next();
              //  Look for the lowest F cost square on the open list
              for (PathSegment segment : openList)
              {
                if (segment.fscore<currentBestScoringSegment.fscore)
                {
                  currentBestScoringSegment = segment;
                }
              }
              curSegment = currentBestScoringSegment;

              // found path
              if (startX==curSegment.tileX && startY==curSegment.tileY)
              {
                break;
              }

              // if not in closed list
              if (tileIsClosed[curSegment.tileX][curSegment.tileY]==0)
              {
                    // Switch it to the closed list.
                    tileIsClosed[curSegment.tileX][curSegment.tileY]=1;
                    // remove from openlist
                    openList.remove(curSegment);

                    // add neigbours to the open list if necessary
                    for (int i=0;i<4;i++)
                    {
                        final int surroundingCurrentTileX=curSegment.tileX+offsets[i][0];
                        final int surroundingCurrentTileY=curSegment.tileY+offsets[i][1];
                        if (surroundingCurrentTileX>=0 && surroundingCurrentTileX<64 &&
                            surroundingCurrentTileY>=0 && surroundingCurrentTileY<64 )
                        {
                            newSegment = new PathSegment( curSegment);
                            newSegment.tileX = surroundingCurrentTileX;
                            newSegment.tileY = surroundingCurrentTileY;

                          if (map[surroundingCurrentTileX][surroundingCurrentTileY]=='W')
                          {
                              continue;
                          }

                          int surroundingCurrentGscore=curSegment.gscore+1;
                          newSegment.gscore=surroundingCurrentGscore;
                          newSegment.fscore=surroundingCurrentGscore+Math.abs( surroundingCurrentTileX-startX)+Math.abs( surroundingCurrentTileY-startY);
                          openList.add(newSegment);
                        }
                    }
              }
              else
              {
                  // remove from openlist
                  openList.remove(curSegment);
              }
            } while(true);

            if (curSegment.parent.tileX-startX<0) return (2 << 24) | curSegment.gscore;
            else if (curSegment.parent.tileX-startX>0) return (0 << 24) | curSegment.gscore;
            else if (curSegment.parent.tileY-startY<0) return (3 << 24) | curSegment.gscore;
            else if (curSegment.parent.tileY-startY>0) return (1 << 24) | curSegment.gscore;
        }
        throw new RuntimeException("Path finding failed");
     }
}

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


text:
What exactly was your question?
Introduction
When you are given a boring text, you just want to get it over with as quick as possible. Let's observe the following text:
Ens colligi timenda etc priorem judicem. De quascunque ii at contingere
repugnaret explicetur intellectu. Adjuvetis hoc fortassis suspicari opportune
obversari vix eam? Dei praemia prudens hominum iii constet requiri haberem. Ima
sane nemo modi fuit lus pro dem haud. Vestro age negare tactum hoc cui lor. Ne et
ut quod id soli soni deus. At constare innumera is occurret ea. Nia calebat seu
acquiro fraudem effingo dicimus.

Note: This text has newlines for readability, while the test cases you need to handle don't have newline characters.
One way to skim text is to find questions that the writer has put into the text. For example, there is 1 question in the text above. Namely:
Adjuvetis hoc fortassis suspicari opportune obversari vix eam?

This can be done by splitting the text into sentences. A sentence will always end with one of the following punctuation symbols: .?! (others don't have to be handled). Other symbols than these are part of the sentence.

The Task
Given a line of text consisting of only

letters (A-Za-z)
numbers (0-9)
spaces
punctuation (,.;:?!) (a sentence cannot start with one of these).

Output the questions that are in the text in any reasonable format. You may assume that the text will always have at least 1 question. Outputting trailing and leading spaces before and after a question is allowed.
Important: Next to a punctuation symbol, there will never be another punctuation symbol (e.g. ?? is invalid and will not be required to handle).

Test cases
In the format:
Input
Output(s)

The test cases:
Huh? I haven't heard what you just said. Could you repeat that please?
Huh?
Could you repeat that please?

plz can i haz cheesburgr? i am cat pls.
plz can i haz cheesburgr?

This is a badly formatted question.Can u please help me,or my friends,with formatting this question    ?thankyou.
Can u please help me,or my friends,with formatting this question    ?

a.b.c.d?
d?

Does this question have a question mark? yes
Does this question have a question mark?

Why example.com resolves to 127.0.0.1 in 99.9 percent of cases?
9 percent of cases?

A? b? c? d!
A?
b?
c?

This is code-golf, so the submission with the lowest number of bytes wins!

.?! Others must not be handled, as your rules specify, but you have said others don't have to be handled.

No testcase with more than one question?

@edc65 The first test case has 2 questions, but I'll add another test case.

Retina, 13 11 bytes
!`[^.?!]*\?

Try it online!
!`       print all matches
[^.?!]*  any number of non-ending-punctuation symbols
\?       followed by a question mark

Thanks to @MartinEnder for 2 bytes!

Python, 46 Bytes
import re
f=lambda s:re.findall("[^!?.]*\?",s)

Call with:
f("your string here")

output on tests:
['Can u please help me,or my friends,with formatting this question    ?', 'Can u please help me,or my friends,with formatting this question    ?', ' Huh?', ' Could you repeat that please?', ' plz can i haz cheesburgr?', 'd?', 'Does this question have a question mark?', '9 percent of cases?', 'A?', ' b?', ' c?']

another idea, 77 bytes (in python3 you'd need a list around filter):
import re
f=lambda s:filter(lambda x:x[-1]=="?",re.split("(?<=[\.\?!]).",s)))

I'm new to this so this, so this could probably be much shorter.
-17 (!) bytes thanks to Martin
-2 bytes by matching anything that is not "!","?" or "." (Getting close to the shell solutions, but I doubt I could save much more)

Welcome to Programming Puzzles and Code Golf! Very nice first answer :).

I don't think you need that lookbehind at all and neither do you need to make the [\w,:; ]* ungreedy (because that group can't go past a punctuation character anyway), and then you also don't need to prepend . to your input. You calso shorten the remaining character class to [^.!?].

Thank you, Martin! I have tried around with this a bit, but didn't see the obvious.

JavaScript, 35 24 bytes
a=>a.match(/[^.?!]*\?/g)

Returns all substrings that start after a ., ?, or ! (or the beginning of the text) and end in a ?.

Urgh. And I thought I did good with 40 bytes. Good Job OP and @MartinEnder

V, 12 bytes
Í[^.!?]*[.!]

Try it online!
A very straightforward answer.
Í             "Remove every occurrence, on every line
 [^.!?]       "Of any character that isn't '.', '!', or '?'
       *      "Repeated any number of times
        [.!]  "Followed by a a '.' or a '!'

Thankfully, handling newlines, or verifying all test-cases does not add any bytes.

Shell utilities, 43 38 bytes
Thanks to rexkogitans for trimming 5 bytes!
tr ? "\n"|sed "s/.*[\.!]//;s/.\+/&?/"

Pipe input in, like this:
echo Huh? I haven't heard what you just said. Could you repeat that please?|tr ? "\n"|sed "s/.*[\.!]//;s/.\+/&?/"

If if matters, I'm using:
GNU tr 5.3.0
GNU sed 4.2.1
Microsoft's cmd.exe, shipped with Windows 5.1.2600

I've never submitted an answer using multiple utilities before, so if I'm doing something wrong, let me know.

Do you use windows versions of the GNU utililties, or a shell for windows?

tr ? "\n"|sed "s/.*[\.!]//;s/.\+/&?/" saves 5 Bytes (two added in tr and 7 saved in sed - this was tested in bash). /g is not necessary, as it is processed line by line.

@EʀɪᴋᴛʜᴇGᴏʟғᴇʀ, I'm using the Windows ports of the GNU utilities.

@rexkogitans, thanks! I forgot about []; my first attempt at doing that looked something like \(\.|!\).

@SirBidenXVII If you were to do it with groups (not necessarily good in this case), you could use the -r option to sed, which allows you to write (\.|!)

Jelly, 16 bytes
f€“.?!”0;œṗfÐf”?

Try it online! or verify all test cases

28 bytes, isn't it? (16 UTF-8 chars)

@bruce965 Jelly uses a custom code page that encodes each of the 256 characters it understands as the single byte each. The bytes link in the header points to it.

Oh, cool! I'm not a codegolfer yet, so I'm not aware of this tricks, sorry for the question.

@bruce965 For the record, it's not really a trick: the language could just as well use ISO 8859-1 (or some other existing single-byte encoding) and be just as powerful, but using a custom code page allows you to use more easily typable characters and better mnemonics than if you had to code with control characters for example. At the end of the day, it's just a stream of bytes, where every byte has been assigned some meaning.

OK, "trick" might have sounded with a bad connotation, I should have said "stratagem" or something. I couldn't find any better word than "trick".

@bruce965 Have a look here so you'll be prepared for more odd glyphs.

Perl 5.10, 21 18 bytes (with -n flag)
say m/[^?.!]+\?/g

Straightforward implementation of the question.
Try it here!

You can get rid of the leading m of your regex, and then you'll be able to remove the space between say and /

Ruby 1.9, 17 bytes
$_=$F

A 5 bytes program that must be invoked with the following command line options:
paF[^?]*[.!]

I didn't know Ruby flags could be wrestled with in such a manner, +1! Feels kind of odd, though, since consecutive questions will be together as one string within that array while other questions are separate, right? Unless there's a Ruby 1.9 quirk I'm not aware of.

@ValueInk The contents of the array will be concatenated so the program outputs a single string, not an array literal. You can try it out at http://golf.shinh.org/check.rb which has ruby 1.9. The flags can be set in the shebang.

Aha, that explains why you need 1.9 since 2.0 and up output it to look like an actual array.

Batch, 174 bytes
@echo off
set/ps=
set t=
:l
set c=%s:~0,1%
set t=%t%%c%
if "%c%"=="?" echo %t%&set t=
if "%c%"=="!" set t=
if "%c%"=="." set t=
set s=%s~1%
if not "%s%"=="" goto l

Reading a line from STDIN is a byte shorter than using set s=%*.

PowerShell v4+, 43 bytes
([regex]::Matches($args,'[^?!.]*\?')).Value

Really straightforward. Takes input $args and feeds that in as the first parameter to a .NET [regex]::Matches(...) static function. The regex we're matching is [^?!.]*\? -- that is, any number of non-sentence-ending characters that are followed by a question mark. The static function returns an array of objects detailing what capture group, index, etc., but we only want the .Values, so the return is encapsulated in parens and we call that property. This is where the v4+ requirement comes into play, as in prior versions you'd need to instead do something like a loop |%{$_.Value} or |Select Value to get the appropriate properties.
Example without the parens and .Value
PS C:\Tools\Scripts\golfing> .\what-exactly-was-your-question.ps1 "Huh? I haven't heard what you just said! Could you repeat that please?"

Groups   : {Huh?}
Success  : True
Captures : {Huh?}
Index    : 0
Length   : 4
Value    : Huh?

Groups   : { Could you repeat that please?}
Success  : True
Captures : { Could you repeat that please?}
Index    : 40
Length   : 30
Value    :  Could you repeat that please?

Example with the parens and .Value
PS C:\Tools\Scripts\golfing> .\what-exactly-was-your-question.ps1 "Huh? I haven't heard what you just said! Could you repeat that please?"
Huh?
 Could you repeat that please?

Python 3, 91 bytes
def f(x,a=0):
 for n in range(len(x)):
  if x[n]in".!":a=n+1
  if x[n]is"?":print(x[a:n+1])

Saves 1 byte in Python 2:
def f(x,a=0):
 for n in range(len(x)):
  if x[n]in".!":a=n+1
  if x[n]is"?":print x[a:n+1]

><> (Fish), 72 69 bytes
>i:0(?^:"?"=?v\"!."@=?v=?v
^>l?v00. > ovr:    .12<  <
 ^ ~< ;!0^?l<<:

Animated Version
Explanation

The top row reads a character, pushes it onto the stack, and checks if it is ., ! or ?.
If it's a ! or a ., we jump to 2,1 where there is a loop to clear the stack.
If it's a ? there is a similar loop, futher to the right. Instead of discarding elements we reverse the stack first and print items instead of just discarding them. We then enter the same green loop but the stack is already empty so we will soon exit it. We push a 0 to the stack so the program doesn't crash here.

Japt, 11 bytes
Using replace rather than match. Works out at the same byte count.
r"[^?]*[.!]

Try it

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


text:
Inverting lists of lists of indices
Inspired by this StackOverflow post.
Introduction
Bob's job is to create spreadsheets and organize them.  The way he organizes them is known to very few except for Bob, but he creates a list of each of the spreadsheets that fall under the same group.  There's a bunch of data in the spreadsheet he creates, but there's only one piece of data that we're looking at right now: The number of days between the day he started this job and the day he made the spreadsheet.  The first day he created two spreadsheets, noted them both as 0 and sorted them in to their proper locations.
Now, his boss is asking for a review of what kinds of spreadsheet happened each day, and it's your job to write some code that will figure that out for Bob; he has far too many spreadsheets to do it by hand.
Input
Bob's info that he gives you comes in the form of a (0-or-1 indexed) jagged array where each datum is of the form x = a[i][j].  a is what I'm calling the jagged array itself, i is the type of spreadsheet, and x is the date the array was created.  j is unimportant.
The task
Given a jagged array of spreadsheet creation days organized by their type, return a jagged array of spreadsheet types organized by spreadsheet creation day.
Examples
Bob isn't going to just leave you with this abstract data. He's given me a subset of some of his spreadsheets to help you out with figuring out what everything is supposed to be.
Example input (0-indexed):
a = [
[3,2,5,0], # Bob doesn't necessarily sort his lists
[1,3],
[2,1,0,4],
[4,5,3],
[6,6]
]

Example output (with commentary, which of course is not required):
output = [
[0,2] # On day 0, Bob made one type 0 and one type 2 spreadsheet
[1,2] # On day 1, Bob made one type 1 and one type 2 spreadsheet
[0,2] # On day 2, Bob made one type 0 and one type 2 spreadsheet
[0,1,3] # On day 3, Bob made one type 0, one type 1, and one type 3 spreadsheet
[2,3] # On day 4, Bob made one type 2 and one type 3 spreadsheet
[0,3] # On day 5, Bob made one type 0 and one type 3 spreadsheet
[4,4] # On day 6, Bob made two type 4 spreadsheets
]

Note that Bob doesn't always make two spreadsheets every day, and so the output may be jagged as well. But he always makes at least one spreadsheet every day, so the output will never need to contain empty arrays - although if your output has empty arrays at the end, you don't need to remove them.
More test cases:
[[3,5,6,2],[0,0,0],[1,0,3,4]] -> [[1,1,1,2],[2],[0],[0,2],[2],[0],[0]]
[[-1]] -> Undefined behavior, as all input numbers will be non-negative integers.
[[0],[0],[],[0]] -> [[0,1,3]]

The output's inner lists do not need to be sorted.
As always, no standard loopholes, and of course shortest code wins.
(As this is my first question, please let me know of anything I can do to improve it.)

Might Bob make no spreadsheets of some type?

@xnor Bob definitely sometimes has no spreadsheets of some type (see the last test case, where he doesn't have any type 2 spreadsheets).

Oops, what I meant is, does Bob ever create no spreadsheets on some day, causing there to be an empty list in the output?

@xnor No, Bob will always create a spreadsheet every day.  These spreadsheets are so crucial to the operation of the company that if Bob has to call in sick, another person is temporarily posted to create that day's spreadsheets and Bob organizes them the next morning before creating his own spreadsheets.

A few questions/comments: 1. The example output doesn't match my implementation. On day 2, the comment say 0, 2, but the output [2,2]. Also, day 3 seems to be missing the 3. 2. Can both input and output be 1-based, i.e., would input [[1],[1],[],[1]] and output [[1,2,4]] be acceptable for the last test case? 3. -1 is a whole number. It's just negative.

@Dennis 2. "in the form of a (0-or-1 indexed) jagged array"

@LeakyNun Yes, but does that apply to the input, the output or both? (I'm assuming both for now, but I want to make sure I understood correctly.)

It applies to both.

@Dennis I was a little tired when putting that example together, and I guess it showed.  :P  Fixed (both)!

Looking good. This is a very nice challenge, especially considering that it's your first. :) Btw, in case you're not aware, we have a sandbox where the community can provide feedback before "going live".

I edited in a statement based on your comment "No, Bob will always create a spreadsheet every day", but now that I've tried optimising my own answer I've realised that it's possibly more restrictive than you intended. Are trailing empty arrays permitted? E.g. can [[0 0]] give output [[0 0] []]?

@PeterTaylor You can have trailing empty arrays, but they are most certainly not required.  I'll edit that part in as well.

Somewhat related.

Related.

my brain sees type 0 and won't stop reading typo.

Jelly, 11 10 bytes
FṀ⁸ċþµJ€x"

Input and output are 1-based.
Try it online! or verify all test cases (0-based for easy comparison).

Pyth, 13 bytes
eMM.ghkSs,RVU

         ,RV      vectorized right map of pair, over:
            UQ      [0, …, len(input) - 1] and
              Q     input
                  (this replaces each date with a [date, type] pair)
        s         concatenate
       S          sort
   .ghk           group by first element (date)
eMM               last element (type) of each sublist

Try it online

Pyth, 14 bytes
ms.e*]k/bdQS{s

Test suite.

Brachylog, 28 bytes
:1f.
cdo:Im:?:2f.
t:.m:Im~h?

Explanation

Main predicate, Input (?) = a list of lists
:1f.              Find all valid outputs of predicate 1 with ? as input

Predicate 1:
c                 Concatenate the list of lists into a single list
 do               Remove duplicates and sort
   :Im            Take the Ith element of that sorted list
      :?:2f.      Find all valid outputs of predicate 2 with [Element:?] as input

Predicate 2:
t:.m              Take the (Output)th element of the list of lists
    :Im           Take the Ith element of that list
       ~h?        This element is the element of the input [Element:List of lists]

Lua, 114 bytes
r={}for i,t in ipairs(...)do for _,v in ipairs(t)do if r[v] then r[v][#r[v]+1]=i else r[v]={i}end end end return r

Ideone it!
Inspired by Dennis' answer in Python 2.

JavaScript (ES6), 58 bytes
a=>a.map((b,i)=>b.map(j=>(r[j]=r[j]||[]).push(i)),r=[])&&r

CJam (30 29 bytes)
Mq~{W):W;{:X)Me]_X=W+X\t}/}/`

Online demo
Curiously it's shorter to hack around with W than to use ee, mainly because I want the index to end up in a variable anyway. e] saved two bytes over first finding the maximum element m and initialising an array of m+1 empty arrays.
Thanks to Martin for a one-byte saving by storing a value in X instead of juggling it around the stack.
NB If trailing empty arrays are permitted, there's alternative 29-byte approach by instead initialising the array of as many empty days as there are spreadsheets:
q~_e_,Ma*\{W):W;{_2$=W+t}/}/`

CJam, 20 bytes
Thanks to Peter Taylor for letting me base this code on his solution and saving 3 bytes.
{ee::f{S*\+S/}:~:.+}

An unnamed block which expects the input on top of the stack and replaces it with the output.
Test it here.
Explanation
ee    e# Enumerate the input. E.g. if the input is
      e#   [[3 5 6 2] [0 0 0] [1 0 3 4]]
      e# this gives:
      e#   [[0 [3 5 6 2]] [1 [0 0 0]] [2 [1 0 3 4]]]
::f{  e# The exact details of how this works are a bit tricky, but in effect
      e# this calls the subsequent block once for every spreadsheet and
      e# its correspond index, so the first time we'll have 0 and 3 on the
      e# stack, the next time 0 5, and at the last iteration 2 and 4.
      e# Note that this is a map operation, so we'll end up with an array
      e# on the stack.
  S*  e#   So the stack holds [... index date] now. We start by creating
      e#   a string of 'date' spaces, so "   " on the first iteration.
  \+  e#   We swap this with the index and append the index.
  S/  e#   Now we split this thing on spaces, which gives us 'date' empty
      e#   lists and a list containing the index, e.g. [[] [] [] [0]].
}
:~    e# This flattens the first level of the result, so that we get a list
      e# of all those lists we just created. This is simply one list for
      e# every spreadsheet with its type in the last element.
:.+   e# Finally we fold pairwise concatenation over this list. All the
      e# empty lists won't affect the result so we'll just end up with all
      e# the types in lists for the correct date.

Python 2, 82 bytes
r=[];i=0
for t in input():
 for v in t:r+=[()]*-(~v+len(r));r[v]+=i,
 i+=1
print r

Test it on Ideone.

Mathematica, 35 bytes
Table[#&@@@#~Position~i,{i,Max@#}]&

An unnamed function which accepts and returns a ragged list. Uses 1-based indices.
Thankfully Max automatically flattens all its inputs, so this gets us the last day index even though the input is a ragged list. We then simply compute a list of #&@@@#~Position~i for all day indices i. This expression itself finds the position of i inside the ragged list (return as an array of indices at successive depths), so the values we want are the first values of each of those lists. #&@@@ is a standard golfing trick to retrieve the first element from every sublist, by applying #& to each of those sublists, which is an unnamed function that returns its first argument.
Alternatively, we can define a unary operator for the same byte-count (assuming an ISO 8859-1 encoded source file):
±n_:=#&@@@n~Position~#&~Array~Max@n

Java, 314 bytes
int[][]f(int[][]n){int w=0;Map<Integer,List<Integer>>m=new TreeMap<>();for(int i=0;i<n.length;i++)for(Integer x:n[i]){if(m.get(x)==null)m.put(x,new ArrayList<>());m.get(x).add(i);w=x>w?x:w;}int[][]z=new int[w+1][];for(int i=0,j;i<w+1;i++){z[i]=new int[m.get(i).size()];j=0;for(int x:m.get(i))z[i][j++]=x;}return z;

Detailed
public static Integer[][] f(Integer[][]n)
{
    int w=0;
    Map<Integer,List<Integer>>m=new TreeMap<>();

    for(int i=0;i<n.length;i++)
    {
        for(Integer x : n[i])
        {
            if(m.get(x)==null) m.put(x,new ArrayList<Integer>());
            m.get(x).add(i);
            w=x>w?x:w;
        }
    }

    Integer[][]z=new Integer[w+1][];
    for(int i=0,j; i<w+1; i++)
    {
        z[i]=new Integer[m.get(i).size()];
        j=0;for(Integer x : m.get(i))z[i][j++]=x;
    }

    return z;
}

Do you really need Map?

Jelly, 9 bytes
œẹⱮFṀ$Ḣ€€

Try it online!
Input and output is 1-indexed, the Footer converts from 0-indexing to 1-indexing and back for I/O purposes.
How it works

œẹⱮFṀ$Ḣ€€ - Main link. Takes a 2D array, a, on the left
     $    - To a:
   F      -   Flatten
    Ṁ     -   Maximum
  Ɱ       - Over each number i in [1, 2, ..., max(flat(a))]:
œẹ        -   Get the multidimensional indices of i in a
              This returns [x, y] for each occurrence of i in a
              where x is the index of the array in a in which i is in
              and y is the index of i in that array. For example

              [[1,2,3],[4,5,6],[7,8,9]] œẹ 7 = [[3,1]]

              as 7 is in the 3rd subarray at index 1 (using 1 indexing)

      Ḣ€€ - Extract the x values only and return them

Perl 5, 48 bytes
A subroutine:
{for$i(0..@_){map{push@{$b[$_]},$i}@{$_[$i]}}@b}

See it in action like this:
perl -e'print "@$_$/" for sub{for$i(0..@_){map{push@{$b[$_]},$i}@{$_[$i]}}@b}->([3,2,5,0],[1,3],[2,1,0,4],[4,5,3],[6,6])'