# Repeat average‎

## Background

It was a normal presentation that I were in as a audience, until the presenter gave a math problem about repeat taking 2 number out of a list a replacing them with average, claiming that there will be something special about it, and our math teacher, sitting at the end of classroom, exciting rushed to me, and tasked me to code that out.

2 input length and generation

1. Generate a range, start from 0, with length of length

2. Randomly choose 2 number (or item) X and Y and replace both X and Y with the average of X and Y

3. Repeat step 2 for generation times

4. Output minimum, maximum, average, and the processed list.

## Example

I'll let this semi-golfed python code explain itself :)

import random
a,b=map(int,input().split())
l=[*range(a)]
s=lambda:random.randint(0,a-1)
for i in range(b):
x,y=s(),s();l[x],l[y]=[(l[x]+l[y])/2]*2
print(min(l),max(l),sum(l)/a,l)


## Rules

• Standard rules applies
• Input can be in any convenience form.
• As long as you output is clean, understandable, readable, it is allowed.
• The two random value X,Y should be uniform statistically independent random by itself(X and Y are not affecting each other no matter what)

## what you should do?

• Start golfing right now!
• Technically the procedure doesn't change the average, it's always (length-1)/2, isn't it?
– Neil
Dec 23, 2021 at 0:04
• @Neil exactly yes, you are smart, you can also prove it with math.
– okie
Dec 23, 2021 at 0:07
• Can X and Y be equal? Dec 23, 2021 at 0:14
• "Randomly choose 2 number" - this needs further specification. Does it have to be a uniform random distribution? Must they be independently chosen? Dec 23, 2021 at 1:27
• Is it random with replacement or without? Dec 23, 2021 at 8:54

# Jelly, 25 bytes

ḶJX,XƊṬ×ịÆm¥oʋƊ⁹¡µṂ;Ṁ;Æm,


Try it online!

Outputs [[min, max, mean], list]. Takes length as the first argument, and generation as the second

## How it works

ḶJX,XƊṬ×ịÆm¥oʋƊ⁹¡µṂ;Ṁ;Æm, - Main link. Takes L on the left, G on the right
Ḷ                         - [0, 1, ..., L-1]
J                        -   Indices of R
Ɗ                    -   To the indices of R:
X                       -     Randomly choose one
X                     -     Randomly choose one again
,                      -     Pair; [i, j]
Ṭ                   -     Boolean array with 1s at i and j
ị                 -       Get R[i] and R[j]
Æm               -       Take the mean
×                  -     Replace the 1s with the mean
o             -     Or; replace the elements at i and j in R with the mean
⁹¡         - Apply f(R) G times
µ        - Use this list L' as the new argument
Ṃ       - Minimum
Ṁ     - Maximum
Æm  - Mean
; ;    - [Min, Max, Mean]
, - Pair with L'


# APL+WIN, 60 bytes

Prompts for length and generation. Index origin = 0

v←⍳l←⎕⋄⍎∊⎕⍴⊂'v[i]←(+/v[i←(?l),?l])÷2⋄'⋄(⌊/v),(⌈/v),(+/v÷l),v


Try it online!Thanks to Dyalog Classic

The results in TIO are output in the order listed in the question. The second example in TIO shows that by generation=1000 all elements of the output have converged to the mean in that particular case.

# Vyxal, 25 bytes

ʁ?(₅‹₍℅℅~İṁ£(n¥Ȧ)):₌₍GgṁW


Try it Online!

25 bytes of fun. Takes length then generations and outputs [list, [Max, Min], average]. Can be 24 bytes with the W flag

## Explained

ʁ?(₅‹₍℅℅~İṁ£(n¥Ȧ)):₌₍GgṁW
ʁ                          # The range [0, length) - this will be the list we modify
?(                        # (generation) times:
₅‹                      #   push the top of the stack, and its length + 1
₍℅℅                   #   choose two random items from the range [0, length) and place them into a list
~İ                 #   without popping anything, get the item at each randomly chosen index from the top list - this leaves [list, indexes, items] on the stack
ṁ£               #   place the average of those two items into the register
(...)          #   for each index i in the indexes list:
n¥Ȧ           #      list[i] = register (the mean)
)         # close the main for loop
:        # now the top of the stack is the list with all the replaced items. We duplicate it so we can extract the juicy info from it
₌₍Ggṁ   # Push a list of [max, min] and push the mean of that list
W  # Wrap everything into a single list and implicitly print

