><> (Fish), 107 106 103 bytes
<v}:{r&" "
1xv+
2<v+
v}<
<~v!?=&:&:
6.>ol2-?!;a
:{{:}l1-[rv
v2<
<1x|!}:}-1<v!?:{{:o-+
^3<v ~}}r]~<
.40<
Try it online!
It isn't super random, but it is random. Just place the string and integer on the stack (Example: "Hello world!", 5).
Input: "Hello world!", 5
Output: H^\^]^eceeedldcdeclgfffhowhhfggojkkkkrdccedl]]\]\d
Full Explanation
This is a slightly older version of the code, until I update the explanation. It's mostly the same, just maybe a bit easier to read:
< v}:{r&" "
+1xv
+2<v
}
:&:<~ v!?=&
?!;a6.>ol2-
:{{:}l1-[rv
v2<
<1x|!}:}-1<v!?:{{:o+*
^3<v ~}}r]~<
.43<
We'll pretend the string parameter is s
and the integer parameter is i
.
< v}:{r&" "
The <
tells the fish to immediately move left, which wraps around to " "
, which adds a space characted to the stack. Then the fish travels over &
, which adds the space to the register. r
reverses the stack and {:}
shifts the stack to the left (putting i
on the end of the stack), copies the value on the end of the stack, then shifts it to the right. v
tells the fish to begin moving downwards.
+1xv
+2<v
}
x
tells the fish to move in a random direction, ultimately resulting in the fish going right and continuing downwards, or pass over 1+
or 2+
beforehand. These add 1 or 2 respectively to the number on the end of the stack. If the fish travels upwards, it hits v
again and travels back down. }
shifts the stack to the right, then having i
at position 1 on the stack and this new variable at position 0 (we'll call it m
).
:&:<~ v!?=&
This section is a function, let's call it whitespaceTrimmer. It begins where the <
is. It simply strips spaces that're on the end of the stack (so the beginning of the string) until it runs into a non-space character.
So immediately the fish swims into a <
and must travel to the left. It then runs into :&:&
which copies the value on the end of the stack, places the space from the register onto the end of the stack, copies it, then places it back onto the register.
Then the fish hits =?!v ~
, or more specifically, =
, which pops the last two values (the two we just created) off of the stack, compares them, places a 1 on the end of the stack if they're equal, and a 0 on the end of the stack if they're different. The ?
pops the new value off the end of the stack, if it is 0 it doesn't execute the next instruction, which in this case is !
, it instead executes v
, which orders the fish to move downwards (exiting the function).
If it is 1 however, then it has found a space, so it executes the !
which is a trampoline, and that causes the fish to skip the next instruction, which is a v
, so the fish continues. In front of the fish, it sees ~
which tells it to pop the last value off the stack (confirmed to be a space), then the fish continues, and runs the function again.
?!;a6.>ol2-
The fish is immediately told to swim right by a >
, then output the last character on the stack by o
(which, the first time this is run, is the first character of s
). It gets the length of the stack from l
, places a 2
on the end of the stack, then -
causes 2 to be subtracted from l
. It hits ?!;
which, remembering what ?
does, causes the fish to skip the !
if the stack is empty, and land on ;
, which ends the program.
Following if there are still characters on the stack, we execute !
which causes the fish to bounce over the ;
and execute a6.
, which stores a
(AKA 10
), and 6
on the end of the stack, which are x, y
coordinates for .
, which pops them off the end of the stack, then teleports the fish to 10, 6
, and execute the instruction to the right of that postion (as the fish is swimming right).
This is less complicated than it sounds when you realise y
position 6 is the line below this one. x
position 10 is then v
, and to the right of that is
, which is a no-op. This causes the fish to continue swimming right and actually begin execution at the beginning of the line...
:{{:}l1-[rv
v2<
<1x|!}:}-1<v!?:{{:o+*
^3<v ~}}r]~<
.43<
So this is the function that adds the random text in between the characters. It's a bit of a mouthful, but that's just because I tried to make it a little bit extra random. Let's call this genRandomChars.
The :{{:}l1-[rv
is actually the setup for the function, and less-so part of the actual function itself. The fish first swims over :{{
which copies the value on the end of the stack, then shifts it to the left twice. If you recall that i
was at postion 1 on the stack, then you'd know i
is now on the end of the stack.
The fish then swims over :}
which copies i
, and shifts the stack to the right, placing i
both at the beginning and end of the stack. l1-[
has the fish place the length on the end of the stack, subtract 1 from it, then [
creates a new stack, moving l-1
(stack length minus 1) values to the new stack (so just leaving i
on the old stack). Then the fish simply hits rv
which reverses the stack again (I think creating a new stack reverses it for some reason), and orders the fish to swim downwards once more, truely beginning the function at the <
below.
So currently the end of the stack has m
and our temporary i
, which we'll call ti
. Immediately the fish swims over 1-}
, which subtracts 1 from ti
and moves it to the beginning of the stack. Then :}
which simply copies m
and moves it to the beginning of the stack (putting ti
at stack position 1).
This is when we hit this little thing:
v2<
<1x|!
^3<
This is actually dead simple. The !
causes the fish to skip |
and execute x
. Remembering what x
does, we remember this makes the fish move in any 4 directions. |
is simply a mirror, and causes the fish to swim back to x
. So basically, the fish will place 1, 2, or 3 onto the end of the stack, and continue moving left, wrapping around.
The fish then executes *+o
which causes the last two values on the stack to be popped off, multiplied together, and the result push back on, then the same thing with addition, then the final value is popped off the stack and outputted with o
. Our stack is now relatively normal again containing just [m
, ti
, s
].
:}}:
causes the value on the end of the stack (basically s
position 0) ot be copied, then the stack is shifted to the right twice (placing ti
on the front again), then ti
is copied. ?!v
should be pretty easy to understand by now. Basically if ti
is 0 then we exit the function with v
, otherwise we execute !
and skip v
(doing another loop).
If ti
is 0 and we are done outputting slightly random characters, then we execute v
and see:
v ~}}r]~<
.43<
Nothing too fancy here. We remove ti
from the stack via ~
. Then ]
is new, it pops all our values off the stack and places them on the old stack! Because of the reversal issue we reverse with r
, then shift the stack right twice with }}~
, shufting the stack to the right, giving us [m
, i
, s
], the ~
is to remove the extra duplicated s[0]
from earlier in the function as we'd need it if we were doing a loop (but we're not, we're exiting). v
tells the fish to swim down and into >34.
(inverted to show execution order), which tells the fish to simply swim left and into 3, 4
(because the .
is a jump!). 3, 4
is actually just to the right of the beginning whitespaceTrimmer
, which is perfect because we are travelling left.
Following all this logic we can follow the fish until the stack is ultimately empty and program exits just after whitespaceTrimmer
is executed.
n
characters consists ofn
copies of the same random character, they are still random, but they are not statistically independent. And so on \$\endgroup\$O
are more likely than spaces or~
? If it has to be uniform, then you should say so explicitly. And if it doesn't have to be uniform, then you should at least state something like each character needs to have a non-zero probability. You've also stated in a previous comment that each character does have to have an independent distribution, so if this is important, it should be mentioned in the challenge. There is a very broad spectrum of randomness. \$\endgroup\$