Ngẫu nhiên tùy ý


26

Ngẫu nhiên là niềm vui. Những thách thức không có điểm là niềm vui.

Viết hàm, cho đầu vào số nguyên n, sẽ xuất ra một tập hợp (không có thứ tự, duy nhất) gồm ncác số nguyên ngẫu nhiên chính xác giữa 1n^2(bao gồm) sao cho tổng của tất cả các số nguyên bằng n^2.

Ngẫu nhiên nào không phải là thống nhất, với điều kiện mỗi bộ giá trị có một tổ chức phi zero-cơ hội xảy ra.

Câu trả lời ngắn nhất tính theo byte (trên mỗi ngôn ngữ) sẽ thắng.

Ví dụ

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

Nhiệm vụ thưởng: Có một công thức để tính số lượng hoán vị hợp lệ cho một cho trước n?


2
có liên quan , nhưng khá khác biệt
Giuseppe

1
(p / s: Nếu bạn có thuật toán nhanh nhưng cần nhiều byte hơn, hãy cân nhắc chờ đợi cho đến khi phiên bản tốc độ (hiện tại trong hộp cát) để đăng nó.)
user202729

1
@EriktheOutgolfer Mặc dù có (nhiều) cách tốt hơn so với việc tạo tất cả các bộ và chọn một bộ ngẫu nhiên, chúng khó thực hiện hơn và có thể lâu hơn. Giữ chúng cho phiên bản tốc độ.
dùng202729

2
Số lượng bộ là OEIS A107379 .
nwellnhof

1
Đó là cả hai. Xem bình luận "Ngoài ra số lượng phân vùng của n ^ 2 thành n phần riêng biệt."
nwellnhof

Câu trả lời:


9

Brachylog (v2), 15 byte (ngẫu nhiên) hoặc 13 byte (tất cả các khả năng)

Ngẫu nhiên

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

Hãy thử trực tuyến!

Trình chức năng (được thấy trong TIO với trình bao bọc làm cho nó thành một chương trình đầy đủ).

Giải trình

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

Tất cả các khả năng

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

Hãy thử trực tuyến!

Chức năng trình, tạo ra tất cả các đầu ra có thể.

Giải trình

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

Tôi khá ngạc nhiên khi nó ∧≜hoạt động (thông thường bạn phải viết ∧~≜để bắt buộc đầu ra chứ không phải đầu vào), nhưng hóa ra có giả định đầu vào = đầu ra nên không quan trọng bạn đi theo hướng nào chạy nó

Nhiệm vụ tiền thưởng

Để hiểu rõ hơn về chuỗi số lượng khả năng, tôi đã tạo một trình bao bọc TIO khác chạy chương trình trên các số nguyên liên tiếp để đưa ra chuỗi số lượng đầu ra:

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

Một chuyến đi đến OEIS phát hiện ra rằng đây đã là một chuỗi đã biết, A107379 , được mô tả khá nhiều như trong câu hỏi (rõ ràng bạn nhận được chuỗi tương tự nếu bạn giới hạn nó thành số lẻ). Trang liệt kê một số công thức cho chuỗi (mặc dù không có công thức nào đặc biệt đơn giản; công thức thứ hai trông giống như một công thức trực tiếp cho giá trị nhưng tôi không hiểu ký hiệu).


Công thức thứ hai là "hệ số x^(n*(n-1)/2)trong việc mở rộng chuỗi Product_{k=1..n} 1/(1 - x^k)" (không hoàn toàn trực tiếp), không may)
user202729

Đặt ràng buộc "tất cả khác nhau" trước bước ghi nhãn ngẫu nhiên (ví dụ A≠≜₁ᵐ) làm cho thời gian chạy trung bình nhanh hơn nhiều.
Gây tử vong vào

Tôi không hiểu tại sao bạn lại biến nó thành wiki cộng đồng. Đó là một cách cổ xưa để có bài viết có thể chỉnh sửa trước khi có thể chỉnh sửa.
ống

@pipe codegolf.stackexchange.com/questions/172716/true-color-code/ Kẻ
khách271314

7

05AB1E , 11 byte

nÅœʒDÙQ}sùΩ

Hãy thử trực tuyến hoặc xác minh tất cả các trường hợp thử nghiệm .

Giải trình:

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 byte (ngẫu nhiên) và 70 byte (xác định)

@ Phương pháp lấy mẫu từ chối của Giuseppe:

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

