Довільна випадковість


26

Випадковість - це весело. Проблеми без жодного сенсу - це задоволення.

Напишіть функцію, яка при заданому цілому введенні nвиведе набір (не упорядкований, унікальний) точно nвипадкових цілих чисел між 1та n^2(включно) таким, що сума всіх цілих чисел дорівнює n^2.

Випадковість не повинна бути рівномірною, за умови, що кожен дійсний набір має ненульовий шанс.

Найкоротша відповідь у байтах (на кожній мові) виграє.

Приклади

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

Бонусне завдання: Чи існує формула для обчислення кількості дійсних перестановок для даної n?


2
споріднене , але зовсім інше
Джузеппе

1
(p / s: Якщо у вас швидкий алгоритм, але ви зайняли більше байтів, подумайте, як дочекатися швидкого видання (зараз у пісочниці), щоб опублікувати його.)
user202729

1
@EriktheOutgolfer Хоча існують (набагато) кращі способи, ніж генерувати всі набори та вибирати випадковий, їх реалізувати набагато складніше та, ймовірно, довше. Тримайте їх для випуску швидкості.
користувач202729

2
Кількість комплектів - OEIS A107379 .
nwellnhof

1
Це обоє. Дивіться коментар "Також кількість розділів n ^ 2 на n різних частин."
nwellnhof

Відповіді:


9

Брахілог (v2), 15 байт (випадково) або 13 байт (усі можливості)

Випадкові

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

Спробуйте в Інтернеті!

Подання функції (переглядається в TIO із обгорткою, що перетворює її на повну програму).

Пояснення

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

Усі можливості

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

Спробуйте в Інтернеті!

Подання функції, яка генерує всі можливі результати.

Пояснення

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

Я досить здивований, що це ∧≜працює (як правило, вам доведеться писати ∧~≜для того, щоб примусити вихід, а не вхід), але виявляється, що має припущення введення = виведення, тому не має значення, в який бік ви запустити його.

Бонусне завдання

Для того, щоб отримати деяке уявлення про послідовність кількості можливостей, я створив іншу обгортку TIO, яка запускає програму на послідовних цілих числах, щоб дати послідовність підрахунків виводу:

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

Поїздка в OEIS виявляє, що це вже відома послідовність, A107379 , описана майже як у питанні (мабуть, ви отримуєте ту саму послідовність, якщо обмежите її непарними номерами). На сторінці перелічено декілька формул послідовності (хоча жодна не є особливо простою; друга виглядає як пряма формула значення, але я не розумію позначення).


Друга формула - "коефіцієнт x^(n*(n-1)/2)розширення ряду Product_{k=1..n} 1/(1 - x^k)" (зовсім не прямо, на жаль)
user202729

Поставлення обмеження "всі різні" перед етапом випадкової мітки (наприклад A≠≜₁ᵐ) робить час виконання в середньому набагато швидшим.
Фаталізувати

Я не розумію, чому ви зробили це вікі спільноти. Це архаїчний спосіб редагувати публікації, перш ніж можна було редагувати.
труба


7

05AB1E , 11 байт

nÅœʒDÙQ}sùΩ

Спробуйте в Інтернеті або перевірте всі тестові випадки .

Пояснення:

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)


5

R , 68, 75 48 байт (випадковий) та 70 байт (детермінований)

@ Метод вибірки відхилення Джузеппе:

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

Спробуйте в Інтернеті!

Оригінальний гольф:

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

Спробуйте в Інтернеті!

Діяльність *!!1:2полягає в тому, щоб уникнути випадкових sampleдій, коли перший аргумент має довжину 1.


@Giuseppe "виправлено" :-)
ngm

дуже хороша. використання pбезпосередньо як індексу замість його обчислення та повторне використання повинно зберегти деякі байти.
Джузеппе

1
У мене також function(n){while(sum(F)!=n^2)F=sample(n^2,n);F}48 років ...
Джузеппе

