Segitiga saya membutuhkan lebih banyak node

20

Pertimbangkan segitiga sama sisi standar, dengan simpul yang berlabel menggunakan koordinat barycentric :

Kita dapat mengubah segitiga 3 simpul ini menjadi segitiga 6 simpul dengan menambahkan baris baru 3 simpul (satu lagi dari yang ada di sisi segitiga 3 simpul asli), menghilangkan tepi internal (tetapi bukan simpul internal) dan kembali menormalkan koordinat:

masukkan deskripsi gambar di sini

Mengulangi proses untuk pergi dari segitiga 6 simpul ke segitiga 10 simpul, tambahkan garis 4 simpul (sekali lagi, satu lagi dari yang ada di sisi segitiga 6 simpul yang asli), hapus setiap tepi internal (tetapi bukan simpul internal ) dan menormalkan kembali koordinat:

masukkan deskripsi gambar di sini

Proses ini dapat diulang tanpa batas. Tujuan dari tantangan ini adalah memberikan bilangan bulat yang Nmenunjukkan berapa kali proses ini telah dilakukan, menampilkan semua node untuk segitiga terkait dalam koordinat barycentric.

Memasukkan

Program / fungsi Anda harus memasukkan bilangan bulat non-negatif tunggal yang Nmenunjukkan berapa kali proses ini telah diterapkan. Perhatikan bahwa untuk N=0, Anda harus menampilkan segitiga asli dengan 3 node.

Input dapat berasal dari sumber apa pun (parameter fungsi, stdio, dll.).

Keluaran

Program / fungsi Anda harus menampilkan semua node dalam koordinat barycentric yang dinormalisasi. Urutan node tidak masalah. Suatu angka dapat ditentukan sebagai fraksi (pengurangan fraksi tidak diperlukan) atau angka floating point. Anda juga dapat menampilkan vektor "skala" untuk menentukan suatu simpul. Misalnya, ketiga output berikut ini setara dan diizinkan:

0.5,0.5,0

1/2,2/4,0

[1,1,0]/2

Jika menggunakan output floating point, output Anda harus akurat hingga dalam 1%. Outputnya dapat berupa sink yang diinginkan (stdio, nilai balik, parameter balik, dll.). Perhatikan bahwa meskipun koordinat barycentric secara unik ditentukan oleh hanya 2 angka per node, Anda harus mengeluarkan semua 3 angka per node.

Contohnya

Contoh kasus diformat sebagai:

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

di mana baris pertama adalah input N, dan semua baris berikut membentuk simpul x,y,zyang harus di output tepat sekali. Semua angka diberikan sebagai perkiraan angka floating point.

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

Mencetak gol

Ini adalah kode golf; kode terpendek dalam byte menang. Celah standar berlaku. Anda dapat menggunakan built-in yang diinginkan.

helloworld922
sumber
Anda mengatakan " Jika menggunakan output floating point ". Apa alternatif yang ada? Pecahan? Jika demikian, apakah harus dikurangi? Bagaimana dengan vektor yang diskalakan [1,2,3]/6?
Peter Taylor
Ya, semua alternatif itu diperbolehkan. Saya akan memperbarui pernyataan masalah.
helloworld922

Jawaban:

7

CJam (22 byte)

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

Ini adalah blok anonim (fungsi) yang mengambil Nstack dan meninggalkan array array ganda pada stack. Demo online

Pembedahan

{         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
}
Peter Taylor
sumber
6

Haskell, 53 byte

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

Python 3, 87 byte

Ini sebenarnya seharusnya menjadi komentar untuk solusi oleh TheBikingViking tetapi saya tidak memiliki reputasi yang cukup untuk komentar.

Satu dapat menyimpan beberapa byte dengan hanya mengulangi variabel i,jdan menggunakan fakta bahwa dengan yang ketiga ditambahkan 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])
Elvorfirilmathredia
sumber
4

Mathematica,  44  43 byte

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

Ini adalah fungsi tanpa nama yang mengambil argumen integer tunggal. Output adalah daftar daftar fraksi yang tepat (dikurangi).

Menghasilkan semua 3-tupel kelipatan 1/(N+1)antara 0 dan 1, inklusif, dan kemudian memilih mereka yang jumlahnya adalah 1 (seperti yang dipersyaratkan oleh koordinat barycentric).

Martin Ender
sumber
4

05AB1E , 10 byte

ÌL<¤/3ãDOÏ

