text:
Convert Complex Chinese Numbers into Arabic Numbers
Your task is to convert Chinese numerals into Arabic numerals.
A problem similar to Convert Chinese numbers, however, more complex. Also, answers given there mostly don't satisfy all the conditions.
Chinese digits/numbers are as follows:
0 零 1 一 2 二 2 两 3 三 4 四 5 五 6 六 7 七 8 八 9 九 10 十 100 百 1000 千 10000 万 10^8 亿
Multiple-digit numbers
Multiple-digit numbers are created by adding from highest to lowest and by multiplying from lowest to highest. In case of additions, each number higher than 9 can be multiplied by 1 and it won't change its meaning. Both 亿万千百十一 and 一亿一万一千一百一十一 are equal to 100011111.
We multiply in the following fashion: 五千 = 5000 一百万 = 1000000 三千万 = 30000000.
Chinese always takes the lowest possible multiplier (just like we don't say hundred hundred but ten thousand). So 百千 doesn't exist to represent 100000 since we have 十万, 十千 doesn't exist since we have 万, 十千万 doesn't exist, since we have 亿, 十百 doesn't exist, since we have 千.
Special cases
0 is very important and it was actually the biggest problem in the other code golf question. Trailing zeroes are omitted in Chinese, so 零 indicates interior zeroes.
Let's look at some examples:

三百零五 = 305
三百五 = 350 - no interior zeroes. You can notice that we don't need 十 here, since a trailing zero is omitted.
一千万零一百 = 10000100
三千零四万 = 30040000
六亿零四百零二 = 600000402 - here we have 2 interior zeroes. As you can see though, even if there's a gap of more than one order of magnitute (in the example it's 亿 and 百), two 零s can't stand next to each other, one is enough for each gap, no matter how big it is.
一亿零一 = 100000001 - again, no need for more than one 零 if there's one gap, no matter how big.
八千万九千 = 80009000 - no need for 零 since there are no interior zeroes. Why are there no interior zeroes? Because it follows the highest-to-lowest addition without omitting an order of magnitude. Right after 万 we have 千 (九 is a multiplication component, not addition one) and not, let's say, 百.

More examples: Check out the two "示例" paragraphs
2 is also special in Chinese as it can be represented with a character 两 if it's a multiplier of 100 and higher numerals. Both 两千两百二十二 and 二千二百二十二 are 2222.
Rules
Constraints: 0 <= N < 10^9
Edit: I don't care what happens from 10^9 onwards. Input doesn't have any examples equal or higher than 10^9 for that reason.
Test cases
Input:
一亿两千三百零二万四千二百零三
四千万零一十
三十四万五千五
四亿二十万零九百零一
两千万九千零一十
二十四万零二百二十二
两千零十二
零

Output:
123024203
40000010
345500
400200901
20009010
240222
2012
0

Good luck!

Chinese speaker here - I don't think I ever use 零 for interior zeroes unless the place value isn't specified - ex. 350 (三百五) vs 305(三百零五). Otherwise, the position is clearly indicated by the base characters.... (ex. 2012 would be 两千十二 which literally reads two thousand ten two, no need for interior zeroes)

Thank you for your response! You are right that if a zero is before anything other than a unit digit it's optional (but not prohibited). Let's take the 2012 case as an example. It can be both. If you look at chapter numbers for internet novels, they indeed always add 零.

So just to clarify - is it ok to output with or without? You should specify this in the question

The output is Arabic numerals, in the input there are many cases with 零. As long as the input matches the output, it's correct. Your code should therefore be able to correctly interpret an example with 零 inside, while also output 0 for 零 as input.

Is there any special logic by which one can say 一亿两千三百零二万四千二百零三 is 1100000000+(21000+3100+010+2)10000+41000+2100+010+3 and not (1100000000+21000+3100+010+2)10000+41000+2100+010+3? )

I'm not sure if I understand the question, as your second example returns a number higher than a trillion. The first one is correct. Maybe you can think of it as building blocks? (1)[10^8] (2302)[10000] (4)[1000] (2)[100] (0)[10] (3)[1]
Edit: Of course the (2302) block creator is also made of a smaller block - (2)[1000] (3)[100] (0)[10] (2)[1]

Ok, I understand the question now, Yes, there is. "Multiple-digit numbers are created by adding from highest to lowest and by multiplying from lowest to highest." and "Chinese always takes the lowest possible multiplier." Just like in English you don't have thousand hundred but hundred thousand.

As you can see in my blocks example, () bracket have to be smaller than [] bracket, unless it's [1]. Also for [100] and [1000] the () bracket has to be lower than 10. For [10000] the () bracket has to be lower than 10000. For [10^8] we have a constraint, so () has to be lower than 10. Hope that helps.

Remember that the output for 零 itself should be 0. Why not make it a test case, then?

Fair point. Added.

05AB1E, 52 51 bytes
0•9∊»£¬ƵçoiKβÐg•19вIÇƵª%èvX¨UOy¬iθ°UX‰¤_ªX*]DgiX*}O

Try it online!
0                              # literal 0
 •9∊»£¬ƵçoiKβÐg•19в            # compressed list [2, 14, 0, 3, 0, 8, 0, 6, 2, 9, 0, 18, 0, 1, 0, 13, 5, 0, 10, 0, 0, 7, 12, 4]
                   IÇ          # codepoints of the input
                     Ƶª%       # modulo 270
                        è      # index into the above list, with wraparound
v                 ]            # for each number y in that list:
 X                             #  push the variable X
  ¨                            #  drop the last digit
   U                           #  store that in X
    O                          #  sum all numbers on the stack
     y                         #  push y
      ¬i          ]            #  if the first digit of y is 1:
        θ°                     #   10**(the last digit of y)
          U                    #   store that in X
           X‰                  #   divmod X
             ¤_ª               #   if the modulo is 0, append 1
                X*             #   multiply by X
Dgi  }                         # if length of the top of stack is 1:
   X*                          #  multiply it by X
      O                        # sum of the stack
                               # implicit output

The output is wrong for 一亿两千三百零二万四千二百零三 and will be wrong for anything that ends with 零2-9.

