การแบ่งตารางออกเป็นสามเหลี่ยม


18

เป้าหมาย

เป้าหมายของความท้าทายนี้คือการสร้างฟังก์ชั่นnซึ่งคำนวณจำนวนวิธีในการแบ่งn X 1ตารางเป็นสามเหลี่ยมซึ่งจุดยอดทั้งหมดของสามเหลี่ยมอยู่บนจุดกริด

ตัวอย่าง

ตัวอย่างเช่นมี 14 วิธีในการแบ่งพาร์ติชันตาราง 2 x 1 ดังนั้นf(2) = 14ผ่านพาร์ติชันต่อไปนี้พาร์ติชันของ 2 x 1 โดยที่พาร์ติชันมี 2, 2, 2, 2, 2, 4 และ 2 ทิศทางที่แตกต่างกันตามลำดับ

เกณฑ์การให้คะแนน

นี่คือดังนั้นรหัสที่สั้นที่สุดจึงชนะ


10
กรณีทดสอบเพิ่มเติมบางอย่างอาจเป็นประโยชน์ดังนั้นเราจึงสามารถตรวจสอบว่าการส่งของเราถูกต้อง
AdmBorkBork

8
คุณอาจต้องการระบุรูปสามเหลี่ยมที่ไม่เสื่อม
Arnauld

1
ฉันได้ทำการแก้ไขตามลำดับ OEIS A051708เพื่อสะท้อนการตีความนี้
Peter Kagey

คำตอบ:


2

05AB1E , 13 ไบต์

·LÉœÙεÅγo;P}O

คำตอบ Jellyของพอร์ต@Bubblerคำตอบวุ้น

ช้ามากเนื่องจากการเรียงสับเปลี่ยนในตัว

ลองมันออนไลน์หรือตรวจสอบปัจจัยสี่ครั้งแรก

คำอธิบาย:

·                # Double the (implicit) input
 L               # Create a list in the range [1, doubled_input]
  É              # Check for each if they're odd (1 if truthy, 0 is falsey)
                 # We now have a list of n 0s and n 1s (n being the input)
   œ             # Get all permutations of that list
    Ù            # Only leave the unique permutations
     ε     }     # Map each permutation to:
      Åγ         #  Run-length encode the current value (short for `γ€g`)
        o        #  Take 2 to the power for each
         ;       #  Halve each
          P      #  Take the product of the mapped permutation
            O    # Sum all mapped values together (and output implicitly)

19

Haskell , 60 55 54 52 ไบต์

หลังจากการวาดภาพและการเขียนโปรแกรมเป็นจำนวนมากมันเกิดขึ้นกับฉันว่านี่เป็นปัญหาของ rooks:

บนกระดานหมากรุก(n+1)×(n+1)กระดานหมากรุกมีกี่วิธีที่จะไปจาก(0,0)ถึง(n,n)เพียงแค่เลื่อนไปทางขวา+(1,0)หรือสูงกว่า+(0,1) ?

โดยทั่วไปคุณมีเส้นด้านบนและล่างของตาราง1×nตอนนี้คุณต้องกรอกข้อมูลในบรรทัดที่ไม่ใช่แนวนอน แต่ละสามเหลี่ยมต้องมีสองบรรทัดที่ไม่ใช่แนวนอน ไม่ว่าด้านใดด้านหนึ่งของมันจะเป็นส่วนหนึ่งของเส้นด้านบนหรือด้านล่างสอดคล้องกับทิศทางและความยาวที่คุณต้องเผชิญกับปัญหาโกง นี่คือOEIS A051708 ดังภาพประกอบของจดหมายนี้ให้พิจารณาตัวอย่างต่อไปนี้ ที่นี่บรรทัดบนสุดสอดคล้องกับการเคลื่อนไหวในขณะที่บรรทัดล่างสอดคล้องกับการเคลื่อนไหวขวา

ขอบคุณ @PeterTaylor สำหรับ -6 ไบต์และ @ PostLeftGarfHunter สำหรับ -2 ไบต์!

