เห็นภาพทฤษฎีบท Nicomachus


35

ทฤษฎีบทของ Nichomachus เชื่อมโยงกับผลบวกของผลรวมของลูกบาศก์:

ทฤษฎีบทของ Nichomachus

และมีการสร้างภาพทางเรขาคณิตที่สวยงาม:

การแสดง

ถาม: สร้างส่วนที่ 2d ของการสร้างภาพข้อมูลนี้ใน ascii

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

อินพุต / เอาต์พุต

อินพุตเป็นจำนวนเต็มเดียวที่มากกว่า 0 เอาท์พุทเป็นตาราง ASCII คล้ายกับตัวอย่างด้านล่างซึ่งสอดคล้องกับกริดแบนสำหรับหมายเลขอินพุตนั้นในภาพด้านบน ช่องว่างนำหน้าและต่อท้ายก็โอเค

นี่คือรหัสกอล์ฟที่มีกฎมาตรฐาน

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

N = 1

#

N = 2

#oo   
o@@   
o@@   

N = 3

#oo+++
o@@+++
o@@+++
+++###
+++###
+++###

N = 4

#oo+++oooo
o@@+++oooo
o@@+++@@@@
+++###@@@@
+++###@@@@
+++###@@@@
oo@@@@oooo
oo@@@@oooo
oo@@@@oooo
oo@@@@oooo

N = 5

#oo+++oooo+++++
o@@+++oooo+++++
o@@+++@@@@+++++
+++###@@@@+++++
+++###@@@@+++++
+++###@@@@#####
oo@@@@oooo#####
oo@@@@oooo#####
oo@@@@oooo#####
oo@@@@oooo#####
+++++#####+++++
+++++#####+++++
+++++#####+++++
+++++#####+++++
+++++#####+++++

รุ่นสามสีสำหรับ N = 4 ต้องขอบคุณ @BruceForte:

#oo+++oooo
o##+++oooo
o##+++####
+++ooo####
+++ooo####
+++ooo####
oo####++++
oo####++++
oo####++++
oo####++++

6
ทฤษฎีบทสี่สี: D
Leun Nun

1
คุณสามารถเพิ่มเอาต์พุตสำหรับ N = 5 ได้ไหม
Uriel

1
@Uriel เรียบร้อยแล้ว ดูการแก้ไขของฉัน
โยนาห์

ขอบคุณ! นอกจากนี้ฉันสามารถสลับ @ และระบบปฏิบัติการได้เฉพาะในแถบด้านนอกใน N = 4 หรือไม่ หรือผลลัพธ์จะต้องมีการทดแทนอย่างเข้มงวดของข้อความเหล่านี้ด้วยชุดอักขระอื่น?
Uriel

@ การสลับยูริลเป็นเรื่องปกติ สิ่งที่สำคัญคือสีที่อยู่ติดกันจะไม่ขัดแย้งกันเพื่อให้มองเห็นลวดลายได้
Jonah

คำตอบ:


17

MATL , 30 28 27 ไบต์

t:P"@:s:@/Xk&+@+8MPt&(]30+c

ลองออนไลน์!

คุณสมบัติโบนัส:

  • สำหรับ26 ไบต์เวอร์ชันที่แก้ไขต่อไปนี้จะสร้างเอาต์พุตกราฟิก :

    t:P"@:s:@/Xk&+@+8MPt&(]1YG
    

    ลองที่MATL Online!

  • รูปภาพกำลังขอทานสำหรับบางสีและมีราคาเพียง 7 ไบต์:

    t:P"@:s:@/Xk&+@+8MPt&(]1YG59Y02ZG
    

    ลองที่MATL Online!

  • หรือใช้เวอร์ชันที่ยาวกว่า (37 ไบต์) เพื่อดูว่าตัวอักขระเมทริกซ์นั้นถูกสร้างขึ้นอย่างค่อยเป็นค่อยไป :

    t:P"@:s:@/Xk&+@+8MPt&(t30+cD9&Xx]30+c
    

    ลองที่MATL Online!

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

สำหรับอินพุตคือ8สิ่งต่อไปนี้แสดงเวอร์ชันพื้นฐานเอาต์พุตกราฟิกและเอาต์พุตกราฟิกสี

ป้อนคำอธิบายรูปภาพที่นี่

ป้อนคำอธิบายรูปภาพที่นี่

ป้อนคำอธิบายรูปภาพที่นี่

คำอธิบาย

ขั้นตอนทั่วไป