Also, it doesn't meet the upper constraint. I put it in place for 3 reasons: because the numbers are already high enough as it is; it just gets repetitive; we encounter a problem similar to long-short scale for arabic numbers (e.g. billion). The next numeral after 亿 is 兆. However, it can mean both 10^6, 10^12 or 10^16 depending on context. I think due to this confusion you would more often see 万亿 instead of 兆 in the context of e.g. trillion yuan. There's also an abberation of 亿亿 after this point... So let's just stop at 10^9.

@Rysicin: I fixed the 零2-9 case. I don’t understand your second comment, could you give an example of an input I handle incorrectly, and what the correct output would be?

The second comment is about the constraints. If the number is 10^9, then there shouldn't be any output as it goes over the limit. (If you wish, I can raise the constraint, however, we'd need to stop somewhere.)
Your code edit created a bug with numbers ending with 0 instead ending with 1. Check for example 一百 一千.

@Rysicin Things to avoid when writing challenges: Input validation. By default, it is assumed that all inputs are valid. If you really want to make input validation part of the question, you should explicitly state so in the question and add several test cases covering it.

@Rysicin I fixed the issue with numbers ending with 0.

Good job, looks like everything is correct! Thanks for the feedback, I'll remove constraints and just write that I don't care about what happens starting 10^9.


text:
Substitute Unprintable ASCII Characters
 Sandbox
Have y'all ever written an answer with unprintable ASCII characters in it and wished that there was an easy way to represent those characters in a printable way? Well, that's why the Control Pictures Unicode block was invented.
However, manually substituting these characters into one's answer is time-consuming, so that's what today's challenge is about: swapping out the nasty invisible characters for nice, readable characters.
Input
You will be given strings that contain a mix of ASCII-only characters (i.e. the UTF-8 code point of each character will be in the range: \$0 \lt char \le 127\$).
Output
For all unprintable characters, replace it with its corresponding character in the Control Pictures Unicode range.
In other words:

Characters in the range \$0 \lt char \lt 9\$ are replaced with their corresponding character
Horizontal tabs and newlines (9 and 10) aren't replaced
Characters in the range \$11 \le char \lt 32\$ are replaced with their corresponding character
Spaces (32) aren't replaced
The delete character (127) is replaced with its corresponding character: ␡

Tests
Characters are given as escapes for nice formatting here, but each character will be replaced with the unprintable character
In -> Out
\x1f\x1c\x1f\x1e\x1f\x1e\x1f\x1f\x1e\x1f\x1e\x1f -> ␟␜␟␞␟␞␟␟␞␟␞␟
Hello\x07World! -> Hello␇World!
\x01\x02\x03\x04\x05\x06\x07\x08\x0c\x0b\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x7f -> ␁␂␃␄␅␆␇␈␌␋␎␏␐␑␒␓␔␕␖␗␘␙␚␛␜␝␞␟␡
\r -> ␍

Rules

All standard loopholes are forbidden
Character substitutions must be made according to the Control Pictures Unicode block
Input will be given with the literal unprintable characters

Scoring
This is code-golf so the answer with the fewest amount of bytes wins.
Test-Case Generator
I have provided a test case generator for y'all. It prints inputs in the way they will be passed to your program and outputs the expected result.
Try it here!
Leaderboards
Here is a Stack Snippet to generate both a regular leaderboard and an overview of winners by language.
To make sure that your answer shows up, please start your answer with a headline, using the following Markdown template:
# Language Name, N bytes

where N is the size of your submission. If you improve your score, you can keep old scores in the headline, by striking them through. For instance:
# Ruby, <s>104</s> <s>101</s> 96 bytes

If there you want to include multiple numbers in your header (e.g. because your score is the sum of two files or you want to list interpreter flag penalties separately), make sure that the actual score is the last number in the header:
# Perl, 43 + 2 (-p flag) = 45 bytes

You can also make the language name a link which will then show up in the leaderboard snippet:
# [><>](http://esolangs.org/wiki/Fish), 121 bytes

