Pigeonhole Principle & Code Golf


26

หลักรังนกพิราบระบุว่า

หากมีการใส่รายการNลงในกล่องMโดยมีN > Mอย่างน้อยหนึ่งกล่องจะต้องมีมากกว่าหนึ่งรายการ

สำหรับหลาย ๆ คนหลักการนี้มีสถานะพิเศษเมื่อเทียบกับการคำนวณทางคณิตศาสตร์อื่น ๆ ในฐานะที่เป็น EW Dijkstra เขียน ,

มันถูกล้อมรอบไปด้วยความลึกลับบางอย่าง บทพิสูจน์ที่ใช้มันมักถูกมองว่าเป็นสิ่งที่พิเศษ

ความท้าทาย

จุดประสงค์ของการท้าทายนี้คือเพื่อแสดงให้เห็นถึงหลักการของนกพิราบในช่องว่างโดยใช้การแทนด้วยศิลปะ ASCII โดยเฉพาะ:

  1. ใช้เป็นอินพุตN(จำนวนรายการ) และM(จำนวนกล่อง) โดยNไม่ลบและMบวก Nอาจมีขนาดเล็กกว่าM(แม้ว่าหลักการไม่ได้ใช้ในกรณีนั้น)
  2. สุ่มเลือกหนึ่งในการกำหนดรายการที่เป็นไปได้ให้กับกล่อง แต่ละการมอบหมายควรมีความน่าจะเป็นที่ไม่เป็นศูนย์ในการเลือก
  3. สร้างการแทนค่า ASCII art ของการมอบหมายดังนี้:

    • มีMเส้นแต่ละเส้นตรงกับกล่อง
    • |แต่ละบรรทัดเริ่มต้นด้วยตัวอักษรที่ไม่ใช่ช่องว่างเช่น
    • การติดตามตัวละครนั้นเป็นอีกตัวที่ไม่ใช่ช่องว่างเช่น#ซ้ำหลายครั้งเนื่องจากมีรายการในกล่องนั้น

พิจารณาตัวอย่างเช่น,N = 8 M = 5หาก assigment เลือกของรายการที่จะเป็นกล่อง4, 1, 0, 3, 0ตัวแทนคือ

|####
|#
|
|###
|

การทำงานที่แตกต่างกัน (ส่งผลให้มีการมอบหมายต่างกัน) ของโปรแกรมเดียวกันอาจให้

|#
|##
|#
|#
|###

มีความยืดหยุ่นบางอย่างเกี่ยวกับการเป็นตัวแทน; ดูด้านล่าง

กฎเฉพาะ

รหัสควรทำงานในทางทฤษฎีสำหรับค่าใด ๆของและN Mในทางปฏิบัติอาจถูก จำกัด ด้วยขนาดหน่วยความจำหรือข้อ จำกัด ชนิดข้อมูล

เนื่องจากการสังเกตผลลัพธ์ไม่เพียงพอที่จะตัดสินว่าการมอบหมายทั้งหมดมีความน่าจะเป็นที่ไม่เป็นศูนย์หรือไม่การส่งแต่ละครั้งควรอธิบายว่ารหัสประสบความสำเร็จได้อย่างไรหากไม่ชัดเจน

อนุญาตให้ใช้รูปแบบการนำเสนอต่อไปนี้:

  • สามารถเลือกคู่ของอักขระที่ไม่ใช่ช่องว่างที่แตกต่างกันได้ พวกเขาจะต้องสอดคล้องกันในการทำงานของโปรแกรม
  • การหมุนที่ใช้ในการแสดง 90 องศาเป็นที่ยอมรับได้ ตัวเลือกจะต้องสอดคล้องกันอีกครั้ง
  • อนุญาตให้ใช้ช่องว่างต่อท้ายหรือนำหน้า

เป็นตัวอย่างที่มีรูปแบบการแสดงที่แตกต่างกันสำหรับN = 15, M = 6ผลของการประหารชีวิตสองของโปรแกรมที่อาจจะ

VVVVVV
@@@@@@
@@ @@@
 @  @@
    @

หรือ

VVVVV
@@@ @
@@@ @
@ @ @
@ @ @
@

ในทำนองเดียวกันN = 5, M = 7จะให้ใช้รูปแบบของการแสดงอีก

  *
* * * *
UUUUUUU

หรือ

 *** **
UUUUUUU

หรือ

   *
*  *
*  * 
UUUUUUU

หมายเหตุว่าหลักการที่ไม่สามารถใช้ได้ในกรณีนี้เพราะ<NM

