Hình dung Định lý Nicomachus


35

Định lý của Nichomachus liên quan đến bình phương của một tổng với tổng các hình khối:

Định lý của Nichomachus

và có một hình ảnh trực quan đẹp:

Hình dung

Thách thức: Tạo phần 2d của trực quan hóa này trong ascii.

Bạn sẽ cần đảm bảo rằng tất cả các ranh giới trực quan được duy trì bằng sơ đồ của bạn. Đây là cách đơn giản nhất để thực hiện với bốn "màu", mặc dù có thể đạt được chỉ với ba màu (xem ví dụ cuối cùng bên dưới để biết cách thực hiện). Với bốn màu, bạn sử dụng hai màu để phân biệt giữa các vùng trong một "dải" (nghĩa là các phần khác nhau tạo thành một khối) và hai để phân biệt giữa các dải liền kề. Bạn cũng có thể sử dụng nhiều hơn bốn màu nếu bạn thích. Nếu bất kỳ điều này là khó hiểu, đầu ra ví dụ dưới đây sẽ làm rõ.

Đầu ra đầu vào

Đầu vào là một số nguyên lớn hơn 0. Đầu ra là một lưới ascii tương tự như các ví dụ bên dưới, tương ứng với lưới được làm phẳng cho số đầu vào đó trong hình trên. Khoảng trắng hàng đầu và dấu là ok.

Đây là mã golf, với các quy tắc tiêu chuẩn.

Đầu ra mẫu

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#####
+++++#####+++++
+++++#####+++++
+++++#####+++++
+++++#####+++++
+++++#####+++++

Phiên bản ba màu cho N = 4, nhờ @BruceForte:

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

6
Định lý bốn màu: D
Leaky Nun

1
Bạn có thể thêm đầu ra cho N = 5 không?
Uriel

1
@Uriel Xong. Xem chỉnh sửa của tôi.
Giô-na

Cảm ơn! Ngoài ra, tôi có thể chuyển đổi @ và os chỉ ở dải ngoài trong N = 4 không? Hoặc phải là đầu ra là một sự thay thế nghiêm ngặt của các văn bản này với một bộ ký tự khác?
Uriel

@Uriel chuyển đổi là tốt. Tất cả vấn đề là màu sắc liền kề không xung đột, để có thể nhìn thấy mô hình.
Giô-na

Câu trả lời:


17

MATL , 30 28 27 byte

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

Hãy thử trực tuyến!

Tính năng thưởng:

  • Dành cho 26 byte , phiên bản sửa đổi sau đây tạo đầu ra đồ họa :

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

    Hãy thử nó tại MATL Online!

  • Hình ảnh đang cầu xin một số màu và nó chỉ tốn 7 byte:

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

    Hãy thử nó tại MATL Online!

  • Hoặc sử dụng phiên bản dài hơn (37 byte) để xem ma trận ký tự là như thế nào xây dựng dần dần :

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

    Hãy thử nó tại MATL Online!

Ví dụ đầu ra

Đối với đầu vào là 8, sau đây cho thấy phiên bản cơ bản, đầu ra đồ họa và đầu ra đồ họa màu.

nhập mô tả hình ảnh ở đây

nhập mô tả hình ảnh ở đây

nhập mô tả hình ảnh ở đây

Giải trình

Thủ tục chung

Một ma trận số được xây dựng từ các lớp bên ngoài đến bên trong Ntheo các bước, trong đó Nlà đầu vào. Mỗi bước ghi đè lên một phần bên trong (phía trên bên trái) của ma trận trước đó. Cuối cùng, các số trong ma trận thu được được thay đổi thành ký tự.

Thí dụ

Đối với đầu vào 4ma trận đầu tiên là

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

Bước thứ hai, ma trận

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

được ghi đè lên nửa trên của cái sau. Sau đó, tương tự được thực hiện với

6 5 5
5 4 4
5 4 4

và cuối cùng với

3

Ma trận kết quả là

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

Cuối cùng, 30được thêm vào mỗi mục và các số kết quả được hiểu là các điểm mã và được chuyển đổi thành các ký tự (do đó bắt đầu từ 33, tương ứng với !).

Xây dựng các ma trận trung gian

Đối với đầu vào N, xem xét giảm giá trị ktừ Nđến 1. Đối với mỗi k, một vectơ số nguyên từ 1đến k*(k+1)được tạo ra, và sau đó mỗi mục được chia cho kvà làm tròn lên. Ví dụ, đối với k=4điều này mang lại (tất cả các khối có kích thước kngoại trừ cuối cùng):

1 1 1 1 2 2 2 2 3 3

trong khi đó đối k=3với kết quả sẽ là (tất cả các khối có kích thước k):

1 1 1 2 2 2

Vectơ này được thêm vào, yếu tố khôn ngoan với phát sóng, vào một bản sao được chuyển đổi của chính nó; và sau đó kđược thêm vào mỗi mục. Đối với k=4điều này cho

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

