Randomness arbitraire

26

L'aléatoire est amusant. Les défis sans intérêt sont amusants.

Écrivez une fonction qui, étant donnée une entrée entière n, produira un ensemble (non ordonné, unique) d' nentiers exactement aléatoires entre 1et n^2(inclus) de telle sorte que la somme de tous les entiers soit égale à n^2.

L'aléatoire ne doit pas être uniforme, à condition que chaque ensemble valide ait une chance non nulle de se produire.

La réponse la plus courte en octets (pour chaque langue) l'emporte.

Exemples

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

Tâche bonus: existe-t-il une formule pour calculer le nombre de permutations valides pour une donnée n?

Skidsdev
la source
2
liés , mais assez différents
Giuseppe
1
(p / s: si vous avez un algorithme rapide mais prend plus d'octets, pensez à attendre que l'édition de vitesse (actuellement dans le bac à sable) pour le publier.)
user202729
1
@EriktheOutgolfer Bien qu'il existe (bien) de meilleures façons que de générer tous les ensembles et d'en choisir un au hasard, ils sont beaucoup plus difficiles à implémenter et probablement plus longs. Conservez-les pour l'édition rapide.
user202729
2
Le nombre d'ensembles est OEIS A107379 .
nwellnhof
1
C'est les deux. Voir le commentaire "Aussi le nombre de partitions de n ^ 2 en n parties distinctes."
nwellnhof

Réponses:

9

Brachylog (v2), 15 octets (aléatoire) ou 13 octets (toutes les possibilités)

au hasard

~lℕ₁ᵐA+√?∧A≜₁ᵐ≠

Essayez-le en ligne!

Soumission de fonction (vu dans TIO avec un wrapper en faisant un programme complet).

Explication

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

Toutes les possibilités

~lℕ₁ᵐ<₁.+√?∧≜

Essayez-le en ligne!

Soumission de fonction, qui génère toutes les sorties possibles.

Explication

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

Je suis assez surpris que cela ∧≜fonctionne (vous devriez normalement écrire ∧~≜pour forcer la sortie plutôt que l'entrée), mais il se trouve que cela a une hypothèse d'entrée = sortie, donc peu importe le chemin autour de vous exécuter.

Tâche bonus

Afin d'avoir un aperçu de la séquence du nombre de possibilités, j'ai créé un wrapper TIO différent qui exécute le programme sur des entiers successifs pour donner la séquence des nombres de sortie:

1,1,3,9,30,110,436,1801,7657,33401

Un voyage à OEIS découvre qu'il s'agit déjà d'une séquence connue, A107379 , décrite à peu près comme dans la question (apparemment, vous obtenez la même séquence si vous la limitez à des nombres impairs). La page répertorie plusieurs formules pour la séquence (bien qu'aucune ne soit particulièrement simple; la seconde ressemble à une formule directe pour la valeur mais je ne comprends pas la notation).

ais523
la source
La deuxième formule est "le coefficient d' x^(n*(n-1)/2)expansion de la série de Product_{k=1..n} 1/(1 - x^k)" (pas direct du tout, malheureusement)
user202729
Le fait de placer la contrainte «tous différents» avant l'étape d'étiquetage aléatoire (par exemple A≠≜₁ᵐ) accélère en moyenne le temps d'exécution.
Fatalize
Je ne comprends pas pourquoi vous en avez fait un wiki communautaire. C'est un moyen archaïque d'avoir des messages modifiables avant qu'il ne soit possible de les modifier.
pipe
7

05AB1E , 11 octets

nÅœʒDÙQ}sùΩ

Essayez-le en ligne ou vérifiez tous les cas de test .

Explication:

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)
Kevin Cruijssen
la source
5

R , 68, 75 48 octets (aléatoires) et 70 octets (déterministes)

@ Méthode d'échantillonnage par rejet de Giuseppe:

function(n){while(sum(F)!=n^2)F=sample(n^2,n);F}

