[Question]
  [
[Reproductive strategy of oozes](https://rpg.stackexchange.com/questions/4272/is-an-ooze-a-living-creature/4273#comment4503_4273) can be summarized as follows:
> 
> o O 8 oo
> 
> 
> 
A population of oozes at generation N is described by a string, for example:
```
ooooo88ooOoOo8Ooooo8OOoo8Oo8Oo8oo8oooooo8OOooO88o
```
To compute the population at generation N+1, take one character randomly, and replace it by the result of ooze evolution:
* If `o`, replace by `O`
* If `O`, replace by `8`
* If `8`, replace by `oo`
Generation 0 is the one-character string `o`. Your program or function should get a positive number N, and output the population of oozes at generation N. At each generation, each ooze should have the same chance (to within 1% accuracy) to evolve.
Test cases (actual results may vary due to randomness):
```
1 -> O
2 -> 8
3 -> oo
4 -> Oo
5 -> OO
10 -> OO8
20 -> oo8oooo
30 -> oOoooOO8O
100 -> 8o8oO8OOooOo8OOoo88oOO8OOO
200 -> 88OOo8oooo8OOoooOoOOO8O8OO88o8Oo8oooOooooooOo8OooO888
1000 -> 8Ooooo88OO8o8O8oooOOoOOO88oOoO88OOoO8OOOooOOo8OO88O8OO8OO8ooo8oOO8OoooO88OooooooooOo8oooOO8OO8Oo8Oooo8O88oooOooO8Oo8ooOOOOo8OooOo8OoooooooO8oOooooOooOO8oOO8ooo8Ooooo8ooo8ooOOooO8OOoO8oO8oo88ooo8oO8OO8o888oO8OOoO8o8ooO8O88OOOoO8oooO8OoOoOo88O88oo88ooo8oO8o8oOooOo
```
---
If your solution has running time of O(n), please specify it explicitly!
  
[Answer]
# [Python 3](https://docs.python.org/3/), 114 bytes
```
from random import*
def f(n,s=b'o'):k=randrange(len(s));return n and f(n-1,s[:k]+b'oO8o'[-~s[k]%3::3]+s[k+1:])or s
```
[Try it online!](https://tio.run/##FYwxDsIwDEV3TuEFNaGulBAqQVDPwAGqDKCmUJU6VRIGFq4e3MH@3/rve/3mVyBTyhjDAvFOA8u0rCHmw27wI4yCMHWPKlTSzt0G8Dy9eHsSScpr9PkTCQg42eBGY@rt7Gqu3M6h6ptf6me3N9YaV7OttXUyREhl5E0wESjUeESDJ2xRK2z5VpsovChld7DGibLg51KWPw "Python 3 – Try It Online")
Interesting observation: the ascii values of `oO8` are `111`, `79`, and `56`, respectively. If you take these modulo 3, you get `0`, `1` and `2`.
---
Additional observation: you can validate the generation of your final string by substituting `'o'` with 3, `'O'` with 4 and `'8'` with 5; then taking the sum of your list and subtracting 3 from the total.
This works for all strings regardless of random variations, because each replacement in your string increases this sum by 1:
```
'o' (3) -> 'O'  (4)
'O' (4) -> '8'  (5)
'8' (5) -> 'oo' (3+3 = 6)
```
We then just need to correct for the offset of 3.
[Validate it online!](https://tio.run/##K6gsycjPM/7/v6AoM69Eo7g0V6NaPV/dylhH3V/dykRH3ULdyrQ2OjNWIS2/SCFTITMPiApKSzQ0NXWNNf//zwcBC4v8fH8gtPAH8/z9QQQY5YMQXNAfqBAA)
[Answer]
# [Ruby](https://www.ruby-lang.org/), ~~79 77 73 72~~ 61 bytes
```
->n,s=?o{n.times{s[w=rand(s.size)]=%w[O 8 oo][s[w].ord%3]};s}
```
[Try it online!](https://tio.run/##KypNqvyfZvtf1y5Pp9jWPr86T68kMze1uLo4uty2KDEvRaNYrzizKlUz1la1PNpfwUIhPz82GigZq5dflKJqHFtrXVz7v6C0pFghLdrQzCD2PwA "Ruby – Try It Online")
-11 bytes thanks to Value Ink and [Jitse](https://codegolf.stackexchange.com/a/196141/18535)
[Answer]
# [APL (Dyalog Unicode)](https://www.dyalog.com/), ~~40~~ ~~32~~ 31 [bytes](https://codegolf.meta.stackexchange.com/a/9429/43319 "When can APL characters be counted as 1 byte each?")[SBCS](https://github.com/abrudz/SBCS ".dyalog files using a single byte character set")
Full program. Prompts for N from stdin.
```
'o8O'[{∊⌷∘3(1 1)2@(?≢⍵)⊢⍵}⍣⎕,1]
```
[Try it online!](https://tio.run/##SyzI0U2pTMzJT///qKO94L96voW/enT1o46uRz3bH3XMMNYwVDDUNHLQsH/UuehR71bNR10gqvZR7@JHfVN1DGNB2v4rgEEBlyEXjGUEZxnDWSZwlimcZWiA0IJgGhsgKUBWgSJuAAA "APL (Dyalog Unicode) – Try It Online")
`'o8O'[`…`]` select the following characters from the string `"oO8"`:
 `,1` the list `[1]`
 `⎕` prompt for N from stdin
 `{`…`}⍣` apply the following anonymous lambda to `[1]`, that N times:
  `⊢⍵` on the argument…
  `@(`…`)` **at** position…
   `≢⍵` the length of the argument
   `?` random index in that range
  … apply the following tacit function:
  `⌷∘3(1 1)2` use the number to select from the list `[3,[1 1],2]`:
  `∊` **ϵ**nlist (flatten)
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E), 26 bytes
```
'osFÐg<ÝΩ©è…oO8S„O8„ooª‡®ǝ
```
[Try it online!](https://tio.run/##ATcAyP9vc2FiaWX//ydvc0bDkGc8w53OqcKpw6jigKZvTzhT4oCeTzjigJ5vb8Kq4oChwq7Hnf//MjAw "05AB1E – Try It Online")
[Answer]
# [Pyth](https://github.com/isaacg1/pyth), 25 bytes
```
uXGJOlG@c"O 8 oo")C@GJQ\o
```
[Try it online!](https://tio.run/##K6gsyfj/vzTC3cs/x90hWclfwUIhP19J09nB3SswJv//f0MDAA "Pyth – Try It Online")
Written by @FryAmTheEggman, similar idea to my earlier post but much cleaner as it reduces instead of looping.
## How it works
```
uXGJOlG@c"O 8 oo")C@GJQ\o
u                     Q\o - Reduce 'o' Q=input times
   JOlG                   - With random number J in the range [0,length G), 
                            where G is the previous list
 XG                       - Replace the element in G at index J...
       @c"O 8 oo")        - With an element of "O 8 oo" split by 
                            whitespace, at index...
                  C@GJ    - ...of the codepoint of the element in G at index J
```
# [Pyth](https://github.com/isaacg1/pyth), 38 bytes
```
K\oJ["oo"\o\O\8)VQ=kOlK=KXKk@JhxJ@Kk;K
```
[Try it online!](https://tio.run/##K6gsyfj/3zsm3ytaKT9fKSY/xj/GQjMs0DbbP8fb1jvCO9vBK6PCy8E729r7/39DAwA "Pyth – Try It Online")
My original solution, less sophisticated.
## How it works
```
K\oJ["oo"\o\O\8)VQ=kOlK=KXKk@JhxJ@Kk;K
K\o                                    - K = 'o', start
   J["oo"\o\O\8)                       - J = ['oo', 'o', 'O', '8']
                VQ                     - Loop Q=input times
                  =kOlK                - k = random number from 0..length of K
                       =K              - K equals...
                         XKk           - K with the element at index k replaced by...
                            @Jh        - The item in J at index+1 of...
                               xJ      - The index (in J) of...
                                 @Kk   - The element of K at index k
                                    ;K - End loop, print K     
```
[Answer]
# [R](https://www.r-project.org/), ~~109~~ ~~97~~ 93 bytes
```
for(i in 1:scan())T=append(T,switch(T[j],"O",O=8,"8"=c("o","o")),j<-sample(sum(T>0),1))[-j];T
```
[Try it online!](https://tio.run/##DcPBCkBAEADQX9GcZmoUByWsX3CZmxy2RXZjbZZ8/vLqXSmt54U2sz4rm2i0RyJROoTFzygcX3ubDWV0E8MAPKiaoQZlEE7gPxG7Lo/6CPuC8TlQ@oK4JBpzN7WSqvQB "R – Try It Online")
Output as an array.
Thanks to [Robin Ryder](https://codegolf.stackexchange.com/users/86301/robin-ryder) for golfing out 6 bytes, for pointing out a bug in a previous version, and for golfing out an additional 4 bytes.
[Answer]
# [Perl 6](https://github.com/nxadm/rakudo-pkg), 55 bytes
```
{('o',{S:p(rand*.comb)[.]=<O 8 oo>[$/.ord%3]}...*)[$_]}
```
[Try it online!](https://tio.run/##JcfBCsIgAIfxV/kzrOkwc1kR1fYKHTqKyGp5ajnsNMRnt1WHD37f@AjPfR4mLB2aHGnpSx6vx5GG7tVX4u6HG9PCNOcLDvC@1WQtfOgXyiQhRMU0sSbldzehIBarFtFRYlkq4HxAzbHhUBxbjh1HLeefU/Lr3/wlT/kD "Perl 6 – Try It Online")
### Explanation
```
{                                                     }  # Anonymous block
     ,                                       ...*  # Infinite sequence
  'o'  # Start with string "o"
      {                                     }  # Compute next item by
       S  # replacing
        :p(rand*.comb)  # starting at random position
                      [.]  # any character
                         =<O 8 oo>  # with "O", "8" or "oo"
                                  [$/.ord%3]  # depending on ASCII code mod 3
 (                                               )[$_]  # nth item of sequence
```
[Answer]
# [C# (Visual C# Interactive Compiler)](http://www.mono-project.com/docs/about-mono/releases/5.0.0/#csc), ~~172~~ ~~158~~ ~~150~~ ~~149~~ ~~144~~ ~~137~~ ~~130~~ 128 bytes
```
a=>{dynamic r=new Random(),g="o",i;while(a-->0)g=g.Remove(i=r.Next(g.Length),1).Insert(i,"O,8,oo".Split(',')[g[i]%3]);return g;}
```
[Try it online!](https://tio.run/##bcxBS8MwGMbx@z5FKMgSSENrFYSYHoXBcDAPHsYOoXuXvbC@keTdpsg@e9Wj7a4//s/T5bLLOGT2jJ14OVH3jMQ6c0IKrdgLN3jXfu@@yPe/QXIEF7H2tIu9VDq4IhYa7eWAR5C@LNtKBRfMGvp4BokumVf4ZBnMEijwQelamQVlSCxRFyv9pGMszNvHEVnO9Vxtwga3d81W2QR8SiSCvQ52NntPyLBEArmXtVL2H9yPoRnDwxgex1BXk9eJNNV0dWN2q/qz4Qc "C# (Visual C# Interactive Compiler) – Try It Online")
-14 bytes thanks to @Jitse's observation about character modulus
-8 bytes by renaming a variable I forgot about
-1 byte by switching to a while loop
-5 bytes by not saving the current character to a variable
-7 bytes by switching to the interactive compiler
-7 bytes by chaining declarations and inlining assignment thanks to @my pronoun is monicareinstate
-2 bytes by changing to string split over character comparison thanks to @Olivier Grégoire for inspiration
[Answer]
# [J](http://jsoftware.com/), 54 bytes
```
'oO8'{~(((1+2={)`[`(1"0@])}#(3|1+{)`[`]})~1?#)^:(]`0:)
```
[Try it online!](https://tio.run/##y/pvqWhlGGumaGWprs6lpKeepmBrpaCuoKNgoGAFxLp6Cs5BPm7/1fP9LdSr6zQ0NAy1jWyrNROiEzQMlQwcYjVrlTWMawy1wUKxtZp1hvbKmnFWGrEJBlaa/zW5UpMz8hXSFEwN/gMA "J – Try It Online")
Wholly different approach to shave off 2 bytes
# original solution
# [J](http://jsoftware.com/), 56 bytes
```
'oO8'{~(({.,(i.@3(>:@i.{ ::0 0[){),>:@[}.])~1?#)^:(]`0:)
```
[Try it online!](https://tio.run/##y/pvqWhlGGumaGWprs6lpKeepmBrpaCuoKNgoGAFxLp6Cs5BPm7/1fP9LdSr6zQ0qvV0NDL1HIw17KwcMvWqFaysDBQMojWrNXWAAtG1erGadYb2yppxVhqxCQZWmv81uVKTM/IV0hRMDf4DAA "J – Try It Online")
Had an equal byte solution, but adjusted it slightly using Adam's idea of doing all the calculation in pure integers, and saving the translation-to-string step till last, which I felt looked a bit cleaner.
[Answer]
# [Perl 5](https://www.perl.org/), 79 bytes
```
sub f{$_[0]?do{$_=f(-1+pop);substr($_,rand length,1)=~y/oO8/O82/;s,2,oo,r}:"o"}
```
[Try it online!](https://tio.run/##FYxBCsIwEEWvMoQsEpw2bVEsluoRegCVoLRRoWRCEhci9eox3X147303@XmXUnjfwXy5PlfX00h59EYU9caRk11mIXrBNfqbHWGe7CM@sZb976NoaNXQNqoL2CAR@uXAiC0prKrYS1gL5182AuMaiiMwNPlKIrtYBoY81GW5rdIf "Perl 5 – Try It Online")
```
sub f {
  $_[0]
  ? do{
      $_ = f(-1+pop);
      substr($_,rand length,1) =~ y/oO8/O82/;
      s,2,oo,r
    }
  : "o"
}
srand(7) and print "$_ -> ",f($_),"\n" for 1..40
```
[Answer]
# [Charcoal](https://github.com/somebody1234/Charcoal), 38 bytes
```
⊞υoＦＮ«≡⊟υo⊞υO¦O⊞υ8Ｆ²⊞υo≔‽ＬυιＵＭυ§υ⁺λι»υ
```
[Try it online!](https://tio.run/##VY1LCsIwFEXHzSpCRwlUqI6kHRVHBbXBHcQ2bQP5lHxUkK49NlVEZ493zr23HalpNRUhEG9H5DOY6hSXoNcGolpN3p29vDKDMIZPkNg7d@0IEdET8u9XSy2LoQJ@G5rY8AHNL9ivoGM99cIVcB3ZYfg/ncwgqazlg0IXqjot0ZGpwY1xMIM8Gic6HbSUC42xytWqY494EuEtEtHCizcDYrhyS7AMYZvnYXMTLw "Charcoal – Try It Online") Link is to verbose version of code. Outputs an array, which is like a string but vertical (+1 byte to output the array horizontally). Explanation:
```
⊞υo
```
Start with a single `o`.
```
ＦＮ«
```
Loop the given number of generations.
```
≡⊟υ
```
Remove the last character and switch on it.
```
o⊞υO
```
If it's an `o` then push an `O`.
```
O⊞υ8
```
If it's an `O` then push an `8`.
```
Ｆ²⊞υo
```
Otherwise push `o` twice.
```
≔‽ＬυιＵＭυ§υ⁺λι
```
Rotate the array by a random amount. This causes the oozes to be evolved in a random order.
```
»υ
```
Finally output the resulting array.
[Answer]
# [Japt](https://github.com/ETHproductions/japt), ~~32~~ ~~31~~ 29 [bytes](https://en.wikipedia.org/wiki/ISO/IEC_8859-1)
```
_gZÊö _Ä %3ª1ö2Ãc}g[]á)Ëg"oO8
```
[Try it](https://petershaggynoble.github.io/Japt-Interpreter/?v=1.4.6&code=X2dayvYgX8QgJTOqMfYyw2N9Z1td4SnLZyJvTzg&input=MTAwCg)
```
 _               // function taking array
  gZÊö           // replace a random element with :
       _Ä %3     // element incremented mod 3
      ª1ö2Ã      // or [0,0]
            c}   // flattens
g[]á)            // run the function input times with initial value of array, return last element
      Ëg"oO8     // convert values to o O 8
```
Thanks to @Embodiment of Ignorance for reminding me I don't need = at beginning
[Answer]
# [Python 2](https://docs.python.org/2/), 104 bytes
```
from random import*
l=['o']
exec"i=randrange(len(l));l[i:i+1]='oO8o'[-~ord(l[i])%3::3];"*input()
print l
```
[Try it online!](https://tio.run/##K6gsycjPM/r/P60oP1ehKDEvBUhl5hbkF5VoceXYRqvnq8dypVakJitl2oJkgTg9VSMnNU8jR1PTOic60ypT2zDWVj3f3yJfPVq3Lr8oRQMoGqupamxlZRxrraSVmVdQWqKhyVVQlJlXopDz/7@hAQA "Python 2 – Try It Online")
Golfing [Jitse's](https://codegolf.stackexchange.com/a/196141/20260) solution using the mutability of lists.
[Answer]
# [Java (JDK)](http://jdk.java.net/), 138 bytes
```
n->{var s=new StringBuffer("o");for(int i;n-->0;s.replace(i*=Math.random(),i+1,"O,8,oo".split(",")[s.charAt(i)%3]))i=s.length();return s;}
```
[Try it online!](https://tio.run/##PY8xa8MwEIX3/IpDYJBSWThNCiWuA@1Q6BAyZCwZFFtO5NqSkc4pIfi3p7IdOhy6h959966SFxlXxc9dN611CFXQokNdi7IzOWprxDyd5bX0HrZSG7jNANruWOscPEoMz8XqAprwR/fotDl9H0C6k2ejFeDL4OcD9bY7VirHDZSQ3U28uV2kA58Z9QvT6EdXlspRYglLS@uoNgg6NXG8SVIvnGprmSuq59lW4lk4aQrbUMb104KTHX/l1hLh21ojJZywby/ys3TvSDWLlgfGdOZFrcwJz5SlTmHnDPi0v6dj0LAsREfl0UP2CA@w4PDMYclhxeGFwyIJOtQyGfpRTF0y@vsJFbLDGH6grScm@0furx5VI2yHog1XY0lJtCrWEPnIED66OZRCtm19pYNibML2s6H6@x8 "Java (JDK) – Try It Online")
## Credits
* -2 bytes thanks to [Kevin Cruijssen](https://codegolf.stackexchange.com/users/52210/kevin-cruijssen)
[Answer]
# [Zsh](https://www.zsh.org/), ~~75~~ 73 bytes
```
s=o
m=(oo 8 O)
repeat $1 ((n=1+RANDOM%$#s))&&s[n]=$m[m[(i)$s[n]]-1]
<<<$s
```
~~[Try it online!](https://tio.run/##TYwxC8IwEEb3@xUHvZY7i7RBBIdmEFy14Bo6iKTUoYmYDsXS3x4jLm7vPT6@dxhiz8IxaA@jZo8tHtB7gZd92tuEpJDZaVVej5dTe84pCyJFEYzrNI1GlaPhh9DXuw6apqEQBaBHVdcAGU42TOA0Mf8OMMd9XYuAnVPskVzC@@AToMY0w92GKbPzVgmWSEtGi52ryq/rvxrfdqmIxA8 "Zsh – Try It Online")~~
[Try it online!](https://tio.run/##TYwxC8IwEEb3@xUHvZY7S7FBBIdmEFy14Bo6iKTUoYmYDsXS3x4jLm7vPT6@dxhiz8IxaA@jZu/xgK3Ayz7tbUJSyOy0Kq/Hy6k955QFkaIIxnWaRjMafgh9ratUB03TUIgC0KOqa4AMJxsmcJqYfweY476uRcDOKfZILuF98AlQY5rhbsOU2blSgiXSktFi5@3Wr@u/Gt92qYjEDw "Zsh – Try It Online")
I want to focus here specifically:
```
$m[m[(i)$s[n]]-1]
   m[        ]     # from array $m:
     (i)           #   get the index of 
        $s[n]      #   the nth character in the string (as a pattern)
                   #   if not found substitute 4 (length of array + 1)
              -1   # subtract one
$m[             ]  # substitute the element at that index
```
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), ~~21~~ 16 bytes
```
1F‘JX$¦ḃ3Ʋ¡ị“oO8
```
[Try it online!](https://tio.run/##y0rNyan8/9/Q7VHDDK8IlUPLHu5oNj626dDCh7u7HzXMyfe3eNQw9z9QgYEBAA "Jelly – Try It Online")
A full program that takes `n` as its argument and implicitly outputs the state of the oozes after that many generations.
Thanks to @cairdcoinheringaahing for saving a byte!
## Explanation
```
1                 | Literal 1
         Ʋ¡       | Repeat the following the number of times given by the argument
 F                | - Flatten
  ‘  $¦           | - Increment the item at the index given by:
   J              |   - Sequence along the list
    X             |   - Random number fron the sequence
       ḃ3         | Convert to bijective base 3
           ị“oO8” | Index into "oO8"
```
[Answer]
# [Python 3.8](https://docs.python.org/3.8/), 91 bytes
```
f=lambda n,s='o':n and f(n-1,s[:(k:=id(s)//7%len(s))]+'oO8o'[-~ord(s[k])%3::3]+s[k+1:])or s
```
[Try it online!](https://tio.run/##FY1BDoIwEEX3nmI2pG0YQmsl4iScwQOQLjBIJOC0adm48eq1bv5/L3/xw@d4ebZ9iDkvwz69H/MEjGkQXhDDxDMskhuDaSS50bDOMqm2vVb7kwspVwt/770Ym6@PZRs3pypLZF1duDbklI@Q8lKSYWXQaPCMFi/YodHYFdf/0njTmk4Q4sqHLJ9K5R8 "Python 3.8 (pre-release) – Try It Online")
I'll be perfectly honest, I don't know for sure that this is valid randomness. It seems like it to me, but I'm not sure how I'd determine one way or the other - if someone could confirm or deny, that'd be much appreciated.
Assuming validity, this is a modification of [Jitse's](https://codegolf.stackexchange.com/questions/196139/simulate-reproduction-in-a-population-of-oozes/196141#196141) answer that gets rid of the import. `id(s)` gives a different integer every time, but just taking it modulo `len(s)` gave results that were too consistent. Integer dividing the id by 7 seemed to do the trick, but again, I'm not sure how to verify.
If this turns out not to be valid, I'll delete immediately.
[Answer]
# JavaScript (ES10), 91 bytes
Similar to the ES6 version, but returns an array of characters.
```
n=>(g=P=>n--?g(P.flatMap(c=>i--?c:'8O'[c|c>g]||['o','o'],i=Math.random()*P.length|0)):P)`o`
```
[Try it online!](https://tio.run/##HYixCoMwFAD3foVbkvIMUVsolqRTR6m7CIaoUbHviUon/93aDscdN9iPXdzcT2uIVDd7q3fUhnuda4Nh@PA8l@1o18xO3GnTH8ul7PZihduc8eW2FYwYHJTQ68yunZwt1vTm4pzLsUG/dpsSIs1FRdV@LyKIIYELXCFSECtI1BG/@luVJ9nS/LSu4xhoEzjChcZGjuQ5QtByFHKgHjljQoj9Cw "JavaScript (Node.js) – Try It Online")
---
# JavaScript (ES6), ~~98 ... 94~~ 93 bytes
```
n=>(g=P=>n--?g(P.replace(/./g,c=>i--?c:'8O'[c|c>g]||'oo',i=Math.random()*P.length|0)):P)('o')
```
[Try it online!](https://tio.run/##HcixDoIwFEDR3a9ga2sepYAmBtM6ORrZCUNTSsHgewSIE/@O6HRP7st@7OymflxipMZvrd5QGx50qQ3G8S3wUk5@HKzzPJFJAKdNv39XsMuTVW51JtTryogY9Pphl05OFht6c3Es5eAxLN2qhChKwRkxsV2rFDLI4QRnSBVkCnK146d/VX2QLU136zqOkTaRI5xp8HKgwBGilqMQYvsC "JavaScript (Node.js) – Try It Online")
### Commented
```
n => (                       // n = number of generations
  g = P =>                   // g is a recursive function taking the population string P
    n-- ?                    // decrement n; if it was not equal to 0:
      g(                     //   do a recursive call:
        P.replace(/./g, c => //     for each character c in P:
          i-- ?              //       if we haven't reached the requested position:
            c                //         leave c unchanged
          :                  //       else:
            '8O'[            //         replace with:
              c | c > g      //           'O' is c != 8 and c is lowercase
            ]                //           '8' is c != 8 and c is uppercase
            || 'oo',         //           'oo' if c = 8
          i = Math.random()  //       compute a random position i within the current
              * P.length | 0 //       population string
        )                    //     end of replace()
      )                      //   end of recursive call
    :                        // else:
      P                      //   return the final population
)('o')                       // initial call to g with P = 'o'
```
[Answer]
# [Red](http://www.red-lang.org), 93 bytes
```
func[n][s: copy"o"loop n[replace at s i: random length? s s/:i select[#"o"#"O"#"8":oo]s/:i]s]
```
[Try it online!](https://tio.run/##JY7BCsIwEETv/Yoh/YDG1oLk4icIXkMOIdnaQt0NSUX8@prqYXkzuzOwmeJ@p2hdkz1HeXaFKILl3UwG@/TiYNnZYhAkfZSoVSSBbaa0@kDwGwoWg38ZK/Fjm691VzqzoNBKYbNt7bXqVueijIg7bq64fZJMPsxg2BN6DDhjxEmj1xg0Rl31YX7UDjblhbcKXx@sWWUUJrBz@xc "Red – Try It Online")
[Answer]
# [K (oK)](https://github.com/JohnEarnest/ok), 51 bytes
```
{"oO8"x{{,/(x#t),((1;2;0 0)t@x),(x+1)_t}1?#t:x}/,0}
```
[Try it online!](https://tio.run/##y9bNz/7/P82qWinf30KporpaR1@jQrlEU0dDw9DayNpAwUCzxKECyK3QNtSML6k1tFcusaqo1dcxqP2fpm6oYKRgrGCiYKpgaKBgZKBgagBkgFgG/wE "K (oK) – Try It Online")
No doubt this can be done much shorter / more elegant (using ammend?). I'm somewhat happy that it works at least.
[Answer]
# [Retina](https://github.com/m-ender/retina/wiki/The-Language), ~~29~~ 27 bytes
```
K`o
"$+"{@T`\oo`\O80`.
0
oo
```
[Try it online!](https://tio.run/##K0otycxLNPz/3zshn0tJRVup2iEkISY/PyHG38IgQY/LgCs///9/QwMDAA "Retina – Try It Online") Edit: Saved 2 bytes when I realised how I could combine `@` with `T`. Explanation:
```
K`o
```
Replace the input with the initial generation.
```
"$+"{
```
Repeat the remaining stages for the given number of generations.
```
@T`\oo`\O80`.
```
The `O` is a metacharacter and needs to be escaped. The `o` is also a metacharacter, so the first `o` is literal, while the second `o` represents `O80` from the destination pattern. This therefore transliterates the characters `oO8` to `O80`. The final `.` means that each character is treated as a separate match for the purposes of the `@` operator, which chooses one match (i.e. character) at random to be transliterated.
```
0
oo
```
Fix up any `0` to `oo`. (This stage does not need to be conditional.)
[Answer]
# Python 3, 142 bytes
```
from random import*
def f(i,x='o'):i-=1;s=randint(0,len(x)-1);o={'o':'O','O':'8','8':'oo'};x=x[:s]+o[x[s]]+x[s+1:];return x if i<1else f(i,x)
```
[Answer]
# [Icon](https://github.com/gtownsend/icon), 85 bytes
```
procedure f(n)
s:="o"
1to n&s[p:=?*s]:=["O",8,"oo"][find(s[p],"oO8")]&\z
return s
end
```
[Try it online!](https://tio.run/##bc/NCoMwDAfwe5@i5CDt8KD7ACnIHsEHcD2IrVA2E2mVgS/vlO2w1eX2S/4kxLWEy8PhnfsGDfXL4Km1ZvKWdwIlC6oEApaPxDEJ9aDK6yFoVdZQQVqkQAS67hwasQ716qoAqZPbzLwdJ488MIvma2vfOBSS8bXeF91sP356N1rRiVz@@hj5FPkc@RI5z@KF2S6xj/zJbK3tmxc "Icon – Try It Online")
[Answer]
# [C (gcc)](https://gcc.gnu.org/), 101 bytes ~~104 117 bytes~~
```
char*h,g[9999];l;f(a){*g='o';for(l=1;a--;(*h="O8o"[*h%3])-'o'?:bcopy(h,h+1,l++))h=g+rand()%l;g[l]=0;}
```
[Try it online!](https://tio.run/##hY5NCsIwEEb3PUUpFCf9gdQqqEPwCB6gdhGjTcSYSFoXIj17LEVcmm81zHvDfKKUQngvFHeZKmSzndKixg44eWeSLewCO@tAswp5WSJkiiWHjU2aTKV1S8pJ2O9Owj5eoAqVV4XOc0IUk7nj5gwk1Sgb3TKKo7@aIb7zqwESvaN4Sj87QltxA0Jw3nVQfaeHmw46SNL@aJJC/vgywOsAXwX4OsArGioYEmoafEH/K@4yPJ2JKUZj5D8 "C (gcc) – Try It Online")
**(Many thanks to ceilingcat for the awesome code golfing help and ideas!)**
Ok, except for large generation count buffer overflow and the fact that I seeded random outside the code, this now works. Making g bigger could put the overflow size above what an int can hold if needed.
### Commented
```
char *h,g[9999]         // Work pointer and a fixed size buffer.  
l;                      // int length of string (number of slimes)
f(a){                   // a is generation
  *g='o'                // Set first value. 
  for(l=1;              // Length is 1.
   a--;                 // consume a generation
   (*h="O8o"[*h%3])     // Use the mod 3 trick to index into the next symbol and assign the new slime character.
   -'o'?:               // if we went back to 'o', grow the string
   bcopy(h,h+1,l++))    // move all the values up in in array to length (including new 'o' symbol) Note: bcopy() can overlap src and dest.
    h=g+rand()%l;       // for each loop, find which slime to evolve and point h to it.
  g[l]=0;}              // NUL Terminate the g buffer to make it a string. 
```
[Answer]
# [C (gcc)](https://gcc.gnu.org/) (with `-m32` compiler flag), 174 172 bytes
Thanks to ceilingcat for the suggestions.
Not competing (there are already shorter versions in C), but this uses a different method.
Instead of using a hard-coded output buffer, I use a linked list on the stack to hold each cell's state and traverse the list to locate cells to mutate. If the cell splits in two, the function calls itself to hold the new cell state and adds itself into the list chain. As the list is not necessarily linear on the stack, the last function prints the list of cells (intermediate callers set their list start to `NULL` after control returns to them to prevent unwanted output.)
```
g(i,j,s,p)int*s,*p;{int a[2]={},r;for(j++?*a=*p,*p=a:(s=a);i--;++p[1]>2?p[1]=0,g(i,j,s,a),s=i=0:0)for(r=rand(p=s)%j;r--;p=*p);for(;s;s=*s)printf(L"oO8"+s[1]);}f(i){g(i,0);}
```
[Try it online!](https://tio.run/##VU9BTsMwELznFaugSrbjIDcFCdW4/UAFJ04VB@M0qas2sewUDlG@zmIHOPS0s7Oe8YwpW2MQW2L5iQfuqO0GFjhzcowI9L56V@PEvWx6T05FsWVaMRfvSq9JUJpKW5ayKNx@@b6ptmkowf/tNOVBWSXWgia9V153NXEq0MVJ@ih00YzO3jLIoFigzsd/G7LL@9envAjRj8qpIZaOyVTEBe9sZ87X@gDPYahtf3/cZDfU2X7ccoO9HBKTpUoXbTsyd/Ot4WCO2gNjcfmkMGYA6WRlBClVmAMnPXl52@0olcCKIj2W4K5DIHlOowz@UueLGtQGcg5W6aG35Nc3qlIDCVM2IQpcYoUrfMBHXAqsBK4iJRKap/g2zVm3AcvLqsLy6wc "C (gcc) – Try It Online")
[Answer]
# [Lua](https://www.lua.org/), ~~106~~ ~~101~~ 110 bytes
**Changed Code to function format + 9 bytes**
```
e={"O",8,"oo"}for i=1,t do s=math.random(1,#o)o=o:sub(1,s-1)..e[o:sub(s,s):byte()%3+1]..o:sub(s+1)end return o
```
[Try it online!](https://tio.run/##TY6xasNAEER7fcVyJnBrnw4fIRAMqlOmMKQJKc7SCiuRb83tXmGbfLsixSkyxcAbBmbGEqdT1KPPMXV8EqLOsvh25PbL4jpsf4VQ1/fCcCXQIwEXPReFzyIKPWfoS6qq2VodOEFv2YHiRM3NvBr37Ayz@V56QxOcQscgzb9ZG9yKkRveSTnMIHVA7@n9zuIEd4eLksWHx0348P4v3wSk1EEmLTkBTzNU1TkPSW1vDRsHT1tcvsNeY1Z4i2MhBy@UKMflqEw/ "Lua – Try It Online")
[Answer]
# APL(NARS), chars 62, bytes 124
```
{⍵{⍺=0:⍵⋄(⍺-1)∇(⍵↑⍨k-1),(('oO'⍸k⊃⍵)⊃"O"'8'"oo"),⍵↓⍨k←?≢⍵},'o'}
```
test:
```
  h←{⍵{⍺=0:⍵⋄(⍺-1)∇(⍵↑⍨k-1),(('oO'⍸k⊃⍵)⊃"O"'8'"oo"),⍵↓⍨k←?≢⍵},'o'}
  h 0
o
  h 4
oO
  h 10
8OO
  h 100
8oOOO8ooOO8oOOoO8oOooooO8OO
  h 200
8OO888Ooo8OO8oO88O8oo8oooooOo8ooO8OooOO88OoO8O8o8Oo
```
but it has problems if the argument is >500, the 73 chars code below has not
these problems:
```
r←f w;k
r←,'o'
→0×⍳0>w-←1⋄r←(r↑⍨k-1),(('oO'⍸k⊃r)⊃"O"'8'"oo"),r↓⍨k←?≢r⋄→2
  f 1000
    O8oooo8OoooO8ooOO88oo88OOOoo8oOoO8888oo88ooOOOoooooo8oooOO8OooO8O8oOO8oOOOo88Oo
  Ooooo88O8o8ooooo8OOooOO8O8OOOoo8OoO8Oo88ooOOoooO888O8o8OoOOoooOo8oooo8OoO
  88Oooo8O8OoooooooOo88oo8oooooo8OOoO8oOO8Oo8oo8oO88oo8OOoOoOOoOoOoo8O88o8O
  88OoO8OOoOo8Oo8ooo8OoooooooooOOooO8oo88
```
[Answer]
# [Lexurgy](https://www.lexurgy.com/sc), 306 bytes
Uses `oO%` for ooze states. Since Lexurgy doesn't have a random feature, the program deterministically moves a pointer from right to left in the ooze string, incrementing the ooze at that pointer. Iteration stops when the generation counter hits 0.
Note: This seems to work all the way up to 83 generations; 84 or more generations has the interpreter complain about how the propagation doesn't converge to an endpoint.
```
Class u {o,O,%}
Class d {\1,\2,\3,\4,\5,\6,\7,\8,\9,\0}
p:
*=>`ol/_ $
e propagate:
@d=>{\0,\1,\2,\3,\4,\5,\6,\7,\8,s\9}/_ `
@d s=>{\0,\1,\2,\3,\4,\5,\6,\7,\8,\9} *
then:
\0 `=>*/$ _
\0=>*/$ _
then:
@u=>{O, %, oo}/_ l//$ ` _
then:
@u$1 l=>l $1
then:
*=>l/` l @u* _ $
l=>*/` _
s:
{s,l,`}=>*
```
Ungolfed explanation:
```
Class ooze {o, O, %}
Class next {O, %, oo}
Class digit {\1,\2,\3,\4,\5,\6,\7,\8,\9,\0}
Class dec   {\0,\1,\2,\3,\4,\5,\6,\7,\8,s\9}
Class dec2  {\0,\1,\2,\3,\4,\5,\6,\7,\8,\9}
# setup: generate initial digit-ooze sep, `o`, and pointer
pre:
* => `ol / _ $
# [gens left]`[oozes][growth pointer]
# while the input was changed last iteration...
evolve-once propagate:
# decrement the generation counter
@digit => @dec / _ `
@digit s => @dec2 * # handle carries
then:
# remove leading 0s
\0 ` => * / $ _
\0 => * / $ _
then:
# grow an ooze if it's right before the growth pointer
# but not when there's no generations left
@ooze => @next / _ l // $ ` _
then:
# move the growth pointer to the left
@ooze$1 l => l $1
then:
# move the growth pointer to the end if it's at the left side of the ooze string
* => l / ` l @ooze* _ $
l => * / ` _
# remove extraneous characters
strip:
{s,l,`} => *
```
]