• the length, the mighty lyxal god, you forgot about the length!(the list length your code generated is length+1)
– okie
Dec 23, 2021 at 0:13
• @okie fixed‎‎ ‎ ‎ Dec 23, 2021 at 0:15

# JavaScript (ES6), 145 bytes

Expects (length)(generation). Returns [min, max, avg, list].

with(Math)f=(n,a=[k=n],R=random)=>g=m=>k?g(m,a[--k]=k):m?g(m-1,a[i=R()*n|0]=a[j=R()*n|0]=(a[i]+a[j])/2):[min(...a),max(...a),eval(a.join+)/n,a]


Try it online!

• you forgot the statics about the processed list (average,min,max)
– okie
Dec 23, 2021 at 0:31
• @okie Ugh. I missed that part entirely ... :-/ Edit: now fixed. Dec 23, 2021 at 0:32
• Maybe you can simplify eval(a.join+)/n to ~-n/2.
– tsh
Dec 23, 2021 at 3:08

# Python, 134 bytes

from random import*
R=randrange
def f(l,g):*a,=range(l);exec("a[x]=a[y]=a[x:=R(l)]/2+a[y:=R(l)]/2;"*g);return min(a),max(a),sum(a)/l,a

Attempt This Online!

-13 bytes thanks to pxeger using randrange and :=

• your loop method looks awesome! I didn't know you could do that if you don't need iter value
– okie
Dec 23, 2021 at 0:46
• @okie Ah, yeah, it's a pretty helpful tip. Anyway, if you don't need the iter value, another thing you can do is just repeat the code and exec it :P Dec 23, 2021 at 1:18
• 134 bytes Dec 23, 2021 at 1:23

# Charcoal, 39 bytes

ＦＮ⊞υιＦＥＮＥ²‽ＬυＵＭυ⎇№ιλ⊘ΣＥι§υμκＩ⟦⌊υ⌈υ⊘⊖Ｌυυ


Try it online! Link is to verbose version of code. Explanation:

ＦＮ⊞υι


Generate a range of length length.

ＦＥＮＥ²‽Ｌυ


Generate generation pairs of random integers also in that range, and loop over those pairs.

ＵＭυ⎇№ιλ⊘ΣＥι§υμκ


Update the array at those two indices with the average of the two values that are there.

Ｉ⟦⌊υ⌈υ⊘⊖Ｌυυ


Output the minimum, maximum, average and values.

# Python3, 133131 128 bytes

from random import*
def f(l,g):
*r,=range(l)
while g:shuffle(r);*r,x,y=r;r+=[(x+y)/2]*2;g-=1
return min(r),max(r),sum(r)/l,r


Try this online

# J, 44 bytes

(<./;>./;];+/%#)@(2&((?#)(2%~1#.{)[]}])i.)


Try it online!

Outputs Min / Max / List / Avg

# Factor, 87 bytes

[ iota >array [ randomize 2 cut* mean dup 2array append ] repeat dup minmax pick mean ]


Try it online!

# BQN (CBQN), 56 bytes

{A←+´÷≠,(⌈´∾⌊´∾A∾⋈){∾˜∘A⌾((2•rand.Range≠𝕩)⊸⊏)𝕩}⍟𝕨↕𝕩}

Attempt This Online!

fixed after ovs' comment.

-1 from ovs.

• does that recompute 2•rand.Range𝕩 every iteration? Apr 8 at 13:19
• No it didn't. But ∾˜∘A saves a byte over (2⥊A)
– ovs
Apr 8 at 13:41

# Julia, 81 bytes

l\g=(L=[0.:~-l;];1:g.|>_->(r=rand(1:l,2);L[r].=sum(L[r])/2);(extrema(L),~-l/2,L))


Try it online!

expects length\generation and returns ((min, max), mean, list)

# TI-Basic, 85 bytes

Prompt L,G
seq(I,I,0,L-1→A
For(I,1,G
rand(dim(ʟA→B
SortA(ʟB,ʟA
mean({ʟA(1),ʟA(2→ʟA(1
Ans→ʟA(2
End
Disp min(ʟA),max(ʟA),mean(ʟA),ʟA


seq(I,I, can be replaced with randIntNoRep( for -3 bytes if the calculator supports it.

Output is displayed.