g | x | w | all
Bytes Lang Time Link
007Thunno 2230720T095911ZThe Thon
007Pyth170717T155652ZMr. Xcod
031SmileBASIC180313T185331Z12Me21
019Cubix171119T124641ZFlipTack
026Perl 5171119T180625ZXcali
010ngn/apl171119T173828Zngn
042Lean Mean Bean Machine170717T162743ZMayube
025TIBasic170719T014829ZTimtech
019><>170718T021437ZNot a tr
052Bash170719T121505ZOlivier
014APL170717T151740ZUriel
016J170718T213658ZJonah
044Java 8170717T181705ZSocratic
017braingasm170718T183944Zdaniero
064PowerShell170718T182500ZJeff Fre
2530JavaScript ES6170718T105444ZArnauld
025Mathematica170717T154757ZZaMoC
3023Javascript170718T052355ZAlan Rat
038Java OpenJDK 8170717T195904ZOlivier
007Pyth170718T103408Zisaacg
00505AB1E170718T092945Zkalsower
028Octave170718T060706Zrahnema1
198Common Lisp170718T031924ZCheldon
032Applesoft170717T225009ZAlan Rat
035Javascript170717T233957Zasgallan
032Ruby170717T212950Zdaniero
00905AB1E170717T205031ZMagic Oc
055C# .NET Core170717T184031ZCharlie
027Ruby170717T182155Zalexande
049C gcc170717T155002Zcleblanc
060Chip170717T194257ZPhlarx
011Charcoal170717T190820ZNeil
011CJam170717T171909Zgeokavel
00605AB1E170717T163127ZEmigna
056><>170717T162332ZKSmarts
028PHP170717T161149ZTitus
027QBIC170717T161347Zsteenber
031R170717T154634ZGiuseppe
013q/kdb+170717T155844Zmkst
010MATL170717T153647ZLuis Men
051Python 3170717T152551ZMr. Xcod
106C170717T153106Zcaylee
050Python170717T153034ZJonathan
006Jelly170717T152014ZJonathan
00805AB1E170717T151607ZRiley
008Jelly170717T151602ZLeaky Nu

Thunno 2, 7 bytes

«¦/d×Jɼ

Try it online!

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.

Try it here!

Pyth, 10 8 bytes

O+<Q2*2t

Uses the exact same algorithm as is Jonathan Allan's Python answer.

Try it here!


Explanation

Applying this algorithm for ABCD:


-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:

Image showing probabilities of each direction

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

Perl 5, 26 bytes

say((A..D,B..D,B)[rand 8])

Try it online!

ngn/apl, 10 bytes

⎕a[⌈/?2 4]

?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?

Try it online!

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]}

Try it online!

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

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]

Try it online!

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

Test suite

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:

05AB1E, 5 bytes

¦Ćì.R

Try it online!

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

Try it online!

Previous answer:

@(S)S('ABBBCCDD'(randi(8))-64)

Try it online!

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

Try it online!

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]
]

Ruby, 32 bytes

Pretty straightforward..?

->s{s[[0,1,1,1,2,2,3,3].sample]}

Try it online!

05AB1E, 9 bytes

•20åÝ•.Rè

Try it online!

•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)]

Try it online!

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

try it n times! (I converted it to a function to repeat it more easily, but the algorithm is the same)

C (gcc), 50 49 bytes

i[8]={1,1,1,2,2,3,3};f(char*m){m=m[i[rand()%8]];}

Try it online!

Chip, 60 bytes

)//Z
)/\Z
)\/^.
)\x/Z
)\\\+t
|???`~S
|z*
`{'AabBCcdDEefFGghH

Try it online!

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

Try it Online

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

Try it online!

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

><>, 56 bytes

v
!

"
D
C
B
A ;
" o
! @
! ^<
x!^xv!
@  v<
@  o
o  ;
;
o

Try it online!

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.

Try it online!

Try it n times!

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'

Python 3, 64 55 51 bytes

-9 bytes thanks to @ovs

lambda s:choice((s*2)[1:]+s[1])
from random import*

Try it online!


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

Try it online!

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.

Try it online!

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

Try it online!

         # 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

Jelly, 8 bytes

122b4⁸xX

Try it online!

Remove the X to see "ABBBCCDD". The X chooses a random element.