b 0=1
b 1=2
b n=div((10*n-6)*b(n-1)-9*(n-2)*b(n-2))n

ลองออนไลน์!


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

BTW A051708(n+1)คุณจำเป็นต้องปรับการจัดทำดัชนีเพราะคำตอบที่ถูกต้องที่นี่คือ ดังนั้นฉันโพสต์คำตอบแรกที่ถูกต้อง :-P
Peter Taylor

ฉันคิดว่ามันเป็นการเคลื่อนที่แผนที่ไปยังรูปสามเหลี่ยมโดยการทำรูปสามเหลี่ยมที่มีขอบด้านบนและด้านล่างสอดคล้องกับการเลื่อนขึ้นหรือลงใช่ไหม
นีล

@PeterTaylor ประณามขอบคุณสำหรับการชี้ให้เห็นความผิดพลาดของฉัน :)
flawr

5
@ ไม่มีฉันเพิ่มคำอธิบายแบบกราฟิก
ข้อบกพร่อง

8

Haskell , 42 ไบต์

0?0=1
a?b=sum[a?i+i?a|i<-[0..b-1]]
f n=n?n

ลองออนไลน์!

การประยุกต์ใช้โดยตรงอย่างเป็นธรรมที่เรียกซ้ำกว่า 2 ตัวแปร

นี่คือวิธีที่เราจะได้รับโซลูชันนี้ เริ่มต้นด้วยรหัสที่ใช้สูตรแบบเรียกซ้ำโดยตรง:

54 ไบต์

0%0=1
a%b=sum$map(a%)[0..b-1]++map(b%)[0..a-1]
f n=n%n

ลองออนไลน์!

การใช้การตีความโกงย้าย flawr ของ , a%bคือจำนวนของเส้นทางที่ได้รับจากเกมหมากรุก(a,b)การ(0,0)ใช้เพียงย้ายการลดลงของการประสานงาน การย้ายครั้งแรกจะลดaหรือลดลงbทำให้อีกอันหนึ่งเหมือนเดิมดังนั้นสูตรเวียนเกิดซ้ำ

49 ไบต์

a?b=sum$map(a%)[0..b-1]
0%0=1
a%b=a?b+b?a
f n=n%n

ลองออนไลน์!

เราสามารถหลีกเลี่ยงการทำซ้ำmap(a%)[0..b-1]++map(b%)[0..a-1]โดยสังเกตว่าทั้งสองครึ่งเหมือนกันaและbสลับกัน สายช่วยa?bนับเส้นทางที่ย้ายครั้งแรกลดลงaและเพื่อให้นับผู้ที่ย้ายครั้งแรกลดลงb?a เหล่านี้อยู่ในที่แตกต่างกันโดยทั่วไปและพวกเขาเพิ่มba%b

ในผลรวมยังสามารถเขียนเป็นความเข้าใจรายการa?ba?b=sum[a%i|i<-[0..b-1]]

42 ไบต์

0?0=1
a?b=sum[a?i+i?a|i<-[0..b-1]]
f n=n?n

ลองออนไลน์!

สุดท้ายเราก็กำจัดทิ้งไป%และเขียนการสอบถามซ้ำในแง่ของ?ด้วยการแทนที่a%iด้วยa?i+i?aการโทรซ้ำ

กรณีฐานใหม่ที่ทำให้เกิดนี้?จะให้ผลอีกครั้งว่าของ?ในรุ่น 49 ไบต์ตั้งแต่ที่มีเราจะมี0?0=1 0%0=0?0+0?0=2สิ่งนี้ช่วยให้ใช้ define f n=n?nโดยไม่ต้องแบ่งครึ่งที่เราต้องทำ


โซลูชัน 49 ไบต์ของคุณใช้การเรียกซ้ำแบบเดียวกับคำตอบของฉัน แต่ฉันยังไม่ได้หา 42 ไบต์ คำอธิบายจะดี
Peter Taylor

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