Đây là một trong những ma trận trung gian được hiển thị ở trên, ngoại trừ việc nó được lật theo chiều ngang và chiều dọc. Vì vậy, tất cả những gì còn lại là lật ma trận này và viết nó vào góc trên bên trái của ma trận "tích lũy" cho đến nay, được khởi tạo thành một ma trận trống cho bước đầu tiên ( 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

Tôi hoàn toàn không biết MATL, nhưng bạn có thể lưu bất kỳ byte nào bằng cách sử dụng mod10 thay vì thêm 30 và chuyển đổi thành ký tự không?
dùng2390246

Hoặc thậm chí mod4 ...
user2390246

@ user2390246 Bạn có nghĩa là giữ chúng dưới dạng số với một chữ số và tránh chuyển đổi thành char? Điều đó sẽ không hoạt động, bởi vì ma trận số sẽ được in với khoảng trắng giữa các số. Nhưng dù sao cũng cảm ơn vì ý tưởng này :-)
Luis Mendo

Đủ công bằng. Điều gì xảy ra với n> 226? Không đi ra ngoài phạm vi của các ký tự hợp lệ? (Không có gì đáng ngạc nhiên, hết thời gian trên TIO, vì vậy tôi không thể kiểm tra)
user2390246

@ user2390246 Có, đối với số lượng đầu vào cao, nó đi ra ngoài. Và nếu chúng ta xem xét ký tự ASCII, điểm mã tối đa là 127, vì vậy nó sẽ ra ngoài sớm hơn. Nhưng như bạn nhận thấy nó hết bộ nhớ trước khi điều đó xảy ra (ma trận char kết quả là quá lớn). Dù sao, làm việc với kích thước đầu vào nhất định chỉ do giới hạn bộ nhớ hoặc loại dữ liệu thường được cho phép
Luis Mendo

7

Python 2 , 187 178 164 162 152 byte

-8 byte nhờ vào Mr.Xcoder
-1 byte nhờ Stephen
-10 byte nhờ 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]

Hãy thử trực tuyến!


Vì khi bạn về nhà, 179 byte .
Ông Xcoder

@ Mr.Xcoder 178 byte
Stephen

1
Được phép không bao gồm số byte tên của hàm lambda của bạn khi bạn đang sử dụng đệ quy, tức là sử dụng tên của nó trong phần còn lại của mã?
Jonathan Frech

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

@JonathanFrech yeah, khi nó đệ quy thì nó phải ở đó.
Rod

7

Than , 50 46 byte

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

Hãy thử trực tuyến!Liên kết là phiên bản dài dòng của mã. Phiên bản 50 byte trước với lời giải thích: Hãy thử trực tuyến!

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ưu ý: Tôi lặp qua ký tự thay vì cố gắng gán ký tự trực tiếp lvì bạn không thể gán trực tiếp kết quả của việc lập chỉ mục chuỗi cho một biến vì đó là một cấu trúc mơ hồ trong Char than. May mắn là số byte là như nhau.


Về mặt kỹ thuật, bạn có thể, với một biến ASCII vì thứ tự đối số của nó bị đảo ngược (lưu ý rằng nó cần một toán tử để truy cập để nó vẫn ít bị đánh gôn hơn)
ASCII chỉ có

5

C (gcc) , 135 128 120 byte

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;}

Hãy thử trực tuyến!

Chỉ sử dụng ba màu.

Về mặt khái niệm, các công trình trên lưới xoay 180 độ:

000111
000111
000111
111220
111220
111001

Và tính toán màu sắc theo công thức:

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 Đây không phải là C hợp lệ và vi phạm gcc -O2.
nwellnhof

Đủ công bằng; có thể là mã thứ hai chỉ hoạt động cho ba màu vì mô đun ba ( g(i%m,i/m,n)%3)?
Jonathan Frech

Gợi ý x/k&&y/kthay vìx>=k&y>=k
trần mèo

2

R , 131 126 123 byte

3 byte được lưu nhờ @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,,"")}

Hãy thử trực tuyến!

Điều này sử dụng thuật toán tương tự như câu trả lời MATL của @LuisMendo . Sự khác biệt duy nhất là thay vì chuyển đổi thành các ký tự, ma trận là đầu ra với tất cả các giá trị mod4 để đảm bảo rằng mỗi phần tử là một ký tự ascii duy nhất.


1
123 byte! Tôi đã mang forvòng lặp trở lại cho -1 byte :)
Giuseppe

1

Python 2 , 176 175 byte

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)

Hãy thử trực tuyến!


Nếu bạn xác định J="".join;(+10 byte) và thay thế cả "".joins (-2 * 7 = -14 byte) bằng J(+2 byte), bạn có thể lưu một byte (vì phải có thêm một khoảng trắng sau print; +1 byte) .
Jonathan Frech
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.