สร้างลำดับ Skolem


10

ลำดับ Skolem

ลำดับ Skolemเป็นลำดับของ2nตัวเลขซึ่งมีจำนวนทุกiระหว่าง1และnเกิดขึ้นสองเท่าและระยะห่างระหว่างทั้งสองเกิดขึ้นของiอยู่ตรงiขั้นตอน นี่คือตัวอย่างของลำดับ Skolem:

1 1
1 1 4 2 3 2 4 3
16 13 15 12 14 4 7 3 11 4 3 9 10 7 13 12 16 15 14 11 9 8 10 2 6 2 5 1 1 8 6 5

ลำดับต่อไปนี้ไม่ใช่ลำดับ Skolem:

1 2 1 2      (The distance between the 1's is 2, not 1)
3 1 1 3      (The number 2 is missing)
1 1 2 1 1 2  (There are four 1's)

วัตถุประสงค์

เขียนโปรแกรมฟังก์ชั่นหรือการแสดงออกเพื่อนับจำนวนลำดับ Skolem ทั้งหมดของความยาวที่กำหนด เพิ่มเติมอย่างชัดเจนป้อนข้อมูลของคุณเป็นจำนวนเต็มnและส่งออกของคุณคือจำนวนของลำดับ Skolem 2nของความยาว ลำดับนี้มีรายการ OEIS สำหรับn = 0คุณอาจจะกลับมาอย่างใดอย่างหนึ่งหรือ0 1ค่าแรก ๆ ที่เริ่มต้นจาก0คือ

0, 1, 0, 0, 6, 10, 0, 0, 504, 2656, 0, 0, 455936, 3040560, 0, 0, 1400156768

กฎและการให้คะแนน

นี่คือรหัสกอล์ฟ รูปแบบผลลัพธ์เป็นหละหลวมในเหตุผล


แค่อยากรู้อยากเห็น แต่0, 1, 0, 0, 6...ในคำถามของคุณคืออะไร? เป็นข้อมูลโค้ดหรือไม่หากเป็นเช่นนั้นภาษาใด
PhiNotPi

2
ทำไมเป็นรายการแรกในการส่งออกของคุณ0? หากคุณกำลังจะยอมรับเป็นสัญญาณเข้าที่ถูกต้องแล้วออกที่ควรจะเป็น0 1
Peter Taylor

1
บางคน (รวมถึงรหัสของฉัน) เชื่อว่าไม่มีลำดับที่ว่างเปล่า หาก 1 ทำให้คุณรู้สึกดีขึ้นให้ส่งคืน
บูธโดย

2
AFAIK ในทุกบริบทที่คุณคิดว่ามีเพียงหนึ่งในลำดับ / วัตถุว่างเปล่า / ชุดว่างเปล่าหนึ่ง / อื่น ๆ / ฟังก์ชั่นเพื่อ / จากชุดว่างเปล่า / กราฟว่าง / อื่น ๆ
บาคุริว

1
@boothby คุณเพียงแค่เรียก Knuth a fool?
Peter Taylor

คำตอบ:


8

GolfScript, 48 46 ตัวอักษร

:b,1,{)2\?){{.2$&!{.2$|@@}*.+.4b?<}do;;}+%}@/,

รุ่นที่เร็วกว่า ( ลองออนไลน์ ) - ทำงานอย่างรวดเร็วเช่นn=8ใช้เวลาประมาณสองวินาที และวิธีการที่เลือกนั้นใช้ตัวละครน้อยมาก

รุ่นนี้ยังทำงานร่วมกับ bitmasks มันจะสร้างอาเรย์ผลลัพธ์ที่เป็นไปได้ตั้งแต่ 1 ขึ้นไปเช่นn=3:

1: 000011        000110 001100 011000 110000
2: 010111 101011 101110        011101 110101 111010

ในขณะที่ผลลัพธ์บางรายการ (เช่น 000011) มีสองสิ่งต่อเนื่องที่เป็นไปได้อื่น ๆ (เช่น 001100) ไม่มีและจะถูกลบออกจากอาร์เรย์ผลลัพธ์

คำอธิบายของรหัส:

