Arbitrary Randomness
up vote
22
down vote
favorite
Randomness is fun. Challenges with no point are fun.
Write a function that, given integer input n
, will output a set (unordered, unique) of exactly n
random integers between 1
and n^2
(inclusive) such that the sum of all integers is equal to n^2
.
Randomness does not have to be uniform, provided each valid set has a non-zero chance to occur.
Shortest answer in bytes (per each language) wins.
Examples
Input (n) = 1, Target (n^2) = 1
Sample of possible outputs:
1
Input = 2, Target = 4
Sample of possible outputs:
3, 1
1, 3
Input = 3, Target = 9
Sample of possible outputs:
6, 1, 2
3, 5, 1
4, 3, 2
Input = 4, Target = 16
Sample of possible outputs:
1, 3, 5, 7
2, 4, 1, 9
8, 3, 1, 4
Input = 5, Target = 25
Sample of possible outputs:
11, 4, 7, 1, 2
2, 3, 1, 11, 8
6, 1, 3, 7, 8
Input = 8, Target = 64
Sample of possible outputs:
10, 3, 9, 7, 6, 19, 8, 2
7, 16, 2, 3, 9, 4, 13, 10
7, 9, 21, 2, 5, 13, 6, 1
Bonus Task: Is there a formula to calculate the number of valid permutations for a given n
?
code-golf random combinatorics
|
show 10 more comments
up vote
22
down vote
favorite
Randomness is fun. Challenges with no point are fun.
Write a function that, given integer input n
, will output a set (unordered, unique) of exactly n
random integers between 1
and n^2
(inclusive) such that the sum of all integers is equal to n^2
.
Randomness does not have to be uniform, provided each valid set has a non-zero chance to occur.
Shortest answer in bytes (per each language) wins.
Examples
Input (n) = 1, Target (n^2) = 1
Sample of possible outputs:
1
Input = 2, Target = 4
Sample of possible outputs:
3, 1
1, 3
Input = 3, Target = 9
Sample of possible outputs:
6, 1, 2
3, 5, 1
4, 3, 2
Input = 4, Target = 16
Sample of possible outputs:
1, 3, 5, 7
2, 4, 1, 9
8, 3, 1, 4
Input = 5, Target = 25
Sample of possible outputs:
11, 4, 7, 1, 2
2, 3, 1, 11, 8
6, 1, 3, 7, 8
Input = 8, Target = 64
Sample of possible outputs:
10, 3, 9, 7, 6, 19, 8, 2
7, 16, 2, 3, 9, 4, 13, 10
7, 9, 21, 2, 5, 13, 6, 1
Bonus Task: Is there a formula to calculate the number of valid permutations for a given n
?
code-golf random combinatorics
2
related, but quite different
– Giuseppe
2 days ago
1
(p/s: If you have a fast algorithm but takes more bytes, consider waiting until the speed edition (currently in sandbox) to post it.)
– user202729
2 days ago
1
@EriktheOutgolfer Although there are (much) better ways than generating all sets and pick a random one, they're much harder to implement and likely longer. Keep them for the speed edition.
– user202729
2 days ago
2
The number of sets is OEIS A107379.
– nwellnhof
2 days ago
1
It's both. See the comment "Also the number of partitions of n^2 into n distinct parts."
– nwellnhof
2 days ago
|
show 10 more comments
up vote
22
down vote
favorite
up vote
22
down vote
favorite
Randomness is fun. Challenges with no point are fun.
Write a function that, given integer input n
, will output a set (unordered, unique) of exactly n
random integers between 1
and n^2
(inclusive) such that the sum of all integers is equal to n^2
.
Randomness does not have to be uniform, provided each valid set has a non-zero chance to occur.
Shortest answer in bytes (per each language) wins.
Examples
Input (n) = 1, Target (n^2) = 1
Sample of possible outputs:
1
Input = 2, Target = 4
Sample of possible outputs:
3, 1
1, 3
Input = 3, Target = 9
Sample of possible outputs:
6, 1, 2
3, 5, 1
4, 3, 2
Input = 4, Target = 16
Sample of possible outputs:
1, 3, 5, 7
2, 4, 1, 9
8, 3, 1, 4
Input = 5, Target = 25
Sample of possible outputs:
11, 4, 7, 1, 2
2, 3, 1, 11, 8
6, 1, 3, 7, 8
Input = 8, Target = 64
Sample of possible outputs:
10, 3, 9, 7, 6, 19, 8, 2
7, 16, 2, 3, 9, 4, 13, 10
7, 9, 21, 2, 5, 13, 6, 1
Bonus Task: Is there a formula to calculate the number of valid permutations for a given n
?
code-golf random combinatorics
Randomness is fun. Challenges with no point are fun.
Write a function that, given integer input n
, will output a set (unordered, unique) of exactly n
random integers between 1
and n^2
(inclusive) such that the sum of all integers is equal to n^2
.
Randomness does not have to be uniform, provided each valid set has a non-zero chance to occur.
Shortest answer in bytes (per each language) wins.
Examples
Input (n) = 1, Target (n^2) = 1
Sample of possible outputs:
1
Input = 2, Target = 4
Sample of possible outputs:
3, 1
1, 3
Input = 3, Target = 9
Sample of possible outputs:
6, 1, 2
3, 5, 1
4, 3, 2
Input = 4, Target = 16
Sample of possible outputs:
1, 3, 5, 7
2, 4, 1, 9
8, 3, 1, 4
Input = 5, Target = 25
Sample of possible outputs:
11, 4, 7, 1, 2
2, 3, 1, 11, 8
6, 1, 3, 7, 8
Input = 8, Target = 64
Sample of possible outputs:
10, 3, 9, 7, 6, 19, 8, 2
7, 16, 2, 3, 9, 4, 13, 10
7, 9, 21, 2, 5, 13, 6, 1
Bonus Task: Is there a formula to calculate the number of valid permutations for a given n
?
code-golf random combinatorics
code-golf random combinatorics
edited yesterday
nwellnhof
6,1581125
6,1581125
asked 2 days ago
Skidsdev
6,0662667
6,0662667
2
related, but quite different
– Giuseppe
2 days ago
1
(p/s: If you have a fast algorithm but takes more bytes, consider waiting until the speed edition (currently in sandbox) to post it.)
– user202729
2 days ago
1
@EriktheOutgolfer Although there are (much) better ways than generating all sets and pick a random one, they're much harder to implement and likely longer. Keep them for the speed edition.
– user202729
2 days ago
2
The number of sets is OEIS A107379.
– nwellnhof
2 days ago
1
It's both. See the comment "Also the number of partitions of n^2 into n distinct parts."
– nwellnhof
2 days ago
|
show 10 more comments
2
related, but quite different
– Giuseppe
2 days ago
1
(p/s: If you have a fast algorithm but takes more bytes, consider waiting until the speed edition (currently in sandbox) to post it.)
– user202729
2 days ago
1
@EriktheOutgolfer Although there are (much) better ways than generating all sets and pick a random one, they're much harder to implement and likely longer. Keep them for the speed edition.
– user202729
2 days ago
2
The number of sets is OEIS A107379.
– nwellnhof
2 days ago
1
It's both. See the comment "Also the number of partitions of n^2 into n distinct parts."
– nwellnhof
2 days ago
2
2
related, but quite different
– Giuseppe
2 days ago
related, but quite different
– Giuseppe
2 days ago
1
1
(p/s: If you have a fast algorithm but takes more bytes, consider waiting until the speed edition (currently in sandbox) to post it.)
– user202729
2 days ago
(p/s: If you have a fast algorithm but takes more bytes, consider waiting until the speed edition (currently in sandbox) to post it.)
– user202729
2 days ago
1
1
@EriktheOutgolfer Although there are (much) better ways than generating all sets and pick a random one, they're much harder to implement and likely longer. Keep them for the speed edition.
– user202729
2 days ago
@EriktheOutgolfer Although there are (much) better ways than generating all sets and pick a random one, they're much harder to implement and likely longer. Keep them for the speed edition.
– user202729
2 days ago
2
2
The number of sets is OEIS A107379.
– nwellnhof
2 days ago
The number of sets is OEIS A107379.
– nwellnhof
2 days ago
1
1
It's both. See the comment "Also the number of partitions of n^2 into n distinct parts."
– nwellnhof
2 days ago
It's both. See the comment "Also the number of partitions of n^2 into n distinct parts."
– nwellnhof
2 days ago
|
show 10 more comments
21 Answers
21
active
oldest
votes
up vote
7
down vote
05AB1E, 11 bytes
nÅœʒDÙQ}sùΩ
Try it online or verify all test cases.
Explanation:
n # Take the square of the (implicit) input
# i.e. 3 → 9
Ŝ # Get all integer-lists using integers in the range [1, val) that sum to val
# i.e. 9 → [[1,1,1,1,1,1,1,1,1],...,[1,3,5],...,[9]]
ʒ } # Filter the list to only keep lists with unique values:
D # Duplicate the current value
Ù # Uniquify it
# i.e. [2,2,5] → [2,5]
Q # Check if it's still the same
# i.e. [2,2,5] and [2,5] → 0 (falsey)
s # Swap to take the (implicit) input again
ù # Only leave lists of that size
# i.e. [[1,2,6],[1,3,5],[1,8],[2,3,4],[2,7],[3,6],[4,5],[9]] and 3
# → [[1,2,6],[1,3,5],[2,3,4]]
Ω # Pick a random list from the list of lists (and output implicitly)
add a comment |
up vote
6
down vote
Brachylog (v2), 15 bytes (random) or 13 bytes (all possibilities)
Random
~lℕ₁ᵐA+√?∧A≜₁ᵐ≠
Try it online!
Function submission (seen in TIO with a wrapper making it into a full program).
Explanation
~lℕ₁ᵐA+√?∧A≜₁ᵐ≠
~l Specify a property of a list: its length is equal to the input,
ᵐ and it is composed entirely of
ℕ₁ integers ≥ 1,
√ for which the square root of the
+ sum of the list
? is the input.
A ∧A Restricting yourself to lists with that property,
≜₁ pick random possible values
ᵐ for each element in turn,
≠ until you find one whose elements are all distinct.
All possibilities
~lℕ₁ᵐ<₁.+√?∧≜
Try it online!
Function submission, which generates all possible outputs.
Explanation
~lℕ₁ᵐ<₁.+√?∧≜
~l Specify a property of a list: its length is equal to the input,
ᵐ it is composed entirely of
ℕ₁ integers ≥ 1,
<₁ it is strictly increasing,
√ and the square root of the
+ sum of the list
? is the input.
. ∧≜ Generate all specific lists with that property.
I'm fairly surprised that ∧≜
works (you'd normally have to write ∧~≜
in order to brute-force the output rather than the input), but it turns out that ≜
has an input=output assumption so it doesn't matter which way round you run it.
Bonus task
In order to get some insight into the sequence of the number of possibilities, I created a different TIO wrapper which runs the program on successive integers to give the sequence of output counts:
1,1,3,9,30,110,436,1801,7657,33401
A trip to OEIS discovers that this is already a known sequence, A107379, described pretty much as in the question (apparently you get the same sequence if you restrict it to odd numbers). The page lists several formulas for the sequence (although none is particularly simple; the second looks like a direct formula for the value but I don't understand the notation).
The second formula is "the coefficient ofx^(n*(n-1)/2)
in the series expansion ofProduct_{k=1..n} 1/(1 - x^k)
" (not direct at all, unfortunately)
– user202729
2 days ago
Placing the "all different" constraint before the random labelization step (e.g.A≠≜₁ᵐ
) makes the run time much faster on average.
– Fatalize
yesterday
I don't understand why you made this a community wiki. Those are an archaic way to have editable posts before it was possible to edit.
– pipe
yesterday
@pipe codegolf.stackexchange.com/questions/172716/true-color-code/…
– guest271314
yesterday
add a comment |
up vote
5
down vote
Python (2 or 3), 85 bytes
def f(n):r=sample(range(1,n*n+1),n);return(n*n==sum(r))*r or f(n)
from random import*
Try it online!
add a comment |
up vote
4
down vote
Jelly, 9 bytes
²œcS=¥Ƈ²X
Try it online!
Generate all n-combinations of the list [1..n²], filter to keep those with sum n², then pick a random one.
add a comment |
up vote
4
down vote
Java 10, 250 242 222 bytes
import java.util.*;n->{for(;;){int i=n+1,r=new int[i],d=new int[n];for(r[n<2?0:1]=n*n;i-->2;r[i]=(int)(Math.random()*n*n));var S=new HashSet();for(Arrays.sort(r),i=n;i-->0;)S.add(d[i]=r[i+1]-r[i]);if(!S.contains(0)&S.size()==n)return S;}}
-20 bytes thanks to @nwellnhof.
Watch out, Java coming through.. It's 'only' five times as long as the other four answers combined, so not too bad I guess.. rofl.
It does run n=1
through n=25
(combined) in less than 2 seconds though, so I'll probably post a modified version to the speed version of this challenge (that's currently still in the Sandbox) as well.
Try it online.
Explanation:
In pseudo-code we do the following:
1) Generate an array of size n+1
containing: 0
, n
squared, and n-1
amount of random integers in the range [0, n squared)
2) Sort this array
3) Create a second array of size n
containing the forward differences of pairs
These first three steps will give us an array containing n
random integers (in the range [0, n squared)
that sum to n
squared.
4a) If not all random values are unique, or any of them is 0: try again from step 1
4b) Else: return this differences array as result
As for the actual code:
import java.util.*; // Required import for HashSet and Arrays
n->{ // Method with int parameter and Set return-type
for(;;){ // Loop indefinitely
int i=n+1, // Set `i` to `n+1`
r=new int[i]; // Create an array of size `n+1`
var S=new HashSet(); // Result-set, starting empty
for(r[n<2? // If `n` is 1:
0 // Set the first item in the first array to:
: // Else:
1] // Set the second item in the first array to:
=n*n; // `n` squared
i-->2;) // Loop `i` in the range [`n`, 2]:
r[i]= // Set the `i`'th value in the first array to:
(int)(Math.random()*n*n);
// A random value in the range [0, `n` squared)
for(Arrays.sort(r), // Sort the first array
i=n;i-->0;) // Loop `i` in the range (`n`, 0]:
S.add( // Add to the Set:
r[i+1]-r[i]); // The `i+1`'th and `i`'th difference of the first array
if(!S.contains(0) // If the Set does not contain a 0
&S.size()==n) // and its size is equal to `n`:
return S;}} // Return this Set as the result
// (Implicit else: continue the infinite loop)
1
n=25
in under 2 seconds is impressive! I'll have to read through the explanation and see how it does it. Is it still a bruteforce method?
– Skidsdev
2 days ago
Is it uniform? -
– user202729
2 days ago
@user202729 Although I'm not sure how to prove it, I think it is. The Java builtin is uniform, and it uses that to get random values in the range[0, n squared)
first, and then calculates the differences between those sorted random values (including leading0
and trailingn squared
. So I'm pretty sure those differences are uniform as well. But again, I'm not sure how to prove it. Uniformity in randomness isn't really my expertise tbh.
– Kevin Cruijssen
2 days ago
3
You never read from the differences arrayd
or am I missing something?
– nwellnhof
2 days ago
1
I'm kind of happy with my 127 bytes solution :D
– Olivier Grégoire
yesterday
|
show 5 more comments
up vote
4
down vote
R, 68, 75 48 bytes (random) and 70 bytes (deterministic)
@Giuseppe's rejection sampling method:
function(n){while(sum(F)!=n^2)F=sample(n^2,n);F}
Try it online!
Golfed original:
function(n,m=combn(1:n^2,n))m[,sample(which(colSums(m)==n^2)*!!1:2,1)]
Try it online!
The *!!1:2
business is to avoid the odd way sample
act when the first argument has length 1.
@Giuseppe "fixed" :-)
– ngm
2 days ago
very nice. usingp
directly as an index instead of calculating it and re-using it should save some bytes.
– Giuseppe
2 days ago
1
I havefunction(n){while(sum(F)!=n^2)F=sample(n^2,n);F}
for 48 as well...
– Giuseppe
2 days ago
1
@J.Doe to avoid the issue when calling something likesample(2,1)
which happens withn=2
. Sorep
just guarantees that this will never happen. There might be a better way but this was quick and I was mad atsample
.
– ngm
2 days ago
1
You can save a byte withx*!!1:2
overrep(x,2)
if your meta question gets a no.
– J.Doe
2 days ago
|
show 4 more comments
up vote
4
down vote
Perl 6, 41 bytes
{first *.sum==$_²,(1..$_²).pick($_)xx*}
Try it online!
(1 .. $_²)
is the range of numbers from 1 to the square of the input number
.pick($_)
randomly chooses a distinct subset of that range
xx *
replicates the preceding expression infinitely
first *.sum == $_²
selects the first of those number sets that sums to the square of the input number
40 bytes
– Jo King
2 days ago
add a comment |
up vote
2
down vote
Pyth, 13 12 bytes
Ofq*QQsT.cS*
Try it online here. Note that the online interpreter runs into a MemoryError for inputs greater than 5.
Ofq*QQsT.cS*QQQ Implicit: Q=eval(input())
Trailing QQQ inferred
S*QQQ [1-Q*Q]
.c Q All combinations of the above of length Q, without repeats
f Keep elements of the above, as T, where the following is truthy:
sT Is the sum of T...
q ... equal to...
*QQ ... Q*Q?
O Choose a random element of those remaining sets, implicit print
Edit: saved a byte by taking an alternative approach. Previous version: Of&qQlT{IT./*
add a comment |
up vote
2
down vote
Python 3, 136 134 127 121 114 bytes
from random import*
def f(n):
s={randint(1,n*n)for _ in range(n)}
return len(s)==n and sum(s)==n*n and s or f(n)
Try it online!
A commenter corrected me, and this now hits recursion max depth at f(5) instead of f(1). Much closer to being a real competing answer.
I've seen it do f(5) once, and I'm working on trying to implement this with shuffle.
I tried making some lambda expressions for s=...
, but that didn't help on bytes. Maybe someone else can do something with this:
s=(lambda n:{randint(1,n*n)for _ in range(n)})(n)
Thanks to Kevin for shaving off another 7 bytes.
1
So this uses recursion to "regenerate" the set if the one generated is invalid? Definitely something wrong with your code if it's hitting recursion depth atf(1)
, the only possible array that should be generable atn=1
is[1]
Also there's a lot of extraneous whitespace to be removed here. Remember this is a code-golf challenge, so the goal is to achieve the lowest bytecount
– Skidsdev
2 days ago
1
range(1,n)
->range(n)
I believe should resolve the bug.
– Jonathan Allan
2 days ago
1
This should fix your bug, and also removes extraneous whitespace. I imagine there's a lot more room for golfing too
– Skidsdev
2 days ago
1
Although the recursion slightly worsens from 5 to 4, you can combine your two return statements like this:return len(s)==n and sum(s)==n*n and s or f(n)
(Try it online 114 bytes).
– Kevin Cruijssen
2 days ago
1
You can have it all on one line. 111 bytes
– Jo King
2 days ago
|
show 1 more comment
up vote
1
down vote
MATL, 18 13 bytes
`xGU:GZrtsGU-
Try it online!
` # do..while:
x # delete from stack. This implicitly reads input the first time
# and removes it. It also deletes the previous invalid answer.
GU: # paste input and push [1...n^2]
GZr # select a single combination of n elements from [1..n^2]
tsGU- # is the sum equal to N^2? if yes, terminate and print results, else goto top
I wouldn't try this in R - random characters almost never produce a valid program.
– ngm
2 days ago
@ngm hahaha I suppose an explanation is in order.
– Giuseppe
2 days ago
add a comment |
up vote
1
down vote
Japt, 12 bytes
²õ àU ö@²¥Xx
Try it
:Implicit input of integer U
² :U squared
õ :Range [1,U²]
àU :Combinations of length U
ö@ :Return a random element that returns true when passed through the following function as X
² : U squared
¥ : Equals
Xx : X reduced by addition
According to a comment made by the OP, order of elements in the output is irrelevant soà
should be fine.
– Kamil Drakari
2 days ago
Thanks, @KamilDrakari. Updated.
– Shaggy
2 days ago
add a comment |
up vote
1
down vote
Java (JDK), 127 bytes
n->{for(int s;;){var r=new java.util.TreeSet();for(s=n*n;s>0;)r.add(s-(s-=Math.random()*n*n+1));if(r.size()==n&s==0)return r;}}
Try it online!
Infinite loop until a set with the criteria matches.
I hope you have the time, because it's very sloooooow! It can't even go to 10 without timing out.
You can golf 3 bytes by changingif(r.size()==n&s==0)
toif(r.size()+s==n)
.
– Kevin Cruijssen
8 hours ago
@KevinCruijssen I've thought about it too, but no I can't because s could be -1 and n could be size() - 1.
– Olivier Grégoire
7 hours ago
add a comment |
up vote
1
down vote
JavaScript, 647 bytes
(n,s=(n,g=n**2,a=[...Array(g).keys()].map(k=>k+1),c=_=>eval(_.join`+`))=>[...function*(r=,p=a.slice(0,-2).sort(_=>.5-Math.random())){while(r.length<n)r.push(p.splice(Math.floor(Math.random()*p.length),1)[0]);if(c(r)==g)return r;while(c(r)>g){for(let x=0;x<r.length;x++){if(c(r)==g)break;if(r[x]-1==0||r.find(_=>r[x]-1==_)){continue}else r[x]-=1}}while(c(r)<g){for(let x=0;x<r.length;x++){if(c(r)==g)break;if(r.find(_=>r[x]+1==_)){continue}else r[x]+=1;}}yield* r}()])=>n<2?[n]:[...function*(){for(let k=0,r=;k<n;k++){let z=s(n).slice(0,n);if(!r.length){r.push(z.join``)}else{if(r.find(_=>_==z.join``)){z.reverse()}r.push(z.join``)}yield z}}()]
Try it online!
Un-golfed
f=(n
, s = (n, g = n ** 2, a = [...Array(g).keys()].map(k => k + 1), c = _ => eval(_.join `+`)) =>
[...function * (r = , p = a.slice(0, -2).sort(_ => .5 - Math.random())) {
while (r.length < n) r.push(p.splice(Math.floor(Math.random() * p.length), 1)[0]);
if (c(r) == g) return r;
while (c(r) > g) {
for (let x = 0; x < r.length; x++) {
if (c(r) == g) break;
if (r[x] - 1 == 0 || r.find(_ => r[x] - 1 == _)) {
continue
} else r[x] -= 1
}
}
while (c(r) < g) {
for (let x = 0; x < r.length; x++) {
if (c(r) == g) break;
if (r.find(_ => r[x] + 1 == _)) {
continue
} else r[x] += 1;
}
}
yield * r
}()]) => n < 2 ? [n] : [...function * () {
for (let k = 0, r = ; k < n; k++) {
let z = s(n).slice(0, n);
if (!r.length) {
r.push(z.join ``)
} else {
if (r.find(_ => _ == z.join ``)) {
z.reverse()
}
r.push(z.join ``)
}
yield z
}
}()]
1
637 bytes by pulling z.join into a variable, andk++
– Veskah
5 hours ago
@Veskah The twowhile
loops could probably also be reduced to the body of a single function which accepts parameters; and could substitute conditional operators (ternary) for theif..else
statements; among other portions of the code that could more than likely be adjusted for golf; i.e.g., removinglet
statements.
– guest271314
5 hours ago
@Veskah 601 bytes without substituting ternary forif..else
– guest271314
5 hours ago
1
Oh yeah, you're outputting all the sets whereas the challenge asks for a random one to be returned (See the OP comments for more details)
– Veskah
5 hours ago
@Veskah Must have misinterpreted the challenge and examples, or was too focused on solving this part of the question "Bonus Task: Is there a formula to calculate the number of valid permutations for a givenn
?". testing if the algorithm consistently returned expected result forn^2
output arrays generated in a single call to the function, and simultaneously considering the similarities to this question N-dimensional N^N array filled with N.
– guest271314
5 hours ago
|
show 1 more comment
up vote
1
down vote
Batch, 182 145 bytes
@set/an=%1,r=n*n,l=r+1
@for /l %%i in (%1,-1,1)do @set/at=n*(n-=1)/2,m=(r+t+n)/-~n,r-=l=m+%random%%%((l-=x=r+1-t)*(l^>^>31)+x-m)&call echo %%l%%
Explanation: Calculates the minimum and maximum allowable pick, given that the numbers are to be picked in descending order, and chooses a random value within the range. Example for an input of 4
:
- We start with 16 left. We can't pick 11 or more because the remaining 3 picks must add to at least 6. We also need to pick at least 6, because if we only pick 5, the remaining 3 picks can only add to 9, which isn't enough for 16. We pick a random value from 6 to 10, say 6.
- We have 10 left. We can't pick 8 or more because the remaining 2 picks must add to at least 3. As it happens, we can't pick 6 or more because we picked 6 last time. We also need to pick at least 5, because if we only pick 4, the remaining 2 picks can only add to 5, for a grand total of 15. We pick a random value from 5 to 5, say 5 (!).
- We have 5 left. We can't pick 5 or more because the remaining pick must add to at least 1, and also because we picked 5 last time. We also need to pick at least 3, because if we only pick 2, the remaining pick can only be 1, for a grand total of 14. We pick a random value from 3 to 4, say 4.
- We have 1 left. As it turns out, the algorithm chooses a range of 1 to 1, and we pick 1 as the final number.
add a comment |
up vote
0
down vote
Japt, 20 bytes
²õ ö¬oU íUõ+)Õæ@²¥Xx
Try it online!
Extremely heavily takes advantage of "Non-uniform" randomness, almost always outputs the first n
odd numbers, which happens to sum to n^2
. In theory it can output any other valid set, though I've only been able to confirm that for small n
.
Explanation:
²õ :Generate the range [1...n^2]
ö¬ :Order it randomly
oU :Get the last n items
í )Õ :Put it in an array with...
Uõ+ : The first n odd numbers
æ_ :Get the first one where...
Xx : The sum
²¥ : equals n^2
add a comment |
up vote
0
down vote
Ruby, 46 bytes
->n{z=0until(z=[*1..n*n].sample n).sum==n*n;z}
Try it online!
add a comment |
up vote
0
down vote
C (gcc), 128 125 bytes
p(_){printf("%d ",_);}f(n,x,y,i){x=n*n;y=1;for(i=0;++i<n;p(y),x-=y++)while(rand()&&(n-i)*(n-i+1)/2+(n-i)*(y+1)+y<x)y++;p(x);}
Try it online!
-3 bytes thanks to ceilingcat
NOTE: The probability is very very far from uniform. See explanation for what I mean and a better means to test that it works (by making the distribution closer to uniform [but still a far cry from it]).
How?
The basic idea is to only choose increasing numbers so as to not worry about duplicates. Whenever we pick a number we have a non-zero chance of 'skipping' it if allowable.
To decide if we can skip a number we need to know x
the total left to be reached, k
the number of elements we still have to use, and y
the current candidate value. The smallest possible number that we could still pick would consist of $$y+(y+1)+(y+2)+...$$ added to the current value. In particular we require the above expression to be less than x
. The formula will be $$frac{k(k+1)}{2}+k(y+1)+y<x$$ Unfortunately we have to be a bit careful about rearranging this formula due to integer truncation in C, so I couldn't really find a way to golf it.
Nonetheless the logic is to have a chance to discard any y
that satisfies the above equation.
The code
p(_){printf("%d ",_);} // Define print(int)
f(n,x,y,i){ // Define f(n,...) as the function we want
x=n*n; // Set x to n^2
y=1; // Set y to 1
for(i=0;++i<n;){ // n-1 times do...
while(rand()&& // While rand() is non-zero [very very likely] AND
(n-i)* // (n-i) is the 'k' in the formula
(n-i+1)/2+ // This first half takes care of the increment
(n-i)*(y+1) // This second half takes care of the y+1 starting point
+y<x) // The +y takes care of the current value of y
y++; // If rand() returned non-zero and we can skip y, do so
p(y); // Print y
x-=y++; // Subtract y from the total and increment it
}p(x);} // Print what's left over.
The trick I mentioned to better test the code involves replacing rand()&&
with rand()%2&&
so that there is a 50-50 chance that any given y is skipped, rather than a 1 in RAND_MAX
chance that any given y is used.
I would love it if someone checked my math for consistency. I also wonder if this type of solution could make the uniform random speed challenge simple. The formula places an upper and lower bound on the answer, does a uniform random number in that range result in uniform random results? I don't see why not - but I haven't done much combinatorics in awhile.
– LambdaBeta
2 days ago
Suggestp(y),x-=y++)while(rand()&&(i-n)*((~n+i)/2+~y)+y<x)y++;
instead of){while(rand()&&(n-i)*(n-i+1)/2+(n-i)*(y+1)+y<x)y++;p(y);x-=y++;}
– ceilingcat
2 days ago
@ceilingcat I love these little improvements you find. I always get so focussed on the overall algorithm I forget to optimize for implementation (I basically go autopilot golfing mode once I have a non-golfed source that works - so I miss a lot of savings)
– LambdaBeta
yesterday
Hey, it's not just you who has those syntax-golfs. I find little improvements in a lot of C/C++ answers like that (except not in yours, @ceilingcat usually snaps those up).
– Zacharý
yesterday
Yeah, I've noticed that you two are probably the most active C/C++ putters (can we use putting to extend the golf analogy to the last few strokes? Why not!). It always impresses me that you can even understand the golfed code well enough to improve it.
– LambdaBeta
yesterday
add a comment |
up vote
0
down vote
Clean, 172 bytes
import StdEnv,Math.Random,Data.List
? ::!Int->Int
?_=code{
ccall time "I:I"
}
$n=find(s=length s==n&&sum s==n^2)(subsequences(nub(map(inc oe=e rem n^2)(genRandInt(?0)))))
Try it online!
add a comment |
up vote
0
down vote
Python (2 or 3), 84 bytes
from random import*;l=lambda n,s=:(sum(s)==n*n)*s or l(n,sample(range(1,n*n+1),n))
Try it online!
Hits max recursion depth at around l(5)
add a comment |
up vote
0
down vote
Mathematica 40 bytes
RandomChoice[IntegerPartitions[2^n, {n}]]
add a comment |
up vote
0
down vote
JavaScript, 291 bytes
Bonus Task: Is there a formula to calculate the number of valid permutations for a given
n
?
Solves for n=3
f=(n=3,x=Math.pow(n,2),p=,r=,z=RegExp(`^[1-${x}]+$`))=>{for(c=n;c;c--){p.unshift(c)};p[p.length-1]=x-n;let i=+p.join``,m= +p.reverse().join``,s=i+'',l=s.length;for(;i<=m;i++){let c=[...''+i];if(new Set(c).size==l&&c.every(_=>z.test(_))&&eval(c.join`+`)==x){r.push([...''+i].map(Number))}}return r}
let r=f();
console.log(JSON.stringify(r,null,2),r.length);
Try it online!
Formula for number of valid permutations for n=3
using addition, comparison and exclusion
- Find the minimum integer which sums to
n=3^2=9
, in this case126
- Convert
n=3
to array[1,2,3]
and integer123
- To derive
126
fromn=3
programmatically, subtract last digit of123
fromn=3^2=9
9=3=6
,[1,2,3]
->[1,2,(9-3)]
- >[1,2,6]
->126
- The last valid lexicographic permutation of
n=3
will be621
;126
with digits in reverse order - Increment
126
to and including621
, match numbers where the.size
as aSet
is equal to.length
of string'123'
and every index of current number as a string in an array teststrue
forRegExp
^[1-(n^2-n=6)]$
and the number of the digits is equal ton^2
, push matches to an array in lexicographic order - Convert matched integers as string to integers in array
- The number of valid permutations for the given
n
,3
, is18
add a comment |
21 Answers
21
active
oldest
votes
21 Answers
21
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
7
down vote
05AB1E, 11 bytes
nÅœʒDÙQ}sùΩ
Try it online or verify all test cases.
Explanation:
n # Take the square of the (implicit) input
# i.e. 3 → 9
Ŝ # Get all integer-lists using integers in the range [1, val) that sum to val
# i.e. 9 → [[1,1,1,1,1,1,1,1,1],...,[1,3,5],...,[9]]
ʒ } # Filter the list to only keep lists with unique values:
D # Duplicate the current value
Ù # Uniquify it
# i.e. [2,2,5] → [2,5]
Q # Check if it's still the same
# i.e. [2,2,5] and [2,5] → 0 (falsey)
s # Swap to take the (implicit) input again
ù # Only leave lists of that size
# i.e. [[1,2,6],[1,3,5],[1,8],[2,3,4],[2,7],[3,6],[4,5],[9]] and 3
# → [[1,2,6],[1,3,5],[2,3,4]]
Ω # Pick a random list from the list of lists (and output implicitly)
add a comment |
up vote
7
down vote
05AB1E, 11 bytes
nÅœʒDÙQ}sùΩ
Try it online or verify all test cases.
Explanation:
n # Take the square of the (implicit) input
# i.e. 3 → 9
Ŝ # Get all integer-lists using integers in the range [1, val) that sum to val
# i.e. 9 → [[1,1,1,1,1,1,1,1,1],...,[1,3,5],...,[9]]
ʒ } # Filter the list to only keep lists with unique values:
D # Duplicate the current value
Ù # Uniquify it
# i.e. [2,2,5] → [2,5]
Q # Check if it's still the same
# i.e. [2,2,5] and [2,5] → 0 (falsey)
s # Swap to take the (implicit) input again
ù # Only leave lists of that size
# i.e. [[1,2,6],[1,3,5],[1,8],[2,3,4],[2,7],[3,6],[4,5],[9]] and 3
# → [[1,2,6],[1,3,5],[2,3,4]]
Ω # Pick a random list from the list of lists (and output implicitly)
add a comment |
up vote
7
down vote
up vote
7
down vote
05AB1E, 11 bytes
nÅœʒDÙQ}sùΩ
Try it online or verify all test cases.
Explanation:
n # Take the square of the (implicit) input
# i.e. 3 → 9
Ŝ # Get all integer-lists using integers in the range [1, val) that sum to val
# i.e. 9 → [[1,1,1,1,1,1,1,1,1],...,[1,3,5],...,[9]]
ʒ } # Filter the list to only keep lists with unique values:
D # Duplicate the current value
Ù # Uniquify it
# i.e. [2,2,5] → [2,5]
Q # Check if it's still the same
# i.e. [2,2,5] and [2,5] → 0 (falsey)
s # Swap to take the (implicit) input again
ù # Only leave lists of that size
# i.e. [[1,2,6],[1,3,5],[1,8],[2,3,4],[2,7],[3,6],[4,5],[9]] and 3
# → [[1,2,6],[1,3,5],[2,3,4]]
Ω # Pick a random list from the list of lists (and output implicitly)
05AB1E, 11 bytes
nÅœʒDÙQ}sùΩ
Try it online or verify all test cases.
Explanation:
n # Take the square of the (implicit) input
# i.e. 3 → 9
Ŝ # Get all integer-lists using integers in the range [1, val) that sum to val
# i.e. 9 → [[1,1,1,1,1,1,1,1,1],...,[1,3,5],...,[9]]
ʒ } # Filter the list to only keep lists with unique values:
D # Duplicate the current value
Ù # Uniquify it
# i.e. [2,2,5] → [2,5]
Q # Check if it's still the same
# i.e. [2,2,5] and [2,5] → 0 (falsey)
s # Swap to take the (implicit) input again
ù # Only leave lists of that size
# i.e. [[1,2,6],[1,3,5],[1,8],[2,3,4],[2,7],[3,6],[4,5],[9]] and 3
# → [[1,2,6],[1,3,5],[2,3,4]]
Ω # Pick a random list from the list of lists (and output implicitly)
edited 2 days ago
answered 2 days ago
Kevin Cruijssen
34.4k554182
34.4k554182
add a comment |
add a comment |
up vote
6
down vote
Brachylog (v2), 15 bytes (random) or 13 bytes (all possibilities)
Random
~lℕ₁ᵐA+√?∧A≜₁ᵐ≠
Try it online!
Function submission (seen in TIO with a wrapper making it into a full program).
Explanation
~lℕ₁ᵐA+√?∧A≜₁ᵐ≠
~l Specify a property of a list: its length is equal to the input,
ᵐ and it is composed entirely of
ℕ₁ integers ≥ 1,
√ for which the square root of the
+ sum of the list
? is the input.
A ∧A Restricting yourself to lists with that property,
≜₁ pick random possible values
ᵐ for each element in turn,
≠ until you find one whose elements are all distinct.
All possibilities
~lℕ₁ᵐ<₁.+√?∧≜
Try it online!
Function submission, which generates all possible outputs.
Explanation
~lℕ₁ᵐ<₁.+√?∧≜
~l Specify a property of a list: its length is equal to the input,
ᵐ it is composed entirely of
ℕ₁ integers ≥ 1,
<₁ it is strictly increasing,
√ and the square root of the
+ sum of the list
? is the input.
. ∧≜ Generate all specific lists with that property.
I'm fairly surprised that ∧≜
works (you'd normally have to write ∧~≜
in order to brute-force the output rather than the input), but it turns out that ≜
has an input=output assumption so it doesn't matter which way round you run it.
Bonus task
In order to get some insight into the sequence of the number of possibilities, I created a different TIO wrapper which runs the program on successive integers to give the sequence of output counts:
1,1,3,9,30,110,436,1801,7657,33401
A trip to OEIS discovers that this is already a known sequence, A107379, described pretty much as in the question (apparently you get the same sequence if you restrict it to odd numbers). The page lists several formulas for the sequence (although none is particularly simple; the second looks like a direct formula for the value but I don't understand the notation).
The second formula is "the coefficient ofx^(n*(n-1)/2)
in the series expansion ofProduct_{k=1..n} 1/(1 - x^k)
" (not direct at all, unfortunately)
– user202729
2 days ago
Placing the "all different" constraint before the random labelization step (e.g.A≠≜₁ᵐ
) makes the run time much faster on average.
– Fatalize
yesterday
I don't understand why you made this a community wiki. Those are an archaic way to have editable posts before it was possible to edit.
– pipe
yesterday
@pipe codegolf.stackexchange.com/questions/172716/true-color-code/…
– guest271314
yesterday
add a comment |
up vote
6
down vote
Brachylog (v2), 15 bytes (random) or 13 bytes (all possibilities)
Random
~lℕ₁ᵐA+√?∧A≜₁ᵐ≠
Try it online!
Function submission (seen in TIO with a wrapper making it into a full program).
Explanation
~lℕ₁ᵐA+√?∧A≜₁ᵐ≠
~l Specify a property of a list: its length is equal to the input,
ᵐ and it is composed entirely of
ℕ₁ integers ≥ 1,
√ for which the square root of the
+ sum of the list
? is the input.
A ∧A Restricting yourself to lists with that property,
≜₁ pick random possible values
ᵐ for each element in turn,
≠ until you find one whose elements are all distinct.
All possibilities
~lℕ₁ᵐ<₁.+√?∧≜
Try it online!
Function submission, which generates all possible outputs.
Explanation
~lℕ₁ᵐ<₁.+√?∧≜
~l Specify a property of a list: its length is equal to the input,
ᵐ it is composed entirely of
ℕ₁ integers ≥ 1,
<₁ it is strictly increasing,
√ and the square root of the
+ sum of the list
? is the input.
. ∧≜ Generate all specific lists with that property.
I'm fairly surprised that ∧≜
works (you'd normally have to write ∧~≜
in order to brute-force the output rather than the input), but it turns out that ≜
has an input=output assumption so it doesn't matter which way round you run it.
Bonus task
In order to get some insight into the sequence of the number of possibilities, I created a different TIO wrapper which runs the program on successive integers to give the sequence of output counts:
1,1,3,9,30,110,436,1801,7657,33401
A trip to OEIS discovers that this is already a known sequence, A107379, described pretty much as in the question (apparently you get the same sequence if you restrict it to odd numbers). The page lists several formulas for the sequence (although none is particularly simple; the second looks like a direct formula for the value but I don't understand the notation).
The second formula is "the coefficient ofx^(n*(n-1)/2)
in the series expansion ofProduct_{k=1..n} 1/(1 - x^k)
" (not direct at all, unfortunately)
– user202729
2 days ago
Placing the "all different" constraint before the random labelization step (e.g.A≠≜₁ᵐ
) makes the run time much faster on average.
– Fatalize
yesterday
I don't understand why you made this a community wiki. Those are an archaic way to have editable posts before it was possible to edit.
– pipe
yesterday
@pipe codegolf.stackexchange.com/questions/172716/true-color-code/…
– guest271314
yesterday
add a comment |
up vote
6
down vote
up vote
6
down vote
Brachylog (v2), 15 bytes (random) or 13 bytes (all possibilities)
Random
~lℕ₁ᵐA+√?∧A≜₁ᵐ≠
Try it online!
Function submission (seen in TIO with a wrapper making it into a full program).
Explanation
~lℕ₁ᵐA+√?∧A≜₁ᵐ≠
~l Specify a property of a list: its length is equal to the input,
ᵐ and it is composed entirely of
ℕ₁ integers ≥ 1,
√ for which the square root of the
+ sum of the list
? is the input.
A ∧A Restricting yourself to lists with that property,
≜₁ pick random possible values
ᵐ for each element in turn,
≠ until you find one whose elements are all distinct.
All possibilities
~lℕ₁ᵐ<₁.+√?∧≜
Try it online!
Function submission, which generates all possible outputs.
Explanation
~lℕ₁ᵐ<₁.+√?∧≜
~l Specify a property of a list: its length is equal to the input,
ᵐ it is composed entirely of
ℕ₁ integers ≥ 1,
<₁ it is strictly increasing,
√ and the square root of the
+ sum of the list
? is the input.
. ∧≜ Generate all specific lists with that property.
I'm fairly surprised that ∧≜
works (you'd normally have to write ∧~≜
in order to brute-force the output rather than the input), but it turns out that ≜
has an input=output assumption so it doesn't matter which way round you run it.
Bonus task
In order to get some insight into the sequence of the number of possibilities, I created a different TIO wrapper which runs the program on successive integers to give the sequence of output counts:
1,1,3,9,30,110,436,1801,7657,33401
A trip to OEIS discovers that this is already a known sequence, A107379, described pretty much as in the question (apparently you get the same sequence if you restrict it to odd numbers). The page lists several formulas for the sequence (although none is particularly simple; the second looks like a direct formula for the value but I don't understand the notation).
Brachylog (v2), 15 bytes (random) or 13 bytes (all possibilities)
Random
~lℕ₁ᵐA+√?∧A≜₁ᵐ≠
Try it online!
Function submission (seen in TIO with a wrapper making it into a full program).
Explanation
~lℕ₁ᵐA+√?∧A≜₁ᵐ≠
~l Specify a property of a list: its length is equal to the input,
ᵐ and it is composed entirely of
ℕ₁ integers ≥ 1,
√ for which the square root of the
+ sum of the list
? is the input.
A ∧A Restricting yourself to lists with that property,
≜₁ pick random possible values
ᵐ for each element in turn,
≠ until you find one whose elements are all distinct.
All possibilities
~lℕ₁ᵐ<₁.+√?∧≜
Try it online!
Function submission, which generates all possible outputs.
Explanation
~lℕ₁ᵐ<₁.+√?∧≜
~l Specify a property of a list: its length is equal to the input,
ᵐ it is composed entirely of
ℕ₁ integers ≥ 1,
<₁ it is strictly increasing,
√ and the square root of the
+ sum of the list
? is the input.
. ∧≜ Generate all specific lists with that property.
I'm fairly surprised that ∧≜
works (you'd normally have to write ∧~≜
in order to brute-force the output rather than the input), but it turns out that ≜
has an input=output assumption so it doesn't matter which way round you run it.
Bonus task
In order to get some insight into the sequence of the number of possibilities, I created a different TIO wrapper which runs the program on successive integers to give the sequence of output counts:
1,1,3,9,30,110,436,1801,7657,33401
A trip to OEIS discovers that this is already a known sequence, A107379, described pretty much as in the question (apparently you get the same sequence if you restrict it to odd numbers). The page lists several formulas for the sequence (although none is particularly simple; the second looks like a direct formula for the value but I don't understand the notation).
edited 2 days ago
community wiki
3 revs
ais523
The second formula is "the coefficient ofx^(n*(n-1)/2)
in the series expansion ofProduct_{k=1..n} 1/(1 - x^k)
" (not direct at all, unfortunately)
– user202729
2 days ago
Placing the "all different" constraint before the random labelization step (e.g.A≠≜₁ᵐ
) makes the run time much faster on average.
– Fatalize
yesterday
I don't understand why you made this a community wiki. Those are an archaic way to have editable posts before it was possible to edit.
– pipe
yesterday
@pipe codegolf.stackexchange.com/questions/172716/true-color-code/…
– guest271314
yesterday
add a comment |
The second formula is "the coefficient ofx^(n*(n-1)/2)
in the series expansion ofProduct_{k=1..n} 1/(1 - x^k)
" (not direct at all, unfortunately)
– user202729
2 days ago
Placing the "all different" constraint before the random labelization step (e.g.A≠≜₁ᵐ
) makes the run time much faster on average.
– Fatalize
yesterday
I don't understand why you made this a community wiki. Those are an archaic way to have editable posts before it was possible to edit.
– pipe
yesterday
@pipe codegolf.stackexchange.com/questions/172716/true-color-code/…
– guest271314
yesterday
The second formula is "the coefficient of
x^(n*(n-1)/2)
in the series expansion of Product_{k=1..n} 1/(1 - x^k)
" (not direct at all, unfortunately)– user202729
2 days ago
The second formula is "the coefficient of
x^(n*(n-1)/2)
in the series expansion of Product_{k=1..n} 1/(1 - x^k)
" (not direct at all, unfortunately)– user202729
2 days ago
Placing the "all different" constraint before the random labelization step (e.g.
A≠≜₁ᵐ
) makes the run time much faster on average.– Fatalize
yesterday
Placing the "all different" constraint before the random labelization step (e.g.
A≠≜₁ᵐ
) makes the run time much faster on average.– Fatalize
yesterday
I don't understand why you made this a community wiki. Those are an archaic way to have editable posts before it was possible to edit.
– pipe
yesterday
I don't understand why you made this a community wiki. Those are an archaic way to have editable posts before it was possible to edit.
– pipe
yesterday
@pipe codegolf.stackexchange.com/questions/172716/true-color-code/…
– guest271314
yesterday
@pipe codegolf.stackexchange.com/questions/172716/true-color-code/…
– guest271314
yesterday
add a comment |
up vote
5
down vote
Python (2 or 3), 85 bytes
def f(n):r=sample(range(1,n*n+1),n);return(n*n==sum(r))*r or f(n)
from random import*
Try it online!
add a comment |
up vote
5
down vote
Python (2 or 3), 85 bytes
def f(n):r=sample(range(1,n*n+1),n);return(n*n==sum(r))*r or f(n)
from random import*
Try it online!
add a comment |
up vote
5
down vote
up vote
5
down vote
Python (2 or 3), 85 bytes
def f(n):r=sample(range(1,n*n+1),n);return(n*n==sum(r))*r or f(n)
from random import*
Try it online!
Python (2 or 3), 85 bytes
def f(n):r=sample(range(1,n*n+1),n);return(n*n==sum(r))*r or f(n)
from random import*
Try it online!
answered 2 days ago
Jonathan Allan
50.1k534165
50.1k534165
add a comment |
add a comment |
up vote
4
down vote
Jelly, 9 bytes
²œcS=¥Ƈ²X
Try it online!
Generate all n-combinations of the list [1..n²], filter to keep those with sum n², then pick a random one.
add a comment |
up vote
4
down vote
Jelly, 9 bytes
²œcS=¥Ƈ²X
Try it online!
Generate all n-combinations of the list [1..n²], filter to keep those with sum n², then pick a random one.
add a comment |
up vote
4
down vote
up vote
4
down vote
Jelly, 9 bytes
²œcS=¥Ƈ²X
Try it online!
Generate all n-combinations of the list [1..n²], filter to keep those with sum n², then pick a random one.
Jelly, 9 bytes
²œcS=¥Ƈ²X
Try it online!
Generate all n-combinations of the list [1..n²], filter to keep those with sum n², then pick a random one.
answered 2 days ago
user202729
13.5k12550
13.5k12550
add a comment |
add a comment |
up vote
4
down vote
Java 10, 250 242 222 bytes
import java.util.*;n->{for(;;){int i=n+1,r=new int[i],d=new int[n];for(r[n<2?0:1]=n*n;i-->2;r[i]=(int)(Math.random()*n*n));var S=new HashSet();for(Arrays.sort(r),i=n;i-->0;)S.add(d[i]=r[i+1]-r[i]);if(!S.contains(0)&S.size()==n)return S;}}
-20 bytes thanks to @nwellnhof.
Watch out, Java coming through.. It's 'only' five times as long as the other four answers combined, so not too bad I guess.. rofl.
It does run n=1
through n=25
(combined) in less than 2 seconds though, so I'll probably post a modified version to the speed version of this challenge (that's currently still in the Sandbox) as well.
Try it online.
Explanation:
In pseudo-code we do the following:
1) Generate an array of size n+1
containing: 0
, n
squared, and n-1
amount of random integers in the range [0, n squared)
2) Sort this array
3) Create a second array of size n
containing the forward differences of pairs
These first three steps will give us an array containing n
random integers (in the range [0, n squared)
that sum to n
squared.
4a) If not all random values are unique, or any of them is 0: try again from step 1
4b) Else: return this differences array as result
As for the actual code:
import java.util.*; // Required import for HashSet and Arrays
n->{ // Method with int parameter and Set return-type
for(;;){ // Loop indefinitely
int i=n+1, // Set `i` to `n+1`
r=new int[i]; // Create an array of size `n+1`
var S=new HashSet(); // Result-set, starting empty
for(r[n<2? // If `n` is 1:
0 // Set the first item in the first array to:
: // Else:
1] // Set the second item in the first array to:
=n*n; // `n` squared
i-->2;) // Loop `i` in the range [`n`, 2]:
r[i]= // Set the `i`'th value in the first array to:
(int)(Math.random()*n*n);
// A random value in the range [0, `n` squared)
for(Arrays.sort(r), // Sort the first array
i=n;i-->0;) // Loop `i` in the range (`n`, 0]:
S.add( // Add to the Set:
r[i+1]-r[i]); // The `i+1`'th and `i`'th difference of the first array
if(!S.contains(0) // If the Set does not contain a 0
&S.size()==n) // and its size is equal to `n`:
return S;}} // Return this Set as the result
// (Implicit else: continue the infinite loop)
1
n=25
in under 2 seconds is impressive! I'll have to read through the explanation and see how it does it. Is it still a bruteforce method?
– Skidsdev
2 days ago
Is it uniform? -
– user202729
2 days ago
@user202729 Although I'm not sure how to prove it, I think it is. The Java builtin is uniform, and it uses that to get random values in the range[0, n squared)
first, and then calculates the differences between those sorted random values (including leading0
and trailingn squared
. So I'm pretty sure those differences are uniform as well. But again, I'm not sure how to prove it. Uniformity in randomness isn't really my expertise tbh.
– Kevin Cruijssen
2 days ago
3
You never read from the differences arrayd
or am I missing something?
– nwellnhof
2 days ago
1
I'm kind of happy with my 127 bytes solution :D
– Olivier Grégoire
yesterday
|
show 5 more comments
up vote
4
down vote
Java 10, 250 242 222 bytes
import java.util.*;n->{for(;;){int i=n+1,r=new int[i],d=new int[n];for(r[n<2?0:1]=n*n;i-->2;r[i]=(int)(Math.random()*n*n));var S=new HashSet();for(Arrays.sort(r),i=n;i-->0;)S.add(d[i]=r[i+1]-r[i]);if(!S.contains(0)&S.size()==n)return S;}}
-20 bytes thanks to @nwellnhof.
Watch out, Java coming through.. It's 'only' five times as long as the other four answers combined, so not too bad I guess.. rofl.
It does run n=1
through n=25
(combined) in less than 2 seconds though, so I'll probably post a modified version to the speed version of this challenge (that's currently still in the Sandbox) as well.
Try it online.
Explanation:
In pseudo-code we do the following:
1) Generate an array of size n+1
containing: 0
, n
squared, and n-1
amount of random integers in the range [0, n squared)
2) Sort this array
3) Create a second array of size n
containing the forward differences of pairs
These first three steps will give us an array containing n
random integers (in the range [0, n squared)
that sum to n
squared.
4a) If not all random values are unique, or any of them is 0: try again from step 1
4b) Else: return this differences array as result
As for the actual code:
import java.util.*; // Required import for HashSet and Arrays
n->{ // Method with int parameter and Set return-type
for(;;){ // Loop indefinitely
int i=n+1, // Set `i` to `n+1`
r=new int[i]; // Create an array of size `n+1`
var S=new HashSet(); // Result-set, starting empty
for(r[n<2? // If `n` is 1:
0 // Set the first item in the first array to:
: // Else:
1] // Set the second item in the first array to:
=n*n; // `n` squared
i-->2;) // Loop `i` in the range [`n`, 2]:
r[i]= // Set the `i`'th value in the first array to:
(int)(Math.random()*n*n);
// A random value in the range [0, `n` squared)
for(Arrays.sort(r), // Sort the first array
i=n;i-->0;) // Loop `i` in the range (`n`, 0]:
S.add( // Add to the Set:
r[i+1]-r[i]); // The `i+1`'th and `i`'th difference of the first array
if(!S.contains(0) // If the Set does not contain a 0
&S.size()==n) // and its size is equal to `n`:
return S;}} // Return this Set as the result
// (Implicit else: continue the infinite loop)
1
n=25
in under 2 seconds is impressive! I'll have to read through the explanation and see how it does it. Is it still a bruteforce method?
– Skidsdev
2 days ago
Is it uniform? -
– user202729
2 days ago
@user202729 Although I'm not sure how to prove it, I think it is. The Java builtin is uniform, and it uses that to get random values in the range[0, n squared)
first, and then calculates the differences between those sorted random values (including leading0
and trailingn squared
. So I'm pretty sure those differences are uniform as well. But again, I'm not sure how to prove it. Uniformity in randomness isn't really my expertise tbh.
– Kevin Cruijssen
2 days ago
3
You never read from the differences arrayd
or am I missing something?
– nwellnhof
2 days ago
1
I'm kind of happy with my 127 bytes solution :D
– Olivier Grégoire
yesterday
|
show 5 more comments
up vote
4
down vote
up vote
4
down vote
Java 10, 250 242 222 bytes
import java.util.*;n->{for(;;){int i=n+1,r=new int[i],d=new int[n];for(r[n<2?0:1]=n*n;i-->2;r[i]=(int)(Math.random()*n*n));var S=new HashSet();for(Arrays.sort(r),i=n;i-->0;)S.add(d[i]=r[i+1]-r[i]);if(!S.contains(0)&S.size()==n)return S;}}
-20 bytes thanks to @nwellnhof.
Watch out, Java coming through.. It's 'only' five times as long as the other four answers combined, so not too bad I guess.. rofl.
It does run n=1
through n=25
(combined) in less than 2 seconds though, so I'll probably post a modified version to the speed version of this challenge (that's currently still in the Sandbox) as well.
Try it online.
Explanation:
In pseudo-code we do the following:
1) Generate an array of size n+1
containing: 0
, n
squared, and n-1
amount of random integers in the range [0, n squared)
2) Sort this array
3) Create a second array of size n
containing the forward differences of pairs
These first three steps will give us an array containing n
random integers (in the range [0, n squared)
that sum to n
squared.
4a) If not all random values are unique, or any of them is 0: try again from step 1
4b) Else: return this differences array as result
As for the actual code:
import java.util.*; // Required import for HashSet and Arrays
n->{ // Method with int parameter and Set return-type
for(;;){ // Loop indefinitely
int i=n+1, // Set `i` to `n+1`
r=new int[i]; // Create an array of size `n+1`
var S=new HashSet(); // Result-set, starting empty
for(r[n<2? // If `n` is 1:
0 // Set the first item in the first array to:
: // Else:
1] // Set the second item in the first array to:
=n*n; // `n` squared
i-->2;) // Loop `i` in the range [`n`, 2]:
r[i]= // Set the `i`'th value in the first array to:
(int)(Math.random()*n*n);
// A random value in the range [0, `n` squared)
for(Arrays.sort(r), // Sort the first array
i=n;i-->0;) // Loop `i` in the range (`n`, 0]:
S.add( // Add to the Set:
r[i+1]-r[i]); // The `i+1`'th and `i`'th difference of the first array
if(!S.contains(0) // If the Set does not contain a 0
&S.size()==n) // and its size is equal to `n`:
return S;}} // Return this Set as the result
// (Implicit else: continue the infinite loop)
Java 10, 250 242 222 bytes
import java.util.*;n->{for(;;){int i=n+1,r=new int[i],d=new int[n];for(r[n<2?0:1]=n*n;i-->2;r[i]=(int)(Math.random()*n*n));var S=new HashSet();for(Arrays.sort(r),i=n;i-->0;)S.add(d[i]=r[i+1]-r[i]);if(!S.contains(0)&S.size()==n)return S;}}
-20 bytes thanks to @nwellnhof.
Watch out, Java coming through.. It's 'only' five times as long as the other four answers combined, so not too bad I guess.. rofl.
It does run n=1
through n=25
(combined) in less than 2 seconds though, so I'll probably post a modified version to the speed version of this challenge (that's currently still in the Sandbox) as well.
Try it online.
Explanation:
In pseudo-code we do the following:
1) Generate an array of size n+1
containing: 0
, n
squared, and n-1
amount of random integers in the range [0, n squared)
2) Sort this array
3) Create a second array of size n
containing the forward differences of pairs
These first three steps will give us an array containing n
random integers (in the range [0, n squared)
that sum to n
squared.
4a) If not all random values are unique, or any of them is 0: try again from step 1
4b) Else: return this differences array as result
As for the actual code:
import java.util.*; // Required import for HashSet and Arrays
n->{ // Method with int parameter and Set return-type
for(;;){ // Loop indefinitely
int i=n+1, // Set `i` to `n+1`
r=new int[i]; // Create an array of size `n+1`
var S=new HashSet(); // Result-set, starting empty
for(r[n<2? // If `n` is 1:
0 // Set the first item in the first array to:
: // Else:
1] // Set the second item in the first array to:
=n*n; // `n` squared
i-->2;) // Loop `i` in the range [`n`, 2]:
r[i]= // Set the `i`'th value in the first array to:
(int)(Math.random()*n*n);
// A random value in the range [0, `n` squared)
for(Arrays.sort(r), // Sort the first array
i=n;i-->0;) // Loop `i` in the range (`n`, 0]:
S.add( // Add to the Set:
r[i+1]-r[i]); // The `i+1`'th and `i`'th difference of the first array
if(!S.contains(0) // If the Set does not contain a 0
&S.size()==n) // and its size is equal to `n`:
return S;}} // Return this Set as the result
// (Implicit else: continue the infinite loop)
edited 2 days ago
answered 2 days ago
Kevin Cruijssen
34.4k554182
34.4k554182
1
n=25
in under 2 seconds is impressive! I'll have to read through the explanation and see how it does it. Is it still a bruteforce method?
– Skidsdev
2 days ago
Is it uniform? -
– user202729
2 days ago
@user202729 Although I'm not sure how to prove it, I think it is. The Java builtin is uniform, and it uses that to get random values in the range[0, n squared)
first, and then calculates the differences between those sorted random values (including leading0
and trailingn squared
. So I'm pretty sure those differences are uniform as well. But again, I'm not sure how to prove it. Uniformity in randomness isn't really my expertise tbh.
– Kevin Cruijssen
2 days ago
3
You never read from the differences arrayd
or am I missing something?
– nwellnhof
2 days ago
1
I'm kind of happy with my 127 bytes solution :D
– Olivier Grégoire
yesterday
|
show 5 more comments
1
n=25
in under 2 seconds is impressive! I'll have to read through the explanation and see how it does it. Is it still a bruteforce method?
– Skidsdev
2 days ago
Is it uniform? -
– user202729
2 days ago
@user202729 Although I'm not sure how to prove it, I think it is. The Java builtin is uniform, and it uses that to get random values in the range[0, n squared)
first, and then calculates the differences between those sorted random values (including leading0
and trailingn squared
. So I'm pretty sure those differences are uniform as well. But again, I'm not sure how to prove it. Uniformity in randomness isn't really my expertise tbh.
– Kevin Cruijssen
2 days ago
3
You never read from the differences arrayd
or am I missing something?
– nwellnhof
2 days ago
1
I'm kind of happy with my 127 bytes solution :D
– Olivier Grégoire
yesterday
1
1
n=25
in under 2 seconds is impressive! I'll have to read through the explanation and see how it does it. Is it still a bruteforce method?– Skidsdev
2 days ago
n=25
in under 2 seconds is impressive! I'll have to read through the explanation and see how it does it. Is it still a bruteforce method?– Skidsdev
2 days ago
Is it uniform? -
– user202729
2 days ago
Is it uniform? -
– user202729
2 days ago
@user202729 Although I'm not sure how to prove it, I think it is. The Java builtin is uniform, and it uses that to get random values in the range
[0, n squared)
first, and then calculates the differences between those sorted random values (including leading 0
and trailing n squared
. So I'm pretty sure those differences are uniform as well. But again, I'm not sure how to prove it. Uniformity in randomness isn't really my expertise tbh.– Kevin Cruijssen
2 days ago
@user202729 Although I'm not sure how to prove it, I think it is. The Java builtin is uniform, and it uses that to get random values in the range
[0, n squared)
first, and then calculates the differences between those sorted random values (including leading 0
and trailing n squared
. So I'm pretty sure those differences are uniform as well. But again, I'm not sure how to prove it. Uniformity in randomness isn't really my expertise tbh.– Kevin Cruijssen
2 days ago
3
3
You never read from the differences array
d
or am I missing something?– nwellnhof
2 days ago
You never read from the differences array
d
or am I missing something?– nwellnhof
2 days ago
1
1
I'm kind of happy with my 127 bytes solution :D
– Olivier Grégoire
yesterday
I'm kind of happy with my 127 bytes solution :D
– Olivier Grégoire
yesterday
|
show 5 more comments
up vote
4
down vote
R, 68, 75 48 bytes (random) and 70 bytes (deterministic)
@Giuseppe's rejection sampling method:
function(n){while(sum(F)!=n^2)F=sample(n^2,n);F}
Try it online!
Golfed original:
function(n,m=combn(1:n^2,n))m[,sample(which(colSums(m)==n^2)*!!1:2,1)]
Try it online!
The *!!1:2
business is to avoid the odd way sample
act when the first argument has length 1.
@Giuseppe "fixed" :-)
– ngm
2 days ago
very nice. usingp
directly as an index instead of calculating it and re-using it should save some bytes.
– Giuseppe
2 days ago
1
I havefunction(n){while(sum(F)!=n^2)F=sample(n^2,n);F}
for 48 as well...
– Giuseppe
2 days ago
1
@J.Doe to avoid the issue when calling something likesample(2,1)
which happens withn=2
. Sorep
just guarantees that this will never happen. There might be a better way but this was quick and I was mad atsample
.
– ngm
2 days ago
1
You can save a byte withx*!!1:2
overrep(x,2)
if your meta question gets a no.
– J.Doe
2 days ago
|
show 4 more comments
up vote
4
down vote
R, 68, 75 48 bytes (random) and 70 bytes (deterministic)
@Giuseppe's rejection sampling method:
function(n){while(sum(F)!=n^2)F=sample(n^2,n);F}
Try it online!
Golfed original:
function(n,m=combn(1:n^2,n))m[,sample(which(colSums(m)==n^2)*!!1:2,1)]
Try it online!
The *!!1:2
business is to avoid the odd way sample
act when the first argument has length 1.
@Giuseppe "fixed" :-)
– ngm
2 days ago
very nice. usingp
directly as an index instead of calculating it and re-using it should save some bytes.
– Giuseppe
2 days ago
1
I havefunction(n){while(sum(F)!=n^2)F=sample(n^2,n);F}
for 48 as well...
– Giuseppe
2 days ago
1
@J.Doe to avoid the issue when calling something likesample(2,1)
which happens withn=2
. Sorep
just guarantees that this will never happen. There might be a better way but this was quick and I was mad atsample
.
– ngm
2 days ago
1
You can save a byte withx*!!1:2
overrep(x,2)
if your meta question gets a no.
– J.Doe
2 days ago
|
show 4 more comments
up vote
4
down vote
up vote
4
down vote
R, 68, 75 48 bytes (random) and 70 bytes (deterministic)
@Giuseppe's rejection sampling method:
function(n){while(sum(F)!=n^2)F=sample(n^2,n);F}
Try it online!
Golfed original:
function(n,m=combn(1:n^2,n))m[,sample(which(colSums(m)==n^2)*!!1:2,1)]
Try it online!
The *!!1:2
business is to avoid the odd way sample
act when the first argument has length 1.
R, 68, 75 48 bytes (random) and 70 bytes (deterministic)
@Giuseppe's rejection sampling method:
function(n){while(sum(F)!=n^2)F=sample(n^2,n);F}
Try it online!
Golfed original:
function(n,m=combn(1:n^2,n))m[,sample(which(colSums(m)==n^2)*!!1:2,1)]
Try it online!
The *!!1:2
business is to avoid the odd way sample
act when the first argument has length 1.
edited yesterday
answered 2 days ago
ngm
3,07923
3,07923
@Giuseppe "fixed" :-)
– ngm
2 days ago
very nice. usingp
directly as an index instead of calculating it and re-using it should save some bytes.
– Giuseppe
2 days ago
1
I havefunction(n){while(sum(F)!=n^2)F=sample(n^2,n);F}
for 48 as well...
– Giuseppe
2 days ago
1
@J.Doe to avoid the issue when calling something likesample(2,1)
which happens withn=2
. Sorep
just guarantees that this will never happen. There might be a better way but this was quick and I was mad atsample
.
– ngm
2 days ago
1
You can save a byte withx*!!1:2
overrep(x,2)
if your meta question gets a no.
– J.Doe
2 days ago
|
show 4 more comments
@Giuseppe "fixed" :-)
– ngm
2 days ago
very nice. usingp
directly as an index instead of calculating it and re-using it should save some bytes.
– Giuseppe
2 days ago
1
I havefunction(n){while(sum(F)!=n^2)F=sample(n^2,n);F}
for 48 as well...
– Giuseppe
2 days ago
1
@J.Doe to avoid the issue when calling something likesample(2,1)
which happens withn=2
. Sorep
just guarantees that this will never happen. There might be a better way but this was quick and I was mad atsample
.
– ngm
2 days ago
1
You can save a byte withx*!!1:2
overrep(x,2)
if your meta question gets a no.
– J.Doe
2 days ago
@Giuseppe "fixed" :-)
– ngm
2 days ago
@Giuseppe "fixed" :-)
– ngm
2 days ago
very nice. using
p
directly as an index instead of calculating it and re-using it should save some bytes.– Giuseppe
2 days ago
very nice. using
p
directly as an index instead of calculating it and re-using it should save some bytes.– Giuseppe
2 days ago
1
1
I have
function(n){while(sum(F)!=n^2)F=sample(n^2,n);F}
for 48 as well...– Giuseppe
2 days ago
I have
function(n){while(sum(F)!=n^2)F=sample(n^2,n);F}
for 48 as well...– Giuseppe
2 days ago
1
1
@J.Doe to avoid the issue when calling something like
sample(2,1)
which happens with n=2
. So rep
just guarantees that this will never happen. There might be a better way but this was quick and I was mad at sample
.– ngm
2 days ago
@J.Doe to avoid the issue when calling something like
sample(2,1)
which happens with n=2
. So rep
just guarantees that this will never happen. There might be a better way but this was quick and I was mad at sample
.– ngm
2 days ago
1
1
You can save a byte with
x*!!1:2
over rep(x,2)
if your meta question gets a no.– J.Doe
2 days ago
You can save a byte with
x*!!1:2
over rep(x,2)
if your meta question gets a no.– J.Doe
2 days ago
|
show 4 more comments
up vote
4
down vote
Perl 6, 41 bytes
{first *.sum==$_²,(1..$_²).pick($_)xx*}
Try it online!
(1 .. $_²)
is the range of numbers from 1 to the square of the input number
.pick($_)
randomly chooses a distinct subset of that range
xx *
replicates the preceding expression infinitely
first *.sum == $_²
selects the first of those number sets that sums to the square of the input number
40 bytes
– Jo King
2 days ago
add a comment |
up vote
4
down vote
Perl 6, 41 bytes
{first *.sum==$_²,(1..$_²).pick($_)xx*}
Try it online!
(1 .. $_²)
is the range of numbers from 1 to the square of the input number
.pick($_)
randomly chooses a distinct subset of that range
xx *
replicates the preceding expression infinitely
first *.sum == $_²
selects the first of those number sets that sums to the square of the input number
40 bytes
– Jo King
2 days ago
add a comment |
up vote
4
down vote
up vote
4
down vote
Perl 6, 41 bytes
{first *.sum==$_²,(1..$_²).pick($_)xx*}
Try it online!
(1 .. $_²)
is the range of numbers from 1 to the square of the input number
.pick($_)
randomly chooses a distinct subset of that range
xx *
replicates the preceding expression infinitely
first *.sum == $_²
selects the first of those number sets that sums to the square of the input number
Perl 6, 41 bytes
{first *.sum==$_²,(1..$_²).pick($_)xx*}
Try it online!
(1 .. $_²)
is the range of numbers from 1 to the square of the input number
.pick($_)
randomly chooses a distinct subset of that range
xx *
replicates the preceding expression infinitely
first *.sum == $_²
selects the first of those number sets that sums to the square of the input number
edited yesterday
answered 2 days ago
Sean
3,14636
3,14636
40 bytes
– Jo King
2 days ago
add a comment |
40 bytes
– Jo King
2 days ago
40 bytes
– Jo King
2 days ago
40 bytes
– Jo King
2 days ago
add a comment |
up vote
2
down vote
Pyth, 13 12 bytes
Ofq*QQsT.cS*
Try it online here. Note that the online interpreter runs into a MemoryError for inputs greater than 5.
Ofq*QQsT.cS*QQQ Implicit: Q=eval(input())
Trailing QQQ inferred
S*QQQ [1-Q*Q]
.c Q All combinations of the above of length Q, without repeats
f Keep elements of the above, as T, where the following is truthy:
sT Is the sum of T...
q ... equal to...
*QQ ... Q*Q?
O Choose a random element of those remaining sets, implicit print
Edit: saved a byte by taking an alternative approach. Previous version: Of&qQlT{IT./*
add a comment |
up vote
2
down vote
Pyth, 13 12 bytes
Ofq*QQsT.cS*
Try it online here. Note that the online interpreter runs into a MemoryError for inputs greater than 5.
Ofq*QQsT.cS*QQQ Implicit: Q=eval(input())
Trailing QQQ inferred
S*QQQ [1-Q*Q]
.c Q All combinations of the above of length Q, without repeats
f Keep elements of the above, as T, where the following is truthy:
sT Is the sum of T...
q ... equal to...
*QQ ... Q*Q?
O Choose a random element of those remaining sets, implicit print
Edit: saved a byte by taking an alternative approach. Previous version: Of&qQlT{IT./*
add a comment |
up vote
2
down vote
up vote
2
down vote
Pyth, 13 12 bytes
Ofq*QQsT.cS*
Try it online here. Note that the online interpreter runs into a MemoryError for inputs greater than 5.
Ofq*QQsT.cS*QQQ Implicit: Q=eval(input())
Trailing QQQ inferred
S*QQQ [1-Q*Q]
.c Q All combinations of the above of length Q, without repeats
f Keep elements of the above, as T, where the following is truthy:
sT Is the sum of T...
q ... equal to...
*QQ ... Q*Q?
O Choose a random element of those remaining sets, implicit print
Edit: saved a byte by taking an alternative approach. Previous version: Of&qQlT{IT./*
Pyth, 13 12 bytes
Ofq*QQsT.cS*
Try it online here. Note that the online interpreter runs into a MemoryError for inputs greater than 5.
Ofq*QQsT.cS*QQQ Implicit: Q=eval(input())
Trailing QQQ inferred
S*QQQ [1-Q*Q]
.c Q All combinations of the above of length Q, without repeats
f Keep elements of the above, as T, where the following is truthy:
sT Is the sum of T...
q ... equal to...
*QQ ... Q*Q?
O Choose a random element of those remaining sets, implicit print
Edit: saved a byte by taking an alternative approach. Previous version: Of&qQlT{IT./*
edited 2 days ago
answered 2 days ago
Sok
3,379722
3,379722
add a comment |
add a comment |
up vote
2
down vote
Python 3, 136 134 127 121 114 bytes
from random import*
def f(n):
s={randint(1,n*n)for _ in range(n)}
return len(s)==n and sum(s)==n*n and s or f(n)
Try it online!
A commenter corrected me, and this now hits recursion max depth at f(5) instead of f(1). Much closer to being a real competing answer.
I've seen it do f(5) once, and I'm working on trying to implement this with shuffle.
I tried making some lambda expressions for s=...
, but that didn't help on bytes. Maybe someone else can do something with this:
s=(lambda n:{randint(1,n*n)for _ in range(n)})(n)
Thanks to Kevin for shaving off another 7 bytes.
1
So this uses recursion to "regenerate" the set if the one generated is invalid? Definitely something wrong with your code if it's hitting recursion depth atf(1)
, the only possible array that should be generable atn=1
is[1]
Also there's a lot of extraneous whitespace to be removed here. Remember this is a code-golf challenge, so the goal is to achieve the lowest bytecount
– Skidsdev
2 days ago
1
range(1,n)
->range(n)
I believe should resolve the bug.
– Jonathan Allan
2 days ago
1
This should fix your bug, and also removes extraneous whitespace. I imagine there's a lot more room for golfing too
– Skidsdev
2 days ago
1
Although the recursion slightly worsens from 5 to 4, you can combine your two return statements like this:return len(s)==n and sum(s)==n*n and s or f(n)
(Try it online 114 bytes).
– Kevin Cruijssen
2 days ago
1
You can have it all on one line. 111 bytes
– Jo King
2 days ago
|
show 1 more comment
up vote
2
down vote
Python 3, 136 134 127 121 114 bytes
from random import*
def f(n):
s={randint(1,n*n)for _ in range(n)}
return len(s)==n and sum(s)==n*n and s or f(n)
Try it online!
A commenter corrected me, and this now hits recursion max depth at f(5) instead of f(1). Much closer to being a real competing answer.
I've seen it do f(5) once, and I'm working on trying to implement this with shuffle.
I tried making some lambda expressions for s=...
, but that didn't help on bytes. Maybe someone else can do something with this:
s=(lambda n:{randint(1,n*n)for _ in range(n)})(n)
Thanks to Kevin for shaving off another 7 bytes.
1
So this uses recursion to "regenerate" the set if the one generated is invalid? Definitely something wrong with your code if it's hitting recursion depth atf(1)
, the only possible array that should be generable atn=1
is[1]
Also there's a lot of extraneous whitespace to be removed here. Remember this is a code-golf challenge, so the goal is to achieve the lowest bytecount
– Skidsdev
2 days ago
1
range(1,n)
->range(n)
I believe should resolve the bug.
– Jonathan Allan
2 days ago
1
This should fix your bug, and also removes extraneous whitespace. I imagine there's a lot more room for golfing too
– Skidsdev
2 days ago
1
Although the recursion slightly worsens from 5 to 4, you can combine your two return statements like this:return len(s)==n and sum(s)==n*n and s or f(n)
(Try it online 114 bytes).
– Kevin Cruijssen
2 days ago
1
You can have it all on one line. 111 bytes
– Jo King
2 days ago
|
show 1 more comment
up vote
2
down vote
up vote
2
down vote
Python 3, 136 134 127 121 114 bytes
from random import*
def f(n):
s={randint(1,n*n)for _ in range(n)}
return len(s)==n and sum(s)==n*n and s or f(n)
Try it online!
A commenter corrected me, and this now hits recursion max depth at f(5) instead of f(1). Much closer to being a real competing answer.
I've seen it do f(5) once, and I'm working on trying to implement this with shuffle.
I tried making some lambda expressions for s=...
, but that didn't help on bytes. Maybe someone else can do something with this:
s=(lambda n:{randint(1,n*n)for _ in range(n)})(n)
Thanks to Kevin for shaving off another 7 bytes.
Python 3, 136 134 127 121 114 bytes
from random import*
def f(n):
s={randint(1,n*n)for _ in range(n)}
return len(s)==n and sum(s)==n*n and s or f(n)
Try it online!
A commenter corrected me, and this now hits recursion max depth at f(5) instead of f(1). Much closer to being a real competing answer.
I've seen it do f(5) once, and I'm working on trying to implement this with shuffle.
I tried making some lambda expressions for s=...
, but that didn't help on bytes. Maybe someone else can do something with this:
s=(lambda n:{randint(1,n*n)for _ in range(n)})(n)
Thanks to Kevin for shaving off another 7 bytes.
edited 2 days ago
answered 2 days ago
Gigaflop
1816
1816
1
So this uses recursion to "regenerate" the set if the one generated is invalid? Definitely something wrong with your code if it's hitting recursion depth atf(1)
, the only possible array that should be generable atn=1
is[1]
Also there's a lot of extraneous whitespace to be removed here. Remember this is a code-golf challenge, so the goal is to achieve the lowest bytecount
– Skidsdev
2 days ago
1
range(1,n)
->range(n)
I believe should resolve the bug.
– Jonathan Allan
2 days ago
1
This should fix your bug, and also removes extraneous whitespace. I imagine there's a lot more room for golfing too
– Skidsdev
2 days ago
1
Although the recursion slightly worsens from 5 to 4, you can combine your two return statements like this:return len(s)==n and sum(s)==n*n and s or f(n)
(Try it online 114 bytes).
– Kevin Cruijssen
2 days ago
1
You can have it all on one line. 111 bytes
– Jo King
2 days ago
|
show 1 more comment
1
So this uses recursion to "regenerate" the set if the one generated is invalid? Definitely something wrong with your code if it's hitting recursion depth atf(1)
, the only possible array that should be generable atn=1
is[1]
Also there's a lot of extraneous whitespace to be removed here. Remember this is a code-golf challenge, so the goal is to achieve the lowest bytecount
– Skidsdev
2 days ago
1
range(1,n)
->range(n)
I believe should resolve the bug.
– Jonathan Allan
2 days ago
1
This should fix your bug, and also removes extraneous whitespace. I imagine there's a lot more room for golfing too
– Skidsdev
2 days ago
1
Although the recursion slightly worsens from 5 to 4, you can combine your two return statements like this:return len(s)==n and sum(s)==n*n and s or f(n)
(Try it online 114 bytes).
– Kevin Cruijssen
2 days ago
1
You can have it all on one line. 111 bytes
– Jo King
2 days ago
1
1
So this uses recursion to "regenerate" the set if the one generated is invalid? Definitely something wrong with your code if it's hitting recursion depth at
f(1)
, the only possible array that should be generable at n=1
is [1]
Also there's a lot of extraneous whitespace to be removed here. Remember this is a code-golf challenge, so the goal is to achieve the lowest bytecount– Skidsdev
2 days ago
So this uses recursion to "regenerate" the set if the one generated is invalid? Definitely something wrong with your code if it's hitting recursion depth at
f(1)
, the only possible array that should be generable at n=1
is [1]
Also there's a lot of extraneous whitespace to be removed here. Remember this is a code-golf challenge, so the goal is to achieve the lowest bytecount– Skidsdev
2 days ago
1
1
range(1,n)
-> range(n)
I believe should resolve the bug.– Jonathan Allan
2 days ago
range(1,n)
-> range(n)
I believe should resolve the bug.– Jonathan Allan
2 days ago
1
1
This should fix your bug, and also removes extraneous whitespace. I imagine there's a lot more room for golfing too
– Skidsdev
2 days ago
This should fix your bug, and also removes extraneous whitespace. I imagine there's a lot more room for golfing too
– Skidsdev
2 days ago
1
1
Although the recursion slightly worsens from 5 to 4, you can combine your two return statements like this:
return len(s)==n and sum(s)==n*n and s or f(n)
(Try it online 114 bytes).– Kevin Cruijssen
2 days ago
Although the recursion slightly worsens from 5 to 4, you can combine your two return statements like this:
return len(s)==n and sum(s)==n*n and s or f(n)
(Try it online 114 bytes).– Kevin Cruijssen
2 days ago
1
1
You can have it all on one line. 111 bytes
– Jo King
2 days ago
You can have it all on one line. 111 bytes
– Jo King
2 days ago
|
show 1 more comment
up vote
1
down vote
MATL, 18 13 bytes
`xGU:GZrtsGU-
Try it online!
` # do..while:
x # delete from stack. This implicitly reads input the first time
# and removes it. It also deletes the previous invalid answer.
GU: # paste input and push [1...n^2]
GZr # select a single combination of n elements from [1..n^2]
tsGU- # is the sum equal to N^2? if yes, terminate and print results, else goto top
I wouldn't try this in R - random characters almost never produce a valid program.
– ngm
2 days ago
@ngm hahaha I suppose an explanation is in order.
– Giuseppe
2 days ago
add a comment |
up vote
1
down vote
MATL, 18 13 bytes
`xGU:GZrtsGU-
Try it online!
` # do..while:
x # delete from stack. This implicitly reads input the first time
# and removes it. It also deletes the previous invalid answer.
GU: # paste input and push [1...n^2]
GZr # select a single combination of n elements from [1..n^2]
tsGU- # is the sum equal to N^2? if yes, terminate and print results, else goto top
I wouldn't try this in R - random characters almost never produce a valid program.
– ngm
2 days ago
@ngm hahaha I suppose an explanation is in order.
– Giuseppe
2 days ago
add a comment |
up vote
1
down vote
up vote
1
down vote
MATL, 18 13 bytes
`xGU:GZrtsGU-
Try it online!
` # do..while:
x # delete from stack. This implicitly reads input the first time
# and removes it. It also deletes the previous invalid answer.
GU: # paste input and push [1...n^2]
GZr # select a single combination of n elements from [1..n^2]
tsGU- # is the sum equal to N^2? if yes, terminate and print results, else goto top
MATL, 18 13 bytes
`xGU:GZrtsGU-
Try it online!
` # do..while:
x # delete from stack. This implicitly reads input the first time
# and removes it. It also deletes the previous invalid answer.
GU: # paste input and push [1...n^2]
GZr # select a single combination of n elements from [1..n^2]
tsGU- # is the sum equal to N^2? if yes, terminate and print results, else goto top
edited 2 days ago
answered 2 days ago
Giuseppe
16k31052
16k31052
I wouldn't try this in R - random characters almost never produce a valid program.
– ngm
2 days ago
@ngm hahaha I suppose an explanation is in order.
– Giuseppe
2 days ago
add a comment |
I wouldn't try this in R - random characters almost never produce a valid program.
– ngm
2 days ago
@ngm hahaha I suppose an explanation is in order.
– Giuseppe
2 days ago
I wouldn't try this in R - random characters almost never produce a valid program.
– ngm
2 days ago
I wouldn't try this in R - random characters almost never produce a valid program.
– ngm
2 days ago
@ngm hahaha I suppose an explanation is in order.
– Giuseppe
2 days ago
@ngm hahaha I suppose an explanation is in order.
– Giuseppe
2 days ago
add a comment |
up vote
1
down vote
Japt, 12 bytes
²õ àU ö@²¥Xx
Try it
:Implicit input of integer U
² :U squared
õ :Range [1,U²]
àU :Combinations of length U
ö@ :Return a random element that returns true when passed through the following function as X
² : U squared
¥ : Equals
Xx : X reduced by addition
According to a comment made by the OP, order of elements in the output is irrelevant soà
should be fine.
– Kamil Drakari
2 days ago
Thanks, @KamilDrakari. Updated.
– Shaggy
2 days ago
add a comment |
up vote
1
down vote
Japt, 12 bytes
²õ àU ö@²¥Xx
Try it
:Implicit input of integer U
² :U squared
õ :Range [1,U²]
àU :Combinations of length U
ö@ :Return a random element that returns true when passed through the following function as X
² : U squared
¥ : Equals
Xx : X reduced by addition
According to a comment made by the OP, order of elements in the output is irrelevant soà
should be fine.
– Kamil Drakari
2 days ago
Thanks, @KamilDrakari. Updated.
– Shaggy
2 days ago
add a comment |
up vote
1
down vote
up vote
1
down vote
Japt, 12 bytes
²õ àU ö@²¥Xx
Try it
:Implicit input of integer U
² :U squared
õ :Range [1,U²]
àU :Combinations of length U
ö@ :Return a random element that returns true when passed through the following function as X
² : U squared
¥ : Equals
Xx : X reduced by addition
Japt, 12 bytes
²õ àU ö@²¥Xx
Try it
:Implicit input of integer U
² :U squared
õ :Range [1,U²]
àU :Combinations of length U
ö@ :Return a random element that returns true when passed through the following function as X
² : U squared
¥ : Equals
Xx : X reduced by addition
edited 2 days ago
answered 2 days ago
Shaggy
18.2k21663
18.2k21663
According to a comment made by the OP, order of elements in the output is irrelevant soà
should be fine.
– Kamil Drakari
2 days ago
Thanks, @KamilDrakari. Updated.
– Shaggy
2 days ago
add a comment |
According to a comment made by the OP, order of elements in the output is irrelevant soà
should be fine.
– Kamil Drakari
2 days ago
Thanks, @KamilDrakari. Updated.
– Shaggy
2 days ago
According to a comment made by the OP, order of elements in the output is irrelevant so
à
should be fine.– Kamil Drakari
2 days ago
According to a comment made by the OP, order of elements in the output is irrelevant so
à
should be fine.– Kamil Drakari
2 days ago
Thanks, @KamilDrakari. Updated.
– Shaggy
2 days ago
Thanks, @KamilDrakari. Updated.
– Shaggy
2 days ago
add a comment |
up vote
1
down vote
Java (JDK), 127 bytes
n->{for(int s;;){var r=new java.util.TreeSet();for(s=n*n;s>0;)r.add(s-(s-=Math.random()*n*n+1));if(r.size()==n&s==0)return r;}}
Try it online!
Infinite loop until a set with the criteria matches.
I hope you have the time, because it's very sloooooow! It can't even go to 10 without timing out.
You can golf 3 bytes by changingif(r.size()==n&s==0)
toif(r.size()+s==n)
.
– Kevin Cruijssen
8 hours ago
@KevinCruijssen I've thought about it too, but no I can't because s could be -1 and n could be size() - 1.
– Olivier Grégoire
7 hours ago
add a comment |
up vote
1
down vote
Java (JDK), 127 bytes
n->{for(int s;;){var r=new java.util.TreeSet();for(s=n*n;s>0;)r.add(s-(s-=Math.random()*n*n+1));if(r.size()==n&s==0)return r;}}
Try it online!
Infinite loop until a set with the criteria matches.
I hope you have the time, because it's very sloooooow! It can't even go to 10 without timing out.
You can golf 3 bytes by changingif(r.size()==n&s==0)
toif(r.size()+s==n)
.
– Kevin Cruijssen
8 hours ago
@KevinCruijssen I've thought about it too, but no I can't because s could be -1 and n could be size() - 1.
– Olivier Grégoire
7 hours ago
add a comment |
up vote
1
down vote
up vote
1
down vote
Java (JDK), 127 bytes
n->{for(int s;;){var r=new java.util.TreeSet();for(s=n*n;s>0;)r.add(s-(s-=Math.random()*n*n+1));if(r.size()==n&s==0)return r;}}
Try it online!
Infinite loop until a set with the criteria matches.
I hope you have the time, because it's very sloooooow! It can't even go to 10 without timing out.
Java (JDK), 127 bytes
n->{for(int s;;){var r=new java.util.TreeSet();for(s=n*n;s>0;)r.add(s-(s-=Math.random()*n*n+1));if(r.size()==n&s==0)return r;}}
Try it online!
Infinite loop until a set with the criteria matches.
I hope you have the time, because it's very sloooooow! It can't even go to 10 without timing out.
edited yesterday
answered yesterday
Olivier Grégoire
8,26711842
8,26711842
You can golf 3 bytes by changingif(r.size()==n&s==0)
toif(r.size()+s==n)
.
– Kevin Cruijssen
8 hours ago
@KevinCruijssen I've thought about it too, but no I can't because s could be -1 and n could be size() - 1.
– Olivier Grégoire
7 hours ago
add a comment |
You can golf 3 bytes by changingif(r.size()==n&s==0)
toif(r.size()+s==n)
.
– Kevin Cruijssen
8 hours ago
@KevinCruijssen I've thought about it too, but no I can't because s could be -1 and n could be size() - 1.
– Olivier Grégoire
7 hours ago
You can golf 3 bytes by changing
if(r.size()==n&s==0)
to if(r.size()+s==n)
.– Kevin Cruijssen
8 hours ago
You can golf 3 bytes by changing
if(r.size()==n&s==0)
to if(r.size()+s==n)
.– Kevin Cruijssen
8 hours ago
@KevinCruijssen I've thought about it too, but no I can't because s could be -1 and n could be size() - 1.
– Olivier Grégoire
7 hours ago
@KevinCruijssen I've thought about it too, but no I can't because s could be -1 and n could be size() - 1.
– Olivier Grégoire
7 hours ago
add a comment |
up vote
1
down vote
JavaScript, 647 bytes
(n,s=(n,g=n**2,a=[...Array(g).keys()].map(k=>k+1),c=_=>eval(_.join`+`))=>[...function*(r=,p=a.slice(0,-2).sort(_=>.5-Math.random())){while(r.length<n)r.push(p.splice(Math.floor(Math.random()*p.length),1)[0]);if(c(r)==g)return r;while(c(r)>g){for(let x=0;x<r.length;x++){if(c(r)==g)break;if(r[x]-1==0||r.find(_=>r[x]-1==_)){continue}else r[x]-=1}}while(c(r)<g){for(let x=0;x<r.length;x++){if(c(r)==g)break;if(r.find(_=>r[x]+1==_)){continue}else r[x]+=1;}}yield* r}()])=>n<2?[n]:[...function*(){for(let k=0,r=;k<n;k++){let z=s(n).slice(0,n);if(!r.length){r.push(z.join``)}else{if(r.find(_=>_==z.join``)){z.reverse()}r.push(z.join``)}yield z}}()]
Try it online!
Un-golfed
f=(n
, s = (n, g = n ** 2, a = [...Array(g).keys()].map(k => k + 1), c = _ => eval(_.join `+`)) =>
[...function * (r = , p = a.slice(0, -2).sort(_ => .5 - Math.random())) {
while (r.length < n) r.push(p.splice(Math.floor(Math.random() * p.length), 1)[0]);
if (c(r) == g) return r;
while (c(r) > g) {
for (let x = 0; x < r.length; x++) {
if (c(r) == g) break;
if (r[x] - 1 == 0 || r.find(_ => r[x] - 1 == _)) {
continue
} else r[x] -= 1
}
}
while (c(r) < g) {
for (let x = 0; x < r.length; x++) {
if (c(r) == g) break;
if (r.find(_ => r[x] + 1 == _)) {
continue
} else r[x] += 1;
}
}
yield * r
}()]) => n < 2 ? [n] : [...function * () {
for (let k = 0, r = ; k < n; k++) {
let z = s(n).slice(0, n);
if (!r.length) {
r.push(z.join ``)
} else {
if (r.find(_ => _ == z.join ``)) {
z.reverse()
}
r.push(z.join ``)
}
yield z
}
}()]
1
637 bytes by pulling z.join into a variable, andk++
– Veskah
5 hours ago
@Veskah The twowhile
loops could probably also be reduced to the body of a single function which accepts parameters; and could substitute conditional operators (ternary) for theif..else
statements; among other portions of the code that could more than likely be adjusted for golf; i.e.g., removinglet
statements.
– guest271314
5 hours ago
@Veskah 601 bytes without substituting ternary forif..else
– guest271314
5 hours ago
1
Oh yeah, you're outputting all the sets whereas the challenge asks for a random one to be returned (See the OP comments for more details)
– Veskah
5 hours ago
@Veskah Must have misinterpreted the challenge and examples, or was too focused on solving this part of the question "Bonus Task: Is there a formula to calculate the number of valid permutations for a givenn
?". testing if the algorithm consistently returned expected result forn^2
output arrays generated in a single call to the function, and simultaneously considering the similarities to this question N-dimensional N^N array filled with N.
– guest271314
5 hours ago
|
show 1 more comment
up vote
1
down vote
JavaScript, 647 bytes
(n,s=(n,g=n**2,a=[...Array(g).keys()].map(k=>k+1),c=_=>eval(_.join`+`))=>[...function*(r=,p=a.slice(0,-2).sort(_=>.5-Math.random())){while(r.length<n)r.push(p.splice(Math.floor(Math.random()*p.length),1)[0]);if(c(r)==g)return r;while(c(r)>g){for(let x=0;x<r.length;x++){if(c(r)==g)break;if(r[x]-1==0||r.find(_=>r[x]-1==_)){continue}else r[x]-=1}}while(c(r)<g){for(let x=0;x<r.length;x++){if(c(r)==g)break;if(r.find(_=>r[x]+1==_)){continue}else r[x]+=1;}}yield* r}()])=>n<2?[n]:[...function*(){for(let k=0,r=;k<n;k++){let z=s(n).slice(0,n);if(!r.length){r.push(z.join``)}else{if(r.find(_=>_==z.join``)){z.reverse()}r.push(z.join``)}yield z}}()]
Try it online!
Un-golfed
f=(n
, s = (n, g = n ** 2, a = [...Array(g).keys()].map(k => k + 1), c = _ => eval(_.join `+`)) =>
[...function * (r = , p = a.slice(0, -2).sort(_ => .5 - Math.random())) {
while (r.length < n) r.push(p.splice(Math.floor(Math.random() * p.length), 1)[0]);
if (c(r) == g) return r;
while (c(r) > g) {
for (let x = 0; x < r.length; x++) {
if (c(r) == g) break;
if (r[x] - 1 == 0 || r.find(_ => r[x] - 1 == _)) {
continue
} else r[x] -= 1
}
}
while (c(r) < g) {
for (let x = 0; x < r.length; x++) {
if (c(r) == g) break;
if (r.find(_ => r[x] + 1 == _)) {
continue
} else r[x] += 1;
}
}
yield * r
}()]) => n < 2 ? [n] : [...function * () {
for (let k = 0, r = ; k < n; k++) {
let z = s(n).slice(0, n);
if (!r.length) {
r.push(z.join ``)
} else {
if (r.find(_ => _ == z.join ``)) {
z.reverse()
}
r.push(z.join ``)
}
yield z
}
}()]
1
637 bytes by pulling z.join into a variable, andk++
– Veskah
5 hours ago
@Veskah The twowhile
loops could probably also be reduced to the body of a single function which accepts parameters; and could substitute conditional operators (ternary) for theif..else
statements; among other portions of the code that could more than likely be adjusted for golf; i.e.g., removinglet
statements.
– guest271314
5 hours ago
@Veskah 601 bytes without substituting ternary forif..else
– guest271314
5 hours ago
1
Oh yeah, you're outputting all the sets whereas the challenge asks for a random one to be returned (See the OP comments for more details)
– Veskah
5 hours ago
@Veskah Must have misinterpreted the challenge and examples, or was too focused on solving this part of the question "Bonus Task: Is there a formula to calculate the number of valid permutations for a givenn
?". testing if the algorithm consistently returned expected result forn^2
output arrays generated in a single call to the function, and simultaneously considering the similarities to this question N-dimensional N^N array filled with N.
– guest271314
5 hours ago
|
show 1 more comment
up vote
1
down vote
up vote
1
down vote
JavaScript, 647 bytes
(n,s=(n,g=n**2,a=[...Array(g).keys()].map(k=>k+1),c=_=>eval(_.join`+`))=>[...function*(r=,p=a.slice(0,-2).sort(_=>.5-Math.random())){while(r.length<n)r.push(p.splice(Math.floor(Math.random()*p.length),1)[0]);if(c(r)==g)return r;while(c(r)>g){for(let x=0;x<r.length;x++){if(c(r)==g)break;if(r[x]-1==0||r.find(_=>r[x]-1==_)){continue}else r[x]-=1}}while(c(r)<g){for(let x=0;x<r.length;x++){if(c(r)==g)break;if(r.find(_=>r[x]+1==_)){continue}else r[x]+=1;}}yield* r}()])=>n<2?[n]:[...function*(){for(let k=0,r=;k<n;k++){let z=s(n).slice(0,n);if(!r.length){r.push(z.join``)}else{if(r.find(_=>_==z.join``)){z.reverse()}r.push(z.join``)}yield z}}()]
Try it online!
Un-golfed
f=(n
, s = (n, g = n ** 2, a = [...Array(g).keys()].map(k => k + 1), c = _ => eval(_.join `+`)) =>
[...function * (r = , p = a.slice(0, -2).sort(_ => .5 - Math.random())) {
while (r.length < n) r.push(p.splice(Math.floor(Math.random() * p.length), 1)[0]);
if (c(r) == g) return r;
while (c(r) > g) {
for (let x = 0; x < r.length; x++) {
if (c(r) == g) break;
if (r[x] - 1 == 0 || r.find(_ => r[x] - 1 == _)) {
continue
} else r[x] -= 1
}
}
while (c(r) < g) {
for (let x = 0; x < r.length; x++) {
if (c(r) == g) break;
if (r.find(_ => r[x] + 1 == _)) {
continue
} else r[x] += 1;
}
}
yield * r
}()]) => n < 2 ? [n] : [...function * () {
for (let k = 0, r = ; k < n; k++) {
let z = s(n).slice(0, n);
if (!r.length) {
r.push(z.join ``)
} else {
if (r.find(_ => _ == z.join ``)) {
z.reverse()
}
r.push(z.join ``)
}
yield z
}
}()]
JavaScript, 647 bytes
(n,s=(n,g=n**2,a=[...Array(g).keys()].map(k=>k+1),c=_=>eval(_.join`+`))=>[...function*(r=,p=a.slice(0,-2).sort(_=>.5-Math.random())){while(r.length<n)r.push(p.splice(Math.floor(Math.random()*p.length),1)[0]);if(c(r)==g)return r;while(c(r)>g){for(let x=0;x<r.length;x++){if(c(r)==g)break;if(r[x]-1==0||r.find(_=>r[x]-1==_)){continue}else r[x]-=1}}while(c(r)<g){for(let x=0;x<r.length;x++){if(c(r)==g)break;if(r.find(_=>r[x]+1==_)){continue}else r[x]+=1;}}yield* r}()])=>n<2?[n]:[...function*(){for(let k=0,r=;k<n;k++){let z=s(n).slice(0,n);if(!r.length){r.push(z.join``)}else{if(r.find(_=>_==z.join``)){z.reverse()}r.push(z.join``)}yield z}}()]
Try it online!
Un-golfed
f=(n
, s = (n, g = n ** 2, a = [...Array(g).keys()].map(k => k + 1), c = _ => eval(_.join `+`)) =>
[...function * (r = , p = a.slice(0, -2).sort(_ => .5 - Math.random())) {
while (r.length < n) r.push(p.splice(Math.floor(Math.random() * p.length), 1)[0]);
if (c(r) == g) return r;
while (c(r) > g) {
for (let x = 0; x < r.length; x++) {
if (c(r) == g) break;
if (r[x] - 1 == 0 || r.find(_ => r[x] - 1 == _)) {
continue
} else r[x] -= 1
}
}
while (c(r) < g) {
for (let x = 0; x < r.length; x++) {
if (c(r) == g) break;
if (r.find(_ => r[x] + 1 == _)) {
continue
} else r[x] += 1;
}
}
yield * r
}()]) => n < 2 ? [n] : [...function * () {
for (let k = 0, r = ; k < n; k++) {
let z = s(n).slice(0, n);
if (!r.length) {
r.push(z.join ``)
} else {
if (r.find(_ => _ == z.join ``)) {
z.reverse()
}
r.push(z.join ``)
}
yield z
}
}()]
answered 7 hours ago
guest271314
271211
271211
1
637 bytes by pulling z.join into a variable, andk++
– Veskah
5 hours ago
@Veskah The twowhile
loops could probably also be reduced to the body of a single function which accepts parameters; and could substitute conditional operators (ternary) for theif..else
statements; among other portions of the code that could more than likely be adjusted for golf; i.e.g., removinglet
statements.
– guest271314
5 hours ago
@Veskah 601 bytes without substituting ternary forif..else
– guest271314
5 hours ago
1
Oh yeah, you're outputting all the sets whereas the challenge asks for a random one to be returned (See the OP comments for more details)
– Veskah
5 hours ago
@Veskah Must have misinterpreted the challenge and examples, or was too focused on solving this part of the question "Bonus Task: Is there a formula to calculate the number of valid permutations for a givenn
?". testing if the algorithm consistently returned expected result forn^2
output arrays generated in a single call to the function, and simultaneously considering the similarities to this question N-dimensional N^N array filled with N.
– guest271314
5 hours ago
|
show 1 more comment
1
637 bytes by pulling z.join into a variable, andk++
– Veskah
5 hours ago
@Veskah The twowhile
loops could probably also be reduced to the body of a single function which accepts parameters; and could substitute conditional operators (ternary) for theif..else
statements; among other portions of the code that could more than likely be adjusted for golf; i.e.g., removinglet
statements.
– guest271314
5 hours ago
@Veskah 601 bytes without substituting ternary forif..else
– guest271314
5 hours ago
1
Oh yeah, you're outputting all the sets whereas the challenge asks for a random one to be returned (See the OP comments for more details)
– Veskah
5 hours ago
@Veskah Must have misinterpreted the challenge and examples, or was too focused on solving this part of the question "Bonus Task: Is there a formula to calculate the number of valid permutations for a givenn
?". testing if the algorithm consistently returned expected result forn^2
output arrays generated in a single call to the function, and simultaneously considering the similarities to this question N-dimensional N^N array filled with N.
– guest271314
5 hours ago
1
1
637 bytes by pulling z.join into a variable, and
k++
– Veskah
5 hours ago
637 bytes by pulling z.join into a variable, and
k++
– Veskah
5 hours ago
@Veskah The two
while
loops could probably also be reduced to the body of a single function which accepts parameters; and could substitute conditional operators (ternary) for the if..else
statements; among other portions of the code that could more than likely be adjusted for golf; i.e.g., removing let
statements.– guest271314
5 hours ago
@Veskah The two
while
loops could probably also be reduced to the body of a single function which accepts parameters; and could substitute conditional operators (ternary) for the if..else
statements; among other portions of the code that could more than likely be adjusted for golf; i.e.g., removing let
statements.– guest271314
5 hours ago
@Veskah 601 bytes without substituting ternary for
if..else
– guest271314
5 hours ago
@Veskah 601 bytes without substituting ternary for
if..else
– guest271314
5 hours ago
1
1
Oh yeah, you're outputting all the sets whereas the challenge asks for a random one to be returned (See the OP comments for more details)
– Veskah
5 hours ago
Oh yeah, you're outputting all the sets whereas the challenge asks for a random one to be returned (See the OP comments for more details)
– Veskah
5 hours ago
@Veskah Must have misinterpreted the challenge and examples, or was too focused on solving this part of the question "Bonus Task: Is there a formula to calculate the number of valid permutations for a given
n
?". testing if the algorithm consistently returned expected result for n^2
output arrays generated in a single call to the function, and simultaneously considering the similarities to this question N-dimensional N^N array filled with N.– guest271314
5 hours ago
@Veskah Must have misinterpreted the challenge and examples, or was too focused on solving this part of the question "Bonus Task: Is there a formula to calculate the number of valid permutations for a given
n
?". testing if the algorithm consistently returned expected result for n^2
output arrays generated in a single call to the function, and simultaneously considering the similarities to this question N-dimensional N^N array filled with N.– guest271314
5 hours ago
|
show 1 more comment
up vote
1
down vote
Batch, 182 145 bytes
@set/an=%1,r=n*n,l=r+1
@for /l %%i in (%1,-1,1)do @set/at=n*(n-=1)/2,m=(r+t+n)/-~n,r-=l=m+%random%%%((l-=x=r+1-t)*(l^>^>31)+x-m)&call echo %%l%%
Explanation: Calculates the minimum and maximum allowable pick, given that the numbers are to be picked in descending order, and chooses a random value within the range. Example for an input of 4
:
- We start with 16 left. We can't pick 11 or more because the remaining 3 picks must add to at least 6. We also need to pick at least 6, because if we only pick 5, the remaining 3 picks can only add to 9, which isn't enough for 16. We pick a random value from 6 to 10, say 6.
- We have 10 left. We can't pick 8 or more because the remaining 2 picks must add to at least 3. As it happens, we can't pick 6 or more because we picked 6 last time. We also need to pick at least 5, because if we only pick 4, the remaining 2 picks can only add to 5, for a grand total of 15. We pick a random value from 5 to 5, say 5 (!).
- We have 5 left. We can't pick 5 or more because the remaining pick must add to at least 1, and also because we picked 5 last time. We also need to pick at least 3, because if we only pick 2, the remaining pick can only be 1, for a grand total of 14. We pick a random value from 3 to 4, say 4.
- We have 1 left. As it turns out, the algorithm chooses a range of 1 to 1, and we pick 1 as the final number.
add a comment |
up vote
1
down vote
Batch, 182 145 bytes
@set/an=%1,r=n*n,l=r+1
@for /l %%i in (%1,-1,1)do @set/at=n*(n-=1)/2,m=(r+t+n)/-~n,r-=l=m+%random%%%((l-=x=r+1-t)*(l^>^>31)+x-m)&call echo %%l%%
Explanation: Calculates the minimum and maximum allowable pick, given that the numbers are to be picked in descending order, and chooses a random value within the range. Example for an input of 4
:
- We start with 16 left. We can't pick 11 or more because the remaining 3 picks must add to at least 6. We also need to pick at least 6, because if we only pick 5, the remaining 3 picks can only add to 9, which isn't enough for 16. We pick a random value from 6 to 10, say 6.
- We have 10 left. We can't pick 8 or more because the remaining 2 picks must add to at least 3. As it happens, we can't pick 6 or more because we picked 6 last time. We also need to pick at least 5, because if we only pick 4, the remaining 2 picks can only add to 5, for a grand total of 15. We pick a random value from 5 to 5, say 5 (!).
- We have 5 left. We can't pick 5 or more because the remaining pick must add to at least 1, and also because we picked 5 last time. We also need to pick at least 3, because if we only pick 2, the remaining pick can only be 1, for a grand total of 14. We pick a random value from 3 to 4, say 4.
- We have 1 left. As it turns out, the algorithm chooses a range of 1 to 1, and we pick 1 as the final number.
add a comment |
up vote
1
down vote
up vote
1
down vote
Batch, 182 145 bytes
@set/an=%1,r=n*n,l=r+1
@for /l %%i in (%1,-1,1)do @set/at=n*(n-=1)/2,m=(r+t+n)/-~n,r-=l=m+%random%%%((l-=x=r+1-t)*(l^>^>31)+x-m)&call echo %%l%%
Explanation: Calculates the minimum and maximum allowable pick, given that the numbers are to be picked in descending order, and chooses a random value within the range. Example for an input of 4
:
- We start with 16 left. We can't pick 11 or more because the remaining 3 picks must add to at least 6. We also need to pick at least 6, because if we only pick 5, the remaining 3 picks can only add to 9, which isn't enough for 16. We pick a random value from 6 to 10, say 6.
- We have 10 left. We can't pick 8 or more because the remaining 2 picks must add to at least 3. As it happens, we can't pick 6 or more because we picked 6 last time. We also need to pick at least 5, because if we only pick 4, the remaining 2 picks can only add to 5, for a grand total of 15. We pick a random value from 5 to 5, say 5 (!).
- We have 5 left. We can't pick 5 or more because the remaining pick must add to at least 1, and also because we picked 5 last time. We also need to pick at least 3, because if we only pick 2, the remaining pick can only be 1, for a grand total of 14. We pick a random value from 3 to 4, say 4.
- We have 1 left. As it turns out, the algorithm chooses a range of 1 to 1, and we pick 1 as the final number.
Batch, 182 145 bytes
@set/an=%1,r=n*n,l=r+1
@for /l %%i in (%1,-1,1)do @set/at=n*(n-=1)/2,m=(r+t+n)/-~n,r-=l=m+%random%%%((l-=x=r+1-t)*(l^>^>31)+x-m)&call echo %%l%%
Explanation: Calculates the minimum and maximum allowable pick, given that the numbers are to be picked in descending order, and chooses a random value within the range. Example for an input of 4
:
- We start with 16 left. We can't pick 11 or more because the remaining 3 picks must add to at least 6. We also need to pick at least 6, because if we only pick 5, the remaining 3 picks can only add to 9, which isn't enough for 16. We pick a random value from 6 to 10, say 6.
- We have 10 left. We can't pick 8 or more because the remaining 2 picks must add to at least 3. As it happens, we can't pick 6 or more because we picked 6 last time. We also need to pick at least 5, because if we only pick 4, the remaining 2 picks can only add to 5, for a grand total of 15. We pick a random value from 5 to 5, say 5 (!).
- We have 5 left. We can't pick 5 or more because the remaining pick must add to at least 1, and also because we picked 5 last time. We also need to pick at least 3, because if we only pick 2, the remaining pick can only be 1, for a grand total of 14. We pick a random value from 3 to 4, say 4.
- We have 1 left. As it turns out, the algorithm chooses a range of 1 to 1, and we pick 1 as the final number.
edited 4 hours ago
answered 5 hours ago
Neil
78.1k744175
78.1k744175
add a comment |
add a comment |
up vote
0
down vote
Japt, 20 bytes
²õ ö¬oU íUõ+)Õæ@²¥Xx
Try it online!
Extremely heavily takes advantage of "Non-uniform" randomness, almost always outputs the first n
odd numbers, which happens to sum to n^2
. In theory it can output any other valid set, though I've only been able to confirm that for small n
.
Explanation:
²õ :Generate the range [1...n^2]
ö¬ :Order it randomly
oU :Get the last n items
í )Õ :Put it in an array with...
Uõ+ : The first n odd numbers
æ_ :Get the first one where...
Xx : The sum
²¥ : equals n^2
add a comment |
up vote
0
down vote
Japt, 20 bytes
²õ ö¬oU íUõ+)Õæ@²¥Xx
Try it online!
Extremely heavily takes advantage of "Non-uniform" randomness, almost always outputs the first n
odd numbers, which happens to sum to n^2
. In theory it can output any other valid set, though I've only been able to confirm that for small n
.
Explanation:
²õ :Generate the range [1...n^2]
ö¬ :Order it randomly
oU :Get the last n items
í )Õ :Put it in an array with...
Uõ+ : The first n odd numbers
æ_ :Get the first one where...
Xx : The sum
²¥ : equals n^2
add a comment |
up vote
0
down vote
up vote
0
down vote
Japt, 20 bytes
²õ ö¬oU íUõ+)Õæ@²¥Xx
Try it online!
Extremely heavily takes advantage of "Non-uniform" randomness, almost always outputs the first n
odd numbers, which happens to sum to n^2
. In theory it can output any other valid set, though I've only been able to confirm that for small n
.
Explanation:
²õ :Generate the range [1...n^2]
ö¬ :Order it randomly
oU :Get the last n items
í )Õ :Put it in an array with...
Uõ+ : The first n odd numbers
æ_ :Get the first one where...
Xx : The sum
²¥ : equals n^2
Japt, 20 bytes
²õ ö¬oU íUõ+)Õæ@²¥Xx
Try it online!
Extremely heavily takes advantage of "Non-uniform" randomness, almost always outputs the first n
odd numbers, which happens to sum to n^2
. In theory it can output any other valid set, though I've only been able to confirm that for small n
.
Explanation:
²õ :Generate the range [1...n^2]
ö¬ :Order it randomly
oU :Get the last n items
í )Õ :Put it in an array with...
Uõ+ : The first n odd numbers
æ_ :Get the first one where...
Xx : The sum
²¥ : equals n^2
answered 2 days ago
Kamil Drakari
2,581416
2,581416
add a comment |
add a comment |
up vote
0
down vote
Ruby, 46 bytes
->n{z=0until(z=[*1..n*n].sample n).sum==n*n;z}
Try it online!
add a comment |
up vote
0
down vote
Ruby, 46 bytes
->n{z=0until(z=[*1..n*n].sample n).sum==n*n;z}
Try it online!
add a comment |
up vote
0
down vote
up vote
0
down vote
Ruby, 46 bytes
->n{z=0until(z=[*1..n*n].sample n).sum==n*n;z}
Try it online!
Ruby, 46 bytes
->n{z=0until(z=[*1..n*n].sample n).sum==n*n;z}
Try it online!
answered yesterday
G B
7,5361328
7,5361328
add a comment |
add a comment |
up vote
0
down vote
C (gcc), 128 125 bytes
p(_){printf("%d ",_);}f(n,x,y,i){x=n*n;y=1;for(i=0;++i<n;p(y),x-=y++)while(rand()&&(n-i)*(n-i+1)/2+(n-i)*(y+1)+y<x)y++;p(x);}
Try it online!
-3 bytes thanks to ceilingcat
NOTE: The probability is very very far from uniform. See explanation for what I mean and a better means to test that it works (by making the distribution closer to uniform [but still a far cry from it]).
How?
The basic idea is to only choose increasing numbers so as to not worry about duplicates. Whenever we pick a number we have a non-zero chance of 'skipping' it if allowable.
To decide if we can skip a number we need to know x
the total left to be reached, k
the number of elements we still have to use, and y
the current candidate value. The smallest possible number that we could still pick would consist of $$y+(y+1)+(y+2)+...$$ added to the current value. In particular we require the above expression to be less than x
. The formula will be $$frac{k(k+1)}{2}+k(y+1)+y<x$$ Unfortunately we have to be a bit careful about rearranging this formula due to integer truncation in C, so I couldn't really find a way to golf it.
Nonetheless the logic is to have a chance to discard any y
that satisfies the above equation.
The code
p(_){printf("%d ",_);} // Define print(int)
f(n,x,y,i){ // Define f(n,...) as the function we want
x=n*n; // Set x to n^2
y=1; // Set y to 1
for(i=0;++i<n;){ // n-1 times do...
while(rand()&& // While rand() is non-zero [very very likely] AND
(n-i)* // (n-i) is the 'k' in the formula
(n-i+1)/2+ // This first half takes care of the increment
(n-i)*(y+1) // This second half takes care of the y+1 starting point
+y<x) // The +y takes care of the current value of y
y++; // If rand() returned non-zero and we can skip y, do so
p(y); // Print y
x-=y++; // Subtract y from the total and increment it
}p(x);} // Print what's left over.
The trick I mentioned to better test the code involves replacing rand()&&
with rand()%2&&
so that there is a 50-50 chance that any given y is skipped, rather than a 1 in RAND_MAX
chance that any given y is used.
I would love it if someone checked my math for consistency. I also wonder if this type of solution could make the uniform random speed challenge simple. The formula places an upper and lower bound on the answer, does a uniform random number in that range result in uniform random results? I don't see why not - but I haven't done much combinatorics in awhile.
– LambdaBeta
2 days ago
Suggestp(y),x-=y++)while(rand()&&(i-n)*((~n+i)/2+~y)+y<x)y++;
instead of){while(rand()&&(n-i)*(n-i+1)/2+(n-i)*(y+1)+y<x)y++;p(y);x-=y++;}
– ceilingcat
2 days ago
@ceilingcat I love these little improvements you find. I always get so focussed on the overall algorithm I forget to optimize for implementation (I basically go autopilot golfing mode once I have a non-golfed source that works - so I miss a lot of savings)
– LambdaBeta
yesterday
Hey, it's not just you who has those syntax-golfs. I find little improvements in a lot of C/C++ answers like that (except not in yours, @ceilingcat usually snaps those up).
– Zacharý
yesterday
Yeah, I've noticed that you two are probably the most active C/C++ putters (can we use putting to extend the golf analogy to the last few strokes? Why not!). It always impresses me that you can even understand the golfed code well enough to improve it.
– LambdaBeta
yesterday
add a comment |
up vote
0
down vote
C (gcc), 128 125 bytes
p(_){printf("%d ",_);}f(n,x,y,i){x=n*n;y=1;for(i=0;++i<n;p(y),x-=y++)while(rand()&&(n-i)*(n-i+1)/2+(n-i)*(y+1)+y<x)y++;p(x);}
Try it online!
-3 bytes thanks to ceilingcat
NOTE: The probability is very very far from uniform. See explanation for what I mean and a better means to test that it works (by making the distribution closer to uniform [but still a far cry from it]).
How?
The basic idea is to only choose increasing numbers so as to not worry about duplicates. Whenever we pick a number we have a non-zero chance of 'skipping' it if allowable.
To decide if we can skip a number we need to know x
the total left to be reached, k
the number of elements we still have to use, and y
the current candidate value. The smallest possible number that we could still pick would consist of $$y+(y+1)+(y+2)+...$$ added to the current value. In particular we require the above expression to be less than x
. The formula will be $$frac{k(k+1)}{2}+k(y+1)+y<x$$ Unfortunately we have to be a bit careful about rearranging this formula due to integer truncation in C, so I couldn't really find a way to golf it.
Nonetheless the logic is to have a chance to discard any y
that satisfies the above equation.
The code
p(_){printf("%d ",_);} // Define print(int)
f(n,x,y,i){ // Define f(n,...) as the function we want
x=n*n; // Set x to n^2
y=1; // Set y to 1
for(i=0;++i<n;){ // n-1 times do...
while(rand()&& // While rand() is non-zero [very very likely] AND
(n-i)* // (n-i) is the 'k' in the formula
(n-i+1)/2+ // This first half takes care of the increment
(n-i)*(y+1) // This second half takes care of the y+1 starting point
+y<x) // The +y takes care of the current value of y
y++; // If rand() returned non-zero and we can skip y, do so
p(y); // Print y
x-=y++; // Subtract y from the total and increment it
}p(x);} // Print what's left over.
The trick I mentioned to better test the code involves replacing rand()&&
with rand()%2&&
so that there is a 50-50 chance that any given y is skipped, rather than a 1 in RAND_MAX
chance that any given y is used.
I would love it if someone checked my math for consistency. I also wonder if this type of solution could make the uniform random speed challenge simple. The formula places an upper and lower bound on the answer, does a uniform random number in that range result in uniform random results? I don't see why not - but I haven't done much combinatorics in awhile.
– LambdaBeta
2 days ago
Suggestp(y),x-=y++)while(rand()&&(i-n)*((~n+i)/2+~y)+y<x)y++;
instead of){while(rand()&&(n-i)*(n-i+1)/2+(n-i)*(y+1)+y<x)y++;p(y);x-=y++;}
– ceilingcat
2 days ago
@ceilingcat I love these little improvements you find. I always get so focussed on the overall algorithm I forget to optimize for implementation (I basically go autopilot golfing mode once I have a non-golfed source that works - so I miss a lot of savings)
– LambdaBeta
yesterday
Hey, it's not just you who has those syntax-golfs. I find little improvements in a lot of C/C++ answers like that (except not in yours, @ceilingcat usually snaps those up).
– Zacharý
yesterday
Yeah, I've noticed that you two are probably the most active C/C++ putters (can we use putting to extend the golf analogy to the last few strokes? Why not!). It always impresses me that you can even understand the golfed code well enough to improve it.
– LambdaBeta
yesterday
add a comment |
up vote
0
down vote
up vote
0
down vote
C (gcc), 128 125 bytes
p(_){printf("%d ",_);}f(n,x,y,i){x=n*n;y=1;for(i=0;++i<n;p(y),x-=y++)while(rand()&&(n-i)*(n-i+1)/2+(n-i)*(y+1)+y<x)y++;p(x);}
Try it online!
-3 bytes thanks to ceilingcat
NOTE: The probability is very very far from uniform. See explanation for what I mean and a better means to test that it works (by making the distribution closer to uniform [but still a far cry from it]).
How?
The basic idea is to only choose increasing numbers so as to not worry about duplicates. Whenever we pick a number we have a non-zero chance of 'skipping' it if allowable.
To decide if we can skip a number we need to know x
the total left to be reached, k
the number of elements we still have to use, and y
the current candidate value. The smallest possible number that we could still pick would consist of $$y+(y+1)+(y+2)+...$$ added to the current value. In particular we require the above expression to be less than x
. The formula will be $$frac{k(k+1)}{2}+k(y+1)+y<x$$ Unfortunately we have to be a bit careful about rearranging this formula due to integer truncation in C, so I couldn't really find a way to golf it.
Nonetheless the logic is to have a chance to discard any y
that satisfies the above equation.
The code
p(_){printf("%d ",_);} // Define print(int)
f(n,x,y,i){ // Define f(n,...) as the function we want
x=n*n; // Set x to n^2
y=1; // Set y to 1
for(i=0;++i<n;){ // n-1 times do...
while(rand()&& // While rand() is non-zero [very very likely] AND
(n-i)* // (n-i) is the 'k' in the formula
(n-i+1)/2+ // This first half takes care of the increment
(n-i)*(y+1) // This second half takes care of the y+1 starting point
+y<x) // The +y takes care of the current value of y
y++; // If rand() returned non-zero and we can skip y, do so
p(y); // Print y
x-=y++; // Subtract y from the total and increment it
}p(x);} // Print what's left over.
The trick I mentioned to better test the code involves replacing rand()&&
with rand()%2&&
so that there is a 50-50 chance that any given y is skipped, rather than a 1 in RAND_MAX
chance that any given y is used.
C (gcc), 128 125 bytes
p(_){printf("%d ",_);}f(n,x,y,i){x=n*n;y=1;for(i=0;++i<n;p(y),x-=y++)while(rand()&&(n-i)*(n-i+1)/2+(n-i)*(y+1)+y<x)y++;p(x);}
Try it online!
-3 bytes thanks to ceilingcat
NOTE: The probability is very very far from uniform. See explanation for what I mean and a better means to test that it works (by making the distribution closer to uniform [but still a far cry from it]).
How?
The basic idea is to only choose increasing numbers so as to not worry about duplicates. Whenever we pick a number we have a non-zero chance of 'skipping' it if allowable.
To decide if we can skip a number we need to know x
the total left to be reached, k
the number of elements we still have to use, and y
the current candidate value. The smallest possible number that we could still pick would consist of $$y+(y+1)+(y+2)+...$$ added to the current value. In particular we require the above expression to be less than x
. The formula will be $$frac{k(k+1)}{2}+k(y+1)+y<x$$ Unfortunately we have to be a bit careful about rearranging this formula due to integer truncation in C, so I couldn't really find a way to golf it.
Nonetheless the logic is to have a chance to discard any y
that satisfies the above equation.
The code
p(_){printf("%d ",_);} // Define print(int)
f(n,x,y,i){ // Define f(n,...) as the function we want
x=n*n; // Set x to n^2
y=1; // Set y to 1
for(i=0;++i<n;){ // n-1 times do...
while(rand()&& // While rand() is non-zero [very very likely] AND
(n-i)* // (n-i) is the 'k' in the formula
(n-i+1)/2+ // This first half takes care of the increment
(n-i)*(y+1) // This second half takes care of the y+1 starting point
+y<x) // The +y takes care of the current value of y
y++; // If rand() returned non-zero and we can skip y, do so
p(y); // Print y
x-=y++; // Subtract y from the total and increment it
}p(x);} // Print what's left over.
The trick I mentioned to better test the code involves replacing rand()&&
with rand()%2&&
so that there is a 50-50 chance that any given y is skipped, rather than a 1 in RAND_MAX
chance that any given y is used.
edited yesterday
answered 2 days ago
LambdaBeta
2,079418
2,079418
I would love it if someone checked my math for consistency. I also wonder if this type of solution could make the uniform random speed challenge simple. The formula places an upper and lower bound on the answer, does a uniform random number in that range result in uniform random results? I don't see why not - but I haven't done much combinatorics in awhile.
– LambdaBeta
2 days ago
Suggestp(y),x-=y++)while(rand()&&(i-n)*((~n+i)/2+~y)+y<x)y++;
instead of){while(rand()&&(n-i)*(n-i+1)/2+(n-i)*(y+1)+y<x)y++;p(y);x-=y++;}
– ceilingcat
2 days ago
@ceilingcat I love these little improvements you find. I always get so focussed on the overall algorithm I forget to optimize for implementation (I basically go autopilot golfing mode once I have a non-golfed source that works - so I miss a lot of savings)
– LambdaBeta
yesterday
Hey, it's not just you who has those syntax-golfs. I find little improvements in a lot of C/C++ answers like that (except not in yours, @ceilingcat usually snaps those up).
– Zacharý
yesterday
Yeah, I've noticed that you two are probably the most active C/C++ putters (can we use putting to extend the golf analogy to the last few strokes? Why not!). It always impresses me that you can even understand the golfed code well enough to improve it.
– LambdaBeta
yesterday
add a comment |
I would love it if someone checked my math for consistency. I also wonder if this type of solution could make the uniform random speed challenge simple. The formula places an upper and lower bound on the answer, does a uniform random number in that range result in uniform random results? I don't see why not - but I haven't done much combinatorics in awhile.
– LambdaBeta
2 days ago
Suggestp(y),x-=y++)while(rand()&&(i-n)*((~n+i)/2+~y)+y<x)y++;
instead of){while(rand()&&(n-i)*(n-i+1)/2+(n-i)*(y+1)+y<x)y++;p(y);x-=y++;}
– ceilingcat
2 days ago
@ceilingcat I love these little improvements you find. I always get so focussed on the overall algorithm I forget to optimize for implementation (I basically go autopilot golfing mode once I have a non-golfed source that works - so I miss a lot of savings)
– LambdaBeta
yesterday
Hey, it's not just you who has those syntax-golfs. I find little improvements in a lot of C/C++ answers like that (except not in yours, @ceilingcat usually snaps those up).
– Zacharý
yesterday
Yeah, I've noticed that you two are probably the most active C/C++ putters (can we use putting to extend the golf analogy to the last few strokes? Why not!). It always impresses me that you can even understand the golfed code well enough to improve it.
– LambdaBeta
yesterday
I would love it if someone checked my math for consistency. I also wonder if this type of solution could make the uniform random speed challenge simple. The formula places an upper and lower bound on the answer, does a uniform random number in that range result in uniform random results? I don't see why not - but I haven't done much combinatorics in awhile.
– LambdaBeta
2 days ago
I would love it if someone checked my math for consistency. I also wonder if this type of solution could make the uniform random speed challenge simple. The formula places an upper and lower bound on the answer, does a uniform random number in that range result in uniform random results? I don't see why not - but I haven't done much combinatorics in awhile.
– LambdaBeta
2 days ago
Suggest
p(y),x-=y++)while(rand()&&(i-n)*((~n+i)/2+~y)+y<x)y++;
instead of ){while(rand()&&(n-i)*(n-i+1)/2+(n-i)*(y+1)+y<x)y++;p(y);x-=y++;}
– ceilingcat
2 days ago
Suggest
p(y),x-=y++)while(rand()&&(i-n)*((~n+i)/2+~y)+y<x)y++;
instead of ){while(rand()&&(n-i)*(n-i+1)/2+(n-i)*(y+1)+y<x)y++;p(y);x-=y++;}
– ceilingcat
2 days ago
@ceilingcat I love these little improvements you find. I always get so focussed on the overall algorithm I forget to optimize for implementation (I basically go autopilot golfing mode once I have a non-golfed source that works - so I miss a lot of savings)
– LambdaBeta
yesterday
@ceilingcat I love these little improvements you find. I always get so focussed on the overall algorithm I forget to optimize for implementation (I basically go autopilot golfing mode once I have a non-golfed source that works - so I miss a lot of savings)
– LambdaBeta
yesterday
Hey, it's not just you who has those syntax-golfs. I find little improvements in a lot of C/C++ answers like that (except not in yours, @ceilingcat usually snaps those up).
– Zacharý
yesterday
Hey, it's not just you who has those syntax-golfs. I find little improvements in a lot of C/C++ answers like that (except not in yours, @ceilingcat usually snaps those up).
– Zacharý
yesterday
Yeah, I've noticed that you two are probably the most active C/C++ putters (can we use putting to extend the golf analogy to the last few strokes? Why not!). It always impresses me that you can even understand the golfed code well enough to improve it.
– LambdaBeta
yesterday
Yeah, I've noticed that you two are probably the most active C/C++ putters (can we use putting to extend the golf analogy to the last few strokes? Why not!). It always impresses me that you can even understand the golfed code well enough to improve it.
– LambdaBeta
yesterday
add a comment |
up vote
0
down vote
Clean, 172 bytes
import StdEnv,Math.Random,Data.List
? ::!Int->Int
?_=code{
ccall time "I:I"
}
$n=find(s=length s==n&&sum s==n^2)(subsequences(nub(map(inc oe=e rem n^2)(genRandInt(?0)))))
Try it online!
add a comment |
up vote
0
down vote
Clean, 172 bytes
import StdEnv,Math.Random,Data.List
? ::!Int->Int
?_=code{
ccall time "I:I"
}
$n=find(s=length s==n&&sum s==n^2)(subsequences(nub(map(inc oe=e rem n^2)(genRandInt(?0)))))
Try it online!
add a comment |
up vote
0
down vote
up vote
0
down vote
Clean, 172 bytes
import StdEnv,Math.Random,Data.List
? ::!Int->Int
?_=code{
ccall time "I:I"
}
$n=find(s=length s==n&&sum s==n^2)(subsequences(nub(map(inc oe=e rem n^2)(genRandInt(?0)))))
Try it online!
Clean, 172 bytes
import StdEnv,Math.Random,Data.List
? ::!Int->Int
?_=code{
ccall time "I:I"
}
$n=find(s=length s==n&&sum s==n^2)(subsequences(nub(map(inc oe=e rem n^2)(genRandInt(?0)))))
Try it online!
edited yesterday
answered yesterday
Οurous
5,80311031
5,80311031
add a comment |
add a comment |
up vote
0
down vote
Python (2 or 3), 84 bytes
from random import*;l=lambda n,s=:(sum(s)==n*n)*s or l(n,sample(range(1,n*n+1),n))
Try it online!
Hits max recursion depth at around l(5)
add a comment |
up vote
0
down vote
Python (2 or 3), 84 bytes
from random import*;l=lambda n,s=:(sum(s)==n*n)*s or l(n,sample(range(1,n*n+1),n))
Try it online!
Hits max recursion depth at around l(5)
add a comment |
up vote
0
down vote
up vote
0
down vote
Python (2 or 3), 84 bytes
from random import*;l=lambda n,s=:(sum(s)==n*n)*s or l(n,sample(range(1,n*n+1),n))
Try it online!
Hits max recursion depth at around l(5)
Python (2 or 3), 84 bytes
from random import*;l=lambda n,s=:(sum(s)==n*n)*s or l(n,sample(range(1,n*n+1),n))
Try it online!
Hits max recursion depth at around l(5)
answered yesterday
ArBo
1
1
add a comment |
add a comment |
up vote
0
down vote
Mathematica 40 bytes
RandomChoice[IntegerPartitions[2^n, {n}]]
add a comment |
up vote
0
down vote
Mathematica 40 bytes
RandomChoice[IntegerPartitions[2^n, {n}]]
add a comment |
up vote
0
down vote
up vote
0
down vote
Mathematica 40 bytes
RandomChoice[IntegerPartitions[2^n, {n}]]
Mathematica 40 bytes
RandomChoice[IntegerPartitions[2^n, {n}]]
answered 21 hours ago
David G. Stork
1857
1857
add a comment |
add a comment |
up vote
0
down vote
JavaScript, 291 bytes
Bonus Task: Is there a formula to calculate the number of valid permutations for a given
n
?
Solves for n=3
f=(n=3,x=Math.pow(n,2),p=,r=,z=RegExp(`^[1-${x}]+$`))=>{for(c=n;c;c--){p.unshift(c)};p[p.length-1]=x-n;let i=+p.join``,m= +p.reverse().join``,s=i+'',l=s.length;for(;i<=m;i++){let c=[...''+i];if(new Set(c).size==l&&c.every(_=>z.test(_))&&eval(c.join`+`)==x){r.push([...''+i].map(Number))}}return r}
let r=f();
console.log(JSON.stringify(r,null,2),r.length);
Try it online!
Formula for number of valid permutations for n=3
using addition, comparison and exclusion
- Find the minimum integer which sums to
n=3^2=9
, in this case126
- Convert
n=3
to array[1,2,3]
and integer123
- To derive
126
fromn=3
programmatically, subtract last digit of123
fromn=3^2=9
9=3=6
,[1,2,3]
->[1,2,(9-3)]
- >[1,2,6]
->126
- The last valid lexicographic permutation of
n=3
will be621
;126
with digits in reverse order - Increment
126
to and including621
, match numbers where the.size
as aSet
is equal to.length
of string'123'
and every index of current number as a string in an array teststrue
forRegExp
^[1-(n^2-n=6)]$
and the number of the digits is equal ton^2
, push matches to an array in lexicographic order - Convert matched integers as string to integers in array
- The number of valid permutations for the given
n
,3
, is18
add a comment |
up vote
0
down vote
JavaScript, 291 bytes
Bonus Task: Is there a formula to calculate the number of valid permutations for a given
n
?
Solves for n=3
f=(n=3,x=Math.pow(n,2),p=,r=,z=RegExp(`^[1-${x}]+$`))=>{for(c=n;c;c--){p.unshift(c)};p[p.length-1]=x-n;let i=+p.join``,m= +p.reverse().join``,s=i+'',l=s.length;for(;i<=m;i++){let c=[...''+i];if(new Set(c).size==l&&c.every(_=>z.test(_))&&eval(c.join`+`)==x){r.push([...''+i].map(Number))}}return r}
let r=f();
console.log(JSON.stringify(r,null,2),r.length);
Try it online!
Formula for number of valid permutations for n=3
using addition, comparison and exclusion
- Find the minimum integer which sums to
n=3^2=9
, in this case126
- Convert
n=3
to array[1,2,3]
and integer123
- To derive
126
fromn=3
programmatically, subtract last digit of123
fromn=3^2=9
9=3=6
,[1,2,3]
->[1,2,(9-3)]
- >[1,2,6]
->126
- The last valid lexicographic permutation of
n=3
will be621
;126
with digits in reverse order - Increment
126
to and including621
, match numbers where the.size
as aSet
is equal to.length
of string'123'
and every index of current number as a string in an array teststrue
forRegExp
^[1-(n^2-n=6)]$
and the number of the digits is equal ton^2
, push matches to an array in lexicographic order - Convert matched integers as string to integers in array
- The number of valid permutations for the given
n
,3
, is18
add a comment |
up vote
0
down vote
up vote
0
down vote
JavaScript, 291 bytes
Bonus Task: Is there a formula to calculate the number of valid permutations for a given
n
?
Solves for n=3
f=(n=3,x=Math.pow(n,2),p=,r=,z=RegExp(`^[1-${x}]+$`))=>{for(c=n;c;c--){p.unshift(c)};p[p.length-1]=x-n;let i=+p.join``,m= +p.reverse().join``,s=i+'',l=s.length;for(;i<=m;i++){let c=[...''+i];if(new Set(c).size==l&&c.every(_=>z.test(_))&&eval(c.join`+`)==x){r.push([...''+i].map(Number))}}return r}
let r=f();
console.log(JSON.stringify(r,null,2),r.length);
Try it online!
Formula for number of valid permutations for n=3
using addition, comparison and exclusion
- Find the minimum integer which sums to
n=3^2=9
, in this case126
- Convert
n=3
to array[1,2,3]
and integer123
- To derive
126
fromn=3
programmatically, subtract last digit of123
fromn=3^2=9
9=3=6
,[1,2,3]
->[1,2,(9-3)]
- >[1,2,6]
->126
- The last valid lexicographic permutation of
n=3
will be621
;126
with digits in reverse order - Increment
126
to and including621
, match numbers where the.size
as aSet
is equal to.length
of string'123'
and every index of current number as a string in an array teststrue
forRegExp
^[1-(n^2-n=6)]$
and the number of the digits is equal ton^2
, push matches to an array in lexicographic order - Convert matched integers as string to integers in array
- The number of valid permutations for the given
n
,3
, is18
JavaScript, 291 bytes
Bonus Task: Is there a formula to calculate the number of valid permutations for a given
n
?
Solves for n=3
f=(n=3,x=Math.pow(n,2),p=,r=,z=RegExp(`^[1-${x}]+$`))=>{for(c=n;c;c--){p.unshift(c)};p[p.length-1]=x-n;let i=+p.join``,m= +p.reverse().join``,s=i+'',l=s.length;for(;i<=m;i++){let c=[...''+i];if(new Set(c).size==l&&c.every(_=>z.test(_))&&eval(c.join`+`)==x){r.push([...''+i].map(Number))}}return r}
let r=f();
console.log(JSON.stringify(r,null,2),r.length);
Try it online!
Formula for number of valid permutations for n=3
using addition, comparison and exclusion
- Find the minimum integer which sums to
n=3^2=9
, in this case126
- Convert
n=3
to array[1,2,3]
and integer123
- To derive
126
fromn=3
programmatically, subtract last digit of123
fromn=3^2=9
9=3=6
,[1,2,3]
->[1,2,(9-3)]
- >[1,2,6]
->126
- The last valid lexicographic permutation of
n=3
will be621
;126
with digits in reverse order - Increment
126
to and including621
, match numbers where the.size
as aSet
is equal to.length
of string'123'
and every index of current number as a string in an array teststrue
forRegExp
^[1-(n^2-n=6)]$
and the number of the digits is equal ton^2
, push matches to an array in lexicographic order - Convert matched integers as string to integers in array
- The number of valid permutations for the given
n
,3
, is18
f=(n=3,x=Math.pow(n,2),p=,r=,z=RegExp(`^[1-${x}]+$`))=>{for(c=n;c;c--){p.unshift(c)};p[p.length-1]=x-n;let i=+p.join``,m= +p.reverse().join``,s=i+'',l=s.length;for(;i<=m;i++){let c=[...''+i];if(new Set(c).size==l&&c.every(_=>z.test(_))&&eval(c.join`+`)==x){r.push([...''+i].map(Number))}}return r}
let r=f();
console.log(JSON.stringify(r,null,2),r.length);
f=(n=3,x=Math.pow(n,2),p=,r=,z=RegExp(`^[1-${x}]+$`))=>{for(c=n;c;c--){p.unshift(c)};p[p.length-1]=x-n;let i=+p.join``,m= +p.reverse().join``,s=i+'',l=s.length;for(;i<=m;i++){let c=[...''+i];if(new Set(c).size==l&&c.every(_=>z.test(_))&&eval(c.join`+`)==x){r.push([...''+i].map(Number))}}return r}
let r=f();
console.log(JSON.stringify(r,null,2),r.length);
edited 2 hours ago
answered 2 hours ago
guest271314
271211
271211
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodegolf.stackexchange.com%2fquestions%2f176284%2farbitrary-randomness%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
2
related, but quite different
– Giuseppe
2 days ago
1
(p/s: If you have a fast algorithm but takes more bytes, consider waiting until the speed edition (currently in sandbox) to post it.)
– user202729
2 days ago
1
@EriktheOutgolfer Although there are (much) better ways than generating all sets and pick a random one, they're much harder to implement and likely longer. Keep them for the speed edition.
– user202729
2 days ago
2
The number of sets is OEIS A107379.
– nwellnhof
2 days ago
1
It's both. See the comment "Also the number of partitions of n^2 into n distinct parts."
– nwellnhof
2 days ago