1
@ J.Doe, щоб уникнути проблеми під час виклику чогось подібного, sample(2,1)що відбувається з n=2. Тож repпросто гарантує, що цього ніколи не станеться. Можливо, буде кращий спосіб, але це було швидко, і я злий на нього sample.
ngm

1
Ви можете зберегти байт з x*!!1:2над, rep(x,2)якщо ваш мета-питання отримає "ні".
J.Doe


4

Java 10, 250 242 222 байти

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 байт завдяки @nwellnhof .

Слідкуйте за тим, що Java проникає .. Це "лише" в п’ять разів довше, ніж інші чотири відповіді разом, так що не дуже погано, я думаю ... rofl.
Він мчить n=1через n=25(комбінований) менш ніж за 2 секунди , хоча, так що я , ймовірно , опублікувати змінену версію до версії швидкості цього завдання (яка в даний час все ще знаходиться в пісочниці) , а також.

Спробуйте в Інтернеті.

Пояснення:

У псевдокоді ми робимо наступне:

1) Створення масиву розміру , n+1що містить: 0, nквадрат, а n-1кількість випадкових чисел в діапазоні від [0, n squared)
2) Сортування цього масиву
3) створити другий масив розміру , nщо містить вперед відмінність пар
Цього перші три крок дасть нам масив , що містить nвипадковий образ цілих чисел (в діапазоні, [0, n squared)який дорівнює nквадрату.
4а) Якщо не всі випадкові значення є унікальними, або будь-яке з них дорівнює 0: спробуйте ще раз із кроку 1
4b) Інакше: поверніть цей масив відмінностей у результаті

Що стосується фактичного коду:

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за 2 секунди вражає! Мені доведеться прочитати пояснення і подивитися, як це робиться. Це все-таки метод грубої сили?
Skidsdev

Він рівномірний? -
користувач202729