:b           # save the input into variable b for later use
,            # make the list 0..b-1 (the outer loop)
1,           # puts the list [0] on top of the stack - initially the only possible
             # combination
{)           # {...}@/ does the outer loop counting from i=1 to b
  2\?)       # computes the smalles possible bit mask m=2^i+1 with two bits set 
             # and distance of those equal to i (i.e. i=1: 11, i=2: 101, ...)
  {          # the next loop starts with this bitmask (prepended to code via
             # concatination {...}+
             # the loop itself iterates the top of the stack, i.e. at this point 
             # the result array                 
             # stack here contains item of result array (e.g. 00000011)
             # and bitmask (e.g. 00000101)
    {        # the inner-most loop tries all masks with the current item in the result set
      .2$&!  # do item and result set share not single bit? then - {...}*
      {
        .2$| # then generate the new entry by or-ing those two
        @@   # push it down on the stack (i.e. put working items to top)
      }*
      .+     # shift the bit mask left by one
      .4b?<  # if still in the range loop further
    }do;;    # removes the remainders of the loop (i.e. item processed and mask)
  }+%        # stack now contains the new result array
}@/
,            # length of result array, i.e. the number of Skolem sequences

ยอมรับวิธีแก้ปัญหาที่เชื่อมโยงเร็วกว่า
บูธโดย

6

นิพจน์ J, 47 ตัวอักษร

 +/*/"1((=&{:+.2-#@])#;.2)\"1~.(i.!+:y)A.,~>:i.y

ตัวอย่าง:

    y=:5
    +/*/"1((=&{:+.2-#@])#;.2)\"1~.(i.!+:y)A.,~>:i.y
10

ใช้เวลาประมาณ 30 วินาทีสำหรับy=:5เครื่องของฉัน

