| Bytes | Lang | Time | Link |
|---|---|---|---|
| 007 | Thunno 2 | 230720T095911Z | The Thon |
| 007 | Pyth | 170717T155652Z | Mr. Xcod |
| 031 | SmileBASIC | 180313T185331Z | 12Me21 |
| 019 | Cubix | 171119T124641Z | FlipTack |
| 026 | Perl 5 | 171119T180625Z | Xcali |
| 010 | ngn/apl | 171119T173828Z | ngn |
| 042 | Lean Mean Bean Machine | 170717T162743Z | Mayube |
| 025 | TIBasic | 170719T014829Z | Timtech |
| 019 | ><> | 170718T021437Z | Not a tr |
| 052 | Bash | 170719T121505Z | Olivier |
| 014 | APL | 170717T151740Z | Uriel |
| 016 | J | 170718T213658Z | Jonah |
| 044 | Java 8 | 170717T181705Z | Socratic |
| 017 | braingasm | 170718T183944Z | daniero |
| 064 | PowerShell | 170718T182500Z | Jeff Fre |
| 2530 | JavaScript ES6 | 170718T105444Z | Arnauld |
| 025 | Mathematica | 170717T154757Z | ZaMoC |
| 3023 | Javascript | 170718T052355Z | Alan Rat |
| 038 | Java OpenJDK 8 | 170717T195904Z | Olivier |
| 007 | Pyth | 170718T103408Z | isaacg |
| 005 | 05AB1E | 170718T092945Z | kalsower |
| 028 | Octave | 170718T060706Z | rahnema1 |
| 198 | Common Lisp | 170718T031924Z | Cheldon |
| 032 | Applesoft | 170717T225009Z | Alan Rat |
| 035 | Javascript | 170717T233957Z | asgallan |
| 032 | Ruby | 170717T212950Z | daniero |
| 009 | 05AB1E | 170717T205031Z | Magic Oc |
| 055 | C# .NET Core | 170717T184031Z | Charlie |
| 027 | Ruby | 170717T182155Z | alexande |
| 049 | C gcc | 170717T155002Z | cleblanc |
| 060 | Chip | 170717T194257Z | Phlarx |
| 011 | Charcoal | 170717T190820Z | Neil |
| 011 | CJam | 170717T171909Z | geokavel |
| 006 | 05AB1E | 170717T163127Z | Emigna |
| 056 | ><> | 170717T162332Z | KSmarts |
| 028 | PHP | 170717T161149Z | Titus |
| 027 | QBIC | 170717T161347Z | steenber |
| 031 | R | 170717T154634Z | Giuseppe |
| 013 | q/kdb+ | 170717T155844Z | mkst |
| 010 | MATL | 170717T153647Z | Luis Men |
| 051 | Python 3 | 170717T152551Z | Mr. Xcod |
| 106 | C | 170717T153106Z | caylee |
| 050 | Python | 170717T153034Z | Jonathan |
| 006 | Jelly | 170717T152014Z | Jonathan |
| 008 | 05AB1E | 170717T151607Z | Riley |
| 008 | Jelly | 170717T151602Z | Leaky Nu |
Thunno 2, 7 bytes
«¦/d×Jɼ
Explanation
«¦/d×Jɼ # Implicit input
«¦/ # Push 1322
d # Cast to digits
× # Multiply elementwise
J # Join into a string
ɼ # Choose a random character
# Implicit output
Pyth, 8 7 bytes
O+@Q1t+
Uses the exact same algorithm as in my Python answer.
Pyth, 10 8 bytes
O+<Q2*2t
Uses the exact same algorithm as is Jonathan Allan's Python answer.
Explanation
O- Takes a random element of the String made by appending (with+):<Q2- The first two characters of the String.*2tDouble the full String (*2) except for the first character (t).
Applying this algorithm for ABCD:
<Q2takesAB.*2ttakesBCDand doubles it:BCDBCD.+joins the two Strings:ABBCDBCD.Otakes a random character.
-2 thanks to Leaky Nun (second solution)
-1 thanks to mnemonic (first solution)
SmileBASIC, 31 bytes
LINPUT S$N=RND(8)?S$[N+!N*2>>1]
Pick a number from 0 to 7, add 2 if it's 0, then divide by 2.
Cubix, 39 24 22 21 19 bytes
.<.^iD>D|@oioi.\i;U
View in the online interpreter!
This maps out to the following cube net:
. <
. ^
i D > D | @ o i
o i . \ i ; U .
. .
. .
Random Distribution Implementation Explanation
Cubix is a language in which an instruction pointer travels around the faces of a cube, executing the commands it encounters. The only form of randomness is the command D, which sends the IP in a random direction: an equal chance of 1/4 each way.
However, we can use this to generate the correct weighted probabilites: by using D twice. The first D has a 1/4 of heading to a second D. This second D, however, has two directions blocked off with arrows (> D <) which send the instruction pointer back to the D to choose another direction. This means there are only two possible directions from there, each with a 1/8 overall chance of happening. This can be used to generate the correct character, as shown in the diagram below:
(Note that, in the actual code, the arrow on the right is replaced with a mirror, |)
Code Explanation
. <
. ^
IP> i D > D | @ o i
o i . \ i ; U .
. .
. .
The instruction pointer starts on the right, at the character i, facing right. It executes this i, taking the first character as input, and then moves onto the D, beginning the random process shown above.
Char A: In the case that the first
Dsends us east, and the second south, we need to print character A. This is already on stack from the firsti. The following is executed:\- Reflect the IP so it heads easti;- Take an input, then pop it again (no-op)U- Perform a U-turn, turning the IP left twiceo- Output the TOS, character A@- Terminate the program
Char B: If either the first or second
Dhead north, we need to generate character B, which will be the next input. Both paths execute the following commands:^- Head north<- Head west, wrapping round to...i- Take another input, character Bo- Output the TOS, character B;- Pop the TOS@- Terminate the program
Char C: If the first
Dsends us west, the following is executed:i- Take another input, character Bi- Take another input, character Co- Output TOS, character C@- Terminate the program
Char D: If the first
Dsends us south, the following is executed:i- Take another input, character B..- Two no-opsi- Take another input, character C|- This mirror reflects east-west, but the IP is heading north, so we pass through it.^- This joins up with the path taken for character B. However, because we have taken two inputs already, the fourth character (character D) will end up being printed.
ngn/apl, 10 bytes
?2 4 chooses randomly a pair of numbers - the first among 0 1 and the second among 0 1 2 3
⌈/ is "max reduce" - find the larger number
⎕a is the uppercase alphabet
[ ] indexing
note the chart for max(a,b) when a∊{0,1} and b∊{0,1,2,3}:
┏━━━┯━━━┯━━━┯━━━┓
┃b=0│b=1│b=2│b=3┃
┏━━━╋━━━┿━━━┿━━━┿━━━┫
┃a=0┃ 0 │ 1 │ 2 │ 3 ┃
┠───╂───┼───┼───┼───┨
┃a=1┃ 1 │ 1 │ 2 │ 3 ┃
┗━━━┻━━━┷━━━┷━━━┷━━━┛
if a and b are chosen randomly and independently, we can substitute 0123=ABCD to get the desired probability distribution
Lean Mean Bean Machine, 55 43 42 bytes
-13 bytes thanks to Alex Varga
O
i
^
^ ^
\ ^ ^
i / U
ii
^
i U
U
Hope you guys don't mind me answering my own question after only 2 hours, but I highly doubt anybody else was planning on posting an answer in LMBM.
This literally just reflects the Plinko layout shown in the OP, flipped horizontally to cut down on unnecessary whitespace.
TI-Basic, 25 bytes
sub(Ans,randInt(1,8),1
If int(2rand(Ans="A
"B
><>, 25 22 19 bytes
i_ixio;o
ox</;
;\$o
Try it online!, or watch it at the fish playground!
A brief overview of ><>: it's a 2D language with a fish that swims through the code, executing instructions as it goes. If it reaches the edge of the code, it wraps to the other side. The fish starts in the top left corner, moving right. Randomness is tricky in ><>: the only random instruction is x, which sets the fish's direction randomly out of up, down, left and right (with equal probability).
At the start of the program, the fish reads in two characters of input with i_i (each i reads a character from STDIN to the stack, and _ is a horizontal mirror, which the fish ignores now). It then reaches an x.
If the x sends the fish rightwards, it reads in one more character (the third), prints it with o and halts with ;. The left direction is similar: the fish reads two more characters (so we're up to the fourth), wraps around to the right, prints the fourth character and halts. If the fish swims up, it wraps and prints the second character, before being reflected right by / and halting. If it swims down, it gets reflected left by the / and hits another x.
This time, two directions just send the fish back to the x (right with an arrow, <, and up with a mirror, _). The fish therefore has 1/2 chance of escaping this x in each of the other two directions. Leftwards prints the top character on the stack, which is the second one, but downwards first swaps the two elements on the stack with $, so this direction prints the first character.
In summary, the third and fourth characters are printed with probability 1/4 each; the first character has probability 1/2 x 1/4 = 1/8; and the second character has probability 1/4 + 1/2 x 1/4 = 3/8.
Bash, 52 bytes
f(){ c=$1$2$2$2$3$3$4$4;echo ${c:$(($RANDOM%8)):1};}
Usage exemple:
$ f a b c d
b
$ f a b c d
d
$ f a b c d
b
$ f a b c d
a
APL, 14 bytes
(?8)⊃1 3 2 2\⊢
Input as a string.
How?
1 3 2 2\⊢ - repeat each letter x times ('ABCD' → 'ABBBCCDD')
⊃ - take the element at index ..
(?8) - random 1-8
J, 16 bytes
(1?8:){1 3 2 2&#
how?
1 3 2 2&#- copy the input elementwise, ie, 1 copy of A, 3 copies of B, etc, yielding the listABBBCCDD1?8:- choose 1 element at random from the list0 1 2 3 4 5 6 7{- "From", ie, choose fromABBBCCDDthe random index generated by1?8:
Java 8, 53 44 bytes
s->s[-~Math.abs((int)(Math.random()*8)-6)/2]
This is a Function<char[], Character>.
Try it online! (this test program runs the above function 1,000,000 times and outputs the experimental probabilities of choosing A, B, C, and D).
The general idea here is to find some way to map 0-7 to 0-3, such that 0 appears 1/8 times, 1 appears 3/8 times, 2 appears 2/8 times, and 3 appears 2/8 times. round(abs(k - 6) / 2.0)) works for this, where k is a random integer in the range [0,8). This results in the following mapping:
k -> k - 6 -> abs(k-6) -> abs(k-6)/2 -> round(abs(k-6)/2)
0 -> -6 -> 6 -> 3 -> 3
1 -> -5 -> 5 -> 2.5 -> 3
2 -> -4 -> 4 -> 2 -> 2
3 -> -3 -> 3 -> 1.5 -> 2
4 -> -2 -> 2 -> 1 -> 1
5 -> -1 -> 1 -> 0.5 -> 1
6 -> 0 -> 0 -> 0 -> 0
7 -> 1 -> 1 -> 0.5 -> 1
Which, as you can see, results in the indices 0 111 22 33, which produces the desired probabilities of 1/8, 3/8, 2/8 and 2/8.
But wait! How in the world does -~Math.abs(k-6)/2 achieve the same result (again, where k is a random integer in the range [0,8])? It's pretty simple actually... (x+1)/2 (integer division) is the same thing as round(x/2), and x + 1 is the same thing as -~x. Although x+1 and -~x are the same length, in the above function it is better to use -~x since it -~ takes precedence and thus does not require parenthesis.
braingasm, 17 bytes
4[,>]<4r<#z[2r>].
Works like this:
4[,>]< Input 4 bytes from stdin and stay in cell 3 (0-indexed).
< Move left ...
4r ... randomly between 0 (inclusive) and 4 (exclusive) times.
#z[ ] If we're at cell 0,
> move right ...
2r ... with 50% probability.
. Print the byte value of the cell.
Given the input ABCD, each character has 1/4 = 2/8 chance of being printed because of 4r, but if we selected A, we have 1/2 chance of printing B instead, giving A (1/4)/2 = 1/8 chance and B 1/4 + 1/8 = 3/8 chance.
PowerShell, 64 bytes
$args|%{($_-replace '(^.)(.)',"`$1`$2`$2`$2$'")[(Get-Random)%8]}
It replaces the string abcd with abbbcdcd using regex witchcraft and then randomizes which of the eight characters it chooses. The regex is expensive; it requires a backtick per grouping, so there may be a better method using recursive lookups.
Here's a quick explanation of the regex:
For input abcd the full match is ab, grouping $1 is 'a', grouping $2 is 'b', and $' (note quote, not backtick) returns everything after the full match. Then, the pattern $1$2$2$2$' is substituted for the full match: abcd goes to $1$2$2$2$' + cd = abbbcdcd
JavaScript (ES6), 25 bytes / 30 bytes
In both following versions, we're looking for two positive integers m and n such that n MOD (m + i) MOD 4 gives us results in [0...3] at the expected frequencies for i in [0...7].
Version 1, 25 bytes
If a time-dependent formula is allowed, we can just do:
s=>s[11%(new Date%8+2)%4]
This one is using n = 11 (smallest possible value of n) and m = 2.
i | 2 + i | 11 % (2 + i) | 11 % (2 + i) % 4
--+-------+--------------+-----------------
0 | 2 | 1 | 1
1 | 3 | 2 | 2
2 | 4 | 3 | 3
3 | 5 | 1 | 1
4 | 6 | 5 | 1
5 | 7 | 4 | 0
6 | 8 | 3 | 3
7 | 9 | 2 | 2
Demo
let f =
s=>s[11%(new Date%8+2)%4]
for(stat = {A:0, B:0, C:0, D:0}, i = 0; i < 80000; i++) {
stat[f("ABCD")]++;
}
console.log(stat);
Version 2, 30 bytes
With the native JavaScript PRNG -- which generates a floating-point number in [0...1) -- we'd rather do:
s=>s[21%(Math.random()*8|8)%4]
Here, we use n = 21 and m = 8 because it allows us to do the addition and isolate the integer part at the same time with Math.random()*8|8.
i | 8 + i | 21 % (8 + i) | 21 % (8 + i) % 4
--+-------+--------------+-----------------
0 | 8 | 5 | 1
1 | 9 | 3 | 3
2 | 10 | 1 | 1
3 | 11 | 10 | 2
4 | 12 | 9 | 1
5 | 13 | 8 | 0
6 | 14 | 7 | 3
7 | 15 | 6 | 2
Demo
let f =
s=>s[21%(Math.random()*8|8)%4]
for(stat = {A:0, B:0, C:0, D:0}, i = 0; i < 80000; i++) {
stat[f("ABCD")]++;
}
console.log(stat);
Mathematica, 25 bytes
RandomChoice@{##,##2,#2}&
input
["A", "B", "C", "D"]
-23 bytes from @MarkS!
Javascript, 31 30 bytes / 23 bytes
Seeing asgallant's earlier Javascript answer got me to thinking about JS. As he said:
Takes a string
ABCDas input, outputsA1/8th of the time,B3/8ths of the time,C1/4th of the time, andD1/4th of the time.
Mine is:
x=>(x+x)[Math.random()*8&7||1]
Explanation:
x=>(x+x)[ // return character at index of doubled string ('ABCDABCD')
Math.random()*8 // select a random number from [0, 8]
&7 // bitwise-and to force to integer (0 to 7)
||1 // use it except if 0, then use 1 instead
]
From Math.random()*8&7 it breaks down as follows:
A from 4 = 12.5% (1/8)
B from 0,1,5 = 37.5% (3/8)
C from 2,6 = 25% (1/4)
D from 3,7 = 25% (1/4)
Version 2, 23 bytes
But then thanks to Arnauld, who posted after me, when he said:
If a time-dependent formula is allowed, we can just do:
which, if it is indeed allowed, led me to:
x=>(x+x)[new Date%8||1]
in which new Date%8 uses the same break-down table as above.
And %8 could also be &7; take your pick. Thanks again, Arnauld.
Java (OpenJDK 8), 40 38 bytes
s->s[5551>>2*(int)(Math.random()*8)&3]
5551 in base 10 is 01112233 in base 4. So let's randomly pick one of those base-4 digits using bit shift and selection, then pick the n-th character from the originating char[].
Pyth, 7 bytes
@z|O8 1
O8 generates a random number from 0 to 7. | ... 1 applies a logical or with 1, converting the 0 to a 1 and leaving everything else the same. The number at this stage is 1 2/8th of the time, and 2, 3, 4, 5, 6, 7 or 8 1/8 of the time.
@z indexes into the input string at that position. The indexing is performed modulo the length of the string, so 4 indexes at position 0, 5 at position 1, and so on.
The probabilities are:
Position 0: Random number 4. 1/8 of the time.
Position 1: Random number 0, 1 or 5. 3/8 of the time.
Position 2: Random number 2 or 6. 2/8 of the time.
Position 3: Random number 3 or 7. 2/8 of the time.
05AB1E, 5 bytes
¦Ćì.R
Explanation
¦Ćì.R Argument s "ABCD"
¦ Push s[1:] "BCD"
Ć Enclose: Pop a, Push a + a[0] "BCDB"
ì Pop a, Concatenate a and s "ABCDBCDB"
.R Random pick
Octave, 30 28 bytes
@(S)S([1:4 2 2:4])(randi(8))
Previous answer:
@(S)S('ABBBCCDD'(randi(8))-64)
Input is taken as a string of 4 characters.
Explanation:
Instead of [1 2 2 2 3 3 4 4 ] we can write 'ABBBCCDD'-64 and randomly select one of indexes and use the index to extract the desired character from the string.
Common Lisp, 198 bytes
(setf *random-state*(make-random-state t))(defun f(L)(setf n(random 8))(cond((< n 1)(char L 0))((and(>= n 1)(< n 4))(char L 1))((and(>= n 4)(< n 6))(char L 2))((>= n 6)(char L 3))))(princ(f "ABCD"))
Readable:
(setf *random-state* (make-random-state t))
(defun f(L)
(setf n (random 8))
(cond
((< n 1)
(char L 0))
((and (>= n 1)(< n 4))
(char L 1))
((and (>= n 4)(< n 6))
(char L 2))
((>= n 6)
(char L 3))
)
)
(princ (f "abcd"))
Applesoft, 29 oops, 32 bytes
A little "retrocomputing" example. Bear with me, I'm brand new at this. I gather that what is designated as the "input" need not be byte-counted itself. As stated in the OP, the input would be given as "ABCD". (I didn't initially realize that I needed to specify input being obtained, which added 4 bytes, while I golfed the rest down a byte.)
INPUTI$:X=RND(1)*4:PRINTMID$(I$,(X<.5)+X+1,1)
The terms INPUT, RND, PRINT and MID$ are each encoded internally as single-byte tokens.
First, X is assigned a random value in the range 0 < X < 4. This is used to choose one of the characters from I$, according to (X < .5) + X + 1. Character-position value is taken as truncated evaluation of the expression. X < .5 adds 1 if X was less than .5, otherwise add 0. Results from X break down as follows:
A from .5 ≤ X < 1 = 12.5%
B from X < .5 or 1 ≤ X < 2 = 37.5%
C from 2 ≤ X < 3 = 25%
D from 3 ≤ X < 4 = 25%
Javascript 35 bytes
Takes a string ABCD as input, outputs A 1/8th of the time, B 3/8ths of the time, C 1/4th of the time, and D 1/4th of the time.
x=>x[5551>>2*~~(Math.random()*8)&3]
Explanation
x=>x[ // return character at index
5551 // 5551 is 0001010110101111 in binary
// each pair of digits is a binary number 0-3
// represented x times
// where x/8 is the probability of selecting
// the character at the index
>> // bitshift right by
2 * // two times
~~( // double-bitwise negate (convert to int, then
// bitwise negate twice to get the floor for
// positive numbers)
Math.random() * 8 // select a random number from [0, 8)
) // total bitshift is a multiple of 2 from [0, 14]
&3 // bitwise and with 3 (111 in binary)
// to select a number from [0, 3]
]
05AB1E, 9 bytes
•20åÝ•.Rè
•20åÝ• # Push 33221110.
.R # Randomly selected index.
è # Character at that index.
C# (.NET Core), 76 55 bytes
s=>(s+s[1]+s[1]+s[2]+s[3])[new System.Random().Next(8)]
My first answer written directly on TIO using my mobile phone. Level up!
Explanation: if the original string is "ABCD", the function creates the string "ABCDBBCD" and takes a random element from it.
Ruby, 34 33 29 27 bytes
Saved 2 bytes thanks to @Value Inc
Input as four characters
a=$**2
a[0]=a[1]
p a.sample
construct an array [B,B,C,D,A,B,C,D] and sample it.
try it n times! (I converted it to a function to repeat it more easily, but the algorithm is the same)
Chip, 60 bytes
)//Z
)/\Z
)\/^.
)\x/Z
)\\\+t
|???`~S
|z*
`{'AabBCcdDEefFGghH
The three ?'s each produce a random bit. On the first cycle, these bits are run through the switches above (/'s and \'s) to determine which value we are going to output from this table:
000 a
01_ b
0_1 b
10_ c
11_ d
(where _ can be either 0 or 1). We then walk along the input as necessary, printing and terminating when the correct value is reached.
The big alphabetic blob at the end is copied wholesale from the cat program, this solution simply suppresses output and terminates to get the intended effect.
Charcoal, 11 bytes
‽⟦εεζζηηηθ⟧
Try it online! Link is to verbose version of code, although you hardly need it; ‽ picks a random element, ⟦⟧ creates a list, and the variables are those that get the appropriate input letters (in reverse order because I felt like it).
CJam, 11 bytes
XZYY]q.*smR
XZYY] e# add [1,3,2,2] to stack
q e# add input string to stack
.* e# element-wise multiply the two arrays. char * int in CJam = repeat character x times
s e# flatten result to string
mR e# pick random char from string
05AB1E, 6 bytes
«À¨Ć.R
Explanation
Works for both lists and strings.
« # concatenate input with itself
À # rotate left
¨ # remove the last character/element
Ć # enclose, append the head
.R # pick a character/element at random
PHP, 28 bytes
<?=$argn[5551>>2*rand(0,7)];
Run as pipe with -nR.
01112233 in base-4 is 5551 in decimal ...
QBIC, 27 bytes
?_s;+;+B+B+;+C+;+D,_r1,8|,1
Explanation
? PRINT
_s A substring of
;+ A plus
;+B+B+ 3 instances of B plus
;+C+ 2 instances of C plus
;+D 2 instances of D plus
,_r1,8| from position x randomly chosen between 1 and 8
,1 running for 1 character
R, 31 bytes
sample(scan(,''),1,,c(1,3,2,2))
Reads the characters from stdin separated by spaces. sample draws random samples from its first input in quantity of the second input (so 1), (optional replacement argument), with weights given by the last argument.
For the latter code, I sample n times (set n in the header) with replacement set to True (it's false by default), tabulate the results, and divide by n to see the relative probabilities of the inputs.
q/kdb+, 15 13 bytes
Solution:
1?a[0],7#1_a:
Example:
q)1?a[0],7#1_a:"ABCD"
,"B"
Explanation:
This is pretty much a q version of the jelly solution. Create the list "ABCDBCDB" and then pick one item from it at random
Bonus:
Another q solution in 15 bytes, same style as the APL one:
1?(,/)1 3 2 2#'
A k version of this solution is 13 bytes:
1?,/1 3 2 2#'
MATL, 12 10 bytes
l3HHvY"1Zr
Try it online! Or run it 1000 times (slightly modified code) and check the number of times each char appears.
Explanation
l3HH % Push 1, 3, 2, 2
v % Concatenate all stack contents into a column vector: [1; 3; 2; 2]
Y" % Implicit input. Run-length decode (repeat chars specified number of times)
1Zr % Pick an entry with uniform probability. Implicit display
Changes in modified code: 1000:"Gl3HH4$vY"1Zr]vSY'
1000:"...]is a loop to repeat1000times.Gmakes sure the input is pushed at he beginning of each iteration.- Results are accumulated on the stack across iterations. So
vneeds to be replaced by4$vto concatenate only the top4numbers. - At the end of the loop,
vconcatenates the1000results into a vector,Ssorts it, andY'run-length encodes it. This gives the four letters and the number of times they have appeared.
Python 3, 64 55 51 bytes
-9 bytes thanks to @ovs
lambda s:choice((s*2)[1:]+s[1])
from random import*
Explanation
random.choice() gets a random character of the String, while (s*2)[1:]+s[1] creates BCDABCDB for an input of ABCD, which has 1/8 As, 2/8 Cs, 2/8 Ds and 3/8 Bs.
C, 106 bytes
int f(){int r=(int)random()%8;if(!r--)return 'A';if(--r-->0)if(r<2)return 'C';else return 'B';return 'D';}
Python, 50 bytes
lambda x:choice(x[:2]+x[1:]*2)
from random import*
An unnamed function taking and returning strings (or lists of characters).
How?
random.choice chooses a random element from a list, so the function forms a string with the correct distribution, that is, given "ABCD", "ABCD"[:2] = "AB" plus "ABCD"[1:]*2 = "BCD"*2 = "BCDBCD" which is "ABBCDBCD".
Jelly, 6 bytes
Ḋṁ7;ḢX
A monadic link taking a list of four characters and returning one with the probability distribution described.
How?
Ḋṁ7;ḢX - Link: list of characters, s e.g. ABCD
Ḋ - dequeue s BCD
ṁ7 - mould like 7 (implicit range) BCDBCDB
Ḣ - head s A
; - concatenate BCDBCDBA
X - random choice Note that the above has 1*A, 3*B, 2*C, and 2*D
05AB1E, 8 bytes
ìD1è0ǝ.R
# Implicit input | [A,B,C,D]
ì # Prepend the input to itself | [A,B,C,D,A,B,C,D]
D1è # Get the second character | [A,B,C,D,A,B,C,D], B
0ǝ # Replace the first character with this one | [B,B,C,D,A,B,C,D]
.R # Pick a random character from this array | D