@ user202729 Хоча я не впевнений, як це довести, я думаю, що це так. Java вбудований є рівномірним, і він використовує це для отримання випадкових значень в діапазоні [0, n squared), а потім обчислює різниці між цими відсортованими випадковими значеннями (включаючи провідні 0та трейлінг n squared. Тому я впевнений, що ці відмінності однакові. Але знову ж , Я не впевнений, як це довести. Одноманітність у випадковості насправді не є моїм досвідом, тбх.
Кевін Круїйсен

3
Ви ніколи не читаєте з масиву відмінностей dчи я щось пропускаю?
nwellnhof


4

Perl 6 , 41 байт

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

Спробуйте в Інтернеті!

  • (1 .. $_²) - діапазон чисел від 1 до квадрата вхідного числа
  • .pick($_) випадковим чином вибирає окремий підмножина цього діапазону
  • xx * копіює попередній вираз нескінченно
  • first *.sum == $_² вибирає перший із тих наборів чисел, який підсумовує квадрату вхідного числа


2

Pyth, 13 12 байт

Ofq*QQsT.cS*

Спробуйте його онлайн тут . Зауважте, що онлайн-перекладач потрапляє в MemoryError для входів, що перевищують 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

Редагувати: збережений байт, використовуючи альтернативний підхід. Попередня версія: Of&qQlT{IT./*


2

Пітон 3 , 136 134 127 121 114 байт

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)

Спробуйте в Інтернеті!

Коментолог виправив мене, і це тепер потрапляє на максимальну глибину рекурсії при f (5) замість f (1). Набагато ближче до справжньої конкуруючої відповіді.

Я бачив, як це робилося f (5) один раз , і я працюю над тим, щоб намагатися реалізувати це за допомогою перетасовки.

Я спробував зробити кілька лямбда-виразів s=..., але це не допомогло в байтах. Можливо, хтось ще може щось із цим зробити: s=(lambda n:{randint(1,n*n)for _ in range(n)})(n)

Дякую Кевіну за гоління ще 7 байт.


1
Так що для цього використовується рекурсія для "відновлення" набору, якщо створений недійсний? Очевидно, що з вашим кодом щось не так, якщо він вражає глибину рекурсії на f(1), єдиний можливий масив, який повинен бути генеруватися, n=1- [1]також тут має бути видалено багато сторонніх пробілів. Пам'ятайте, що це проблема з кодовим гольфом, тому мета - досягти найнижчого числа рахунків
Skidsdev

1
range(1,n)-> range(n)Я вважаю, що помилка повинна вирішити.
Джонатан Аллан

1
Це має виправити вашу помилку, а також видалити сторонні пробіли. Я думаю, що для гольфу теж багато місця
Скідсдев

1
Хоча рекурсія дещо погіршується з 5 до 4, ви можете поєднати свої дві заяви повернення так: return len(s)==n and sum(s)==n*n and s or f(n)( Спробуйте в Інтернеті 114 байт ).
Kevin Cruijssen

1
Ви можете мати все це в одному рядку. 111 байт
Джо Кінг

2

APL (Dyalog Unicode) , 20 байт SBCS

Анонімний префікс лямбда.

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

Спробуйте в Інтернеті!

{} "Dfn"; є аргументом

⍵*2 квадратний аргумент

s← призначити s(для s quare)

⍵? знайти nвипадкові індекси від 1… sбез заміни

c← призначити c(для c andidate)

+/ підсумуйте їх

s= порівняти s

: якщо рівний

  c повернути кандидата

 ще

  ∇⍵ повторити аргумент


Ви бачили 18 байт мого та H.PWiz ?
ngn

@ngn Ні, явно ні, але я перевірив, що жодне рішення APL не було розміщено перед публікацією. Чому ніхто з вас‽
Adám

ну, як тільки я пограв у нього в гольф і показав його до саду, навряд чи є стимул для публікації :)
ngn

@ngn Для тебе ні, але для мене є.
Adám

1
Звичайно, і я думаю, ви робите велику роботу по популяризації apl тут. я просто переконався, що ви знаєте, що знайдені більш короткі рішення, і, мабуть, краще пояснити одне з них (або варіант) замість цього
ngn

2

APL (Dyalog Classic) , 18 байт

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

Спробуйте в Інтернеті!

використовує ⎕io←1

генерує числа 1 2 ... n

(... )⍣(... )продовжуйте застосовувати функцію зліва, поки функція праворуч не поверне справжнє значення

довжина, тобто n

≢?≢×≢вибирати випадковими nцілими числами від 1 до n2

+.-∘≢ відняти довжину від кожного числа і суму

0= якщо сума дорівнює 0, припиніть циклічно, інакше спробуйте ще раз


1

MATL , 18 13 байт

`xGU:GZrtsGU-

Спробуйте в Інтернеті!

`	# 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

Я б не намагався цього робити в R - випадкові символи майже ніколи не виробляють дійсну програму.
ngm

@ngm hahaha Я вважаю, що пояснення в порядку.
Джузеппе

1

Japt, 12 байт

²õ àU ö@²¥Xx

Спробуй це

                 :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

Відповідно до зауваження, зробленого ОП, порядок елементів у висновку не має значення, тому àмає бути добре.
Каміль Дракарі

Дякую, @KamilDrakari. Оновлено.
Кудлатий

1

Java (JDK) , 127 байт

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

Спробуйте в Інтернеті!

Нескінченний цикл, поки набір з критеріями не збігається.

Я сподіваюся, що у вас є час, тому що це дуже sloooooow! Він навіть не може перейти до 10 без вичерпання часу.


Ви можете пограти в 3 байти, змінивши if(r.size()==n&s==0)на if(r.size()+s==n).
Кевін Кройсейсен

@KevinCruijssen Я теж думав про це, але ні, я не можу, тому що s може бути -1 і n може бути розміром () - 1.
Олів'є Грегоар

Аж зачекайте, ви продовжуєте додавати елементи до набору s>0, поки розмір може бути більшим, ніж n. Гаразд, у цьому випадку це справді не працює. nє константою, але, на жаль, і те, sі інше r.size()є змінними, які можуть бути як нижче, так і вище 0і nвідповідно.
Кевін Кройсейсен

1

Пакетна, 182 145 байт

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

Пояснення: обчислює мінімальний і максимально допустимий вибір, враховуючи, що числа слід вибирати у порядку зменшення, і вибирає випадкове значення в межах діапазону. Приклад для введення 4:

  • Починаємо з 16 зліва. Ми не можемо вибрати 11 або більше, тому що решту 3 вибору потрібно додати щонайменше 6. Нам також потрібно вибрати щонайменше 6, тому що якщо ми виберемо лише 5, решту 3 вибору можна додати лише до 9, що не є достатньо для 16. Вибираємо випадкове значення від 6 до 10, скажімо, 6.
  • У нас залишилося 10. Ми не можемо вибрати 8 або більше, тому що решту 2 вибору потрібно додати принаймні 3. Як це трапляється, ми не можемо вибрати 6 чи більше, тому що ми вибрали 6 в останній раз. Нам також потрібно вибрати щонайменше 5, бо якщо ми виберемо лише 4, решту 2 вибору можна додати лише до 5, за загальну суму 15. Ми вибираємо випадкове значення від 5 до 5, скажімо, 5 (!).
  • У нас залишилось 5. Ми не можемо вибрати 5 чи більше, тому що залишився вибір повинен бути щонайменше 1, а також тому, що ми вибрали 5 в останній раз. Нам також потрібно вибрати щонайменше 3, тому що якщо ми виберемо лише 2, решта вибору може бути лише 1, за загальну суму 14. Ми обираємо випадкове значення від 3 до 4, скажімо 4.
  • У нас залишилося 1. Як виявляється, алгоритм вибирає діапазон від 1 до 1, а ми вибираємо 1 як кінцеве число.

1

JavaScript, 647 291 261 260 259 251 239 байт

Завдяки @Veskah для -10 байт у оригінальній версії та "О так, ви виводите всі набори, тоді як виклик вимагає повернення випадкового"

(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]()]

Спробуйте в Інтернеті!

Створіть масив з n^2індексів на основі 1, сортуйте масив випадковим чином, відріжте nелементи з масиву. Тоді як сума випадкових елементів не дорівнює n^2масиву циклів випадкових елементів; якщо сума елементів масиву більша за n^2та поточний елемент -1не дорівнює нулю або поточний елемент -1не знаходиться в поточному масиві, віднімайте 1; якщо сума масиву менша, n^2а поточний елемент +1відсутній у масиві, додайте 1до елемента. Якщо сума масиву дорівнює n^2циклу розриву, виведіть масив.


1
637 байт , потягнувши z.join в змінну, іk++
Веска

@Veskah Дві whileпетлі, ймовірно, також можуть бути зведені до тіла однієї функції, яка приймає параметри; і може замінити умовні оператори (потрійні) для if..elseзаяв; серед інших частин коду, які більш ніж ймовірно можуть бути скориговані для гольфу; ieg, видалення letтверджень.
гість271314

@Veskah 601 байт, не замінюючи if..else
тернар

1
О так, ви виводите всі набори, тоді як виклик вимагає повернення випадкового (детальніше див. Коментарі до ОП)
Веська

@Veskah Потрібно неправильно трактувати виклик та приклади, або було занадто зосереджено на вирішенні цієї частини питання " Бонусне завдання: чи існує формула для обчислення кількості дійсних перестановок для даної n?" . тестування , якщо алгоритм послідовно повернене очікуваний результат для n^2виведення масивів , що генеруються в одному виконанні функції, і одночасно з урахуванням подібності на це питання N-мірний N ^ N масив заповнений N .
гість271314

0

Japt , 20 байт

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

Спробуйте в Інтернеті!

Надзвичайно сильно користується "неоднорідною" випадковістю, майже завжди виводить перші nнепарні числа, за якими трапляється сума n^2. Теоретично він може вивести будь-який інший дійсний набір, хоча я мав змогу підтвердити це лише для малих n.

Пояснення:

²õ                      :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


0

C (gcc) , 128 125 байт

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

Спробуйте в Інтернеті!

-3 байти завдяки стельовій коті

ПРИМІТКА: Ймовірність дуже далеко не однакова. Дивіться пояснення того, що я маю на увазі, і кращий засіб перевірити, чи працює він (зробивши розподіл ближчим до рівномірного [але все ще далеко від нього]).

Як?

Основна ідея полягає у виборі лише збільшення кількості, щоб не турбуватися про дублікати. Щоразу, коли ми вибираємо число, у нас є ненульовий шанс "пропустити" його, якщо це можливо.

xky

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

Тим не менш, логіка полягає в тому, щоб мати шанс відкинути будь-яке, yщо задовольняє вищевказаному рівнянню.

Кодекс

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.

Трюк, який я згадав для кращого тестування коду, передбачає заміну rand()&&на rand()%2&&так, що існує 50-50 шансів, що будь-яке задане y буде пропущено, а не 1 в RAND_MAXшансі, що використовується будь-який даний y.


Мені б подобалося, якби хтось перевіряв мою математику на послідовність. Мені також цікаво, чи може подібний спосіб рішення спростити єдиний виклик випадкової швидкості. Формула ставить верхню і нижню межу відповіді, чи однорідне випадкове число в цьому діапазоні призводить до однакових випадкових результатів? Я не бачу, чому б ні - але я за останній час не робив багато комбінаторики.
LambdaBeta

Запропонувати p(y),x-=y++)while(rand()&&(i-n)*((~n+i)/2+~y)+y<x)y++;замість){while(rand()&&(n-i)*(n-i+1)/2+(n-i)*(y+1)+y<x)y++;p(y);x-=y++;}
roofcat

@ceilingcat Я люблю ці маленькі покращення, які ви знайдете. Я завжди настільки зосереджений на загальному алгоритмі, я забуваю оптимізувати його для впровадження (я в основному переходжу в режим гольфу на автопілоті, як тільки у мене є джерело без гольфу, яке працює - тому я сумую за
великими

Гей, не тільки ти маєш синтаксис-гольфи. Я знаходжу невеликі вдосконалення в багатьох відповідях на C / C ++ (як не у ваших, @ceilingcat зазвичай підхоплює їх).
Zacharý

Так, я помітив, що ви двоє, мабуть, найактивніші учасники C / C ++ (чи можемо ми використати введення, щоб продовжити аналогію гольфу до останніх кількох ударів? Чому б і ні!). Мене завжди вражає, що ви навіть можете добре зрозуміти код для гольфу, щоб вдосконалити його.
LambdaBeta




0

Математика 40 байт

RandomChoice[IntegerPartitions[n^2, {n}]]

1
Перш за все це n ^ 2, а не 2 ^ n. По-друге, ваша програма повинна бути функцією, а також програмою для гольфу. Спробуйте це RandomChoice@IntegerPartitions[#^2,{#}]&
J42161217

1
Також результат повинен бути (не упорядкований, унікальний), але ця функція виходить з ладу в обох
J42161217

0

Мова Вольфрама (Mathematica) , 49 байт

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

Спробуйте в Інтернеті!

Версія для гольфу від @ J42161217.


Мова Вольфрама (Mathematica) , 62 байти

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

Спробуйте в Інтернеті!

Як це працює

n2nn2(n2n)/2=(n2+n)/20n1n10


Відповідь на бонусне завдання

Бонусне завдання: Чи існує формула для обчислення кількості дійсних перестановок для даної 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)

що є в Mathematica:

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

Спробуйте в Інтернеті!


Це код гольфу .. 49 байт(While[Tr[s=RandomSample[Range[#^2],#]]!=#^2];s)&
J42161217
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.