เมทริกซ์ตัวเลขถูกสร้างจากเลเยอร์ด้านนอกไปยังเลเยอร์ด้านในเป็นNขั้นตอนโดยที่Nอินพุต แต่ละขั้นตอนจะเขียนทับส่วนด้านใน (ซ้ายบน) ของเมทริกซ์ก่อนหน้า ในตอนท้ายตัวเลขในเมทริกซ์ที่ได้จะถูกเปลี่ยนเป็นอักขระ

ตัวอย่าง

สำหรับอินพุต4เมทริกซ์แรกคือ

10 10  9  9  9  9  8  8  8  8
10 10  9  9  9  9  8  8  8  8
 9  9  8  8  8  8  7  7  7  7
 9  9  8  8  8  8  7  7  7  7
 9  9  8  8  8  8  7  7  7  7
 9  9  8  8  8  8  7  7  7  7
 8  8  7  7  7  7  6  6  6  6
 8  8  7  7  7  7  6  6  6  6
 8  8  7  7  7  7  6  6  6  6
 8  8  7  7  7  7  6  6  6  6

ในฐานะที่เป็นขั้นตอนที่สองเมทริกซ์

7 7 7 6 6 6
7 7 7 6 6 6
7 7 7 6 6 6
6 6 6 5 5 5
6 6 6 5 5 5
6 6 6 5 5 5

ถูกเขียนทับลงในครึ่งบนของหลัง จากนั้นก็ทำแบบเดียวกันกับ

6 5 5
5 4 4
5 4 4

และสุดท้ายด้วย

3

เมทริกซ์ที่ได้คือ

3 5 5 6 6 6 8 8 8 8
5 4 4 6 6 6 8 8 8 8
5 4 4 6 6 6 7 7 7 7
6 6 6 5 5 5 7 7 7 7
6 6 6 5 5 5 7 7 7 7
6 6 6 5 5 5 7 7 7 7
8 8 7 7 7 7 6 6 6 6
8 8 7 7 7 7 6 6 6 6
8 8 7 7 7 7 6 6 6 6
8 8 7 7 7 7 6 6 6 6

สุดท้าย30จะถูกเพิ่มเข้าไปในแต่ละรายการและตัวเลขที่ได้จะถูกแปลเป็น codepoints และแปลงเป็นอักขระ (เช่นเริ่มต้นที่33ตรงกับ!)

การสร้างเมทริกซ์ระดับกลาง

สำหรับการป้อนข้อมูลNให้พิจารณาการลดค่าของkจากไปN 1สำหรับแต่ละkเวกเตอร์ของจำนวนเต็มจาก1ถึงk*(k+1)ถูกสร้างขึ้นจากนั้นแต่ละรายการจะถูกหารด้วยkและปัดเศษขึ้น เป็นตัวอย่างสำหรับk=4สิ่งนี้ (บล็อกทั้งหมดมีขนาดkยกเว้นอันสุดท้าย):

1 1 1 1 2 2 2 2 3 3

ในขณะk=3ที่ผลลัพธ์จะเป็น (บล็อกทั้งหมดมีขนาดk):

1 1 1 2 2 2

เวกเตอร์นี้ถูกเพิ่มองค์ประกอบที่ชาญฉลาดพร้อมการออกอากาศไปยังสำเนาที่ถูกย้ายของตัวเอง จากนั้นkจะถูกเพิ่มในแต่ละรายการ สำหรับk=4สิ่งนี้จะช่วยให้

6  6  6  6  7  7  7  7  8  8
6  6  6  6  7  7  7  7  8  8
6  6  6  6  7  7  7  7  8  8
6  6  6  6  7  7  7  7  8  8
7  7  7  7  8  8  8  8  9  9
7  7  7  7  8  8  8  8  9  9
7  7  7  7  8  8  8  8  9  9
7  7  7  7  8  8  8  8  9  9
8  8  8  8  9  9  9  9 10 10
8  8  8  8  9  9  9  9 10 10

นี่เป็นหนึ่งในเมทริกซ์กลางที่แสดงด้านบนยกเว้นว่ามันจะพลิกในแนวนอนและแนวตั้ง ดังนั้นสิ่งที่เหลืออยู่ก็คือการพลิกเมทริกซ์นี้และเขียนลงในมุมบนซ้ายของเมทริกซ์ "สะสม" จนถึงเริ่มต้นให้เป็นเมทริกซ์ที่ว่างเปล่าสำหรับk=Nขั้นตอนแรก ( )

รหัส