ผู้ประกอบการa%bนับจำนวนพาร์ติชันโดยใช้โหนด0,1,...,aบนบรรทัดด้านบนและพยักหน้า0,1,..,bในบรรทัดล่าง ผู้ประกอบการa?bนับจำนวนวิธีที่คุณสามารถเพิ่มบรรทัดใหม่จากโหนดบนสุดaหากโหนดด้านล่างbมีการใช้งานแล้ว (คุณสามารถเชื่อมต่อaกับทุกโหนด[0,1,...,b-1]ได้ แต่คุณจะต้องเสียค่าใช้จ่ายสำหรับแต่ละโหนดอีกครั้ง)
ข้อผิดพลาด

@ flawr นั่นคือ 49- ไบต์ซึ่งฉันเข้าใจ มันเป็น?ของขนาด 42- ไบต์ที่ฉันทำไม่ได้และสิ่งที่น่าประหลาดใจเป็นพิเศษคือมันไม่สมมาตร
Peter Taylor

@ PeterTaylor ขออภัยด้วยความสับสนฉันผสมสองวิธี ฉันคิดว่าเราสามารถเปลี่ยนวิธีแก้ปัญหาทั้งสองให้เป็นแบบอื่นได้ง่ายขึ้น: ในขั้นตอนแรกเราสามารถแทนที่map...ด้วยความเข้าใจในรายการในขั้นตอนที่สองเราเพิ่งเสียบนิยามของ%:a?b=sum$map(a%)[0..b-1], a%b=a?b+b?a a?b=sum[a%i|i<-[0..b-1]], a%b=a?b+b?a a?b=sum[a?i+i?a|i<-[0..b-1]]
ข้อบกพร่อง

7

CJam (24 ไบต์)

{2,*e!{e`0f=:(1b2\#}%1b}

การสาธิตออนไลน์

วิธีนี้ใช้วิธีของ Bubbler ในการหาผลรวมของพีชคณิตของn0s และn1s

การผ่า

{         e# Define a block
  2,*     e#   Given input n, create an array of n 0s and n 1s
  e!      e#   Generate all permutations of that array
  {       e#   Map:
    e`    e#     Run-length encode
    0f=:( e#     Extract just the lengths and decrement them
    1b    e#     Sum
    2\#   e#     Raise 2 to the power of that sum
  }%
  1b      e#  Sum the mapped values
}

วิธีทางเลือก (28 ไบต์)

{_1aa{_2$,f{j}@@,f{j}+1b}2j}

การสาธิตออนไลน์

การผ่า

สามเหลี่ยมทั้งหมดมีหนึ่งขอบแนวนอนและสองขอบซึ่งเชื่อมโยงกับเส้นแนวนอน ทำเครื่องหมายขอบที่ไม่ใช่แนวนอนโดย tuple ของ x-coords สองอันและเรียงตามพจนานุกรม จากนั้นขอบแรกคือขอบ(0,0)สุดท้ายคือ(n,n)และขอบต่อเนื่องสองอันนั้นแตกต่างกันในตำแหน่งใดตำแหน่งหนึ่งในสองตำแหน่ง สิ่งนี้ทำให้การเรียกซ้ำง่าย ๆ ซึ่งฉันได้ดำเนินการโดยใช้ตัวดำเนินการเรียกซ้ำที่บันทึกไว้j:

{            e# Define a block
  _          e#   Duplicate the argument to get n n
  1aa        e#   Base case for recursion: 0 0 => 1
  {          e#   Recursive body taking args a b
    _2$,f{j} e#     Recurse on 0 b up to a-1 b
    @@,f{j}  e#     Recurse on a 0 up to a b-1
    +1b      e#     Combine and sum
  }2j        e#   Memoised recursion with 2 args
}

บันทึก

นี่ไม่ใช่ครั้งแรกที่ฉันต้องการfjได้รับการสนับสนุนใน CJam ที่นี่มันจะนำคะแนนลงมาที่ 24 ไบต์เช่นกัน บางทีฉันควรลองเขียนแผ่นแปะ ...


Yay ฉันเอาชนะคุณ 10 วินาทีฉันไม่คิดว่าฉันเคยเข้าใกล้ :)
ข้อบกพร่อง

