Üçgemin daha fazla düğüme ihtiyacı var


20

Bariyer merkezli koordinatlar kullanılarak etiketlenmiş düğümlerle standart eşkenar üçgeni düşünün :

Bu 3 düğüm üçgenini, 3 köşeden oluşan yeni bir çizgi (orijinal 3 düğüm üçgeninin bir tarafında mevcut olandan bir tane daha) ekleyerek 6 düğüm üçgenine dönüştürebilir, tüm iç kenarları kaldırabiliriz ( iç düğümleri değil ) ve koordinatları normalleştirin:

resim açıklamasını buraya girin

6 düğümlü bir üçgenden 10 düğümlü bir üçgene gitmek için işlemi tekrarlayın, 4 köşeli bir çizgi ekleyin (yine orijinal 6 düğüm üçgeninin bir tarafında mevcut olandan bir tane daha), iç kenarları kaldırın (ancak iç düğümleri değil) ) ve koordinatları yeniden normalleştirin:

resim açıklamasını buraya girin

Bu süreç süresiz olarak tekrarlanabilir. Bu zorluğun amacına, bu Nişlemin kaç kez gerçekleştirildiğini temsil eden bir tamsayı verilir , barycentric koordinatlarda ilişkili üçgen için tüm düğümleri çıkarır.

Giriş

Programınız / işleviniz, Nbu işlemin kaç kez uygulandığını gösteren tek bir negatif olmayan tam sayı girdi olarak almalıdır . İçin N=0, orijinal üçgeni 3 düğümle çıkarmanız gerektiğini unutmayın .

Giriş herhangi bir kaynaktan gelebilir (fonksiyon parametresi, stdio, vb.).

Çıktı

Programınız / işleviniz, normalleştirilmiş barycentric koordinatlardaki tüm düğümleri çıktılamalıdır. Düğümlerin sırası önemli değil. Bir sayı kesir (kesir azaltma gerekli değildir) veya kayan nokta sayısı olarak belirtilebilir. Bir düğüm belirtmek için "ölçeklendirilmiş" vektörler de çıkarabilirsiniz. Örneğin, aşağıdaki çıkışların 3'ünün tamamı eşdeğerdir ve bunlara izin verilir:

0.5,0.5,0

1/2,2/4,0

[1,1,0]/2

Kayan nokta çıkışı kullanılıyorsa, çıktınız% 1 içinde doğru olmalıdır. Çıkış istenen herhangi bir lavaboya olabilir (stdio, dönüş değeri, dönüş parametresi, vb.). Bariyer merkezli koordinatlar, her düğüm için sadece 2 sayı ile benzersiz bir şekilde belirlenmiş olsa da, her düğüm için 3 sayının tümünü çıkarmanız gerektiğini unutmayın.

Örnekler

Örnek durumlar şu şekilde biçimlendirilir:

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

burada ilk satır giriş olur Nve sonraki tüm satırlar x,y,zçıkışta tam olarak bir kez olması gereken bir düğüm oluşturur. Tüm sayılar yaklaşık kayan nokta sayısı olarak verilmiştir.

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

puanlama

Bu kod golf; bayt cinsinden en kısa kod kazanır. Standart boşluklar geçerlidir. İstediğiniz yerleşikleri kullanabilirsiniz.


" Kayan nokta çıktısı kullanıyorsanız " dersiniz . Ne gibi alternatifler var? Kesirler? Eğer öyleyse, azaltılmaları gerekir mi? Ölçekli vektörler nasıl olur [1,2,3]/6?
Peter Taylor

Evet, tüm bu alternatiflere izin veriliyor. Sorun bildirimini güncelleyeceğim.
helloworld922

Yanıtlar:


7

CJam (22 bayt)

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

Bu, Nyığını alan ve yığın üzerinde çiftler dizisi bırakan anonim bir bloktur (işlev) . Çevrimiçi demo

teşrih

