การสุ่มตามอำเภอใจ


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
มีความเกี่ยวข้องแต่ค่อนข้างแตกต่างกัน
Giuseppe

1
(p / s: หากคุณมีอัลกอริทึมที่รวดเร็ว แต่ใช้เวลามากขึ้นให้ลองรอจนกว่ารุ่นความเร็ว (ปัจจุบันอยู่ในแซนด์บ็อกซ์) เพื่อโพสต์)
user202729

1
@EriktheOutgolfer แม้ว่าจะมีวิธีที่ดีกว่ามากในการสร้างชุดทั้งหมดและเลือกสุ่ม แต่ก็ยากกว่าที่จะใช้งานและมีแนวโน้มที่จะนานกว่า เก็บไว้เป็นรุ่นความเร็ว
user202729

2
จำนวนของชุดคือOEIS A107379
nwellnhof

1
มันทั้งคู่ ดูความคิดเห็น "รวมทั้งจำนวนพาร์ติชันของ n ^ 2 เป็น n ส่วนที่แตกต่างกันด้วย"
nwellnhof

คำตอบ:


9

Brachylog (v2), 15 ไบต์ (สุ่ม) หรือ 13 ไบต์ (ความเป็นไปได้ทั้งหมด)

สุ่ม

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

ลองออนไลน์!

การส่งฟังก์ชั่น (เห็นใน TIO พร้อมด้วย wrapper ทำให้เป็นโปรแกรมเต็มรูปแบบ)

คำอธิบาย

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

ฉันค่อนข้างประหลาดใจที่ใช้∧≜งานได้ (ปกติคุณจะต้องเขียน∧~≜เพื่อบังคับเดรัจฉานเอาท์พุทมากกว่าการป้อนข้อมูล) แต่ปรากฎว่ามีการสันนิษฐานเอาท์พุท = เอาท์พุทดังนั้นมันจึงไม่สำคัญว่าคุณจะไปทางไหน เรียกใช้มัน

งานโบนัส

ในการรับข้อมูลเชิงลึกเกี่ยวกับลำดับของความเป็นไปได้ฉันได้สร้างwrapper 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 ไบต์ (กำหนดค่า)

วิธีการสุ่มตัวอย่างการปฏิเสธ @ Giuseppe:

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 "fixed" :-)
ngm

ดีมาก. การใช้pโดยตรงเป็นดัชนีแทนที่จะคำนวณและนำกลับมาใช้ใหม่ควรบันทึกบางไบต์
Giuseppe

1
ฉันมีfunction(n){while(sum(F)!=n^2)F=sample(n^2,n);F}เวลา 48 คนเช่นกัน ...
Giuseppe

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 วินาทีดังนั้นฉันอาจจะโพสต์เวอร์ชันที่แก้ไขไปยังเวอร์ชันความเร็วของความท้าทายนี้ (ซึ่งปัจจุบันยังอยู่ใน Sandbox)

ลองออนไลน์

คำอธิบาย:

ในโค้ดหลอกเราจะทำสิ่งต่อไปนี้:

1) สร้างอาร์เรย์ขนาดn+1ที่มี: 0, nกำลังสองและn-1จำนวนเต็มจำนวนเต็มในช่วงที่[0, n squared)
2) จัดเรียงอาร์เรย์นี้
3) สร้างอาร์เรย์ที่สองnที่มีขนาดต่างกันไปข้างหน้าของคู่
เหล่านี้สามขั้นตอนแรกจะทำให้เรามีอาร์เรย์ที่nสุ่ม จำนวนเต็ม (ในช่วง[0, n squared)ที่หาผลรวมถึงnกำลังสอง
4a) หากไม่ใช่ค่าสุ่มทั้งหมดจะไม่ซ้ำกันหรืออย่างใดอย่างหนึ่งคือ 0: ลองอีกครั้งจากขั้นตอนที่ 1
4b) Else: ส่งกลับอาร์เรย์ความแตกต่างนี้เป็นผลลัพธ์

สำหรับรหัสจริง:

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

มันเหมือนกันไหม -
user202729

@ user202729 แม้ว่าฉันไม่แน่ใจว่าจะพิสูจน์ได้อย่างไรฉันคิดว่ามันเป็น Java builtin นั้นเหมือนกันและใช้เพื่อรับค่าสุ่มในช่วง[0, n squared)ก่อนแล้วจึงคำนวณความแตกต่างระหว่างค่าสุ่มที่เรียงลำดับ (รวมถึงการนำหน้า0และต่อท้ายn squared) ฉันค่อนข้างมั่นใจว่าความแตกต่างเหล่านี้เหมือนกัน แต่อีกครั้ง ฉันไม่แน่ใจว่าจะพิสูจน์ได้อย่างไรความสม่ำเสมอในการสุ่มไม่ได้เป็นความเชี่ยวชาญของฉันจริง ๆ
Kevin Cruijssen