กฎทั่วไป

โปรแกรมหรือฟังก์ชั่นที่ได้รับอนุญาตในการเขียนโปรแกรมภาษา ช่องโหว่มาตรฐานเป็นสิ่งต้องห้าม

การป้อนข้อมูลสามารถนำมาโดยใด ๆวิธีการที่เหมาะสม ; และในรูปแบบใด ๆ เช่นอาร์เรย์ของตัวเลขสองตัวหรือสองสตริงที่แตกต่างกัน

วิธีการส่งออกและรูปแบบยังมีความยืดหยุ่น ตัวอย่างเช่นเอาต์พุตสามารถเป็นรายการของสตริงหรือสตริงที่มีบรรทัดใหม่ ส่งคืนเป็นอาร์กิวเมนต์เอาต์พุตของฟังก์ชันหรือแสดงใน STDOUT ในกรณีหลังไม่จำเป็นต้องกังวลเกี่ยวกับการตัดบรรทัดที่เกิดจากความกว้างของหน้าจอที่ จำกัด

รหัสที่สั้นที่สุดในหน่วยไบต์ชนะ


11
อันที่จริงแล้วฉันก็ใช้ชื่อจนถึงตอนนี้ ...
Martin Ender

@ มาร์ตินเอนเดอร์นั่นคือ "หลักการของนกพิราบ" มีตัวละครมากกว่า "รหัสกอล์ฟ" หรือมีเรื่องตลกอื่น ๆ อีกไหม?
dorukayhan ต้องการโมนิก้ากลับ

5
@dorukayhan ในเบราว์เซอร์มาตรฐานให้ดูข้อความที่อยู่เหนือชื่อคำถามเล็กน้อย ...
Luis Mendo

คำตอบ:


2

เยลลี่ , 9 8 ไบต์

=þṗX¥S⁵*

นี่คือลิงก์ dyadic ที่ใช้Mเป็นซ้ายและNเป็นอาร์กิวเมนต์ที่ถูกต้อง เอาต์พุตคืออาร์เรย์ของจำนวนเต็มโดยที่0แทนนกพิราบและ1แทนหลุม

ลองออนไลน์!

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

=þṗX¥S⁵*  Main link. Left argument: m. Right argument: n

    ¥     Combine the two links to the left into a dyadic chain and call it
          with arguments m and n.
  ṗ        Compute the n-th Cartesian power of [1, ..., m], i.e., generate all
           vectors of length n that consist of elements of [1, ..., m].
   X       Pseudo-randomly choose one of those vectors with a uniform distribution.
=þ        Equal table; for each k in [1, ..., m] and each vector to the right,
          compare the elements of the vector with k. Group the results by the
          vectors, yielding a 2D Boolean matrix.
     R    Range; map 1 to [1], 0 to [].
      S   Take the sum of all columns.
       ⁵* Raise 10 to the resulting powers.

10

Mathematica, 68 ไบต์