Penjelasan

Ì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

Cobalah online

Emigna
sumber
Karena ¤mengkonsumsi array, mengapa /membagi array dengan itu? Apakah itu "mengingat" nilai terakhir yang muncul dan menggunakannya jika diperlukan?
Luis Mendo
@LuisMendo: ¤adalah salah satu dari beberapa perintah yang tidak muncul dan dikonsumsi dari tumpukan. Ini mendorong elemen terakhir dari daftar sambil meninggalkan daftar di tumpukan.
Emigna
Hm? Tampaknya tidak demikian
Luis Mendo
Oh tentu! Terima kasih atas penjelasannya
Luis Mendo
3

MATL , 17 byte

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

Cobalah online!

Penjelasan

Pendekatannya sama dengan jawaban lainnya:

  1. Hasilkan array [0, 1/(n+1), 2/(n+1), ..., 1], di mana ninputnya;
  2. Hasilkan semua 3-tupel dengan nilai-nilai itu;
  3. Simpan hanya mereka yang jumlahnya 1.

Lebih spesifik:

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
Luis Mendo
sumber
1

Ubur-ubur , 37 33 byte

Terima kasih kepada Zgarb karena telah menghemat 4 byte.

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

Cobalah online!

Seperti jawaban Mathematica dan CJam Peter saya, ini menghasilkan satu set kandidat tupel dan kemudian hanya memilih yang jumlahnya 1. Saya belum sepenuhnya senang dengan tata letaknya, dan saya ingin tahu apakah saya dapat menyimpan beberapa byte dengan kait atau garpu, tapi aku harus memeriksanya nanti.

Martin Ender
sumber
1

Perl 6: 50 40 byte

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

Mengembalikan urutan 3-elemen daftar angka rasional (tepat).

Penjelasan:

  • $_
    Parameter yang dinyatakan secara implisit dari lambda.
  • 0, 1/($_ + 1) ... 1
    Menggunakan operator urutan ...untuk membangun urutan aritmatika yang sesuai dengan nilai koordinat yang mungkin.
  • [X] EXPR xx 3
    Mengambil produk Cartesian dari tiga salinan EXPR, yaitu menghasilkan semua 3-tuple yang mungkin.
  • grep *.sum == 1, EXPR
    Saring tupel dengan jumlah 1.
seseorang
sumber
1

Ruby, 62

Saya akan terkejut jika ini tidak dapat diperbaiki pada:

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

Mengambil saran yang tersembunyi dalam teka-teki, ini menghitung opsi simpul kedua berdasarkan yang pertama, dan simpul ketiga dengan mengurangi dua yang pertama.

Bukan itu Charles
sumber
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])

Sebuah fungsi yang mereka ambil input melalui argumen dan mencetak daftar daftar float ke STDOUT.

Python tidak pandai produk Cartesian ...

Bagaimana itu bekerja

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

Cobalah di Ideone

TheBikingViking
sumber
0

Sebenarnya , 15 byte

Ini menggunakan algoritma yang mirip dengan yang ada di jawaban Python TheBikingViking . Saran golf diterima. Cobalah online!

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

Tidak Terkumpul:

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.
Sherlock9
sumber
0

Ruby, 77 74 byte

Jawaban lain menggunakan algoritma dalam jawaban Python TheBikingViking . Saran golf diterima.

->n{a=[*0.step(1,i=1.0/(n+1))];a.product(a,a).reject{|j|j.reduce(&:+)!=1}}

Algoritma 74-byte lain yang didasarkan pada Not that Charles's Ruby menjawab .

->x{y=x+1;z=1.0/y;[*0..y].map{|a|[*0..y-a].map{|b|p [a*z,b*z,(y-a-b)*z]}}}
Sherlock9
sumber
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]]

Mengembalikan array array angka floating-point. Sunting: Disimpan 7 byte dengan menghitung koordinat ketiga secara langsung. Saya mencoba menghilangkan ifdengan menghitung rentang ylangsung tetapi biaya byte tambahan:

n=>[for(x of a=[...Array(++n+1).keys()])for(y of a.slice(x))[x/n,(y-x)/n,(n-y)/n]]
Neil
sumber
Pada akhirnya, Anda menulis [x/n,y/n/z/n], apakah Anda lupa koma?
kamoroso94
@ kamoroso94 Anda benar, saya salah mengetik koma terakhir, terima kasih telah memberi tahu saya.
Neil