{         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 bayt

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

5

Python 3, 87 bayt

Bu aslında TheBikingViking tarafından çözüm için bir yorum olması gerekiyordu ama yorum için yeterli bir üne sahip değilim.

Sadece değişkenler üzerinde yineleme i,jyaparak ve üçüncüsüyle topladıkları gerçeğini kullanarak birkaç bayt kaydedilebilir 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

Mathematica,  44  43 bayt

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

Bu, tek bir tam sayı argümanı alan adsız bir işlevdir. Çıktı, kesin (azaltılmış) kesirlerin listesidir.

1/(N+1)0 ile 1 arasındaki katların tüm 3 tuplesini oluşturur ve toplamı 1 olanları seçer (barycentric koordinatların gerektirdiği gibi).


4

05AB1E , 10 bayt

ÌL<¤/3ãDOÏ

açıklama

Ì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

Çevrimiçi deneyin


Yana ¤tüketir dizisi, neden gelmez /bu diziyi bölmek? Son açılan değeri "hatırlar" ve gerekirse kullanır mı?
Luis Mendo

@LuisMendo: yığıntan çıkmayan ¤ve tüketmeyen birkaç komuttan biridir. Listeyi yığında bırakırken listenin son öğesini iter.
Emigna


@LuisMendo 05AB1E , bir programın sonunda yalnızca yığının üstünü çıkarır .
Emigna

Oo elbette! Açıklamalar için teşekkürler
Luis Mendo

3

MATL , 17 bayt

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

Çevrimiçi deneyin!

açıklama

Yaklaşım diğer cevaplardakiyle aynıdır:

  1. Diziyi oluşturun ; girdi [0, 1/(n+1), 2/(n+1), ..., 1]burada n;
  2. Tüm 3-tuplleri bu değerlerle üretin;
  3. Sadece toplamı olanları sakla 1.

Daha spesifik olarak:

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

Denizanası , 37 33 bayt

4 bayt tasarruf için Zgarb'a teşekkürler.

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

Çevrimiçi deneyin!

Mathematica ve Peter'in CJam cevaplarım gibi, bu da bir dizi aday tuple oluşturur ve daha sonra sadece 1'e kadar olanları seçer. ama buna daha sonra bakmak zorunda kalacağım.


1

Perl 6: 50 40 bayt

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

(Tam) rasyonel sayıların 3 elemanlı listelerinden oluşan bir sıra döndürür.

Açıklama:

  • $_
    Lambda'nın dolaylı olarak beyan edilen parametresi.
  • 0, 1/($_ + 1) ... 1
    ...Olası koordinat değerlerine karşılık gelen aritmetik diziyi oluşturmak için dizi işlecini kullanır .
  • [X] EXPR xx 3
    EXPR'nin üç kopyasının Kartezyen ürününü alır, yani olası tüm 3 tupleri üretir.
  • grep *.sum == 1, EXPR
    Filtreleri toplam 1 ile filtreleyin.

1

Yakut, 62

Eğer bu geliştirilemezse şaşırırdım:

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

Bulmacada gizli olan tavsiyeyi alarak, ilk düğüme göre ikinci düğüm seçeneklerini ve ilk düğümü çıkararak üçüncü düğümü hesaplar.



0

Python 3, 106 bayt

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])

Bağımsız değişken aracılığıyla girdi aldıkları ve kayan listelerin listesini STDOUT'a yazdırırlar.

Python Kartezyen ürünlerde iyi değil ...

Nasıl çalışır

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

Ideone üzerinde deneyin


0

Aslında 15 bayt

Bu, TheBikingViking'in Python yanıtındakine benzer bir algoritma kullanır . Golf önerileri hoş geldiniz. Çevrimiçi deneyin!

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

Ungolfed:

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 bayt

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]]

Kayan noktalı sayı dizilerinden oluşan bir dizi döndürür. Düzenleme: Üçüncü koordinatı doğrudan hesaplayarak 7 bayt kaydedildi. Doğrudan ifaralığı hesaplayarak ortadan kaldırmayı denedim yama ekstra bir bayt maliyeti:

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

Sonunda yazdınız [x/n,y/n/z/n], virgül unuttun mu?
kamoroso94

@ kamoroso94 Haklısın, son virgül yazdım, bana bildirdiğin için teşekkürler.
Neil
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.