t       % Implicitly input N. Duplicate. The first copy of N serves as the
        % initial state of the "accumulated" matrix (size 1×1). This will be 
        % extended to size N*(N+1)/2 × N*(N+1)/2 in the first iteration
 :P     % Range and flip: generates vector [N, N-1, ..., 1]
"       % For each k in that vector
  @:    %   Push vector [1, 2, ..., k]
  s     %   Sum of this vector. This gives 1+2+···+k = k*(k+1)/2
  :     %   Range: gives vector [1, 2, ..., k*(k+1)/2]
  @/    %   Divide each entry by k
  Xk    %   Round up
  &+    %   Add vector to itself transposed, element-wise with broadcast. Gives
        %   a square matrix of size k*(k+1)/2 × k*(k+1)/2
  @+    %   Add k to each entry of the this matrix. This is the flipped
        %   intermediate matrix
  8M    %   Push vector [1, 2, ..., k*(k+1)/2] again
  Pt    %   Flip and duplicate. The two resulting, equal vectors are the row and
        %   column indices where the generated matrix will be written. Note that
        %   flipping the indices has the same effect as flipping the matrix
        %   horizontally and vertically (but it's shorter)
  &(    %   Write the (flipped) intermediate matrix into the upper-left
        %   corner of the accumulated matrix, as given by the two (flipped)
        %   index vectors 
]       % End
30+     % Add 30 to each entry of the final accumulated matrix
c       % Convert to char. Implicitly display

ฉันไม่รู้จัก MATL เลย แต่คุณสามารถบันทึกไบต์ใด ๆ ด้วยการใช้ mod10 แทนที่จะเพิ่ม 30 และแปลงเป็นอักขระ?
2390246

หรือแม้กระทั่ง mod4 ...
2390246

@ user2390246 คุณหมายถึงการทำให้พวกเขาเป็นตัวเลขด้วยตัวเลขหลักเดียวและหลีกเลี่ยงการแปลงเป็นอักขระหรือไม่? ไม่สามารถใช้งานได้เพราะเมทริกซ์ตัวเลขจะถูกพิมพ์ด้วยช่องว่างระหว่างตัวเลข แต่ขอบคุณสำหรับความคิดต่อไป :-)
Luis Mendo

ยุติธรรมพอสมควร เกิดอะไรขึ้นกับ n> 226 จะไม่อยู่นอกขอบเขตของอักขระที่ถูกต้องใช่ไหม (แปลกใจ, หมดเวลากับ TIO, ดังนั้นฉันไม่สามารถตรวจสอบได้)
2390246

@ user2390246 ใช่สำหรับหมายเลขที่มีการป้อนสูงมันจะออกไปข้างนอก และถ้าเราพิจารณา ASCII chars จุดโค้ดสูงสุดคือ 127 ดังนั้นมันจึงออกไปข้างนอกเร็วกว่า แต่เมื่อคุณสังเกตเห็นว่าหน่วยความจำหมดก่อนที่จะเกิดขึ้น (เมทริกซ์ char ที่ได้นั้นใหญ่เกินไป) อย่างไรก็ตามการทำงานจนถึงขนาดอินพุตที่กำหนดเท่านั้นเนื่องจากข้อ จำกัด ของหน่วยความจำหรือชนิดข้อมูลมักจะได้รับอนุญาต
Luis Mendo

7

Python 2 , 187 178 164 162 152 ไบต์

-8 ไบต์ขอบคุณ Mr.Xcoder
-1 ไบต์ขอบคุณ Stephen
-10 ไบต์ขอบคุณ Jonathan Frech

g=lambda y:y>1and[l+y*f(y,i)for i,l in enumerate(g(y-1))]+y*[''.join(f(y,i)for i in range(y*-~y/2))]or['#']
f=lambda y,i:'0@+#'[(y*~-y/2%y+i)/y%2+y%2*2]

ลองออนไลน์!


เมื่อคุณได้รับบ้าน179 ไบต์
Mr. Xcoder

@ Mr.Xcoder 178 ไบต์
Stephen

1
มันอนุญาตให้ไม่นับจำนวนไบต์ของฟังก์ชั่นแลมบ์ดาของคุณเมื่อคุณใช้ซ้ำหรือไม่เช่นใช้ชื่อในรหัสที่เหลือ?
Jonathan Frech

sum(range(y))%y->y*~-y/2%y
Jonathan Frech

@ JonathanFrech ใช่เมื่อมันเกิดขึ้นซ้ำมันต้องอยู่ที่นั่น
ร็อด

