Tam giác của tôi cần nhiều nút hơn


20

Hãy xem xét tam giác đều cạnh chuẩn, với các nút được dán nhãn bằng tọa độ nhị phân :

Chúng ta có thể biến tam giác 3 nút này thành tam giác 6 nút bằng cách thêm một dòng mới gồm 3 đỉnh (nhiều hơn một đỉnh của một cạnh của tam giác 3 nút ban đầu), loại bỏ bất kỳ cạnh bên trong (nhưng không phải các nút bên trong) và re- bình thường hóa tọa độ:

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

Lặp lại quá trình để đi từ tam giác 6 nút sang tam giác 10 nút, thêm một dòng gồm 4 đỉnh (một lần nữa, một lần nữa hiện diện trên một cạnh của tam giác 6 nút ban đầu), loại bỏ bất kỳ cạnh bên trong (nhưng không phải các nút bên trong ) và chuẩn hóa lại tọa độ:

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

Quá trình này có thể được lặp đi lặp lại vô thời hạn. Mục tiêu của thử thách này được đưa ra một số nguyên Nbiểu thị bao nhiêu lần quá trình này đã được thực hiện, xuất ra tất cả các nút cho tam giác liên kết theo tọa độ nhị phân.

Đầu vào

Chương trình / hàm của bạn sẽ lấy đầu vào là một số nguyên không âm duy nhất Nbiểu thị số lần quá trình này đã được áp dụng. Lưu ý rằng N=0, bạn nên xuất ra tam giác ban đầu với 3 nút.

Đầu vào có thể đến từ bất kỳ nguồn nào (tham số chức năng, stdio, v.v.).

Đầu ra

Chương trình / hàm của bạn sẽ xuất tất cả các nút theo tọa độ barycentric chuẩn hóa. Thứ tự của các nút không quan trọng. Một số có thể được chỉ định dưới dạng phân số (không cần giảm phân số) hoặc số dấu phẩy động. Bạn cũng có thể xuất các vectơ "tỷ lệ" để chỉ định một nút. Ví dụ: cả 3 đầu ra sau đây đều tương đương và được phép:

0.5,0.5,0

1/2,2/4,0

[1,1,0]/2

Nếu sử dụng đầu ra dấu phẩy động, đầu ra của bạn phải chính xác trong phạm vi 1%. Đầu ra có thể là bất kỳ mức chìm nào mong muốn (stdio, giá trị trả về, tham số trả về, v.v.). Lưu ý rằng mặc dù tọa độ nhị phân được xác định duy nhất bởi chỉ có 2 số cho mỗi nút, bạn nên xuất cả 3 số cho mỗi nút.

Ví dụ

Các trường hợp ví dụ được định dạng là:

N
x0,y0,z0
x1,y1,z1
x2,y2,z2
...

trong đó dòng đầu tiên là đầu vào Nvà tất cả các dòng sau tạo thành một nút x,y,znên ở đầu ra chính xác một lần. Tất cả các số được đưa ra dưới dạng số dấu phẩy động gần đúng.

0
1,0,0
0,1,0
0,0,1

1
1,0,0
0,1,0
0,0,1
0.5,0,0.5
0.5,0.5,0
0,0.5,0.5

2
1,0,0
0,1,0
0,0,1
0.667,0,0.333
0.667,0.333,0
0.333,0,0.667
0.333,0.333,0.333
0.333,0.667,0
0,0.333,0.667
0,0.667,0.333

3
1,0,0
0.75,0,0.25
0.75,0.25,0
0.5,0,0.5
0.5,0.25,0.25
0.5,0.5,0
0.25,0,0.75
0.25,0.25,0.5
0.25,0.5,0.25
0.25,0.75,0
0,0,1
0,0.25,0.75
0,0.5,0.5
0,0.75,0.25
0,1,0

Chấm điểm

Đây là mã golf; mã ngắn nhất trong byte thắng. Tiêu chuẩn áp dụng. Bạn có thể sử dụng bất kỳ tích hợp nào mong muốn.