@ flawr ฉันพิจารณาการโพสต์ก่อนที่จะเขียน dissection แต่ฉันคิดว่าฉันมีเวลาที่จะเคาะออกอย่างรวดเร็ว จากนั้นฉันเห็น "คำตอบใหม่" ดังนั้นฉันจึงลบการคัดลอกส่วนที่เขียนแล้วโพสต์และแก้ไข
Peter Taylor

1
ขอบคุณสำหรับ -5 ไบต์ btw: D
ข้อบกพร่อง

4

เยลลี่ , 15 14 ไบต์

Ø.xŒ!QŒɠ€’§2*S

ลองออนไลน์!

-1 ไบต์ตามความคิดเห็นของ Peter Taylor

ใช้ภาพประกอบของข้อบกพร่องโดยตรงแทนที่จะเป็นสูตรผลลัพธ์

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

Ø.xŒ!QŒɠ€’§2*S    Main link (monad). Input: positive integer N.
Ø.x               Make an array containing N zeros and ones
   Œ!Q            All unique permutations
      Œɠ€         Run-length encode on each permutation
         ’§       Decrement and sum each
           2*S    Raise to power of 2 and sum

ใช้ทุกเส้นทางที่เป็นไปได้ในตารางสี่เหลี่ยม หลายวิธีที่จะย้ายหน่วย L 2**(L-1)ในทิศทางเดียวเป็นเกมหมากรุกเป็น ใช้สิ่งนี้กับทุกเส้นทางและสรุปจำนวนวิธีในการสำรวจแต่ละเส้นทาง


วิธีการที่ดี เมื่อฉันส่งไปที่ CJam มันสั้นกว่าเพื่อลดความยาว, ผลรวม, แล้วเพิ่ม 2 เป็นผลรวม; แทนที่จะเพิ่ม 2 ความยาวลดลงครึ่งหนึ่งจากนั้นคูณ ไม่ทราบว่าอาจช่วยให้คุณประหยัดไบต์
Peter Taylor

3

ถ่าน , 44 31 ไบต์

ขีดฆ่า 44 ยังคงเป็นปกติ 44

F⊕θ«≔⟦⟧ηF⊕θ⊞ηΣ∨⁺ηEυ§λκ¹⊞υη»I⊟⊟υ

ลองออนไลน์! คำอธิบาย: ทำงานโดยการคำนวณจำนวนวิธีในการแบ่งรูปสี่เหลี่ยมคางหมูที่มีความยาวด้านตรงข้ามกันm,nเป็นรูปสามเหลี่ยมซึ่งทั้งหมดอยู่ในออฟเซ็ตจำนวนเต็ม นี่เป็นกรณีทั่วไปของขนาดสี่เหลี่ยมผืนผ้าnในคำถาม จำนวนพาร์ทิชันจะได้รับซ้ำเป็นผลรวมของตัวเลขของพาร์ทิชันสำหรับทุกด้านและm,0..n-1 n,0..m-1นี้จะเทียบเท่ากับปัญหาทั่วไปของอีกา, OEIS A035002 รหัสจะคำนวณจำนวนของพาร์ติชันที่ทำงานจาก0,0สูงถึงn,nใช้ค่าที่คำนวณก่อนหน้านี้เมื่อมันไป

F⊕θ«

0..nห่วงมากกว่าแถว

≔⟦⟧η

เริ่มต้นด้วยแถวที่ว่างเปล่า

F⊕θ

0..nห่วงมากกว่าคอลัมน์ในแถว

⊞ηΣ∨⁺ηEυ§λκ¹

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

⊞υη»

เพิ่มแถวที่เสร็จแล้วลงในรายการของแถว

I⊟⊟υ

เอาต์พุตมูลค่าสุดท้ายที่คำนวณได้




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