Simulate reproduction in a population of oozes
Python 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!
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!
Ruby, 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!
-11 bytes thanks to Value Ink and Jitse
APL (Dyalog Unicode), 40 32 31 bytesSBCS
Full program. Prompts for N from stdin.
'o8O'[{∊⌷∘3(1 1)2@(?≢⍵)⊢⍵}⍣⎕,1]
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)