Bạn nói " Nếu sử dụng đầu ra dấu phẩy động ". Có những lựa chọn thay thế nào? Phân số? Nếu vậy, họ có phải được giảm? Làm thế nào về vectơ tỷ lệ như thế [1,2,3]/6nào?
Peter Taylor

Vâng, tất cả những lựa chọn thay thế được cho phép. Tôi sẽ cập nhật báo cáo vấn đề.
hellowworld922

Câu trả lời:


7

CJam (22 byte)

{):X),3m*{:+X=},Xdff/}

Đây là một khối ẩn danh (hàm) đảm nhận Nngăn xếp và để lại một mảng các mảng nhân đôi trên ngăn xếp. Bản demo trực tuyến

Mổ xẻ

{         e# Define a block
  ):X     e# Let X=N+1 be the number of segments per edge
  ),3m*   e# Generate all triplets of integers in [0, X] (inclusive)
  {:+X=}, e# Filter to those triplets which sum to X
  Xdff/   e# Normalise
}

6

Haskell, 53 byte

f n|m<-n+1=[map(/m)[x,y,m-x-y]|x<-[0..m],y<-[0..m-x]]

5

Python 3, 87 byte

Đây thực sự được coi là một bình luận cho giải pháp của TheBikingViking nhưng tôi không có đủ danh tiếng cho các bình luận.

Người ta có thể lưu một vài byte bằng cách chỉ lặp qua các biến i,jvà sử dụng thực tế là với cái thứ ba họ thêm vào n+1.

def f(n):d=n+1;r=range(n+2);print([[i/d,j/d,(d-i-j)/d]for i in r for j in r if d>=i+j])

4

Toán học,  44  43 byte

Select[Range[0,x=#+1]~Tuples~3/x,Tr@#==1&]&

Đây là một hàm không tên lấy một đối số nguyên. Đầu ra là một danh sách các danh sách các phân số chính xác (giảm).

Tạo tất cả 3 bộ số bội 1/(N+1)từ 0 đến 1, bao gồm và sau đó chọn những số có tổng bằng 1 (theo yêu cầu của tọa độ barycentric).


4

05AB1E , 10 byte

ÌL<¤/3ãDOÏ

Giải trình

ÌL<          # range(1,n+2)-1
   ¤/        # divide all by last element (n+1)
     3ã      # cartesian product repeat (generate all possible triples)
       DO    # make a copy and sum the triples
         Ï   # keep triples with sum 1

Dùng thử trực tuyến


¤tiêu thụ mảng, tại sao lại /chia mảng đó? Nó có "nhớ" giá trị xuất hiện cuối cùng và sử dụng nó nếu cần không?
Luis Mendo

@LuisMendo: ¤là một trong số ít các lệnh không bật và tiêu thụ từ ngăn xếp. Nó đẩy phần tử cuối cùng của danh sách trong khi rời khỏi danh sách trên ngăn xếp.
Emigna



Ồ dĩ nhiên rồi! Cảm ơn những lời giải thích
Luis Mendo

3

MATL , 17 byte

2+:qGQ/3Z^t!s1=Y)

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

Giải trình

Cách tiếp cận giống như trong các câu trả lời khác:

  1. Tạo mảng [0, 1/(n+1), 2/(n+1), ..., 1], nơi nlà đầu vào;
  2. Tạo tất cả 3 tuple với các giá trị đó;
  3. Chỉ giữ lại những người có tổng 1.

Cụ thể hơn:

2+     % Take input and add 2: produces n+2
:q     % Range [0 1 ... n+1]
GQ/    % Divide by n+1 element-wise: gives [0, 1/(n+1), 2/(n+1)..., 1]
3Z^    % Cartesian power with exponent 3. Gives (n+1)^3 × 3 array. Each row is a 3-tuple
t      % Duplicate
!s     % Sum of each row
1=     % Logical index of entries that equal 1
Y)     % Use that index to select rows of the 2D array of 3-tuples

1

Sứa , 37 33 byte

Cảm ơn Zgarb đã lưu 4 byte.

p
*%
# S
`
=E   S
`/
1+r#>>i
   3

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