var QUESTION_ID=196014;
var OVERRIDE_USER=78850;
var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;function answersUrl(d){return"https://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+d+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(d,e){return"https://api.stackexchange.com/2.2/answers/"+e.join(";")+"/comments?page="+d+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(d){answers.push.apply(answers,d.items),answers_hash=[],answer_ids=[],d.items.forEach(function(e){e.comments=[];var f=+e.share_link.match(/\d+/);answer_ids.push(f),answers_hash[f]=e}),d.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(d){d.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),d.has_more?getComments():more_answers?getAnswers():process()}})}getAnswers();var SCORE_REG=function(){var d=String.raw`h\d`,e=String.raw`\-?\d+\.?\d*`,f=String.raw`[^\n<>]*`,g=String.raw`<s>${f}</s>|<strike>${f}</strike>|<del>${f}</del>`,h=String.raw`[^\n\d<>]*`,j=String.raw`<[^\n<>]+>`;return new RegExp(String.raw`<${d}>`+String.raw`\s*([^\n,]*[^\s,]),.*?`+String.raw`(${e})`+String.raw`(?=`+String.raw`${h}`+String.raw`(?:(?:${g}|${j})${h})*`+String.raw`</${d}>`+String.raw`)`)}(),OVERRIDE_REG=/^Override\s*header:\s*/i;function getAuthorName(d){return d.owner.display_name}function process(){var d=[];answers.forEach(function(n){var o=n.body;n.comments.forEach(function(q){OVERRIDE_REG.test(q.body)&&(o="
"+q.body.replace(OVERRIDE_REG,"")+"
")});var p=o.match(SCORE_REG);p&&d.push({user:getAuthorName(n),size:+p[2],language:p[1],link:n.share_link})}),d.sort(function(n,o){var p=n.size,q=o.size;return p-q});var e={},f=1,g=null,h=1;d.forEach(function(n){n.size!=g&&(h=f),g=n.size,++f;var o=jQuery("#answer-template").html();o=o.replace("{{PLACE}}",h+".").replace("{{NAME}}",n.user).replace("{{LANGUAGE}}",n.language).replace("{{SIZE}}",n.size).replace("{{LINK}}",n.link),o=jQuery(o),jQuery("#answers").append(o);var p=n.language;p=jQuery(""+n.language+"").text().toLowerCase(),e[p]=e[p]||{lang:n.language,user:n.user,size:n.size,link:n.link,uniq:p}});var j=[];for(var k in e)e.hasOwnProperty(k)&&j.push(e[k]);j.sort(function(n,o){return n.uniq>o.uniq?1:n.uniq<o.uniq?-1:0});for(var l=0;l<j.length;++l){var m=jQuery("#language-template").html(),k=j[l];m=m.replace("{{LANGUAGE}}",k.lang).replace("{{NAME}}",k.user).replace("{{SIZE}}",k.size).replace("{{LINK}}",k.link),m=jQuery(m),jQuery("#languages").append(m)}}
body{text-align:left!important}#answer-list{padding:10px;float:left}#language-list{padding:10px;float:left}table thead{font-weight:700}table td{padding:5px}
  <link rel="stylesheet" type="text/css" href="https://cdn.sstatic.net/Sites/codegolf/primary.css?v=f52df912b654">

Winners by Language

Language	User	Score

Leaderboard

	Author	Language	Size

{{PLACE}}	{{NAME}}	{{LANGUAGE}}	{{SIZE}}

{{LANGUAGE}}	{{NAME}}	{{SIZE}}

Your Hello,\x07World testcase disagrees with itself over whether it should contain a comma.

@JoKing, Lynn, both issues fixed

You say input will be limited to 0-127 but you have ¿⊙ in your test cases?

Why not include vertical tabs, newlines, or spaces? The newlines and spaces in particular make this challenge worth it.

Maybe add the idea that the environnement is in the LC_ALL=C locale, so that some ranges are readily available ( [ -~] for exemple). The locale is often compatible with that range... but not always. (for ex see: https://stackoverflow.com/a/3208902/1841533 )

Does the output need to be UTF-8, or can it be any valid Unicode encoding?

Oof. Runic (or the C# interpreter) does not like many of the input bytes. I spent probably 20 minutes trying to figure out why it was dying when trying to handle 0b11 and it turns out that it never gets into the string-on-the-stack.

@Grimmy, fixed. I've got no clue how I missed that.

Zsh, 83 79 78 bytes
-4 bytes by changing to a recursive solution, (-0 from bugfix,) -1 by abusing unquoted empty parameters expanding to 0 words
<<<${1+"${(#)$((x=#1,x>126?x+9122:(x<9)^(x<11)^(x<32)?x+9216:x))}`$0 ${1:1}`"}

Try it online!
Try it online!

Try it online!
In arithmetic contexts, #1 is the code of the first character of $1. We use it 7 times, so x=#1, saves us 2 bytes. There may be a more compact way to do (x<9)^(x<11)^(x<32).
The ${1+foo} expands to foo unless $1 is undefined, providing our recursive base case. The "`$0 ${1:1}`" is the actual recursive call. When an empty parameter is unquoted, it is removed from the word list, thus causing the final recursion be run with zero arguments.
Running strings longer than about 35 characters with the recursive solution causes TIO to complain: "fork failed: resource temporarily unavailable". However, with usual resource limits on a desktop, there shouldn't be a problem.
Potential changes:

With the flag -oCPRECEDENCES, < binds more tightly than ^, which would save 6 bytes by removing parentheses.
With the flag -oEXTENDEDGLOB, we gain access to backreferences using (#m) and the $MATCH parameter. An approach like Arnauld's Javascript answer could be used, but it ends up being longer than the purely arithmetic approach.
I also tried a transliterate solution, but the larger codepoints of the control pictures grew the bytecount too quickly.

JavaScript (Node.js),  67  66 bytes
Saved 1 byte thanks to @Grimmy
s=>s.replace(/[^ -~ \n]/g,c=>(B=Buffer)([226,144,B(c)[0]%94+128]))

includes a literal TAB
Try it online!
How?
We match all characters that are:
   +-------> neither printable
   |  +----> nor a tabulation
   |  | +--> nor a linefeed
  / \ | |
[^ -~\t\n]

and replace them with the UTF-8 sequence \$[226, 144, (n\bmod94)+128]\$, where \$n\$ is the ASCII code of the original character.
This is equivalent to generating the code point \$(n\bmod94)+9216\$. But given the length of the corresponding JS method names, that would be 74 73 bytes in plain ES6:
s=>s.replace(/[^ -~ \n]/g,c=>String.fromCharCode(c.charCodeAt()%94+9216))

Try it online!

This is a good approach. However it must be noted that the [^ -~] range depends on the locale. To be sure it works it should be used along with a LC_ALL=C environnement ... (or LC_COLLATE, but LC_ALL is shorter)

@OlivierDulac As far as I know, regular expressions in Node (or JS) are not locale-aware. But I'd be interested in a counter-example. Also, note that the input characters are guaranteed to be in the range $[1,127]$.

I can't help here, as I don't know yet those 2 langages... But I'd be surprised if they didn't respect the user's locale and decided to overwrite it with their own "internal locale", even though in this case it seems more "logical". for other programs (perl, grep, awk, etc) on unix systems, the regex interpretation depends on the locale. In some locales, for ex,  [a-z] can be "a" or "B" or "b" or "C" or "c" ... or "Y" or "y" or "Z" or "z", ie all letters caps and non caps except for "A". In others, "e" may be followed by "é", etc. Good shell scripts needs to ensure proper locale setting.

That \t can be a literal tab character for -1 (TIO).

@Grimmy Nice catch. Thanks.

C (gcc), 119 109 108 89 75 bytes
Thanks to ceilingcat and Arnauld for the suggestions.
Like my original submission, the UTF-8 code sequence is largely hard-coded, but instead of using string literals an integer is used instead. This takes advantage of the fact that the LSB of an integer (on a little-endian processor) is the first byte stored in memory, and 0 MSB bytes map to NUL which terminates the string. For unprintable characters that map to the control pictures, three bytes are used to represent the value; one byte is used for everything else.
One trick which I use is to force the comparison of a contiguous range of values to zero so that I can use unsigned comparisons. This wraps around any values below the range to high values, allowing me to use a single compare (the d-9U>1, which is true for x<9 or x>10.)
d;f(char*s){for(;d=*s++;printf(&d))d=d>126|d<32&d-9U>1?d%94<<16|8425698:d;}

Try it online!
Original version (89 bytes)
As C doesn't handle UTF-8 natively, I output the hard-coded prefix bytes and compute the trailing byte (which is the only byte that requires changing) if I need to print a control picture glyph. Other than that, it's a pretty standard string-processing function.
d;f(char*s){for(;d=*s++;printf(d>126|d<32&d-9U>1?"\xE2\x90%c":"%2$c",d%94+128,d));}

Try it online!

83 bytes

75 bytes by expanding on @ceilingcat's last version.

Retina 0.8.2, 27 24 bytes
T`-`␁-␟␡`[^	\n]

Try it online! Transliterates the unprintables to the appropriate control pictures, but the tabs and newlines are excluded (for a 3-byte saving). Note: No CRs in the test cases because I don't know how to demonstrate them in TIO. Code would probably work with nulls with the obvious adjustments for the same byte count, but I don't know how to test that either.

Python 3, 69 bytes
lambda s:s.translate({i%128:i%34+9216for i in{*range(-1,32)}-{9,10}})

Try it online!

Red, 94 92 bytes
func[s][n: charset[not{
}#" "-#"~"]parse s[any[p: change n(to sp p/1 % 94 + 9216)| skip]]s]

Try it online!
A port or @Arnauld's 74-byte JavaScript solution, don't forget to upvote his answer!

Perl 5  (-pC -Mutf8), 27 bytes
same as Neil's retina solution
y;--;␁-␈␋-␟␡

Try it online!

Jelly, 24 bytes
32R;Ø⁷’ḟ9ḟ⁵ż%94+⁽ ḥƊ$ỌFy

Try it online!
A monadic link taking a Jelly string and returning a Jelly string with the desired substitutions.

Ruby -p, 36 bytes
\0 should really be a null byte but I was having trouble getting it in the code, oh well.
Input in STDIN should be the direct bytes but I put in some boilerplate code to make it more readable and obvious that they were the test cases.
$_.tr!"\0--","␀-␈␋-␟␡"

Try it online!

source: Stack Exchange

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

sort: votes


text:
Gaussian integer division reminder
Gaussian integer is a complex number in the form \$x+yi\$, where \$x,y\$ are integer and \$i^2=-1\$.
The task is to perform such operation for Gaussian integers \$a,b\$, that
\$a=q \cdot b+r\$ and \$|r|<|b|\$ (\$q,r\$ are Gaussian integers, \$|z|\$ is defined as \$\sqrt{a^2+b^2}\$ for \$a+bi=z\$).
Need to output only \$r\$.
One of possible approaches is here.
Scoring: the fastest in terms of O-notations algorithm wins, though it can consume more time. By fastest I mean \$O(\left(f(n)\right)^a)\$ is preferred for smaller \$a\$ and \$O(\log^a(\log(n)))\$ will be preferred over \$O(\log^b(n))\$, ...over \$O(n^k)\$, ...over \$O(e^{\alpha n})\$ and so on.
If there's a tie, fastest implementation wins in terms of benchmark (e.g. 100 000 random 32-bit \$b\$ and 64-bit \$a\$ (I mean both real and imaginary part to be 32 or 64 signed integer)) or there can be 2-3 winners.
If unsure about algorithm complexity, leave blank. E.g. I believe Euler's algorithm for integers has \$O(\log(n))\$ time complexity.
Test cases can be obtained from wolframalpha in the form like Mod[151 + 62 I, 2 + I], but in case there are some:
4 mod (3+3*i) = either of 1+3*i, -2-0*i, 4-0*i, 1-3*i
10000 mod 30*i = either 10 or -20
(3140462541696034439-9109410646169016036*i) mod (-81008166-205207311*i) =
    either -75816304-29775984*i or 129391007+51232182*i

\$|b|\$ will not exceed 32 bits, but you don't have to code long arithmetic if your selected language doesn't have built-in one.
Good luck. Of course, WolframLanguage is forbidden. )

It looks to me like the algorithm you link is also log(n) time, which is optimal. You might as well just have the tiebreak be the scoring mechanism.

I believe there can exist O(1) algorithms when dealing with entire int32 or int64 as a whole. )

OK, sure, it's O(1) under the word size model. But formally, any algorithm on a bounded  domain of inputs is O(1). I think the whole big-O scoring bit is unnecessary for the question and makes it a chameleon challenge because the "tiebreak" is the real scoring method.

Does 32-bit b mean the real and imaginary parts are each 16 bits or each 32 bits? Could you please add some test cases generated this way into the question? Also, it's confusing that a and b are at first used to denote the real and imaginary parts of a complex number, but elsewhere two different complex numbers.

Why does Wolfram language have to be forbidden? Are its derivatives?

It has this operation built-in.

Python 2 (PyPy), O(1) operations
def cmod(a1, a2, b1, b2):
	# Compute p = a * conj(b)
	p1 =   a1 * b1 + a2 * b2
	p2 = - a1 * b2 + a2 * b1

	# Compute the norm-squared of b
	b_nsq = b1 ** 2 + b2 ** 2
	b_nsq_half = b_nsq // 2

	# Do a symmetric mod of d1 and d2 by b_nsq
	# That is, into the interval [-b_nsq_half, +b_nsq_half)
	d1 = (p1 + b_nsq_half) % b_nsq - b_nsq_half
	d2 = (p2 + b_nsq_half) % b_nsq - b_nsq_half

	# Compute r = d / b
	r1 = (d1 * b1 - d2 * b2) // b_nsq
	r2 = (d1 * b2 + d2 * b1) // b_nsq

	return r1, r2

Try it online!
Uses pure integer arithmetic, with no loops or branching or built-in complex numbers. This should easily complete the benchmark of 100,000 random inputs within a small fraction of a second. Porting this to a faster language would be straightforward and likely improve performance.
One possible low-level optimization is the Karatsuba algorithm trick to do complex multiplication using 3 rather than 4 integer multiplications. But, this might not be worth it for such "small" values.

Sadly the competition ends. ) I should do the test cases...

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


text:
Flag mashup generator
Part 2 of the challenge is here
Flags Mashup Bot is a small Twitter bot that generates a new flag based on two random flags and tweets the result every couple of minutes.
Task
Your task is to replicate what the bot does by writing a script or a function based on the following criteria:

The input is any two lossless images composed of at least two, but no more than eight colours.
To mix up the flags the following algorithm has to be used:

Take the first image
For every colour in the first image assign a colour randomly from the second image
Each colour from the second image has to be used at least once

Unless there are less colours in the first image than colours in the second.
You can choose randomly which colours to drop from the second image in this case.

Each colour from the first image has to be replaced with a different colour

Unless there are not enough colours in the second image.
You can choose randomly which colours will be used multiple times in this case.
However you need to make sure none of the colours are used more than any other colour by more than one
example: if you need to assign 2 colours to a flag of 5 colours you'll need to use one of the colour 3 times, while the other one 2 times. You cannot mix them 1 & 4

If a colour is present in both images you cannot assign that colour with itself you'll need to pick another one

The output is the resulting image

Examples
UK & Hungary

Notes: Both flags have three colours, however both use red and white, so those have to be replaced, hence the first invalid example. The second one doesn't use all three colours, and the third one uses non-existent colours.
South Africa & Sweden

Notes: South Africa's flag has 6 colours, while Sweden's have 2, meaning each of the two colours have to be used exactly 3 times. The invalid ones use the colours in a way which is not compatible with this constraint. Note that although both flags use the colour yellow they are actually not the same shade so are considered different
Poland & Poland

Notes: The only valid solution is switching up the two colours.
Notes

The two images don't need to have the same dimensions
The colour list can be different for the two images, so in total there might be 16 colours
The input can be either a lossless image file (example GIF, PNG, BMP, SVG, etc.), or (especially in case of functions) a two dimensional bitmap array holding the colours of the image in any reasonable format. Any native way of storing a bitmap in your language is also fine.
For both input and output images a two dimensional array holding ASCII characters, where different characters count as different colours, counts as a reasonable format, but solutions that work on "real" bitmaps are preferred
The output and input formats don't need to match
I think the colour replacement rules won't prohibit it to work for any valid two input images, but if yes your program doesn't need to work for them
Colours are considered the same only if they are exactly the same based on their RGB value. E.g. #FF0000 and #FF0001 are considered two different colours.
Standard loopholes, as usual, are prohibited

code-golf, so shortest code by byte count wins and will be accepted. If possible please include example a set of input & output images with your submission

UK+Hungary= Basque country

Jelly, 40 25 bytes
FQ),ṁ@¥/Ẋ€⁺ZE€ẸƊ¿iⱮⱮ@ịƭƒḢ

Try it online!
A monadic link taking a list of two flags as integer matrices and returning the altered version of the first flag. At the moment this assumes there are indexed colours representing each pixel. I've also assumed that each flag can have arbitrary colours.

JavaScript (Node.js),  160  159 bytes
I/O format: matrix of 24-bit integers.
Takes input as (a)(b).
a=>F=b=>(g=a=>[...new Set(a.flat())].sort(_=>Math.random()-.5))(a).every((c,i)=>c^=F[c]=B[i%B.length],B=g(b).slice(-g(a).length))?a.map(r=>r.map(c=>F[c])):F(b)

Try it online!
Commented
Helper function
The helper function \$g\$ takes a matrix as input and returns a shuffled list of the distinct values it holds.
g = a =>
  [...new Set(a.flat())]
  .sort(_ => Math.random() - .5)

Main code
a => F = b =>                 // a[] = first image, b[] = second image
  g(a).every((c, i) =>        // for each color c at position i in the list of shuffled
                              // colors of the first image:
    c ^=                      //   make sure that c is different from the
      F[c] = B[i % B.length], //     substitute color F[c] picked from the second image
    B =                       //   define B[] as:
      g(b)                    //     the list of shuffled colors from the second image
      .slice(-g(a).length)    //     resized to the number of colors in the first image
  ) ?                         // end of every(); if truthy:
    a.map(r =>                //   return a[] with each original color
      r.map(c => F[c])        //   replaced with its substitute color
    )                         //
  :                           // else:
    F(b)                      //   try again

Python 2, 196 bytes
Takes input as two lists of lists, where different elements represent different colors. Anything can be used to represent color: number, hex, string, etc.
from random import*
P=input()
i,j=(list(set(sum(x,[])))for x in P)
d={0:0}
while any(i==d[i]for i in d):y=[];exec'y+=sample(j,len(j));'*len(i);d=dict(zip(i,y))
print[[d[c]for c in r]for r in P[0]]

Try it online!

Explanation:
# get unique elements from input
P=input()
i,j=(list(set(sum(x,[])))for x in P)
# create dictionary, where colors of first image are keys and colors of second image are values
d={0:0}
# keep creating while no color is paired with same color
while any(i==d[i]for i in d):
  y=[]
  # sum different samples of substitution colors to keep random
  # and to make sure none of the colors are used more than any other color by more than one
  # *len(i) is to ensure that we have enough values to match
  exec'y+=sample(j,len(j));'*len(i)
  d=dict(zip(i,y))
# substitute colors and output result
print[[d[c]for c in r]for r in P[0]]

Perl 5, 170 168 bytes
sub f{($a,$b,$e)=map[uniq(/./g)],@_;%n=map{($_,0)}@$b;%s=map{$c=$$b[rand@$b];$e+=/$c/;$n{$c}++;($_,$c)}@$a;@v=values%n;max(@v)-min(@v)>1||$e?f(@_):$_[0]=~s,.,$s{$&},gr}

Try it online!
With spaces, newlines, my's, comments and a small test script added:
sub f{
  my($a,$b,$e)=map[uniq(/./g)],@_; #$a and $b are now arrayrefs to the unique
                                   #  colors in each flag
  my %n=map{($_,0)}@$b;          #init %n with 0 values for each col in flag2
  my %s=map{                     #%s becomes a suggested swap hash
    $c=$$b[rand@$b];             #draw random color from flag2
    $e += /$c/;                  #short for: $error=true if $_ eq $c
    $n{$c}++;                    #count usages of each flag2 color
    ($_,$c)                      #suggest swap this col in flag1 with random
                                 #  col in flag2
  }
  @$a;
  my @v=values%n;
  max(@v)-min(@v)>1              #no more than one more usages of each flag2 color
  || $e                          #cannot swap with itself
  ?  f(@_)                       #retry if %s don't passes
  :  $_[0]=~s,.,$s{$&},gr        #swap colors with %s if %s passes the demands
}

srand(1);
for(1..20){
    my($flag1,$flag2)=
      grep{/../&&!/(.).*\1/||redo}
      map{join'',map chr(65+rand(16)),0..rand(8)}
      1..2;
    ($flag1,$flag2)=qw(GWRYBb Ey) if $_==18; #south africa & sweden example
    ($flag1,$flag2)=qw(RWB RWG)   if $_==19; #uk & hungary example
    ($flag1,$flag2)=qw(WR WR)     if $_==20; #poland example
    my @s=uniq(map f($flag1,$flag2),1..1000);
    print "flag1=$flag1 flag2=$flag2 @{[0+@s]} solutions: ".join(" ",@s)."\n";
}
use List::Util qw(uniq min max);

The image format consists of up to sixteen different capital letters A-P for each pixel. The letter represents a color in a color map (like in gifs). Max eight unique colors in each flag. The function returns the first argument ($a) where each letter is (potentially) swapped with a letter in the second argument ($b) through the swap hash %s. The %n hash is used to count the number of colers each swapped in color is used for and the least frequent (can be zero) shouldn't be less than one below the max frequency. Also $e (error) becomes true if f attempts to swap a color with itself in which case f is also run again.

Charcoal, 70 bytes
ＷＳ⟦ι⟧ＷΦＫＡ¬№υκ⊞υ‽ι≔υθ≔⟦⟧ηＷＳＦιＦ¬№ηκ⊞ηκＷ⊙υ⁼κ§θλ«≔⟦⟧θＷΦη¬№θλ⊞θ‽κ»ＵＭＫＡ§θ⌕υι

Try it online! Link is to verbose version of code. Takes input as character arrays, where different characters represent different colours. For the link I've rendered two flags in ASCII art. Explanation:
ＷＳ⟦ι⟧

Input and print the first character array.
ＷΦＫＡ¬№υκ⊞υ‽ι

Randomly extract the distinct characters into a list.
≔υθ

Make a temporary copy of the list. This copy will be replaced by a shuffle of the transliteration characters.
≔⟦⟧η

Create a second list. (The first list was automatically predefined by Charcoal.)
ＷＳＦιＦ¬№ηκ⊞ηκ

Input the second character array and extract the unique characters to the second list.
Ｗ⊙υ⁼κ§θλ«

Repeat while at least one character in the first list maps to a character in the second list. The mapping is cyclic, so that once all of the colours run out, they are reused again in the same order, thus ensuring that no colour is used an unbalanced number of times.
≔⟦⟧θＷΦη¬№θλ⊞θ‽κ

Shuffle the unique characters from the second list.
»ＵＭＫＡ§θ⌕υι

Once a distinct shuffle has been found, transliterate the whole canvas from the first to the second list.


text:
Inverse Look-and-Say
Background
The Look and Say Sequence is built up by reading off the digits of previous entries in the sequence, counting the number of digits in groups of the same digit. For example:
1 => 11 # (one 1)
11 => 21 # (two 1s)
21 => 1211 # (one 2, then one 1)
1211 => 111221 # (one 1, then one 2, then two 1s)

This sequence was the subject of various previous challenges. A simple Python 3 implementation of the generating function is:
>> from itertools import groupby
>> def look_and_say(obj):
      return "".join(f"{len(list(group))}{digit}" for digit, group in groupby(str(obj)))

Try it online!
Challenge
The purpose of this challenge is to implement an inverse Look and Say function. Given a Look and Say representation of a non-negative integer, your code should return the smallest non-negative integer for which the input is its Look and Say. Note that this is not the same as general Run Length Decoding, since the output must encode back precisely to the input: see the examples below for some of the subtleties involved.
This is code-golf, so shortest code in bytes wins, with all the standard loopholes forbidden. Input can be passed in (or returned) as either an integer or a string.
Test cases
10 => 0 # (1 zero)
12 => 2 # (1 two)
123 => 333333333333 # (12 threes)
1234 => 2444 # (1 two, 3 fours)
1232 => 222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222 # (123 twos, since 2222 would return 42 not 1232)
2019 => 999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 # (201 nines, since the only non-negative starting with 0 is 0)
2109 => 999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 # (210 nines, since 11 would return 21 not 2109)
123456 => 244466666
123454 => 333333333333444444444444444444444444444444444444444444444 # (12 threes, 45 fours)
124234 => 2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222444 (124 twos, 3 fours, which is smaller than the alternatives)

Invalid inputs
Since there are no integers which have the following Look and Say representations, the behaviour for these inputs is undefined:
1
3
20
100
1010
10010

I'd like to recommend some more test cases:22334, 33224, 10101 and 10111, I think they would cover some more edge cases.

With an input of 121212, I assume that a response of 312 (three 12's) is not a valid response?

@Keeta That goes the wrong way.  It's 312 as input does not have 121212 as a valid response.

05AB1E, 11 bytes
∞<ÅΔÅγs.ιJQ

Try it online!
Computes the look and say of all integers until finding one that matches the input. Will timeout for large outputs.

JavaScript (ES6), 111 bytes
f=([x,y,...s],p,o=O='',m='')=>x?y?f([y,...s],p,o,m+=x,+m&&y^p&&f(s,y,o+y.repeat(m))):O||0:!O||O[o.length]?O=o:0

Try it online!
Commented
f = (                     // f is a recursive function taking:
  [x, y,                  //   x, y = next two characters from the input string
         ...s],           //   s[]  = array of remaining characters
  p,                      //   p    = previous repeated digit, initially undefined
  o =                     //   o    = current output
  O = '',                 //   O    = shortest output so far
  m = ''                  //   m    = current multiplier, as a string
) =>                      //
  x ?                     // if x is defined:
    y ?                   //   if y is defined:
      f(                  //     do an unconditional recursive call:
        [y, ...s], p, o,  //       where y is put back in the input
        m += x,           //       and x is appended to m
        +m &&             //       if m is not zero'ish
        y ^ p &&          //       and y is not equal to p:
        f(                //         do another recursive call:
          s, y,           //           where p is updated to y
          o + y.repeat(m) //           and y is appended to o, m times
        )                 //       end of inner recursive call
      )                   //     end of outer recursive call
    :                     //   else:
      O || 0              //     return O, or 0 if it's empty
  :                       // else:
    !O || O[o.length] ?   //   if O is still empty or o is shorter than O:
      O = o               //     update O to o
    :                     //   else:
      0                   //     do nothing

Jelly, 13 bytes
DŒrUDF⁼³µ1#@0

Try it online!
A full program that takes a list of digits and returns the first number that generates that as its look-and-say. Tries all numbers until one matches so will be slow for some inputs.
Alternatives
Jelly, 25 bytes
DŒṖṪxḌƊ€F$€ḌDŒrUƊDF⁼ʋƇDṢḢ

Try it online!
A monadic link taking an integer. Generates all possible inverse look-and-says (including invalid ones) and then tests them by seeing whether generating a look-and-say results in the input. Returns the smallest valid one.
Jelly, 30 bytes
ŒṖUZḢEƲƝẸ$ÐḟṪxḌƊ€€ẠƇF€ḌD$ƑƇḌṢḢ

Try it online!
A monadic link taking a list of digits. Generates all possible inverse look-and-says (including invalid ones) and then tests them by seeing whether they violate any rules. Returns the smallest valid one.
Thanks to @ØranJohansen for pointing out a problem with the last two.

Your fast versions fail for the last two test cases.

@ØrjanJohansen fixed. I thought I could go for the first one. I checked on the first few thousand numbers as input, but annoyingly missed the fact the last two test cases had stopped working! I’ve restored the sort before heading.

Python 2, 200 166 165 bytes
lambda n:min(int(r)for r in b(n)if str(int(r))==r)
b=lambda n:[int(n[:i])*n[i]+v for i in range(1,len(n))for v in b(n[i+1:])if int(n[:i])*(n[i]!=v[:1])]if n else['']

Try it online!

Ruby, 81 bytes
->n{(0..1/0.0).find{|r|r.to_s.chars.chunk{|w|w}.map{|a,b|[b.size,a]}*''==n.to_s}}

Try it online!
Brute force approach, could be 5 bytes shorter on a newer version of Ruby, but it doesn't matter because it's slow as hell for most numbers.

Japt, 16 bytes
Brute force approach that'll crap out for larger outputs.
@¥Xò¦ ËÎiDlÃq}as

Try it
@¥Xò¦ ËÎiDlÃq}as     :Implicit input of integer U
@                    :Function taking an integer string X as argument
 ¥                   :  Test U for equality with
  Xò                 :  Partition X on
    ¦                :    Inequality
      Ë              :  Map each D
       Î             :    First character of D
        i            :    Prepend
         Dl          :    Length of D
           Ã         :  End map
            q        :  Join
             }       :End function
              a      :Return the first integer that returns true when passed through that function
               s     :After converting it to a string

Charcoal, 67 bytes
⊞υ⟦0ωＳ⟧Ｆυ«≔§ι²θＦ∨‹θ1Ｌθ¿∧κ⁻§θκ§ι⁰⊞υ⟦§θκ⁺§ι¹×§θκＩ…θκ✂θ⊕κ⟧»Ｉ⌊ＥΦυ¬⊟ιＩ⊟ι

Try it online! Link is to verbose version of code. Generates all integers with the given look-and-say sequence and outputs the minimum thereof. Explanation:
⊞υ⟦0ωＳ⟧

Start by pushing a list of three items to the predefined list. The first item (initially 0) represents the previous repeated digit (thus preventing the generated number from beginning with 0), the second item (initially an empty string) represents the integer so far (as a string), while the third item (initially the whole input) represents the remaining input to process.
Ｆυ«

Loop over the list. This automatically iterates over additional items as they are pushed to the list.
≔§ι²θ

Get the remaining input into a dedicated variable. This saves several bytes as this variable is used multiple times. It does force me to wrap the block in braces, but this is offset by allowing me to use an if to save a byte.
Ｆ∨‹θ1Ｌθ

Loop over the string, but if it begins with a zero, only loop once (which gets ignored anyway, but this is a byte golfer than not looping at all).
¿∧κ⁻§θκ§ι⁰

Ignore the first character of the string (because there is no number to multiply it by), and also any character equal to the previously processed digit for this entry.
⊞υ⟦§θκ⁺§ι¹×§θκＩ…θκ✂θ⊕κ⟧

Push the next potential step to the list, comprising the current digit, the integer so far with the current digit repeated the prefix number of times, and the suffix.
»Ｉ⌊ＥΦυ¬⊟ιＩ⊟ι

After all possible steps have been processed, filter those that consumed the input exactly, and output the smallest resulting value.


text:
Simulate reproduction in a population of oozes
Reproductive strategy of oozes 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!

Can an output be an array?

Seems reasonable...

does order matter? Can different stages be separated?

Of course the order matters! Otherwise, you could output a sorted string; it would be boring.

I wonder, if we take away the randomness, could this be a Turing complete program? Not too disimilar to a substitution style language

oozes are not aware of death?

@KrystosTheOverlord No; oozes don't mate.  If they mated, maybe.  (the cells need to interact to generate a Turning complete system)

@Yakk Ah, I see your point. It would require an interaction between two oozes to create a dynamic system.

"If your solution has running time of O(n), please specify it explicitly!" Why?

I am interested in any such solution because I thought for some time whether it was possible, and couldn't come to a conclusion. I don't always understand solutions in bizarre languages, so I don't want to miss such a great solution if it appears.

Jelly, 21 16 bytes
1F‘JX$¦ḃ3Ʋ¡ị“oO8

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"

"bijective base 3" - this is a great idea!

Trivial golf, but -1 byte by removing the trailing ”

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!

SECONDS ahead of me. :( great job!

Great observation on character codes! I'll use it in my answer, if I decide to make one.

That observation saved me 14 bytes in my solution so thank you.

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

Using the observation from Jitse's Python solution I got 61 bytes since it let me cut the sub call at the end.

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)

Pyth, 25 bytes
uXGJOlG@c"O 8 oo")C@GJQ\o

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, 38 bytes
K\oJ["oo"\o\O\8)VQ=kOlK=KXKk@JhxJ@Kk;K

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

Good call, @FryAmTheEggman , reduce would be a better way to write this, I hadn't considered that. I also like the idea to use the codepoint of the character! Are you planning to post this as your own answer?

Ooo... you beautiful person. You're gonna make me find 2 more bytes, aren't you?

05AB1E, 26 bytes
'osFÐg<ÝΩ©è…oO8S„O8„ooª‡®ǝ

Try it online!

Every generation, a single random element is evolved.

+1, and you're definitely not a moron - it's the little stuff like this that everyone gets wrong!

@FryAmTheEggman you saved me 6 bytes, I'm thanking you honestly ;).

-1 by replacing Ðg<Ý ... ǝ with Dā ... <ǝ. Bummer that ǝ doesn't wrap around the index like all other indexing-builtins do.. Not sure if it's intentional or a bug.

R, 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!
Output as an array.
Thanks to Robin Ryder for golfing out 6 bytes, for pointing out a bug in a previous version, and for golfing out an additional 4 bytes.

I think this is equivalent in 103 bytes.

@RobinRyder ahhh, of course. That can be golfed further down to 97.

@RobinRyder I am pretty sure I fixed it now by moving the assignment to i in the append instead of in the switch...No idea why that worked.

@RobinRyder I'm an idiot, I used i for the loop index and the index into o which is why it gave incorrect results. So on each pass it appends to after i = 1,2,3,4,5 -- which obviously goes beyond the end, hence why Oo goes to o8 instead of 8o.

93 bytes by using T and changing the order of the arguments in switch.

C# (Visual C# Interactive Compiler), 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!
-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

130 bytes, a few minor golfs: Try it online!

Thanks! Using dynamic to chain the declarations of different types is a great idea. I didn't see that in the tips thread, you should add it there.

Some of my C, umm... puke below may save you a few bytes as well.

Maybe, but I don't see any thing obvious at first glance. I'll have to look more in-depth later

J, 54 bytes
'oO8'{~(((1+2={)`[`(1"0@])}#(3|1+{)`[`]})~1?#)^:(]`0:)

Try it online!
Wholly different approach to shave off 2 bytes
original solution
J, 56 bytes
'oO8'{~(({.,(i.@3(>:@i.{ ::0 0[){),>:@[}.])~1?#)^:(]`0:)

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.

Perl 6, 55 bytes
{('o',{S:p(rand*.comb)[.]=<O 8 oo>[$/.ord%3]}...*)[$_]}

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

Perl 5, 79 bytes
sub f{$_[0]?do{$_=f(-1+pop);substr($_,rand length,1)=~y/oO8/O82/;s,2,oo,r}:"o"}

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

60 bytes - TIO

@NahuelFouilleul Good one, you took it to the next level! :) You could post this one as your own answer.

just rewriting using iterative style for loop or more exactly eval x, because of $_ default variable also used as in loop

Charcoal, 38 bytes
⊞υoＦＮ«≡⊟υo⊞υO¦O⊞υ8Ｆ²⊞υo≔‽ＬυιＵＭυ§υ⁺λι»υ

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.

Japt, 32 31 29 bytes
_gZÊö _Ä %3ª1ö2Ãc}g[]á)Ëg"oO8

Try it
 _               // 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

You don't need the leading equal sign

Python 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!
Golfing Jitse's solution using the mutability of lists.

Java (JDK), 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!
Credits

-2 bytes thanks to Kevin Cruijssen

-2 bytes by using int i; and doing the i=s.length() before the s.replace.

Using string split saved 2 bytes in my C# implementation so thanks for the inspiration =)

Zsh, 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!

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

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!

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!
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'

Python 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!
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 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.

I guess randomness here is subjective, especially when it involves dividing by a small magic number. Seems random enough for this simulation, but I am not sure!

I believe this demonstrates a significant problem with this approach. The first string always has the same id so the progression is always the same. This eventually stops when the strings are longer but it seems very loose to me. I don't think there is a precise consensus on this, so perhaps it is best to ask on meta?

@FryAmTheEggman If you got the id of a new dict {} or new list [] each time it'd gain one byte but be a new object every time, guaranteed

@famous1622 Briefly testing that in the TIO link from my comment gives largely the same problem. I couldn't say why for sure, but it may be being optimised away, or being freed then reused immediately.

Retina, 29 27 bytes
K`o
"$+"{@T`\oo`\O80`.
0
oo

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

Red, 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!

K (oK), 51 bytes
{"oO8"x{{,/(x#t),((1;2;0 0)t@x),(x+1)_t}1?#t:x}/,0}

Try it online!
No doubt this can be done much shorter / more elegant (using ammend?). I'm somewhat happy that it works at least.

Lua, 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!

This can be reduced to 101 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
By shifting all elements in the lookup table by one removing, the temporary variable l is also unnecessary.

Good find @bauen1:)

C (gcc) (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!

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)

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!

C (gcc), 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!
(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.

I get satisfaction when I can get a C solution to be competitive with newer languages that have so many built-in functions :)

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

Lexurgy, 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,`} => *