Print/@(10^RandomSample@RandomChoice[IntegerPartitions[+##,{#}]-1])&

ฟังก์ชั่นที่ไม่มีชื่อที่ใช้เวลาสองอาร์กิวเมนต์จำนวนเต็มจำนวนกล่องตามด้วยจำนวนรายการ

มันเป็นครั้งแรกคำนวณพาร์ทิชันทั้งหมดที่เป็นไปได้ของการN+Mเข้ามาตรงMส่วนที่เป็นบวกและลบ1จากแต่ละพาร์ทิชันนั้น สิ่งนี้ทำให้เรามีพาร์ติชั่นที่เป็นไปได้ทั้งหมดNในส่วนที่Mไม่เป็นลบ (ซึ่งIntegerPartitionsจะไม่สร้างเป็นอย่างอื่น) จากนั้นเลือกพาร์ติชันแบบสุ่มและสุ่ม สิ่งนี้รับประกันว่าอนุญาตให้มีพาร์ติชั่นที่สั่งซื้อด้วยค่าศูนย์ได้ สุดท้ายแปลงถังของพาร์ทิชันกับสายการส่งออกในแต่ละโดยการเพิ่ม 10 ถึงอำนาจที่สอดคล้องกัน (เช่นว่าแต่ละบรรทัดจะกลายเป็น1000...กับkศูนย์) เอาต์พุตตัวอย่างอาจมีลักษณะดังนี้:

100
10000
1
10
10

ผมเชื่อว่าPadRightจะไม่เบาะMศูนย์ถ้า<N M
LegionMammal978

1
@ LegionMammal978 ขอบคุณจัดการเพื่อแก้ไขที่นับไบต์เดียวกัน
Martin Ender

... ฉันประทับใจจริงๆ ฉันกำลังจะแก้ปัญหาที่คล้ายกัน แต่การPadRightไม่ฟังจะทำให้มันอีกต่อไป
LegionMammal978

@ LegionMammal978 อีกวิธีที่จะหลีกเลี่ยงPadRightก็IntegerPartitions[#,{#2},0~Range~#]คือ
Martin Ender

1
ไม่มี buitltin? ฉันประหลาดใจ ... : D แต่คำตอบที่ดี ฉันแค่ต้องคิดออกว่ามันทำงานอย่างไรก่อน: P
HyperNeutrino

9

Python 2, 77 86 ไบต์

from random import*
n,m=input()
exec'c=randint(0,n);n-=c;print 10**c;'*~-m
print 10**n

สร้างตัวเลขใน [0, n] พิมพ์ว่ามีหลายรายการและลบออกจาก n มันทำเช่นนี้ m คูณ

นี้จะทำให้มันไม่น่าเป็นอะไรที่ทำให้มันเป็นกล่องที่ผ่านมา แต่คำถามเพียง แต่ถามว่าการส่งออกทุกเป็นไปได้ที่ไม่เท่าเทียมกันมีแนวโน้ม


7

แบตช์ 164 ไบต์

@for /l %%i in (1,1,%1)do @set h%%i=1
@for /l %%j in (1,1,%2)do @call set/ab=%%random%%%%%%%1+1&call set/ah%%b%%*=10
@for /l %%i in (1,1,%1)do @call echo %%h%%i%%

ฉันคิดว่า 7 %สัญญาณติดต่อกันอาจจะเป็นสิ่งใหม่ที่ดีที่สุด! หมายเหตุ: สิ่งนี้จะสร้างเอาต์พุตแปลก ๆ หากมันกำหนดมากกว่า 9 รายการให้กับกล่องเดียวกัน หากเป็นปัญหาแล้วจะมีขนาด 180 ไบต์:

@for /l %%i in (1,1,%1)do @set h%%i=1
@for /l %%j in (1,1,%2)do @call set/ab=%%random%%%%%%%1+1&call call set h%%b%%=%%%%h%%b%%%%%%0
@for /l %%i in (1,1,%1)do @call echo %%h%%i%%

ใช่นั่นคือทั้งหมด 28 %วินาทีในบรรทัดที่สอง


5

C, 102 ไบต์

n,m;main(x){srand(time(0));for(scanf("%d %d",&n,&m);m--;n-=x)printf("|%0*s\n",x=m?rand()%(n+1):n,"");}

รับอินพุตบน stdin เช่น:

echo "5 4" | ./pigeonhole

จะไม่สร้างแต่ละเอาต์พุตที่มีความน่าจะเป็นเท่ากัน แต่สามารถสร้างชุดค่าผสมที่เป็นไปได้ทั้งหมด

ทำให้พังถล่ม:

n,m;
main(x){
    srand(time(0));             // Seed random number generator
    for(scanf("%d %d",&n,&m);   // Parse input values into n and m
        m--;                    // Loop through each bucket (count down)
        n-=x)                   // Subtract number assigned to bucket from total
        printf(                 // Output a formatted string using padding
            "|%0*s\n",          // (turns out %0s will actually zero-pad a string!)
            x=m?rand()%(n+1):n, // Calculate a number of items for this bucket
            "");
}

อาศัยการจัดการของ GCC เกี่ยวกับพฤติกรรมที่ไม่ได้กำหนดของ%0s- โดยปกติแล้ว%0จะทำให้แผ่นจำนวนเต็มหรือลอยตัวเป็นศูนย์ แต่จะสามารถบีบอัดได้เท่านั้น (ไม่ตัดปลาย) ดังนั้นจึงไม่สามารถพิมพ์ว่างเปล่าได้ แต่พฤติกรรมของสตริงนั้นไม่ได้กำหนดไว้และ GCC ตัดสินใจที่จะทำให้มันเป็นศูนย์แบบเดียวกับที่ใช้ดังนั้นแผ่นนี้จะทำให้สตริงว่างเปล่าเป็นศูนย์เพื่อให้สามารถเขียน zero-or-more 0ได้


2
ตั้งแต่ฟังก์ชั่นได้รับอนุญาตให้คุณสามารถตัดออกไปไม่กี่ตัวอักษรโดยใช้a(b,c){...}แทนและmain scanf
เควิน

3

Python 2, 102 99 97 90 ไบต์

m-1ครั้งเลือกจำนวนสุ่มxระหว่าง0และnรวมและลบออกจาก n จากนั้นพิมพ์และ1'0'*x

สุดท้ายให้พิมพ์1และส่วนที่เหลือของ0s ไม่ได้มีโอกาสเท่ากัน แต่การกำหนดค่าทั้งหมดเป็นไปได้

from random import*
n,m=input()
exec'x=randrange(n+1);n-=x;print 10**x;'*(m-1)
print 10**n

(รหัสที่นำกลับมาใช้ใหม่จากคำตอบของ Python ที่เสียหาย)


ฉันคิดว่าคำตอบนี้ควรเป็นคำแนะนำสำหรับคำตอบของฉันเพราะเป็นคำตอบเดียวกับการแก้ไขข้อบกพร่องเล็ก ๆ
orlp

1
@ orlp หากคุณดูประวัติของคำตอบนี้มันจะกลายเป็นว่าในเวอร์ชั่นล่าสุด ถ้าฉันจะทำให้มันเป็นแบบนี้ในตอนแรกฉันจะโพสต์มันเป็นความคิดเห็นแทน
L3viathan

อาแล้วมันก็ดีวิธีดู (และคุณเขียนว่า 'reused code') ทำให้มันดูแตกต่างจากที่มันเป็น ขอโทษ
orlp

@orlp ไม่มีปัญหา ของคุณกำลังทำงานและสั้นกว่าของฉันอีกต่อไปฉันสามารถลบคำตอบนี้ได้ถ้าคุณรู้สึกว่ามันใกล้กับคุณมากเกินไปฉันไม่รังเกียจแค่อยากจะชี้แจงว่าฉันไม่ได้แค่คัดลอกคำตอบของคุณ
L3viathan

3

Haskell, 114 94 bytes

import System.Random
n#m=map(10^).take m.until((==n).sum.take m)tail.randomRs(0,m)<$>newStdGen

วิธีการบังคับแบบเดรัจฉาน: สร้างรายการสุ่มที่ไม่มีที่สิ้นสุดใช้หมายเลข n ของการเริ่มต้นรายการสรุปผลรวมและตรวจสอบว่าพวกมันเท่ากับ m หรือไม่ หากไม่มีให้ลบองค์ประกอบแรกออกจากรายการแล้วทำซ้ำ

ลองออนไลน์!

หมายเหตุ: 73 ไบต์โดยไม่มีการนำเข้า

แก้ไข: บันทึกบางส่วนด้วยเคล็ดลับ 10 ^ ( ลองเวอร์ชันใหม่ออนไลน์! )


2

REXX, 74 ไบต์

arg n m
m=m-1
o.=@
do n
  a=random(m)
  o.a=o.a||#
  end
do a=0 to m
  say o.a
  end

เอาท์พุท (8 5):

@#
@###
@
@#
@###

เอาท์พุท (8 5):

@#
@#
@
@####
@##

2

C, 175 138 ไบต์

ขอบคุณ @Dave สำหรับการบันทึก 37 ไบต์!

i;f(n,m){char**l=calloc(m,8);for(i=0;i<m;)l[i]=calloc(n+1,1),*l[i++]=124;for(i=n+1;--i;)*strchr(l[rand()%m],0)=35;for(;i<m;)puts(l[i++]);}

ลองออนไลน์!


1
สวัสดีบางสิ่งที่สามารถช่วยให้คุณลดนี้callocจะทำให้คุณมี 0 เริ่มต้นใช้หน่วยความจำ (ไม่จำเป็นต้องตั้ง 0s ทั้งหมดด้วยตัวเอง) strchrสามารถหาจุดสิ้นสุดของสตริงที่ดำเนินงานโซ่จุลภาคสามารถหลีกเลี่ยงความจำเป็นในการและ{} x[0] == *xระวังให้ดี คุณไม่ได้mallocมีหน่วยความจำเพียงพอหากรายการทั้งหมดอยู่ในกล่องเดียวกัน
เดฟ

2

AHK, 66 ไบต์

2-=1
Loop,%2%{
Random,r,0,%1%
Send,|{# %r%}`n
1-=r
}
Send,|{# %1%}

ฉันทำตามหลักการเดียวกันกับที่orlpใช้การสุ่มตัวเลขจาก 0 ถึง N จากนั้นลบมันออกจาก N แต่น่าเสียดายที่ฉันไม่สามารถบันทึกไบต์ได้ด้วยการใช้ 10 ^ r เนื่องจากวิธีการทำงานของฟังก์ชันส่ง อนิจจาและท้ายทอย นี่คือผลลัพธ์บางส่วนสำหรับ n = 8, m = 5:

|##     |#####    |##       |##     |#      |##   
|##     |#        |#####    |       |###    |#    
|#      |##       |         |###    |###    |     
|###    |         |         |       |#      |     
|       |         |#        |###    |       |#####

2

CJam, 30 31 21 ไบต์

:B1a*:C\{CBmrAt.*}*N*

อินพุตเป็นตัวเลขสองตัวn mบนสแต็ก ใช้1สำหรับอักขระคอลัมน์และ0สำหรับอักขระซ้ำ

คำอธิบาย:

:B          e# Store m in B (without deleting it from the stack)
1a          e# Push 1 and wrap it in an array: [1]
*           e# Repeat the array m times
:C          e# Store this array in C (without deleting)
\{          e# Do n times:
  CBmrAt    e#   Create an array of 1s with a random element replaced with 10.
  .*        e#   Vectorized multiplication: multiply the respective elements in the arrays.
            e#   Effectively, we multiply a random value in the array by 10 (and add a 0 to the end).
}*          e# End loop.
N*          e# Join with newlines.


1

PHP, 100 ไบต์

list($z,$m,$n)=$argv;$a=array_fill(0,$n,z);while($m>0){$a[rand(0,$n-1)].=a;$m--;}echo join("\n",$a);

ทำให้พังถล่ม :

list($z,$m,$n)=$argv;     // assigns the input vars to $m and $n
$a=array_fill(0,$n,z);    // creates an array $a of $n elements containing 'z'
while($m>0){              // randomly populate array $a
    $a[rand(0,$n-1)].=a;  //
    $m--;                 //
}                         //
echo join("\n",$a);       // output $a contents separated by a new line

ผลลัพธ์สำหรับm=7และn=5:

การดำเนินการครั้งแรก:

za
zaa
za
za
zaa

การดำเนินการที่สอง:

za
zaa
zaaa
z
za

ลองออนไลน์!


คุณสามารถใช้[,$m,$n]=$argv;จาก PHP 7.1 เพื่อบันทึกตัวอักษรสองสามตัว คุณสามารถแทนที่\nด้วยตัวแบ่งบรรทัดจริงเพื่อบันทึก 1 ไบต์ คุณสามารถใช้for(;$m-->0;)$a[rand(0,$n-1)].=a;เพื่อบันทึกการแบ่ง a $mและเซมิโคลอน [,$m,$n]=$argv;$a=array_fill(0,$n,z);for(;$m-->0;)$a[rand()%$n].=a;echo join("\n",$a);85 byte
Christoph

สนามกอล์ฟนี้ลดลงถึง[,$m,$n]=$argv;for(;$m--;)${rand()%$n}.=a;for(;$n--;)echo"z${$n}\n";67 ไบต์
Christoph

@ Christoph ฉันเห็นสัญกรณ์[,$m,$n]=$argv;บน code-golfs อื่น ๆ แต่ไม่สามารถทำให้มันทำงานได้ทั้งในสภาพแวดล้อมการพัฒนาของฉันหรือบน eval.in
roberto06

ลองที่นี่: sandbox.onlinephpfunctions.com/code/… .
Christoph

1
ดี ฉันคิดว่าคุณสามารถโพสต์ตัวอย่างของคุณเป็นคำตอบเพราะมันแตกต่างกันค่อนข้างมากจากเหมือง;)
roberto06

1

JavaScript, 105 ไบต์

x=>y=>{s=[];for(;x>1;y-=t)s[--x]="|"+"#".repeat(t=Math.random()*(y+1)|0);s[0]="|"+"#".repeat(y);return s}

ลองออนไลน์!

เนื่องจากวิธีการกำหนดแถวสิ่งนี้จะมีแนวโน้มที่จะอยู่ด้านล่างมากขึ้นแม้ว่าจะมีโอกาสเล็กน้อยที่ด้านบนจะได้รับบางส่วน


1

ทับทิม 52 ไบต์

->(n,m){r=Array.new(m){?|};n.times{r[rand m]+=?#};r}

สร้างฟังก์ชั่นที่ไม่ระบุชื่อซึ่งใช้จำนวนเต็มสองจำนวนเป็นอาร์กิวเมนต์และส่งกลับอาร์เรย์ของสตริง:

>> puts ->(n,m){r=Array.new(m){?|};n.times{r[rand m]+=?#};r}.call 7,5
|#
|#
|##
|##
|#

1

Python 2, 81 ไบต์

from random import*
def f(n,m):l=['#']*m;exec('l[randrange(m)]+="o";'*n);return l

ส่งคืนรายการของสตริง


1

Javascript (ES7), 75 ไบต์

(N,M)=>{for(r='';M;M--,N-=x=~~(Math.random()*(N+1)),r+=10**x+`
`);return r}

ฉันคิดว่าฉันฉลาดในการหาพลังของความคิด 10 ข้อเพื่อตระหนักว่าคำตอบส่วนใหญ่ใช้ไปแล้ว


1

AWK, 78 ไบต์

{srand();for(;n++;)c[k]=c[k=int($2*rand())]"#"}END{for(;j<$2;)print"|"c[j++]}

รับอาร์กิวเมนต์ 2 ตัวแรกจำนวนไอเท็มจากนั้นตามด้วยจำนวนกล่อง เริ่มต้นด้วยการ seed ตัวสร้างตัวเลขสุ่มเพื่อให้การทำงานแต่ละครั้งแตกต่างกัน จากนั้นสร้างสตริงในอาร์เรย์ตัวอย่างการใช้งาน:

awk '{srand();for(;n++;)c[k]=c[k=int($2*rand())]"#"}END{for(;j<$2;)print"|"c[j++]}' <<< "12 5"

Example output:
|##
|###
|##
|##
|###

1

MATLAB, 103 94 ไบต์

function a(m,n)
d=@(p)disp(char([1,~(1:p)]+48));for i=1:m-1;p=randi([0,n]);d(p);n=n-p;end;d(n)

ด้วยการจัดรูปแบบ

function a(m,n)
for i=1:m-1 
    d=@(p)disp(char([1,~(1:p)]+48));  % inline function for displaying
    p=randi([0,n]);              % picking a random number b/w 0 and n
    d(p);                        % '1' represents the box/pigeonhole, with '0's denoting entries
    n=n-p;
end
d(n);                            % writing the remaining entries/zeros

ตัวอย่างผลลัพธ์

>> a(4,7)
10
10000
10
10

มีช่องว่างต่อท้ายเนื่องจากแต่ละรายการอาร์เรย์จะแสดงพร้อมกับแท็บคั่นระหว่างแต่ละรายการ แต่ควรยอมรับได้ตามข้อกำหนด

ดูเหมือนจะเป็นการใช้งานที่ง่ายมากสำหรับฉันดังนั้นฉันจึงมั่นใจว่าสิ่งนี้สามารถปรับปรุงได้

ขอบคุณ @Luis Mendo สำหรับคำแนะนำ


คุณสามารถบันทึกได้เพียงไม่กี่ไบต์ซึ่งกำหนดคำสั่งการแสดงผลเป็นฟังก์ชั่นนิรนามเพื่อหลีกเลี่ยงการเขียนสองครั้ง:d=@(p)disp(char([1,~(1:p)]+48));for i=1:m-1;p=randi([0,n]);d(p);n=n-p;end;d(n)
Luis Mendo

@LuisMendo ขอบคุณสำหรับคำแนะนำฉันจะอัปเดต ฉันสามารถกำหนดฟังก์ชั่นที่แท้จริงของฉันได้ด้วยวิธีเดียวกันเช่น a = @ (m, n) ... เนื่องจากจะลดจำนวนไบต์ด้วย คนทั่วไปจะลบ / ย่อ "ชื่อฟังก์ชั่น (args)" ใน MATLAB code-golf ได้อย่างไร?
Krostd

ใช่คุณสามารถใช้ฟังก์ชัน anoymous เป็นคำตอบได้ คุณสามารถข้ามa=ไป ในกรณีนี้คุณไม่สามารถทำตามหลักการได้เพราะฟังก์ชั่นที่ไม่ระบุชื่อไม่สามารถมีลูปได้ eval('...')แต่คุณสามารถใช้เคล็ดลับของการวางทุกอย่างลงไป BTW นั้นถือว่าปกติน่าเกลียดและการปฏิบัติที่ไม่ดีใน Matlab แต่ที่นี่เราชอบภาษาที่ใช้ในทางที่ผิด :-)
Luis Mendo

อืม .. ฉันจะอัปเดตตามข้อเสนอแนะของคุณและคิดเพิ่มเติมเกี่ยวกับเรื่องนี้และดูว่าฉันสามารถหลีกเลี่ยงการวนซ้ำได้ไหม ฉันสามารถคิดตรรกะที่สามารถทำได้ แต่ไม่แน่ใจว่าจะนำไปใช้อย่างไรฉันกำลังคิดที่จะกำหนดหมายเลข 10 ^ n และค้นหาหมายเลข m ซึ่งเป็นพลังทั้งหมด 10 แล้วพิมพ์ออกมา มันจะเหมือนกับผลลัพธ์ที่ฉันได้ตอนนี้ .. : D ข้อเสนอแนะ? รู้สึกอิสระที่จะโพสต์มันเป็นคำตอบอื่น
Krostd

ฉันหมายถึงปัจจัย m (ไม่ใช่แค่ตัวเลขใด ๆ )
Krostd

1

อ็อกเท62 62ไบต์

@(n,m)strcat(62,(sum(randi(m,1,n)==(1:m)',2)>=1:n)*42)

ฟังก์ชั่นไม่ระบุชื่อที่ใช้สองตัวเลขและส่งออกอาร์เรย์ 2 มิติของ chars ด้วย>สำหรับกล่องและ *สำหรับวัตถุ ผลลัพธ์ทั้งหมดมีโอกาสเท่ากัน

ลองออนไลน์!


1

TI-Basic, 63 62 ไบต์

Prompt N,M
For(A,1,M
N→B
If M-A
randInt(0,N→B
":→Str0
For(C,1,B
Ans+"X→Str0
End
Disp Ans
N-B→N
End

แต่ละการมอบหมายควรมีความน่าจะเป็นที่ไม่เป็นศูนย์ในการเลือก

เกณฑ์นี้ทำให้โปรแกรมนี้ง่ายต่อการเขียน

ตัวอย่าง I / O:

prgmPIDGEON
N=?5
M=?2
:XXXX
:X

คำอธิบาย:

Prompt N,M     # 5 bytes, input number of items, number of boxes
For(A,1,M      # 7 bytes, for each box
N→B            # 4 bytes, on last box, make sure the sum is met by adding N items
If M-A         # 5 bytes, if not last box
randInt(0,N→B  # 8 bytes, add random number of items from 0 to N to box A
":→Str0        # 6 bytes, first character
For(C,1,B      # 7 bytes, add B items to the box
Ans+"X→Str0    # 8 bytes
End            # 2 bytes
Disp Ans       # 3 bytes, print this box
N-B→N          # 6 bytes, subtract the items used in this box
End            # 1 byte, move on to next box

1

MATLAB, 73 64 58 ไบต์

อัพเดท # 3

ฉันต้องการเรียงลำดับดูเหมือนว่าเนื่องจากมิฉะนั้นฉันจะได้จำนวนเต็มลบ ฉันได้แทนที่disp(sprintf(...))ด้วยfprintf(...)ตอนนี้ดังนั้นคำตอบยังคง 58 ไบต์

@(m,n)fprintf('%i\n',10.^diff([0;sort(randi(n,m-1,1));n]))

ปรับปรุง # 2:

ฉันรู้ว่าฉันไม่จำเป็นต้องเรียงลำดับอาร์เรย์และในความเป็นจริงการเรียงลำดับจะลดค่าเฉลี่ยของตัวเลขในอาร์เรย์ ดังนั้นฉันจึงลบsort(...)ส่วนนี้ โปรดทราบว่าผลลัพธ์ยังคงเหมือนเดิมดังนั้นฉันจึงไม่อัปเดต "ตัวอย่างผลลัพธ์"

@(m,n)disp(sprintf('%i\n',10.^diff([0;randi(n,m-1,1);n])))

ในที่สุดปิดในคำตอบ Octave โดย Luis! : D

ปรับปรุง # 1:

@(m,n)disp(sprintf('%i\n',10.^diff([0;sort(randi(n,m-1,1));n])))

แทนที่จะแปลงเป็นสตริงฉันแค่แสดงตัวเลขโดยตรง ฉันสามารถลดได้ถึง 58 ไบต์โดยการลบdisp(...)แต่จากนั้นฉันก็เพิ่มพิเศษans =ด้วย sprintf และไม่รู้ว่ามันเป็นที่ยอมรับหรือไม่

รหัสเริ่มต้น:

@(m,n)disp(strjust(num2str(10.^diff([0;sort(randi(n,m-1,1));n])),'left'))

ขอขอบคุณที่ให้คำแนะนำบางอย่างโดยหลุยส์ , ผมได้กำจัดของวงในคำตอบของฉันก่อนหน้า ตอนนี้ฉันแรกสร้างอาร์เรย์แนวตั้งของmตัวเลขสุ่มเพิ่มขึ้นไปn( diff([0;sort(randi(n,m-1,1));n])) จากนั้นใช้พวกเขาเป็นเลขชี้กำลัง 10 จากนั้นแปลงเป็นสตริงสตริงปรับซ้ายและแสดงพวกเขา

ในทางเทคนิคฉันสามารถกำจัด disp (... ) เพื่อบันทึกอีก 6 ไบต์ แต่จากนั้น "ans" จะได้รับการพิมพ์ซึ่งอาจเป็นการละเมิดข้อกำหนด อาจมีวิธีการเปลี่ยนเป็นสตริงและจัดชิดซ้ายเพื่อรับรูปแบบสิ้นสุดที่ต้องการดังนั้นฉันเปิดให้คำแนะนำ

ตัวอย่างผลลัพธ์:

>> a=@(m,n)disp(strjust(num2str(10.^diff([0;sort(randi(n,m-1,1));n])),'left'));
>> a(4,6)
1000
10  
100 
1   

หมายเหตุ : ฉันได้เปลี่ยนฟังก์ชั่นของฉันเป็นฟังก์ชั่นนิรนามที่นี่ ในผลลัพธ์ตัวอย่างฉันได้กำหนดให้aเพื่อแสดง ฉันหวังว่านี่จะไม่ละเมิดรายละเอียด แต่ถ้าเป็นโปรดแจ้งให้เราทราบและฉันจะเปลี่ยน


ฉันเพิ่งรู้ว่าคำตอบยอดนิยมใช้ตรรกะเดียวกันกับ 10 ^ .. สำหรับสิ่งที่คุ้มค่าและถ้ามันเป็นเรื่องสำคัญฉันไม่ได้ใช้มันเป็นข้อมูลอ้างอิงสำหรับคำตอบของฉัน .. (แต่แดงมีคนเอาชนะฉันไปที่มัน!: P)
Krostd

และต้องการบันทึกเครดิตให้กับคำตอบนี้สำหรับแนวคิดในการสร้างmจำนวนเต็มแบบสุ่มที่รวมอยู่nด้วยเนื่องจากฉันติดอยู่กับส่วนนั้นเป็นเวลานาน .. (ยังไม่สามารถเพิ่มลิงก์มากกว่า 2 ลิงก์ในคำตอบของฉันได้ ในความคิดเห็น)
Krostd

1

ซ้อนกัน , 29 ไบต์

('|')\rep\[:randin'#'push@.]*

ลองออนไลน์!

ทำงานโดยการสร้างอาร์เรย์ของMsingletons ที่มีอยู่'|'จากนั้นเพิ่มเวลา'#'อาร์เรย์ที่เลือกแบบสุ่มN


ดี! และผลลัพธ์ทั้งหมดมีแนวโน้มเท่ากันใช่ไหม
Luis Mendo

@ LuisMendo มันควรจะเป็นเพราะrandinใช้อัลกอริทึม Fisher-Yates ภายใน (นี่เป็นอัลกอริทึมแบบเดียวกันกับที่คำตอบของ CJam ใช้ FWIW)
Conor O'Brien

1

Python 2 , 80 95 89 88 ไบต์

from random import*
n,m=input()
while m:x=randint(0,n);print'1'+'0'*[n,x][m>1];m-=1;n-=x

ลองออนไลน์!

  • เพิ่ม 15 ไบท์: การแก้ไขก่อนหน้านี้มีข้อบกพร่องเล็กน้อย, มีรูปเพกรูปบางส่วนถูกปล่อยออกมา
  • บันทึกแล้ว 6 ไบต์: แทนที่ด้วยถ้าอื่นโดย [n, x] [m> 1]
  • บันทึก 1 ไบต์: นำเข้า *

1

ถ่าน 19 ไบต์

≔EN⟦⟧θFN⊞‽θ#Eθ⁺|⪫ιω

ลองออนไลน์! การเชื่อมโยงคือการใช้รหัสเวอร์ชันอย่างละเอียด คำอธิบาย:

  N                 Input `M`
 E                  Map over implicit range
   ⟦⟧               Empty array
≔    θ              Assign resulting nested array to `q`

       N            Input `N`
      F             Loop over implicit range
          θ         Nested array `q`
         ‽          Random element
           #        Literal string
        ⊞           Append to array

             θ      Nested array `q`
            E       Map over array
                 ι  Current element
                  ω Empty string
                ⪫   Join
               |    Literal string
              ⁺     Concatenate
                    Implicitly print on separate lines
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.