Pascal's Rhombus


20

Pascal's Rhombus (ซึ่งจริงๆแล้วเป็นรูปสามเหลี่ยม) ได้มาจากการเพิ่มในรูปแบบ:

  *
 ***
  x

แทน

* *
 x

ซึ่งหมายความว่าแต่ละเซลล์คือผลรวมของสามเซลล์ในแถวที่อยู่เหนือมันโดยตรงและหนึ่งเซลล์ในแถวที่ 2 ที่อยู่เหนือมัน เช่นเดียวกับสามเหลี่ยมของปาสคาลแถวซีโรทมีหนึ่งอัน1ที่สร้างสามเหลี่ยม

นี่คือสองแถวแรกของรูปสี่เหลี่ยมขนมเปียกปูนของ Pascal

      1
    1 1 1
  1 2 4 2 1
1 3 8 9 8 3 1

งาน

กำหนดหมายเลขแถว (เริ่มต้นจากด้านบน) และหมายเลขคอลัมน์ (เริ่มจากรายการที่ไม่ใช่ศูนย์แรกในแถวนั้น) ส่งออกค่าที่เซลล์นั้น ๆ อินพุตทั้งสองอาจเป็นดัชนี 1 หรือ 0 (คุณอาจผสมและจับคู่หากคุณต้องการ)

นี่คือดังนั้นคุณควรตั้งเป้าหมายที่จะทำให้ขนาดไฟล์ของซอร์สโค้ดของคุณเล็กที่สุดเท่าที่จะทำได้

OEIS A059317


4
เช่นเดียวกับสามเหลี่ยมปาสคาล, ความเท่าเทียมกันของรูปสี่เหลี่ยมขนมเปียกปูนทำให้รูปแบบที่ดีและเศษส่วน
Martin Ender

คุณควรตั้งเป้าหมายที่จะทำให้ขนาดไฟล์ของซอร์สโค้ดของคุณเล็กที่สุดเท่าที่จะทำได้ถ้าฉันใส่โค้ดของฉันเป็นอาร์กิวเมนต์บรรทัดคำสั่ง? : P
Erik the Outgolfer

googling ไปหาทางลัดและเห็นได้ชัดว่าarxiv.org/abs/1504.04404กล่าวว่าการคำนวณผลลัพธ์โดยตรงไม่สามารถใช้งานได้สำหรับการเล่นกอล์ฟรหัส
JollyJoker

คำตอบ:


12

Haskell , 59 55 ไบต์

Pascal's Rhombus? เหมือน Rhombus ของ Haskell! ฉันถูกไหม?

บันทึกได้ 4 ไบต์ด้วยØrjan Johansen

ฉันคิดว่าฉันต้องไปที่ปัญหาของตัวเองและฝึกฝน Haskell ของฉัน หวังว่านี่จะเป็นแรงบันดาลใจให้ผู้คนตอบคำถามนี้มากขึ้น

1!1=1
n!k=sum[(n-2)!(k-2)+sum(map((n-1)!)[k-2..k])|n>1]

ลองออนไลน์!

คำอธิบาย

มันค่อนข้างล้าสมัยด้วยสนามกอล์ฟล่าสุด

แทนที่จะคำนวณ

  *
 ***
  x

เราคำนวณ

*
***
  x

นี่ทำให้สามเหลี่ยมทั้งหมดของเรากลายเป็น

1
1 1 1
1 2 4 2 1
1 3 8 9 8 3 1

แถวนี้เรียงแถวของเราทั้งหมดทำให้ง่ายขึ้นในการจัดทำดัชนีรายการที่ n ของคอลัมน์ใด ๆ จากนั้นเราจะกำหนดกรณีฐานของเรา

แถวศูนย์คือศูนย์ทั้งหมด

0!_=0

มี1ตำแหน่งเดียว1,1ดังนั้นเราจึงกำหนดสิ่งนั้น

1!1=1

และเรากำหนดส่วนที่เหลือของแถวแรกให้เป็นศูนย์เช่นกัน

1!_=0

จากนั้นเราจะกำหนดกรณีทั่วไปแบบเรียกซ้ำโดยใช้รูปแบบที่อธิบายไว้ข้างต้น:

n!k=(n-2)!(k-2)+(sum$map((n-1)!)[k-2..k])

เอาชนะฉันไป! นี่มันสะอาดกว่าของฉันอีกมาก
Julian Wolf

@JulianWolf ขออภัยที่เมื่อฉันโพสต์สิ่งนี้ดูเหมือนว่าไม่มีใครอื่นนอกจาก Jorg กำลังทำปัญหา ฉันยังต้องการดูวิธีแก้ปัญหาของคุณ
ข้าวสาลีตัวช่วยสร้าง

1
n!k=sum[(n-2)!(k-2)+sum(map((n-1)!)[k-2..k])|n>1]คุณสามารถบันทึกสี่ไบต์ด้วย
Ørjan Johansen

10

ปาสคาล , 122 ไบต์

มันเป็นรูปสี่เหลี่ยมขนมเปียกปูนของปาสกาล

บันทึก 37 ไบต์ด้วย @manatwork

function f(n,k:integer):integer;begin f:=1-Ord((k<0)or(k>n*2));if n>0then f:=f(n-1,k-2)+f(n-1,k-1)+f(n-1,k)+f(n-2,k-2)end;

ลองออนไลน์!


วงเล็บรอบifเงื่อนไขทั้งหมดไม่มีจุดหมาย (ในวันที่ 1 ifคุณบันทึกอักขระ 2 ตัวบนifอักขระ 1 ตัวที่2 โดยไม่เว้นช่องว่างระหว่างthenคำหลักและตัวเลขก่อนหน้า) โอ้และตัวแปร r ไม่จำเป็นอย่างสมบูรณ์
จัดการ

สัตว์ประหลาดที่ Pascal บน Ideone ไม่เคยเห็นเครื่องหมายคำพูดคั่นคู่ในตัวแปร Pascal ใด ๆ มาก่อน อีกสิ่งหนึ่งที่คุณสามารถลบออก: ;ก่อนหน้าfunctionนี้endคือ
จัดการ

@manatwork เออตอนนี้เมื่อคุณกล่าวว่าทั้งหมดของบรรณาธิการออนไลน์อื่น ๆ บ่นเกี่ยวกับมัน
ยูเรียล

@ การทำงานฉันไม่แน่ใจว่าฉันเข้าใจ จะไม่ว่าเพียงแค่รหัสยาว>= <=หรือไม่ ฉันยังคงต้องรักษาif n=0
Uriel

ขออภัย @Uriel ฉันไม่มีเวอร์ชันนั้นอีกแล้ว ขณะนี้ฉันอยู่ที่function f(n,k:integer):integer;begin f:=1-Ord((k<0)or(k>n*2));if n>0then f:=f(n-1,k-2)+f(n-1,k-1)+f(n-1,k)+f(n-2,k-2)end;
จัดการ

7

PHP , 86 ไบต์

วิธีแบบเรียกซ้ำเฉพาะแถวฟังก์ชั่นและคอลัมน์ 0-Indexed

function f($r,$c){return$r|$c?$r<0?0:f($r-=1,$c)+f($r,$c-1)+f($r,$c-=2)+f($r-1,$c):1;}

ลองออนไลน์!

PHP , 114 ไบต์

วิธีแบบเรียกซ้ำเต็มแถวโปรแกรมและคอลัมน์ 0-Indexed

<?=f(...$_GET);function f($r,$c){return$r|$c?$r<0|$c<0|$c>2*$r?0:f($r-=1,$c)+f($r,$c-1)+f($r,$c-=2)+f($r-1,$c):1;}

ลองออนไลน์!

PHP , 129 ไบต์

แถวและคอลัมน์ 0 ทำดัชนี

for(;$r<=$argv[1];$l=$t[+$r++])for($c=~0;$c++<$r*2;)$t[+$r][$c]=$r|$c?$t[$r-2][$c-2]+$l[$c]+$l[$c-1]+$l[$c-2]:1;echo$l[$argv[2]];

ลองออนไลน์!


และ +1 สำหรับการปรับปรุงจริง :)
Uriel


3

MATL , 22 20 19 ไบต์

Ti:"2Y6Y+FT_Y)]!i_)

อินพุตทั้งสองเป็นแบบอิง 0

ลองออนไลน์!

คำอธิบาย