Essayez-le en ligne!

Golf original:

function(n,m=combn(1:n^2,n))m[,sample(which(colSums(m)==n^2)*!!1:2,1)]

Essayez-le en ligne!

L' *!!1:2activité consiste à éviter la façon étrange d' sampleagir lorsque le premier argument a une longueur de 1.

ngm
la source
@Giuseppe "fixed" :-)
ngm
très agréable. utiliser pdirectement comme index au lieu de le calculer et le réutiliser devrait économiser quelques octets.
Giuseppe
1
J'en ai function(n){while(sum(F)!=n^2)F=sample(n^2,n);F}pour 48 aussi ...
Giuseppe
1
@ J.Doe pour éviter le problème lors de l'appel de quelque chose comme sample(2,1)ce qui se passe avec n=2. Garantit donc repsimplement que cela ne se produira jamais. Il pourrait y avoir une meilleure façon mais c'était rapide et j'étais en colère sample.
ngm
1
Vous pouvez enregistrer un octet avec x*!!1:2plus rep(x,2)si votre méta-question obtient un non.
J.Doe
4

Gelée , 9 octets

²œcS=¥Ƈ²X

Essayez-le en ligne!

Générez toutes les n-combinaisons de la liste [1..n²], filtrez pour garder celles avec la somme n², puis choisissez-en une au hasard.

user202729
la source
4

Java 10, 250 242 222 octets

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 octets grâce à @nwellnhof .

Attention, Java passe à travers .. C'est "seulement" cinq fois plus longtemps que les quatre autres réponses combinées, donc pas trop mal je suppose ... rofl.
Il ne fonctionne n=1par n=25(combiné) en moins de 2 secondes, alors je vais probablement poster une version modifiée à la version de la vitesse de ce défi (qui est actuellement encore dans le bac à sable) ainsi.

Essayez-le en ligne.

Explication:

En pseudo-code, nous faisons ce qui suit:

1) Générer un tableau de taille n+1contenant: 0, ncarré, et n-1nombre d'entiers aléatoires dans l'intervalle [0, n squared)
2) Trier ce tableau
3) créer un second tableau de taille ncontenant les différences avant des paires
Ces trois premières étapes nous donneront un tableau contenant naléatoire entiers (dans la plage de [0, n squared)somme au ncarré.
4a) Si toutes les valeurs aléatoires ne sont pas uniques, ou si l'une d'elles est 0: réessayez à partir de l'étape 1
4b) Sinon: renvoyez ce tableau de différences comme résultat

Quant au code réel:

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)
Kevin Cruijssen
la source
1
n=25en moins de 2 secondes c'est impressionnant! Je vais devoir lire l'explication et voir comment ça se passe. Est-ce toujours une méthode bruteforce?
Skidsdev
Est-ce uniforme? -
user202729
@ user202729 Même si je ne sais pas trop comment le prouver, je pense que oui . Le module intégré Java est uniforme, et il l'utilise pour obtenir des valeurs aléatoires dans la plage en [0, n squared)premier, puis calcule les différences entre ces valeurs aléatoires triées (y compris les valeurs de début 0et de fin n squared. Je suis donc presque sûr que ces différences sont également uniformes. Mais encore une fois , Je ne sais pas trop comment le prouver. L'uniformité dans le hasard n'est pas vraiment mon expertise tbh
Kevin Cruijssen
3
Vous n'avez jamais lu dans le tableau des différences dou est-ce que je manque quelque chose?
nwellnhof
1
Je suis plutôt satisfait de ma solution à 127 octets : D
Olivier Grégoire
4

Perl 6 , 41 octets

{first *.sum==$_²,(1..$_²).pick($_)xx*}

Essayez-le en ligne!

  • (1 .. $_²) est la plage de nombres de 1 au carré du nombre d'entrée
  • .pick($_) choisit au hasard un sous-ensemble distinct de cette plage
  • xx * reproduit à l'infini l'expression précédente
  • first *.sum == $_² sélectionne le premier de ces ensembles de nombres qui correspond au carré du nombre d'entrée