3
คุณไม่เคยอ่านจากอาเรย์ต่างdหรือว่าฉันทำอะไรหายไป?
nwellnhof

1
ฉันมีความสุขกับการแก้ปัญหา 127 bytes ของฉัน : D
Olivier Grégoire

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

Python 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)ฉันเชื่อว่าควรแก้ไขข้อผิดพลาด
Jonathan Allan

1
สิ่งนี้ควรแก้ไขข้อบกพร่องของคุณและยังลบช่องว่างที่ไม่เกี่ยวข้องออกไป ฉันคิดว่ามีพื้นที่สำหรับเล่นกอล์ฟมากขึ้นเช่นกัน
Skidsdev

1
แม้ว่าการสอบถามซ้ำจะแย่ลงเล็กน้อยจาก 5 ถึง 4 คุณสามารถรวมสองข้อความสั่งคืนของคุณเช่นนี้: return len(s)==n and sum(s)==n*n and s or f(n)( ลองออนไลน์114 ไบต์ )
Kevin Cruijssen

1
คุณสามารถมีได้ทั้งหมดในบรรทัดเดียว 111 bytes
Jo King

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 คืนผู้สมัคร

 อื่น

  ∇⍵ รับเงินคืนจากการโต้แย้ง


คุณเห็นของฉันและH.PWiz 18 ไบต์ไหม
ngn

@ngn ไม่ไม่ชัดเจน แต่ฉันตรวจสอบว่าไม่มีการแก้ไขปัญหา APL ก่อนโพสต์ ทำไมไม่ได้ใด ๆ ของyou‽
อดัม

ดีเมื่อฉันได้แข็งแรงเล่นกอล์ฟมันและแสดงให้เห็นว่ามันสวนผลไม้ไม่ค่อยมีแรงจูงใจใด ๆ ที่โพ :)
NGN

@ngn สำหรับคุณไม่มี แต่สำหรับฉันมี
Adám

1
แน่นอนและฉันคิดว่าคุณกำลังทำผลงานยอดเยี่ยมยอดนิยมในแอลพีที่นี่ ฉันแค่ทำให้แน่ใจว่าคุณรู้วิธีแก้ปัญหาที่สั้นกว่านั้นและมันอาจจะดีกว่าที่จะอธิบายหนึ่งในนั้น (หรือรูปแบบ) แทน
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 ฉันคิดว่าคำอธิบายอยู่ในลำดับ
Giuseppe

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

ตามความเห็นที่ทำโดย OP ลำดับขององค์ประกอบในผลลัพธ์ไม่เกี่ยวข้องดังนั้นàควรจะดี
Kamil Drakari

ขอบคุณ @KamilDrakari Updated
Shaggy

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

ลองออนไลน์!

วนซ้ำไม่สิ้นสุดจนกว่าชุดที่ตรงกับเกณฑ์ตรงกัน

ฉันหวังว่าคุณจะมีเวลาเพราะมันยุ่งมาก! มันไม่สามารถไปถึง 10 โดยไม่มีการจับเวลา


คุณสามารถกอล์ฟ 3 ไบต์โดยการเปลี่ยนไปif(r.size()==n&s==0) if(r.size()+s==n)
Kevin Cruijssen

@KevinCruijssen ฉันเคยคิดเกี่ยวกับมันด้วย แต่ไม่ฉันไม่สามารถทำได้เพราะอาจเป็น -1 และ n อาจมีขนาด () - 1
Olivier Grégoire

เดี๋ยวก่อนคุณยังคงเพิ่มรายการลงในชุดตราบใดที่s>0มีขนาดใหญ่กว่าnนั้น ตกลงในกรณีนั้นมันไม่ทำงานแน่นอน nเป็นค่าคงที่ แต่โชคร้ายทั้งสองsและr.size()เป็นตัวแปรที่สามารถเป็นได้ทั้งด้านล่างหรือด้านบน0และnตามลำดับ
Kevin Cruijssen

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^2break loop, output array


1
637 bytesโดยการดึง z.join เป็นตัวแปรและk++
Veskah

@Veskah ทั้งสองwhileลูปอาจถูกลดขนาดไปที่เนื้อความของฟังก์ชันเดียวซึ่งยอมรับพารามิเตอร์ และสามารถทดแทนผู้ประกอบการเงื่อนไข (ประกอบไปด้วย) สำหรับif..elseงบ; ในส่วนอื่น ๆ ของรหัสที่สามารถปรับได้มากกว่าสำหรับกอล์ฟ ieg, การลบletข้อความ
guest271314