อนุญาตrและcแสดงถึงอินพุตทั้งสองระบุแถวและคอลัมน์ตาม 0

แต่ละแถวใหม่ในรูปสี่เหลี่ยมขนมเปียกปูนของ Pascal สามารถสร้างขึ้นจากเมทริกซ์ที่มีสองแถวก่อนหน้าโดยการประสานกับเคอร์เนล[1 1 1; 0 1 0]และทำให้สองแถวสุดท้ายของผลการแลกเปลี่ยน นี้จะทำครั้งที่เริ่มต้นจากเมทริกซ์r1

มันสั้นกว่าที่จะใช้เคอร์เนล[0 1 0; 1 1 1; 0 1 0]ซึ่งเป็นตัวอักษรที่กำหนดไว้ล่วงหน้า สิ่งนี้จะสร้างแถวพิเศษซึ่งจะถูกยกเลิก

ยกตัวอย่างเช่นr = 3มี3การทำซ้ำ

  1. เริ่มจาก

    1
    

    ด้วยการ[0 1 0; 1 1 1; 0 1 0]ให้

    0 1 0
    1 1 1
    0 1 0
    

    การรักษาสองแถวสุดท้าย (เมทริกซ์ทั้งหมดในกรณีนี้) และการแลกเปลี่ยนให้

    0 1 0
    1 1 1
    
  2. Convolutions จากข้างบนด้วยการ[0 1 0; 1 1 1; 0 1 0]ให้

    0 0 1 0 0
    0 1 1 1 0
    1 2 4 2 1
    0 1 1 1 0
    

    เมทริกซ์ที่เกิดขึ้นจากการสลับสองแถวสุดท้ายคือ

    0 1 1 1 0
    1 2 4 2 1
    

    ประกอบด้วยแถวใหม่ที่ด้านล่างและแถวก่อนหน้าขยายด้วยศูนย์

  3. ผลผลิตอีกครั้งที่น่าเชื่อถือ

    0 0 1 1 1 0 0
    0 1 2 3 2 1 0
    1 3 8 9 8 3 1
    0 1 2 4 2 1 0
    

    การสลับสองแถวสุดท้ายให้ได้

    0 1 2 4 2 1 0
    1 3 8 9 8 3 1
    

หลังจากrวนซ้ำแล้วเสร็จเอาต์พุตจะอยู่ในแถวสุดท้ายของเมทริกซ์สุดท้าย ตัวอย่างเช่นสำหรับc = 2(0-based) 8ผลจะเป็น แทนที่จะจัดทำดัชนีแถวสุดท้ายและคอลัมน์ที่ต้องการคุณสามารถใช้กลอุบายซึ่งหาประโยชน์จากความสมมาตรของแต่ละแถว: เมทริกซ์สุดท้ายถูกย้าย

0 1
1 3
2 8
4 9
2 8
1 3
0 1

และ-cองค์ประกอบที่จะถูกนำมา นี้ใช้การจัดทำดัชนีเชิงเส้น, ที่อยู่, เมทริกซ์ที่มีการจัดทำดัชนีโดยดัชนีเดียวในคอลัมน์ที่สำคัญเพื่อ เนื่องจากการจัดทำดัชนีเป็นแบบแยกส่วน - ผู้เข้าร่วม0เป็นมุมล่างขวา (ค่า1) และ-2รายการ -th เป็นสองขั้นตอนด้านบน (ค่า8)

T       % Push true
i       % Input row number
:"      % Do the following that many times
  2Y6   %   Push predefined literal [0 1 0; 1 1 1; 0 1 0]
  Y+    %   2D convolution, increasing size
  FT_   %   Push [0 -1]
  Y)    %   Matrix with rows 0 (last) and -1 (second-last), in that order
]       % End
!       % Transpose
i       % Input: colun number
_       % Negate
)       % Entry with that index. Implicitly display



2

Mathematica, 56 ไบต์