Sean
la source
40 octets
Jo King
2

Pyth, 13 12 octets

Ofq*QQsT.cS*

Essayez-le en ligne ici . Notez que l'interpréteur en ligne s'exécute dans une erreur MemoryError pour les entrées supérieures à 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

Modifier: enregistré un octet en adoptant une approche alternative. La version précédente: Of&qQlT{IT./*

Sok
la source
2

Python 3 , 136 134 127 127 121 114 octets

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)

Essayez-le en ligne!

Un commentateur m'a corrigé, et cela atteint maintenant la profondeur maximale de récursivité à f (5) au lieu de f (1). Beaucoup plus près d'être une vraie réponse concurrente.

Je l'ai vu faire f (5) une fois , et je travaille à essayer de l'implémenter avec shuffle.

J'ai essayé de créer des expressions lambda pour s=..., mais cela n'a pas aidé sur les octets. Peut-être que quelqu'un d'autre peut faire quelque chose avec ça: s=(lambda n:{randint(1,n*n)for _ in range(n)})(n)

Merci à Kevin d'avoir rasé encore 7 octets.

Gigaflop
la source
1
Donc, cela utilise la récursivité pour "régénérer" l'ensemble si celui généré n'est pas valide? Certainement quelque chose de mal avec votre code s'il atteint la profondeur de récursivité à f(1), le seul tableau possible qui devrait être générable à n=1est [1]également il y a beaucoup d'espace blanc à supprimer ici. Rappelez-vous que c'est un défi de code-golf, donc l'objectif est d'atteindre le plus petit nombre de sous
nombres
1
range(1,n)-> range(n)Je crois que devrait résoudre le bug.
Jonathan Allan
1
Cela devrait corriger votre bogue et supprimer également les espaces superflus. J'imagine qu'il y a beaucoup plus de place pour le golf aussi
Skidsdev
1
Bien que la récursivité s'aggrave légèrement de 5 à 4, vous pouvez combiner vos deux instructions de retour comme ceci: return len(s)==n and sum(s)==n*n and s or f(n)( Essayez-le en ligne 114 octets ).
Kevin Cruijssen
1
Vous pouvez tout avoir sur une seule ligne. 111 octets
Jo King
2

APL (Dyalog Unicode) , 20 octets SBCS

Préfixe anonyme lambda.

{s=+/c←⍵?s←⍵*2:c⋄∇⍵}

Essayez-le en ligne!

{} "Dfn"; est l'argument

⍵*2 mettre l'argument au carré

s← assigner à s(pour s quare)

⍵? trouver ndes indices aléatoires de 1… ssans remplacement

c← assigner à c(pour c andidate)

+/ les résumer

s= comparer aux s

: si égal

  c retourner le candidat

 autre

  ∇⍵ recurse sur l'argument

Adam
la source
avez-vous vu mes 18 octets et ceux de H.PWiz ?
ngn
@ngn Non, clairement pas, mais j'ai vérifié qu'aucune solution APL n'a été publiée avant de publier. Pourquoi aucun d'entre vous?
Adám
eh bien, une fois que je l'ai joué au golf et que je l'ai montré au verger, il n'y a guère d'incitation à poster :)
ngn
@ngn Pour vous, non, mais pour moi il y en a.
Adám
1
certainement, et je pense que vous faites un excellent travail de vulgarisation apl ici. je m'assurais juste de savoir que des solutions plus courtes ont été trouvées et il vaut probablement mieux expliquer l'une d'entre elles (ou une variante) à la place
ngn
2

APL (Dyalog Classic) , 18 octets

(≢?≢×≢)⍣(0=+.-∘≢)⍳

Essayez-le en ligne!

les usages ⎕io←1

génère les nombres 1 2 ... n

(... )⍣(... )continuez d'appliquer la fonction à gauche jusqu'à ce que la fonction à droite renvoie true

longueur, c.-à-d. n

≢?≢×≢choisir ndes entiers distincts au hasard entre 1 et n2

+.-∘≢ soustraire la longueur de chaque nombre et somme

0= si la somme est 0, arrêtez la boucle, sinon essayez à nouveau

ngn
la source
1

MATL , 18 13 octets

`xGU:GZrtsGU-

Essayez-le en ligne!

`	# 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
Giuseppe
la source
Je n'essaierais pas cela en R - des caractères aléatoires ne produisent presque jamais un programme valide.
ngm
@ngm hahaha Je suppose qu'une explication s'impose.
Giuseppe
1

Japt, 12 octets

²õ àU ö@²¥Xx

Essayez-le

                 :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
Hirsute
la source
Selon un commentaire du PO, l'ordre des éléments dans la sortie n'est pas pertinent, donc ça àdevrait aller.
Kamil Drakari
Merci, @KamilDrakari. Mis à jour.
Shaggy
1

Java (JDK) , 127 octets

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

Essayez-le en ligne!

Boucle infinie jusqu'à ce qu'un ensemble avec les critères corresponde.

J'espère que vous avez le temps, car c'est très lent! Il ne peut même pas passer à 10 sans expiration.

Olivier Grégoire
la source
Vous pouvez jouer au golf 3 octets en changeant if(r.size()==n&s==0)pour if(r.size()+s==n).
Kevin Cruijssen
@KevinCruijssen J'y ai pensé aussi, mais non je ne peux pas parce que s pourrait être -1 et n pourrait être de taille () - 1.
Olivier Grégoire
Ah, attendez, vous continuez à ajouter des éléments à l'ensemble aussi longtemps que s>0la taille peut être supérieure à n. Ok, dans ce cas, cela ne fonctionne pas. nest une constante, mais malheureusement les deux set r.size()sont des variables qui peuvent être à la fois inférieures ou supérieures 0et nrespectivement.
Kevin Cruijssen
1

Lot, 182145 octets

@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%%

Explication: calcule la sélection minimale et maximale autorisée, étant donné que les nombres doivent être sélectionnés dans l'ordre décroissant, et choisit une valeur aléatoire dans la plage. Exemple pour une entrée de 4:

  • Nous commençons avec 16 à gauche. Nous ne pouvons pas en choisir 11 ou plus, car les 3 choix restants doivent s'ajouter à au moins 6. Nous devons également en choisir au moins 6, car si nous n'en choisissons que 5, les 3 choix restants ne peuvent s'ajouter qu'à 9, ce qui n'est pas assez pour 16. Nous choisissons une valeur aléatoire de 6 à 10, disons 6.
  • Il nous en reste 10. Nous ne pouvons pas en choisir 8 ou plus car les 2 choix restants doivent en ajouter au moins 3. En l'occurrence, nous ne pouvons pas en choisir 6 ou plus car nous en avons choisi 6 la dernière fois. Nous devons également choisir au moins 5, car si nous n'en sélectionnons que 4, les 2 autres choix ne peuvent s'ajouter qu'à 5, pour un grand total de 15. Nous choisissons une valeur aléatoire de 5 à 5, disons 5 (!).
  • Il nous en reste 5. Nous ne pouvons pas en choisir 5 ou plus car le choix restant doit en ajouter au moins 1, et aussi parce que nous en avons sélectionné 5 la dernière fois. Nous devons également choisir au moins 3, car si nous ne choisissons que 2, le choix restant ne peut être que 1, pour un grand total de 14. Nous choisissons une valeur aléatoire de 3 à 4, disons 4.
  • Il nous en reste 1. En fait, l'algorithme choisit une plage de 1 à 1, et nous choisissons 1 comme nombre final.
Neil
la source
1

JavaScript, 647 291 261 260 259 251 239 octets

Merci à @Veskah pour -10 octets dans la version originale et "Oh oui, vous sortez tous les ensembles alors que le défi demande d'en renvoyer un au hasard"

(n,g=m=n**2,r=[...Array(g||1)].map(_=>m--).sort(_=>.5-Math.random()).slice(-n),c=_=>eval(r.join`+`),i=_=>r.includes(_))=>[...{*0(){while(g>1&&c()!=g){for(z of r){y=c();r[m++%n]=y>g&&!(!(z-1)||i(z-1))?z-1:y<g&&!i(z+1)?z+1:z}}yield*r}}[0]()]

Essayez-le en ligne!

Créez un tableau d' n^2index basés sur 1, triez le tableau au hasard, découpez les néléments du tableau. Alors que la somme des éléments aléatoires n'est pas égale au n^2tableau de boucles d'éléments aléatoires; si la somme des éléments du tableau est supérieure à n^2et que l'élément actuel -1n'est pas égal à zéro ou que l'élément actuel -1n'est pas dans le tableau actuel, soustrayez 1; si la somme du tableau est inférieure à n^2et que l'élément actuel +1n'est pas dans le tableau, ajoutez 1à l'élément. Si la somme du tableau est égale à la n^2boucle de rupture, sortez le tableau.

guest271314
la source
1
637 octets en tirant z.join dans une variable, etk++
Veskah
@Veskah Les deux whileboucles pourraient probablement aussi être réduites au corps d'une seule fonction qui accepte des paramètres; et pourrait substituer des opérateurs conditionnels (ternaires) aux if..elseinstructions; entre autres parties du code qui pourraient très probablement être ajustées pour le golf; ieg, suppression des letinstructions.
guest271314
@Veskah 601 octets sans remplacer ternaire parif..else
guest271314
1
Oh ouais, vous sortez tous les sets alors que le défi demande qu'un aléatoire soit retourné (Voir les commentaires OP pour plus de détails)
Veskah
@Veskah Doit avoir mal interprété le défi et les exemples, ou était trop concentré sur la résolution de cette partie de la question " Tâche bonus: existe-t-il une formule pour calculer le nombre de permutations valides pour une donnée n?" . tester si l'algorithme est retourné régulièrement résultat attendu pour les n^2tableaux de sortie générés dans un seul appel à la fonction, et en considérant simultanément les similitudes avec cette question à N dimensions N ^ N tableau rempli de N .
guest271314
0

Japt , 20 octets

²õ ö¬oU íUõ+)Õæ@²¥Xx

Essayez-le en ligne!

Profite extrêmement fortement du caractère aléatoire "non uniforme", produit presque toujours les premiers nnombres impairs, ce qui arrive à additionner n^2. En théorie, il peut produire n'importe quel autre ensemble valide, même si je n'ai pu le confirmer que pour les petits n.

Explication:

²õ                      :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
Kamil Drakari
la source
0

C (gcc) , 128 125 octets

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

Essayez-le en ligne!

-3 octets grâce au plafond

REMARQUE: La probabilité est très très loin d'être uniforme. Voir l'explication de ce que je veux dire et un meilleur moyen de tester que cela fonctionne (en rendant la distribution plus proche de l'uniforme [mais toujours loin de là]).

Comment?

L'idée de base est de choisir uniquement des nombres croissants afin de ne pas se soucier des doublons. Chaque fois que nous choisissons un nombre, nous avons une chance non nulle de le «sauter» si cela est permis.

xky

y+(y+1)+(y+2)+...
x
k(k+1)2+k(y+1)+y<x

Néanmoins, la logique est d'avoir une chance de rejeter tout ce yqui satisfait l'équation ci-dessus.

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

L'astuce que j'ai mentionnée pour mieux tester le code consiste à le remplacer rand()&&par rand()%2&&afin qu'il y ait 50 à 50 chances que tout y donné soit ignoré, plutôt qu'un 1 de RAND_MAXchance que tout y soit utilisé.

LambdaBeta
la source
J'aimerais que quelqu'un vérifie la cohérence de mes mathématiques. Je me demande également si ce type de solution pourrait simplifier le défi de vitesse aléatoire uniforme. La formule place une limite supérieure et inférieure sur la réponse. Un nombre aléatoire uniforme dans cette plage donne-t-il des résultats aléatoires uniformes? Je ne vois pas pourquoi - mais je n'ai pas fait beaucoup de combinatoire depuis un moment.
LambdaBeta
Suggérer à la p(y),x-=y++)while(rand()&&(i-n)*((~n+i)/2+~y)+y<x)y++;place de){while(rand()&&(n-i)*(n-i+1)/2+(n-i)*(y+1)+y<x)y++;p(y);x-=y++;}
plafondcat
@ceilingcat J'adore ces petites améliorations que vous trouvez. Je suis toujours tellement concentré sur l'algorithme global que j'oublie d'optimiser pour la mise en œuvre (je passe essentiellement en mode golf pilote automatique une fois que j'ai une source non golfée qui fonctionne - donc je manque beaucoup d'économies)
LambdaBeta
Hé, ce n'est pas seulement vous qui avez ces golfs syntaxiques. Je trouve de petites améliorations dans beaucoup de réponses C / C ++ comme ça (sauf dans la vôtre, @ceilingcat les prend généralement).
Zacharý
Ouais, j'ai remarqué que vous êtes probablement les putters C / C ++ les plus actifs (pouvons-nous utiliser le put pour étendre l'analogie du golf aux derniers coups? Pourquoi pas!). Cela m'impressionne toujours que vous pouvez même comprendre assez bien le code du golf pour l'améliorer.
LambdaBeta
0

Nettoyer , 172 octets

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 o\e=e rem n^2)(genRandInt(?0)))))

Essayez-le en ligne!

Οurous
la source
0

Python (2 ou 3), 84 octets

from random import*;l=lambda n,s=[]:(sum(s)==n*n)*s or l(n,sample(range(1,n*n+1),n))

Essayez-le en ligne!

Atteint la profondeur de récursivité maximale à environ l (5)

ArBo
la source
0

Kotlin , 32 octets

{(1..it*it).shuffled().take(it)}

Essayez-le en ligne!

escargot_
la source
1
La somme doit être n ^ 2
12Me21
0

Mathematica 40 octets

RandomChoice[IntegerPartitions[n^2, {n}]]
David G. Stork
la source
1
Tout d'abord, c'est n ^ 2, pas 2 ^ n. Deuxièmement, votre programme doit être une fonction et aussi un golf. Essayez ceci RandomChoice@IntegerPartitions[#^2,{#}]&
J42161217
1
De plus, le résultat doit être (non ordonné, unique) mais cette fonction échoue dans les deux
J42161217
0

Wolfram Language (Mathematica) , 49 octets

(While[Tr[s=RandomSample[Range[#^2],#]]!=#^2];s)&

Essayez-le en ligne!

Version golfée par @ J42161217.


Wolfram Language (Mathematica) , 62 octets

Range[#-1,0,-1]+RandomChoice@IntegerPartitions[#*(#+1)/2,{#}]&

Essayez-le en ligne!

Comment ça marche

n2nn2(n2n)/2=(n2+n)/20n1n10 est ajouté à la place.


La réponse à la tâche bonus

Tâche bonus: existe-t-il une formule pour calculer le nombre de permutations valides pour une donnée n?

part(n,k)nk

part(n,k)=part(n1,k1)+part(nk,k)

part(n,1)=1n<kpart(n,k)=0

part(n2+n2,n)

qui est, dans Mathematica:

Length@IntegerPartitions[#*(#+1)/2,{#}]&

Essayez-le en ligne!

Bubbler
la source
Ceci est le code golf .. 49 octets(While[Tr[s=RandomSample[Range[#^2],#]]!=#^2];s)&
J42161217