Giống như câu trả lời CJam của Mathicala và Peter của tôi, điều này tạo ra một bộ các ứng cử viên và sau đó chỉ chọn những câu có tổng bằng 1. Tôi chưa hoàn toàn hài lòng với bố cục này và tôi tự hỏi liệu tôi có thể lưu một số byte bằng móc hoặc dĩa không, nhưng tôi sẽ phải xem xét điều đó sau.


1

Perl 6: 50 40 byte

{grep *.sum==1,[X] (0,1/($_+1)...1)xx 3}

Trả về một chuỗi các danh sách gồm 3 phần tử của các số hữu tỷ (chính xác).

Giải trình:

  • $_
    Thông số khai báo ngầm của lambda.
  • 0, 1/($_ + 1) ... 1
    Sử dụng toán tử trình tự ...để xây dựng chuỗi số học tương ứng với các giá trị tọa độ có thể.
  • [X] EXPR xx 3
    Lấy sản phẩm Cartesian của ba bản sao EXPR, tức là tạo ra tất cả 3 bộ dữ liệu có thể.
  • grep *.sum == 1, EXPR
    Lọc các bộ dữ liệu với tổng bằng 1.

1

Ruby, 62

Tôi sẽ ngạc nhiên nếu điều này không thể được cải thiện về:

->x{0.step(1,i=1.0/(x+1)){|a|0.step(1-a,i){|b|p [a,b,1-a-b]}}}

Lấy lời khuyên tiềm ẩn trong câu đố, điều này sẽ tính toán các tùy chọn nút thứ hai dựa trên nút thứ nhất và nút thứ ba bằng cách trừ hai nút đầu tiên.



0

Python 3, 106 byte

def f(n):r=range(n+2);print([x for x in[[i/-~n,j/-~n,k/-~n]for i in r for j in r for k in r]if sum(x)==1])

Một chức năng họ nhận đầu vào thông qua đối số và in danh sách các danh sách nổi lên STDOUT.

Python không giỏi trong các sản phẩm của Cartesian ...

Làm thế nào nó hoạt động

def f(n):                         Function with input iteration number n
r=range(n+2)                      Define r as the range [0, n+1]
for i in r for j in r for k in r  Length 3 Cartesian product of r
[i/-~n,j/-~n,k/-~n]               Divide each element of each list in the product
                                  by n+1
[x for x in ... if sum(x)==1]     Filter by summation to 1
print(...)                           Print to STDOUT

Hãy thử nó trên Ideone


0

Trên thực tế , 15 byte

Điều này sử dụng một thuật toán tương tự như thuật toán trong câu trả lời Python của TheBikingViking . Gợi ý chơi golf chào mừng. Hãy thử trực tuyến!

u;ur♀/3@∙`Σ1=`░

Ung dung:

u;                Increment implicit input and duplicate.
  ur              Range [0..n+1]
    ♀/            Divide everything in range by (input+1).
      3@∙         Take the Cartesian product of 3 copies of [range divided by input+1]
         `Σ1=`    Create function that takes a list checks if sum(list) == 1.
              ░   Push values of the Cartesian product where f returns a truthy value.


0

JavaScript (Firefox 30-57), 88 81 byte

n=>[for(x of a=[...Array(++n+1).keys()])for(y of a)if(x+y<=n)[x/n,y/n,(n-x-y)/n]]

Trả về một mảng các mảng số dấu phẩy động. Chỉnh sửa: Đã lưu 7 byte bằng cách tính trực tiếp tọa độ thứ ba. Tôi đã cố gắng loại bỏ ifbằng cách tính toán phạm vi ytrực tiếp nhưng nó tốn thêm một byte:

n=>[for(x of a=[...Array(++n+1).keys()])for(y of a.slice(x))[x/n,(y-x)/n,(n-y)/n]]

Cuối cùng, bạn đã viết [x/n,y/n/z/n], bạn đã quên một dấu phẩy?
kamoroso94

@ kamoroso94 Bạn nói đúng, tôi đánh máy dấu phẩy cuối cùng, cảm ơn vì đã cho tôi biết.
Neil
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.