8
\$\begingroup\$

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.

Task

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!
\$\endgroup\$
6
  • \$\begingroup\$ Technically the procedure doesn't change the average, it's always (length-1)/2, isn't it? \$\endgroup\$
    – Neil
    Dec 23, 2021 at 0:04
  • \$\begingroup\$ @Neil exactly yes, you are smart, you can also prove it with math. \$\endgroup\$
    – okie
    Dec 23, 2021 at 0:07
  • \$\begingroup\$ Can X and Y be equal? \$\endgroup\$ Dec 23, 2021 at 0:14
  • 4
    \$\begingroup\$ "Randomly choose 2 number" - this needs further specification. Does it have to be a uniform random distribution? Must they be independently chosen? \$\endgroup\$
    – pxeger
    Dec 23, 2021 at 1:27
  • 3
    \$\begingroup\$ Is it random with replacement or without? \$\endgroup\$
    – Wheat Wizard
    Dec 23, 2021 at 8:54

12 Answers 12

3
\$\begingroup\$

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]
              Ɗ           - Previous 3 links as a monad f(R):
 J                        -   Indices of R
     Ɗ                    -   To the indices of R:
  X                       -     Randomly choose one
    X                     -     Randomly choose one again
   ,                      -     Pair; [i, j]
             ʋ            -   Last 4 links as a dyad g([i, j], R):
      Ṭ                   -     Boolean array with 1s at i and j
           ¥              -     Last 2 links as a dyad h([i, j], R):
        ị                 -       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'
\$\endgroup\$
3
\$\begingroup\$

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.

\$\endgroup\$
2
\$\begingroup\$

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
\$\endgroup\$
2
  • \$\begingroup\$ the length, the mighty lyxal god, you forgot about the length!(the list length your code generated is length+1) \$\endgroup\$
    – okie
    Dec 23, 2021 at 0:13
  • 1
    \$\begingroup\$ @okie fixed‎‎ ‎ ‎ \$\endgroup\$
    – lyxal
    Dec 23, 2021 at 0:15
2
\$\begingroup\$

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!

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

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

\$\endgroup\$
3
  • \$\begingroup\$ your loop method looks awesome! I didn't know you could do that if you don't need iter value \$\endgroup\$
    – okie
    Dec 23, 2021 at 0:46
  • 1
    \$\begingroup\$ @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 \$\endgroup\$
    – hyper-neutrino
    Dec 23, 2021 at 1:18
  • 1
    \$\begingroup\$ 134 bytes \$\endgroup\$
    – pxeger
    Dec 23, 2021 at 1:23
2
\$\begingroup\$

Charcoal, 39 bytes

FN⊞υιFENE²‽LυUMυ⎇№ιλ⊘ΣEι§υμκI⟦⌊υ⌈υ⊘⊖Lυυ

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

FN⊞υι

Generate a range of length length.

FENE²‽Lυ

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

UMυ⎇№ιλ⊘ΣEι§υμκ

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

I⟦⌊υ⌈υ⊘⊖Lυυ

Output the minimum, maximum, average and values.

\$\endgroup\$
2
\$\begingroup\$

Python3, 133 131 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

\$\endgroup\$
2
\$\begingroup\$

J, 44 bytes

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

Try it online!

Outputs Min / Max / List / Avg

\$\endgroup\$
2
\$\begingroup\$

Factor, 87 bytes

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

Try it online!

\$\endgroup\$
2
\$\begingroup\$

BQN (CBQN), 56 bytes

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

Attempt This Online!

fixed after ovs' comment.

-1 from ovs.

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

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)

\$\endgroup\$
1
\$\begingroup\$

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.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.