| Bytes | Lang | Time | Link |
|---|---|---|---|
| 041 | Wolfram Language Mathematica | 210216T181615Z | att |
| 071 | Ruby | 210217T103529Z | Razetime |
| 013 | MATL | 210217T031426Z | Suever |
| 018 | Jelly | 210216T200430Z | Jonathan |
| 017 | 05AB1E | 210216T143933Z | Kevin Cr |
| 121 | Python 3 | 210216T154708Z | Noodle9 |
| nan | J | 210216T150235Z | Jonah |
| 075 | Python 3 + numpy | 210216T163109Z | ovs |
| 045 | R | 210216T152854Z | Kirill L |
| 046 | Julia | 210216T160302Z | MarcMush |
| 088 | JavaScript ES6 | 210216T150812Z | Arnauld |
| 011 | MathGolf | 210216T153713Z | Kevin Cr |
| 025 | Charcoal | 210216T153607Z | Neil |
| 021 | APLDyalog Unicode | 210216T152408Z | ovs |
Wolfram Language (Mathematica), 42 41 bytes
{##2,#}&@@(a=1~RandomReal~#;a/=Tr@a).a|a&
Ruby, 83 82 72 71 bytes
->n{k=(1..n).map{rand};p=k[~-s=0]/z=k.sum;[k.map{|x|s+=p*x/z;p=x/z},s]}
-4,-1,-6 from ASCII-only!
-4, shortening it further.
-1 more byte from ASCII-only.
MATL, 13 bytes
l&rts/ttlYS*s
Explanation
% Implicitly retrieve input (N) as an integer
l % Push the literal 1 to the stack
&r % Create an N x 1 array of random floats
t % Duplicate this array
s % Sum the elements of this array
/ % And perform element-wise division of the original array by this sum
% to get the array, A
tt % Duplicate A (twice)
lYS % Circularly shift A by 1 element
* % Perform element-wise multiplication with A
s % Compute the sum
% Implicitly display A and the sum of the products
Jelly, 18 bytes
No built-in for random floats, so half the code is that!
2ṗ⁹XHCḅ.)÷S$µṙ1ḋƊ,
A monadic Link accepting an integer, n, which yields a list containing a non-negative float (the sum of products) and the generated list of non-negative floats of length n which sums to 1.
Try it online! (Note that ⁹ (\$256\$) has been replaced with 9 (\$9\$) for speed - generating all \$2^{256}\$ lists of bits would take a while. Using a number as big as \$256\$ is not necessary, it's just terse.)
How?
(Bug fixed above, will update this section later.)
Note: Uses 256 random bits to generate a random float in \$[0,1]\$.
2ṗ⁹XHCḅ.)µ÷Sṙ1ḋƊ, - Link: n
) - for each:
2 - 2
⁹ - 256
ṗ - (256) Cartesian product (2 implicitly -> [1,2])
X - pick one at random e.g. [1,2,2,1, ... ,1,2]
H - halve [0.5,1,1,0.5, ... ,0.5,1]
C - complement [0.5,0,0,0.5, ... ,0.5,0]
. - a half 0.5
ḅ - convert (list) from base (0.5) a float in [0,1]
µ - start a new monadic chain (call that x)
S - sum sum(x)
÷ - divide normalised(x)
Ɗ - last three links as a monad: (call that Y=[y1,y2,...,yn])
- one 1
ṙ - rotate left by (1) [y2,...,yn,y1]
ḋ - dot product (with Y) y1.y2+y2.y3+...+yn.y1
, - pair [y1.y2+y2.y3+...+yn.y1, Y]
05AB1E, 17 15 14 17 bytes
₄Ý.rI£DO/ÐÀ*O‚
Outputs as a pair [array, sum].
-2 bytes thanks to @Neil.
-1 byte by changing two explicit prints with enclose/overlap builtins =Ćü*O, to something similar as my MathGolf answer with pair and implicit print ÐÀ*O‚
+2 bytes so duplicated items are possible and +1 byte to maximize the amount of floats possible
Try it online (but uses [0,1000] instead of [0,9876543210] to speed things up a bit).
Explanation:
žmÝ # Push a list in the range [0,9876543210]
Iи # Repeat it the input amount of times
# (so we can potentially get duplicated items)
.r # Randomly shuffle this list
I£ # Only leave the first input amount of values
D # Duplicate this list
O # Sum them together
/ # Divide all values by this sum
# (so we now have a list of random values summing to 1)
Ð # Triplicate this list
À # Rotate the top copy once towards the left
* # Multiply the top two lists position-wise together
O # Sum this list
‚ # Pair the list together with this sum
# (after which this pair is output implicitly as result)
Python 3, 124 121 bytes
Saved a byte thanks to Kevin Cruijssen!!!
Saved 3 bytes thanks to Danis!!!
def f(n):l=[random()for i in[0]*n];l=[e/sum(l)for e in l];return l,sum(a*b for a,b in zip(l,l[1:]+l))
from random import*
J, 30 27 25 bytes
-2 to thanks to ovs's rotate idea
[:(;1#.]*1|.])@(%+/)?@$&0
$&0Duplicate 0 "input" times.?@And "roll" for each (?0produces a random number between 0 and 1).[:...(%+/)Divide each by sum of all.(;1#.]*1|.])To that boxed list append;the sum of1#.the list]times*the list rotated once to the left1|.].
Python 3 + numpy, 75 bytes
from numpy import*
def f(n):x=random.rand(n);x/=sum(x);return x,x@roll(x,1)
JavaScript (ES6), 89 88 bytes
Returns [ array, sum ].
f=(n,a=[],t=s=0)=>n?f(n-1,[...a,v=Math.random()],t+v):[a.map(k=>(s+=v/t*(v=k),v/t)),s/t]
Commented
f = ( // f is a recursive function taking:
n, // n = input
a = [], // a[] = array
t = // t = sum of non-normalized values
s = 0 // s = sum of a[i] * a[(i + 1) mod n] / t
) => //
n ? // if n is not equal to 0:
f( // do a recursive call:
n - 1, // decrement n
[ ...a, // pass a new array with all previous elements of a[]
v = Math.random() ], // followed by a new random value v in [0,1)
t + v // add v to t
) // end of recursive call
: // else:
[ // build the answer array:
a.map(k => // for each value k in a[]:
( s += // add to s:
v / t // the previous normalized value v / t,
* (v = k), // multiplied by k (and update v to k)
v / t // yield the normalized value
) //
), // end of map()
s / t // also return the normalized sum
] // end of answer array
MathGolf, 11 bytes
ă]_Σ/∙╫m*Σ
Outputs the array and sum concatenated to one another.
Explanation:
Ä # Loop the (implicit) input amount of times,
# using a single character as inner code-block:
ƒ # Push a random float in the range [0,1]
] # Wrap all values on the stack into a list
_ # Duplicate this list
Σ # Take the sum of it
/ # Divide all values in the list by this sum
# (so we now have a list of random values summing to 1)
∙ # Triplicate this list
╫ # Rotate the top copy once towards the left
m* # Multiply the top two lists position-wise together
Σ # Take the sum of that list
# (after which the entire stack joined together is output implicitly)
Charcoal, 25 bytes
FN⊞υ‽φ≧∕Συυ⊞υΣEυ×ι§υ⊕κI⮌υ
Try it online! Like the 05AB1E answer, I generate n random numbers between 0 and 999, then scale them so their sum is 1. A larger range could be obtained at the cost of one or two bytes. Also, it's unclear whether the sum has to be first; printing it last would save two bytes. Explanation:
FN
Repeat n times...
⊞υ‽φ
... push a random integer to the predefined empty list.
≧∕Συυ
Divide the list by its sum.
⊞υΣEυ×ι§υ⊕κ
Multiply each element by its neighbour and push the sum to the list.
I⮌υ
Print the list in reverse so that the sum is first.
APL(Dyalog Unicode), 21 bytes SBCS
(+/⊢×1∘⌽)⎕←(⊢÷+/)?⎕⍴0
A tradfn submission which prints the list and returns the sum.
⎕⍴0 ⍝ create a vector with input-many 0's
? ⍝ for each 0, get a random number between 0 and 1
⊢÷ ⍝ divide each number by
+/ ⍝ the sum of all numbers
⎕← ⍝ print the resulting vector
⊢× ⍝ multiply the vector element-wise
1∘⌽ ⍝ with the vector rotated to the left by 1
+/ ⍝ take the sum of all products
If appending the sum to the list is fine as output, this could be 20 bytes: x,+/x×1⌽x←(⊢÷+/)?⎕⍴0