7

ถ่าน , 50 46 ไบต์

F⮌…·¹N«≔⊘×ι⊕ιθF⊕⊘ι«F§#+@⁺ικ«UO⁻θ×ικθλUOθ⁻θ×ικλ

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

F⮌…·¹N«≔÷×ι⁺¹ι²θF⁺¹÷鲫F§#+@⁺ικ«UO⁻θ×ικθλUOθ⁻θ×ικλ

F     «     Loop over
  …·¹       Inclusive range from 1 to
     N      Input as a number
 ⮌          Reversed

   ι⁺¹        Add 1 to current index
  ×   ι       Multiply by current index
 ÷     ²      Divide by 2
≔       θ     Assign to q

F     «      Loop over
             Implicit range from 0 to
   ÷ι²       Half the current index
 ⁺¹          Plus 1

F       «    Loop over
  #+@        Literal string
 §           Circularly indexed by
     ⁺ικ     Sum of outer and inner index

    ×ικ     Multiply outer and inner index
  ⁻θ        Subtract from q
UO     θλ   Draw an oblong (q-ik, q) using that character

UOθ⁻θ×ικλ   Draw an oblong (q, q-ik) using that character

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


ในทางเทคนิคคุณสามารถใช้ตัวแปร ASCII ตั้งแต่ลำดับอาร์กิวเมนต์กลับด้าน (โปรดทราบว่าต้องการโอเปอเรเตอร์ในการเข้าถึงดังนั้นจึงยังไม่ค่อยเล่นกอล์ฟ)
เท่านั้น

5

C (gcc) , 135 128 120 ไบต์

f(n,m,i,x,y,k){for(m=n*-~n/2,i=m*m;i--;printf("\n%d"+!!(~i%m),(x/k+y/k+k)%3))for(x=i%m,y=i/m,k=n;x>=k&y>=k;x-=k--)y-=k;}

ลองออนไลน์!

ใช้เพียงสามสี

แนวคิดทำงานบนตารางที่หมุนได้ 180 องศา:

000111
000111
000111
111220
111220
111001

และคำนวณสีตามสูตร:

c(x,y,n) = c(x-n,y-n,n-1)                   if x >= n and y >= n
         = (x div n + y div n + n) mod 3    otherwise


@JonathanFrech นี้ไม่ได้เป็น C gcc -O2ที่ถูกต้องและแบ่งด้วย
nwellnhof

ยุติธรรมเพียงพอ เป็นไปได้ไหมที่รหัสที่สองใช้ได้กับสามสีเนื่องจากโมดูลัสสาม ( g(i%m,i/m,n)%3)
Jonathan Frech

แนะนำx/k&&y/kแทนx>=k&y>=k
ceilingcat

2

R , 131 126 123 ไบต์

บันทึก 3 ไบต์ด้วย @Giuseppe

function(n){l=w=sum(1:n)
m=matrix(,l,l)
for(i in n:1){m[l:1,l:1]=outer(x<-(1:l-1)%/%i,x,`+`)+i
l=l-i}
write(m%%4,"",w,,"")}

ลองออนไลน์!

นี้ใช้ขั้นตอนวิธีการเดียวกับ @LuisMendo 's คำตอบ MATL ความแตกต่างเพียงอย่างเดียวคือแทนที่จะแปลงเป็นอักขระเมทริกซ์จะถูกเอาต์พุตด้วยค่า mod4 ทั้งหมดเพื่อให้แน่ใจว่าแต่ละองค์ประกอบเป็นอักขระ ASCII เดียว


1
123 ไบต์! ฉันนำforลูปกลับมาที่ -1 ไบต์ :)
Giuseppe

1

Python 2 , 176 175 ไบต์

n=input()
R,J=range,''.join;r=[]
for i in R(n+1):
 S=sum(R(i));c='AxBo'[i%2::2]
 for j in R(S):r[~j]+=c[j/i%2]*i
 r+=[J(c[-j/i%2]for j in R(S+i,0,-1))]*i
for l in r:print J(l)

ลองออนไลน์!


หากคุณกำหนดJ="".join;(+10 ไบต์) และแทนที่ทั้ง"".joins (-2 * 7 = -14 ไบต์) ด้วยJ(+2 ไบต์) คุณสามารถบันทึกไบต์ (เนื่องจากจะต้องมีพื้นที่เพิ่มเติมหลังจากนั้นprint; +1 ไบต์) .
Jonathan Frech
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.