Hãy thử trực tuyến!

Golf gốc:

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

Hãy thử trực tuyến!

Doanh *!!1:2nghiệp là để tránh samplehành động kỳ quặc khi đối số đầu tiên có độ dài 1.


@Giuseppe "đã sửa" :-)
ngm

rất đẹp. sử dụng ptrực tiếp như một chỉ mục thay vì tính toán nó và sử dụng lại nó sẽ tiết kiệm được một số byte.
Giuseppe

1
Tôi cũng có function(n){while(sum(F)!=n^2)F=sample(n^2,n);F}48 ...
Giuseppe

1
@ J.Doe để tránh vấn đề khi gọi một cái gì đó giống như sample(2,1)xảy ra với n=2. Vì vậy, repchỉ cần đảm bảo rằng điều này sẽ không bao giờ xảy ra. Có thể có một cách tốt hơn nhưng điều này nhanh chóng và tôi đã tức giận sample.
ngm

1
Bạn có thể lưu một byte với x*!!1:2hơn rep(x,2)nếu câu hỏi meta của bạn là không.
J.Doe


4

Java 10, 250 242 222 byte

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 byte nhờ @nwellnhof .

Xem ra, Java đi qua .. Nó chỉ dài gấp năm lần bốn câu trả lời khác cộng lại, vì vậy tôi đoán không quá tệ .. rofl.
Tuy nhiên, nó chỉ chạy n=1qua n=25(kết hợp) trong chưa đầy 2 giây, vì vậy tôi có thể sẽ đăng một phiên bản sửa đổi lên phiên bản tốc độ của thử thách này (hiện tại vẫn còn trong Sandbox).

Hãy thử trực tuyến.

Giải trình:

Trong mã giả, chúng tôi làm như sau:

1) Tạo một mảng có kích thước n+1chứa : 0, nbình phương và n-1số lượng số nguyên ngẫu nhiên trong phạm vi [0, n squared)
2) Sắp xếp mảng này
3) Tạo một mảng kích thước thứ hai nchứa sự khác biệt về phía trước của các cặp
Ba bước đầu tiên này sẽ cho chúng ta một mảng chứa nngẫu nhiên số nguyên (trong phạm vi [0, n squared)tính tổng nbình phương.
4a) Nếu không phải tất cả các giá trị ngẫu nhiên là duy nhất hoặc bất kỳ giá trị nào là 0: thử lại từ bước 1
4b) Khác: trả về mảng khác biệt này là kết quả

Đối với mã thực tế:

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=25trong dưới 2 giây là ấn tượng! Tôi sẽ phải đọc qua lời giải thích và xem nó làm như thế nào. Nó vẫn là một phương pháp bruteforce?
Skidsdev

Có đồng phục không? -
dùng202729