อัลกอริทึมช้าที่สุด:

  • ~.(i.!+:y)A.,~>:i.yสร้างทุกการเปลี่ยนแปลง1 2 .. y 1 2 .. yและลบรายการที่ซ้ำกัน
  • ((=&{:+.2-#@])#;.2)\"1 คำนวณ:
    • (...)\"1 สำหรับคำนำหน้าของทุกแถว:
      • #;.2 นับองค์ประกอบก่อนการเกิดขึ้นขององค์ประกอบสุดท้ายแต่ละรายการ
      • #@] นับจำนวนการนับ (เช่นจำนวนการปรากฏขององค์ประกอบสุดท้าย)
      • =&{: กำหนด "ความเท่าเทียมกัน" "ของ" องค์ประกอบสุดท้าย "ของรายการนับและของรายการเดิม
      • +.เป็นตรรกะหรือ =&{:+.2-#@]อ่าน "ทั้งองค์ประกอบสุดท้าย [ของรายการนับและรายการเดิม] เท่ากันหรือมีเพียงหนึ่งองค์ประกอบ [ในรายการนับ] มากกว่าสอง"
  • */"1 ทวีคูณ (ตรรกะ AND) บนแถวของตารางเงื่อนไขระบุว่าการเรียงสับเปลี่ยนเป็นลำดับ Skolem
  • +/ รวมจำนวนและศูนย์ด้วยกัน

6

GolfScript (46 ตัวอักษร)

:&1,\,{0,2@)?)2&*{2${1$^}%@+\2*}*;+}/{4&?(=},,

นี่คือนิพจน์ที่รับอินพุตบนสแต็ก หากต้องการแปลงเป็นโปรแกรมเต็มรูปแบบซึ่งรับอินพุตบน stdin ให้เติม~

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

วิธีการคือการปิดบังผลิตภัณฑ์คาร์ทีเซียนในระดับบิต เช่น (ใช้ไบนารีสำหรับมาสก์) สำหรับn=4รหัส ungolfed จะคำนวณ xor [00000011 00000110 ... 11000000] x [00000101 00001010 ... 10100000] x ... x [00010001 ... 10001000]ของแต่ละองค์ประกอบในผลิตภัณฑ์คาร์ทีเซียน ผลลัพธ์ใด ๆ ที่มี 8 บิตสามารถทำได้โดยมาสก์ที่ไม่ทับซ้อนกัน

ในการปรับขนาดให้เหมาะสมแทนที่จะใช้ความเร็วรหัสจะรวบรวมผลิตภัณฑ์บางส่วน ( S1 u S1xS2 u S1xS2xS3 ...) และทำให้แต่ละผลิตภัณฑ์เป็น2nองค์ประกอบแทนที่จะเป็นเพียงส่วน2n-1-iที่สามารถนำไปสู่ลำดับที่ถูกต้องได้จริง

ความเร็ว

แข็งแรงเล่นกอล์ฟรุ่นวิ่งn=5ใน 10 วินาทีบนคอมพิวเตอร์ของฉันและไม่ต่ำกว่า 5 n=6นาที ฉบับที่ไม่ได้รับการตีพิมพ์คำนวณn=5ในเวลาน้อยกว่าหนึ่งวินาทีและn=6ประมาณ 1 นาที ด้วยตัวกรองแบบง่าย ๆ กับผลลัพธ์ระดับกลางมันสามารถคำนวณได้n=8ใน 30 วินาที ฉันเล่นกอล์ฟถึง 66 ตัวอักษร (เป็นโปรแกรม - ตัวอักษร 65 ตัว) ในขณะที่รักษาลูปให้ถูก จำกัด เท่าที่จะทำได้และกรองการชนระดับกลาง:

~:&1,\,{0,\).2\?)2&*@-{.{[\].~^.@~+<{;}*}+3$%@+\2*}*;\;}/{4&?(=},,

ประณาม. เมื่อฉันคิดว่าโซลูชั่น 48char J ของฉันดีพอที่จะโพสต์ได้
John Dvorak

ประณาม. การผูกตัวละคร 47 ตัวของเราไม่นานนัก +1
John Dvorak

5

GolfScript, 49 ตัวอักษร

~:/..+?:d(,{d+/base(;:w;/,{.w?)w>1$?=},,/=},,/1=+

คาดnหวังว่าจำนวนใน STDIN นี่คือ code-golf - อย่าลองใช้รหัสที่nมากกว่า 5


โอ้ไม่น้อยกว่า 5
บูธตาม

@boothby มันเป็นความพยายามครั้งแรกโดยตรง เรามักจะต้องใช้ความเร็วในการตัดสินใจกับขนาด - และรหัสกอล์ฟเป็นเรื่องเกี่ยวกับขนาด นั่นเป็นเหตุผลที่ฉันยังเพิ่มรุ่นที่รวดเร็ว - ซึ่งเดิมยาวกว่ามาก แต่ตอนนี้สั้นลงกว่าเดิม
Howard

0

Sage, 70

นี่สั้นกว่าต้นฉบับนิดนึง

sum(1for i in DLXCPP([(i-1,j,i+j)for i in[1..n]for j in[n..3*n-i-1]]))

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

รับเมทริกซ์ 0/1 ปัญหาการปกที่แน่นอนสำหรับเมทริกซ์นั้นคือการหาเซตย่อยของแถวที่รวม (เป็นจำนวนเต็ม) ให้กับเวกเตอร์ทุกคน ตัวอย่างเช่น,

11001
10100
01001
00011
00010

มีทางออก

10100
01001
00010

แนวทางที่ฉันชอบในการแก้ไขปัญหาคือการทำให้พวกเขามีปัญหาปกที่แน่นอน ลำดับ Skolem อำนวยความสะดวกอย่างมีประสิทธิภาพนี้ ฉันจะทำให้ปัญหาฝาครอบที่แน่นอนที่การแก้ปัญหาอยู่ใน bijection วนเวียนอยู่กับ Skolem 2nของความยาว ตัวอย่างเช่นแถวของปัญหาn=6คือ

  a   |  b  
001000|001001000000 # S[b] = S[b+a+1] = a

โดยที่ 1 ในตำแหน่งa < nหมายถึงสัญลักษณ์ที่aใช้ ตำแหน่งที่เหลือจะสอดคล้องกับตำแหน่งจริงตามลำดับ ใบปะหน้าที่แน่นอนนั้นตรงกับสัญลักษณ์แต่ละตัวที่ใช้งานเพียงครั้งเดียว โดยการก่อสร้างสัญลักษณ์ใด ๆkในสถานที่ตั้งคือkช่องว่างห่างจากคู่ของมัน

ใน Sage DLXCPPเป็นการใช้งาน "การเชื่อมโยงการเต้นรำ" - มันแก้ปัญหาการปกที่แน่นอนในลักษณะที่สง่างามล้ำ มันเป็นหนึ่งในอัลกอริธึมที่ฉันโปรดปรานและการอยู่ที่พื้นผิวใน Sage ทำให้การนับรวมเป็นความสุข


ว้าวลิงค์เต้น การใช้len(list(...))จะบันทึก 4 ตัวอักษร
เรย์

@ เรย์คอมพิวเตอร์ของฉันจะตายถ้าฉันคำนวณlen(list(...))สำหรับ n = 16 และมันจะฆ่ารันไทม์อย่างเต็มที่
บูธตาม

ถูกต้องเพราะการแปลงเครื่องกำเนิดเป็นรายการหน่วยความจำจำนวนมาก
เรย์
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.