If[#<1,Boole[##==0],Sum[#0[#-i,#2-j],{i,2},{j,2i-2,2}]]&

ฟังก์ชั่นแท้รับสองจำนวนเต็มอาร์กิวเมนต์ (แถวแรกคอลัมน์ที่สอง) และกลับจำนวนเต็ม 0ธิสำหรับอาร์กิวเมนต์จำนวนเต็มเชิงลบเช่นกันกลับ โครงสร้างการเรียกซ้ำที่ค่อนข้างตรงไปตรงมา: If[#<1,Boole[##==0],...]กำหนดลักษณะการทำงานของตัวพิมพ์เล็กสำหรับแถวที่ 0 (และสูงกว่า) ในขณะที่Sum[#0[#-i,#2-j],{i,2},{j,2i-2,2}]ใช้นิยามแบบเรียกซ้ำ





0

Python 3 , 82 84 ไบต์

นี่เป็นการใช้งานแบบเรียกซ้ำพร้อมกับแถวและคอลัมน์ที่มีดัชนี 1 ชุด (ความต้องการด้านเทคนิคf=ด้านหน้ามีคนแจ้งให้ฉันทราบหากฉันควรเปลี่ยนเป็น 84 ไบต์ยังใหม่และไม่แน่ใจ 100% ของกฎ)

ใช้สูตรเรียกซ้ำที่พบในหน้า OEISแต่มีการkเลื่อนหนึ่งไปทางซ้ายเพื่อจัดเรียงอย่างถูกต้อง พ้องกัน, เป็นขนาดเดียวกับsum(f(n-1,k-i)for i in(0,1,2)) f(n-1,k)+f(n-1,k-1)+f(n-1,k-2)ฟังก์ชั่นทั้งหมดคือand orเคล็ดลับPython โดยที่เงื่อนไขแรกตรวจสอบว่า k อยู่ภายในรูปสามเหลี่ยมและไม่ได้อยู่ในขอบเขตซึ่งในกรณีนี้จะใช้สูตรแบบเรียกซ้ำ หากเป็นไม่ได้เป็นส่วนหนึ่งหลังจากที่orถูกส่งกลับซึ่งตรวจสอบว่าkอยู่ใน(1, 2*n-1)คือที่ชายแดนกลับและTrue เป็นหนึ่งไบต์สั้นกว่า การตัดที่อยู่ในวงเล็บและวางด้านหน้าไว้เป็นจำนวนเต็มซึ่งเป็นสิ่งที่จำเป็นFalsek+1in(2,2*n)k in(1,2*n-1)+

f=lambda n,k:2*n-1>k>1and sum(f(n-1,k-i)for i in(0,1,2))+f(n-2,k-2)or+(k+1in(2,2*n))

ลองออนไลน์!


f=ฟังก์ชั่นซ้ำต้อง
ข้าวสาลีตัวช่วยสร้าง

ในขณะที่ผมเองไม่เห็นด้วยกับมันตามนี้ฉันทามติเมตาฝังอยู่บ้างคุณอาจเอาท์พุทTrueแทน1เพราะพฤติกรรมเช่น1หลาม สิ่งนี้จะช่วยให้คุณลบ+(...)ตอนท้าย ฉันเข้าใจว่าถ้าคุณไม่ต้องการทำเช่นนี้เพราะมันจะทำให้ผลลัพธ์ดูแปลก ๆ มันเป็นตัวเลือก
ข้าวสาลีตัวช่วยสร้าง

@WeatWizard ว้าวน่าสนใจมาก ขอบคุณสำหรับทิป.
C McAvoy


0

Python 3 , 75 ไบต์

นี่เป็นแลมบ์ดาแบบเรียกซ้ำที่ใช้คอลัมน์และแถวเป็นจำนวนเต็ม 0 ดัชนี

p=lambda r,c:(r<0 or((c==0)|p(r-1,c-2)+p(r-1,c)+p(r-1,c-1)+p(r-2,c-2))+1)-1

นี่คือรุ่นที่อ่านได้มากกว่า (เล็กน้อย) พร้อมฟังก์ชั่นการพิมพ์:

p = lambda r,c:(r<0 or ((c==0) | p(r-1,c-2)+p(r-1,c)+p(r-1,c-1)+p(r-2,c-2))+1)-1

def pp(r):
    ml = len(str(p(r,r)))+1
    for i in range(0, r):
            a=" "*ml*(r-i)
            for j in range(0,i*2 + 1):
                    a+=str(p(i,j))+(" "*(ml-len(str(p(i,j)))))
            print(a)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.