@ user202729 Mặc dù tôi không chắc làm thế nào để chứng minh điều đó, tôi nghĩ là vậy. Nội dung Java là đồng nhất và [0, n squared)trước tiên, nó sử dụng để nhận các giá trị ngẫu nhiên trong phạm vi và sau đó tính toán sự khác biệt giữa các giá trị ngẫu nhiên được sắp xếp đó (bao gồm cả dẫn 0và theo dõi n squared. Vì vậy, tôi khá chắc chắn rằng những khác biệt đó cũng đồng nhất. , Tôi không chắc làm thế nào để chứng minh điều đó. Tính đồng nhất trong sự ngẫu nhiên không thực sự là chuyên môn của tôi.
Kevin Cruijssen

3
Bạn không bao giờ đọc từ mảng khác biệt dhoặc tôi đang thiếu một cái gì đó?
nwellnhof

1
Tôi rất hài lòng với giải pháp 127 byte của mình : D
Olivier Grégoire

4

Perl 6 , 41 byte

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

Hãy thử trực tuyến!

  • (1 .. $_²) là phạm vi số từ 1 đến bình phương của số đầu vào
  • .pick($_) chọn ngẫu nhiên một tập hợp con khác biệt của phạm vi đó
  • xx * nhân rộng biểu thức trước vô hạn
  • first *.sum == $_² chọn bộ đầu tiên trong số các số đó tính tổng cho bình phương của số đầu vào


2

Bình thường, 13 12 byte

Ofq*QQsT.cS*

Hãy thử trực tuyến tại đây . Lưu ý rằng trình thông dịch trực tuyến chạy vào MemoryError cho các đầu vào lớn hơn 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

Chỉnh sửa: đã lưu một byte bằng cách sử dụng một cách tiếp cận khác. Phiên bản trước: Of&qQlT{IT./*


2

Python 3 , 136 134 127 121 114 byte

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)

Hãy thử trực tuyến!

Một người bình luận đã sửa chữa cho tôi, và điều này bây giờ đạt đến độ sâu tối đa đệ quy ở f (5) thay vì f (1). Gần hơn nhiều để là một câu trả lời cạnh tranh thực sự.

Tôi đã thấy nó làm f (5) một lần và tôi đang cố gắng thực hiện điều này bằng shuffle.

Tôi đã thử tạo một số biểu thức lambda cho s=..., nhưng điều đó không giúp ích gì cho byte. Có lẽ ai đó khác có thể làm điều gì đó với điều này: s=(lambda n:{randint(1,n*n)for _ in range(n)})(n)

Cảm ơn Kevin vì đã cạo đi 7 byte khác.


1
Vì vậy, điều này sử dụng đệ quy để "tái tạo" tập hợp nếu cái được tạo không hợp lệ? Chắc chắn có điều gì đó không đúng với mã của bạn nếu nó chạm vào độ sâu đệ quy tại f(1), mảng duy nhất có thể tạo ra được n=1[1]Ngoài ra còn có rất nhiều khoảng trắng bên ngoài được xóa ở đây. Hãy nhớ rằng đây là một thử thách chơi gôn, vì vậy mục tiêu là đạt được tỷ lệ thấp nhất
Skidsdev vào

1
range(1,n)-> range(n)Tôi tin rằng nên giải quyết lỗi.
Jonathan Allan

1
Điều này sẽ sửa lỗi của bạn, và cũng loại bỏ khoảng trắng bên ngoài. Tôi tưởng tượng còn nhiều chỗ để chơi gôn nữa
Skidsdev

1
Mặc dù đệ quy giảm nhẹ từ 5 đến 4, nhưng bạn có thể kết hợp hai câu lệnh trả về của mình như sau: return len(s)==n and sum(s)==n*n and s or f(n)( Hãy thử trực tuyến 114 byte ).
Kevin Cruijssen

1
Bạn có thể có tất cả trên một dòng. 111 byte
Jo King

2

APL (Dyalog Unicode) , 20 byte SBCS

Tiền tố nặc danh lambda.

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

Hãy thử trực tuyến!

{... } "DFN"; là đối số

⍵*2 bình phương đối số

s← gán cho s(cho s quare)

⍵? tìm nchỉ số ngẫu nhiên từ 1 người smà không cần thay thế

c← gán cho c(cho c andidate)

+/ tổng hợp chúng

s= so với s

: nếu bằng

  c trả lại ứng viên

 khác

  ∇⍵ lặp lại cuộc tranh luận


bạn có thấy 18 byte của tôiH.PWiz không?
ngn

@ngn Không, rõ ràng là không, nhưng tôi đã kiểm tra rằng không có giải pháp APL nào được đăng trước khi tôi đăng. Tại sao không có ai trong các bạn
Adám

tốt, một khi tôi đã chơi nó và đưa nó cho vườn cây, hầu như không có động lực nào để đăng :)
ngn

@ngn Đối với bạn, không, nhưng đối với tôi là có.
Adám

1
chắc chắn, và tôi nghĩ rằng bạn đang làm một công việc tuyệt vời phổ biến apl ở đây. tôi chỉ chắc chắn rằng bạn biết các giải pháp ngắn hơn đã được tìm thấy và có lẽ tốt hơn là giải thích một trong số chúng (hoặc một biến thể) thay vào đó
ngn

2

APL (Dyalog Classic) , 18 byte

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

Hãy thử trực tuyến!

sử dụng ⎕io←1

tạo ra các số 1 2 ... n

(... )⍣(...) tiếp tục áp dụng chức năng bên trái cho đến khi chức năng bên phải trả về đúng

chiều dài, tức là n

≢?≢×≢chọn nsố nguyên khác biệt ngẫu nhiên giữa 1 và n2

+.-∘≢ trừ độ dài từ mỗi số và tổng

0= nếu tổng bằng 0, dừng lặp, nếu không hãy thử lại


1

MATL , 18 13 byte

`xGU:GZrtsGU-

Hãy thử trực tuyến!

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

Tôi sẽ không thử điều này trong R - các ký tự ngẫu nhiên hầu như không bao giờ tạo ra một chương trình hợp lệ.
ngm

@ngm hahaha Tôi cho rằng một lời giải thích là theo thứ tự.
Giuseppe

1

Japt, 12 byte

²õ àU ö@²¥Xx

Thử nó

                 :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

Theo nhận xét của OP, thứ tự các yếu tố trong đầu ra là không liên quan ànên sẽ ổn.
Kamil Drakari

Cảm ơn, @KamilDrakari. Cập nhật.
Shaggy

1

Java (JDK) , 127 byte

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

Hãy thử trực tuyến!

Vòng lặp vô hạn cho đến khi một tập hợp với các tiêu chí phù hợp.

Tôi hy vọng bạn có thời gian, bởi vì nó rất chậm! Nó thậm chí không thể lên 10 mà không hết thời gian.


Bạn có thể chơi golf 3 byte bằng cách thay đổi if(r.size()==n&s==0)thành if(r.size()+s==n).
Kevin Cruijssen

@KevinCruijssen Tôi cũng đã nghĩ về điều đó, nhưng không, tôi không thể vì s có thể là -1 và n có thể là kích thước () - 1.
Olivier Grégoire

Đợi đã, bạn tiếp tục thêm các mục vào tập hợp miễn là s>0, vì vậy kích thước có thể lớn hơn n. Ok, trong trường hợp đó nó thực sự không hoạt động. nlà một hằng số, nhưng không may là cả hai sr.size()là các biến có thể ở cả bên dưới hoặc bên trên 0ntương ứng.
Kevin Cruijssen

1

Hàng loạt, 182 145 byte

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

Giải thích: Tính toán lựa chọn tối thiểu và tối đa cho phép, với điều kiện là các số sẽ được chọn theo thứ tự giảm dần và chọn một giá trị ngẫu nhiên trong phạm vi. Ví dụ cho đầu vào của 4:

  • Chúng tôi bắt đầu với 16 trái. Chúng tôi không thể chọn 11 hoặc nhiều hơn vì 3 lựa chọn còn lại phải thêm ít nhất 6. Chúng tôi cũng cần chọn ít nhất 6, vì nếu chúng tôi chỉ chọn 5, 3 lựa chọn còn lại chỉ có thể thêm vào 9, không phải là 3 đủ cho 16. Chúng tôi chọn một giá trị ngẫu nhiên từ 6 đến 10, nói 6.
  • Chúng tôi có 10 trái. Chúng tôi không thể chọn 8 hoặc nhiều hơn vì 2 lượt chọn còn lại phải thêm ít nhất 3. Khi điều đó xảy ra, chúng tôi không thể chọn 6 hoặc nhiều hơn vì chúng tôi đã chọn 6 lần trước. Chúng tôi cũng cần chọn ít nhất 5, vì nếu chúng tôi chỉ chọn 4, 2 lượt chọn còn lại chỉ có thể thêm vào 5, tổng cộng là 15. Chúng tôi chọn một giá trị ngẫu nhiên từ 5 đến 5, giả sử 5 (!).
  • Chúng tôi có 5 trái. Chúng tôi không thể chọn 5 hoặc nhiều hơn vì lựa chọn còn lại phải thêm ít nhất 1 và vì chúng tôi đã chọn 5 lần trước. Chúng ta cũng cần chọn ít nhất 3, vì nếu chúng ta chỉ chọn 2, thì số còn lại chỉ có thể là 1, với tổng số là 14. Chúng ta chọn một giá trị ngẫu nhiên từ 3 đến 4, giả sử 4.
  • Chúng tôi có 1 trái. Hóa ra, thuật toán chọn phạm vi từ 1 đến 1 và chúng tôi chọn 1 làm số cuối cùng.

1

JavaScript, 647 291 261 260 259 251 239 byte

Cảm ơn @Veskah cho -10 byte ở phiên bản gốc và "Ồ vâng, bạn đang xuất tất cả các bộ trong khi thử thách yêu cầu trả lại một cái ngẫu nhiên"

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

Hãy thử trực tuyến!

Tạo một mảng các n^2chỉ mục dựa trên 1, sắp xếp ngẫu nhiên mảng, ncác phần tử lát từ mảng. Trong khi tổng của các phần tử ngẫu nhiên không bằng n^2mảng vòng lặp của các phần tử ngẫu nhiên; nếu tổng các phần tử mảng lớn hơn n^2và phần tử hiện tại -1không bằng 0 hoặc phần tử hiện tại -1không nằm trong mảng hiện tại, hãy trừ đi 1; nếu tổng của mảng nhỏ hơn n^2và phần tử hiện tại +1không nằm trong mảng, hãy thêm 1vào phần tử. Nếu tổng mảng bằng với n^2vòng lặp ngắt, mảng đầu ra.


1
637 byte bằng cách kéo z.join vào một biến vàk++
Veskah

@Veskah Hai whilevòng lặp có thể cũng có thể được giảm xuống phần thân của một hàm duy nhất chấp nhận các tham số; và có thể thay thế các toán tử có điều kiện (ternary) cho các if..elsecâu lệnh; trong số các phần khác của mã có nhiều khả năng có thể được điều chỉnh cho golf; ieg, loại bỏ các letbáo cáo.
khách271314

@Veskah 601 byte mà không cần thay thế ternary choif..else
guest271314

1
Oh yeah, bạn xuất ra tất cả các bộ trong khi thách thức yêu cầu một ngẫu nhiên để được trả lại (Xem các ý kiến OP để biết thêm chi tiết)
Veskah

@Veskah Phải hiểu sai về thách thức và ví dụ, hoặc quá tập trung vào việc giải quyết phần này của câu hỏi " Nhiệm vụ tiền thưởng: Có công thức nào để tính số lượng hoán vị hợp lệ cho một lần cho nkhông?" . kiểm tra kết quả mong đợi nếu các thuật toán liên tục quay trở lại với n^2mảng sản lượng tạo ra trong một cuộc gọi duy nhất đến chức năng, đồng thời xem xét các điểm tương đồng với câu hỏi này N-chiều N ^ N mảng điền với N .
khách271314

0

Japt , 20 byte

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

Hãy thử trực tuyến!

Vô cùng tận dụng lợi thế của tính ngẫu nhiên "Không đồng nhất", hầu như luôn luôn xuất ra các nsố lẻ đầu tiên , xảy ra để tính tổng n^2. Về lý thuyết, nó có thể xuất bất kỳ tập hợp lệ nào khác, mặc dù tôi chỉ có thể xác nhận điều đó cho nhỏ n.

Giải trình:

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

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

Hãy thử trực tuyến!

-3 byte nhờ trần

LƯU Ý: Xác suất rất xa so với đồng phục. Xem giải thích cho những gì tôi muốn nói và một phương tiện tốt hơn để kiểm tra xem nó có hoạt động không (bằng cách làm cho phân phối gần với đồng phục hơn [nhưng vẫn khác xa với nó]).

Làm sao?

Ý tưởng cơ bản là chỉ chọn tăng số lượng để không lo lắng về sự trùng lặp. Bất cứ khi nào chúng tôi chọn một số, chúng tôi có cơ hội "bỏ qua" số không nếu không được phép.

Để quyết định xem chúng tôi có thể bỏ qua một số không, chúng tôi cần biết xtổng số còn lại sẽ đạt được, ksố phần tử chúng tôi vẫn phải sử dụng và ygiá trị ứng cử viên hiện tại. Số nhỏ nhất có thể mà chúng ta vẫn có thể chọn sẽ bao gồm

y+(y+1)+(y+2)+...
thêm vào giá trị hiện tại. Cụ thể, chúng tôi yêu cầu biểu thức trên phải nhỏ hơn x. Công thức sẽ là
k(k+1)2+k(y+1)+y<x
Thật không may, chúng tôi phải cẩn thận một chút về việc sắp xếp lại công thức này do cắt ngắn số nguyên trong C, vì vậy tôi thực sự không thể tìm ra cách để chơi nó.

Tuy nhiên, logic là để có cơ hội loại bỏ bất kỳ ythỏa mãn phương trình trên.

Mật mã

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.

Thủ thuật mà tôi đã đề cập để kiểm tra tốt hơn mã liên quan đến việc thay thế rand()&&bằng rand()%2&&cách có 50-50 khả năng bất kỳ y đã cho nào bị bỏ qua, thay vì 1 RAND_MAXcơ hội mà bất kỳ y đã cho nào được sử dụng.


Tôi sẽ thích nó nếu ai đó kiểm tra tính nhất quán của tôi. Tôi cũng tự hỏi nếu loại giải pháp này có thể làm cho thách thức tốc độ ngẫu nhiên thống nhất đơn giản. Công thức đặt một giới hạn trên và dưới vào câu trả lời, một số ngẫu nhiên thống nhất trong phạm vi đó có dẫn đến kết quả ngẫu nhiên thống nhất không? Tôi không hiểu tại sao không - nhưng tôi đã không thực hiện nhiều pha phối hợp trong một lúc.
LambdaBeta

Đề xuất p(y),x-=y++)while(rand()&&(i-n)*((~n+i)/2+~y)+y<x)y++;thay vì){while(rand()&&(n-i)*(n-i+1)/2+(n-i)*(y+1)+y<x)y++;p(y);x-=y++;}
trần mèo

@ceilingcat Tôi thích những cải tiến nhỏ mà bạn tìm thấy. Tôi luôn luôn tập trung vào thuật toán tổng thể. Tôi quên tối ưu hóa để thực hiện (về cơ bản tôi chuyển sang chế độ chơi gôn tự động một khi tôi có một nguồn không chơi golf hoạt động - vì vậy tôi bỏ lỡ rất nhiều tiền tiết kiệm)
LambdaBeta

Này, không chỉ bạn là người có những cú đánh golf đó. Tôi tìm thấy một số cải tiến nhỏ trong rất nhiều câu trả lời C / C ++ như thế (ngoại trừ không có trong câu trả lời của bạn, @ceilingcat thường tóm gọn những câu đó).
Zacharý

Vâng, tôi đã nhận thấy rằng hai bạn có lẽ là người mở khóa C / C ++ tích cực nhất (chúng ta có thể sử dụng cách đặt để mở rộng sự tương tự golf đến vài cú đánh cuối cùng không? Tại sao không!). Nó luôn gây ấn tượng với tôi rằng bạn thậm chí có thể hiểu mã golf đủ tốt để cải thiện nó.
LambdaBeta


0

Python (2 hoặc 3), 84 byte

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

Hãy thử trực tuyến!

Lượt truy cập độ sâu đệ quy tối đa vào khoảng l (5)



0

Toán học 40 byte

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

1
Trước hết đó là n ^ 2, không phải 2 ^ n. Thứ hai, chương trình của bạn phải là một chức năng và cũng là một môn đánh gôn. Hãy thử điều này RandomChoice@IntegerPartitions[#^2,{#}]&
J42161217

1
Ngoài ra, kết quả phải là (không có thứ tự, duy nhất) nhưng chức năng này không thành công trong cả hai
J42161217

0

Ngôn ngữ Wolfram (Mathicala) , 49 byte

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

Hãy thử trực tuyến!

Phiên bản chơi gôn của @ J42161217.


Ngôn ngữ Wolfram (Mathicala) , 62 byte

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

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

Chủ yếu dựa trên câu hỏi Math.SE này . Để có được phân vùng củan2 vào n phần riêng biệt, có được phân vùng của n2-(n2-n)/2= =(n2+n)/2 thay vào đó và thêm 0n-1đến từng yếu tố. Vì Mathematica đưa ra các phân vùng theo thứ tự giảm dần,n-10 được thêm vào thay thế.


Câu trả lời cho Nhiệm vụ Tiền thưởng

Nhiệm vụ thưởng: Có một công thức để tính số lượng hoán vị hợp lệ cho một cho trước n?

Vâng. Định nghĩapmộtrt(n,k) là số lượng phân vùng của n vào chính xác kcác bộ phận. Sau đó, nó đáp ứng các mối quan hệ tái phát sau đây:

pmộtrt(n,k)= =pmộtrt(n-1,k-1)+pmộtrt(n-k,k)

Bạn có thể hiểu nó là "Nếu một phân vùng chứa 1, hãy xóa nó đi, nếu không, hãy trừ 1 từ mọi số hạng". Giải thích thêm ở đây về một câu hỏi Math.SE khác . Kết hợp với các điều kiện ban đầupart(n,1)=1 and n<kpart(n,k)=0, you can compute it with a program. The desired answer will be:

part(n2+n2,n)

which is, in Mathematica:

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

Try it online!


This is code golf.. 49 bytes (While[Tr[s=RandomSample[Range[#^2],#]]!=#^2];s)&
J42161217
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.