@Veskah 601 ไบต์โดยไม่ต้องเปลี่ยนif..else
ภาคเรียน

1
Oh yeah คุณ outputting ทุกชุดในขณะที่ความท้าทายขอหนึ่งสุ่มจะถูกส่งกลับ (ดูความคิดเห็น OP สำหรับรายละเอียดเพิ่มเติม)
Veskah

@Veskah ต้องตีความความท้าทายและตัวอย่างเป็นจำนวนมากหรือมุ่งเน้นไปที่การแก้ปัญหานี้เป็นส่วนหนึ่งของคำถาม" โบนัสงาน:มีสูตรคำนวณจำนวนการเปลี่ยนลำดับที่ถูกต้องสำหรับสิ่งที่กำหนดnหรือไม่" . การทดสอบผลที่คาดหวังถ้าขั้นตอนวิธีการกลับมาอย่างต่อเนื่องสำหรับn^2อาร์เรย์ผลผลิตสร้างขึ้นในสายเดียวกับการทำงานและพร้อมกันพิจารณาความคล้ายคลึงกันกับคำถามนี้N-N มิติ ^ N อาร์เรย์ที่เต็มไปด้วย N
guest271314

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 ที่ได้รับจะถูกใช้


ฉันจะรักถ้ามีคนตรวจสอบคณิตศาสตร์ของฉันเพื่อความมั่นคง ฉันยังสงสัยว่าโซลูชันประเภทนี้จะทำให้การสุ่มความเร็วเป็นไปอย่างท้าทายได้หรือไม่ สูตรวางขอบเขตบนและล่างของคำตอบตัวเลขสุ่มสม่ำเสมอในช่วงนั้นส่งผลให้เกิดผลลัพธ์แบบสุ่มสม่ำเสมอหรือไม่ ฉันไม่เห็นว่าทำไมไม่ - แต่ฉันไม่ได้ทำ combinatorics มากในชั่วขณะหนึ่ง
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++;}
ceilingcat

@ceilingcat ฉันรักการปรับปรุงเล็ก ๆ น้อย ๆ ที่คุณพบ ฉันมักจะได้รับการเพ่งความสนใจไปดังนั้นในขั้นตอนวิธีการโดยรวมผมลืมที่จะเพิ่มประสิทธิภาพในการดำเนินงาน (ฉันเป็นพื้นไปโหมดการเล่นกอล์ฟหม้อแปลงไฟฟ้าเมื่อฉันมีแหล่งที่ไม่แข็งแรงเล่นกอล์ฟว่างาน - ดังนั้นฉันคิดถึงมากของการออม)
LambdaBeta

เฮ้ไม่ใช่แค่คุณที่มีซินแทกกอล์ฟเหล่านั้น ฉันพบการปรับปรุงเล็กน้อยในคำตอบ C / C ++ มากมายเช่นนั้น (ยกเว้นในของคุณ @ceilingcat มักจะรวมสิ่งเหล่านั้น)
Zacharý

ใช่ฉันสังเกตเห็นว่าคุณสองคนน่าจะเป็นพัตเตอร์ C / C ++ ที่ใช้งานมากที่สุด (เราสามารถใช้การวางเพื่อขยายการเปรียบเทียบกอล์ฟไปจนถึงการตีสองสามครั้งสุดท้ายทำไมไม่!) มันทำให้ฉันประทับใจเสมอว่าคุณสามารถเข้าใจรหัส golfed ได้ดีพอที่จะปรับปรุงได้
LambdaBeta




0

Mathematica 40 ไบต์

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

1
อย่างแรกเลยคือ n ^ 2 ไม่ใช่ 2 ^ n ประการที่สองโปรแกรมของคุณจะต้องมีฟังก์ชั่นและยังเป็นกอล์ฟ ลองสิ่งนี้ RandomChoice@IntegerPartitions[#^2,{#}]&
J42161217

1
นอกจากนี้ผลลัพธ์จะต้องเป็น (ไม่เรียงลำดับไม่ซ้ำกัน) แต่ฟังก์ชันนี้ล้มเหลวในทั้งสอง
J42161217

0

ภาษา Wolfram (Mathematica) , 49 ไบต์

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

ลองออนไลน์!

รุ่นที่ตีกอล์ฟโดย @ J42161217


ภาษา Wolfram (Mathematica) , 62 ไบต์

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

ลองออนไลน์!

มันทำงานอย่างไร

ส่วนใหญ่ขึ้นอยู่กับคำถาม Math.SEนี้ เพื่อให้ได้พาร์ติชันn2เข้ามาnn2(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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.