我的三角形需要更多节点


20

考虑标准等边三角形,其节点使用重心坐标标记:

我们可以通过添加3个顶点的新线(比原来的3节点三角形的一侧多一个),将3节点三角形变成6节点三角形,删除任何内部边缘(但不包括内部节点),然后重新标准化坐标:

在此处输入图片说明

重复此过程,从6个节点的三角形变为10个节点的三角形,添加一行4个顶点(同样,比原始6个节点三角形的一侧多一个),删除所有内部边缘(但不包括内部节点) )并重新标准化坐标:

在此处输入图片说明

此过程可以无限期重复。挑战的目标是给一个整数,N代表执行此过程的次数,并在重心坐标中输出关联三角形的所有节点。

输入值

您的程序/函数应采用一个非负整数作为输入,该整数N代表已应用此过程的次数。请注意,对于N=0,您应该输出具有3个节点的原始三角形。

输入可以来自任何来源(功能参数,标准输入输出等)。

输出量

您的程序/函数应以归一化的重心坐标输出所有节点。节点的顺序无关紧要。可以将数字指定为分数(不需要减少分数)或浮点数。您也可以输出“缩放”向量来指定节点。例如,以下所有3个输出都是等效的并被允许:

0.5,0.5,0

1/2,2/4,0

[1,1,0]/2

如果使用浮点输出,则您的输出应精确到1%以内。输出可以是所需的任何接收器(stdio,返回值,返回参数等)。请注意,即使重心坐标唯一地由每个节点2个数字确定,您也应该输出每个节点所有3个数字。

例子

示例案例的格式为:

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

其中第一行是input N,所有随后的行形成一个节点x,y,z,该节点应在输出中恰好一次。所有数字均以近似浮点数形式给出。

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

计分

这是代码高尔夫;以字节为单位的最短代码获胜。有标准漏洞。您可以使用所需的任何内置功能。


您说“ 如果使用浮点输出 ”。有哪些替代方案?分数?如果是这样,是否必须减少它们?像这样的比例矢量怎么样[1,2,3]/6
彼得·泰勒

是的,所有这些替代方法都是允许的。我将更新问题陈述。
helloworld922

Answers:


7

CJam(22字节)

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

这是一个匿名块(函数),它占据N堆栈,并在堆栈上保留双精度数组的数组。在线演示

解剖

{         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个字节

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

5

Python 3,87个字节

这实际上应该是TheBikingViking对解决方案的评论,但我没有足够的声誉来发表评论。

通过仅遍历变量i,j并利用与第三个变量加起来的事实,可以节省一些字节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字节

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

这是一个带有单个整数参数的未命名函数。输出是精确(减少的)分数列表的列表。

生成1/(N+1)0到1之间的所有3元组(包括0和1)的倍数,然后选择总和为1 的三元组(按重心坐标的要求)。


4

05AB1E,10个字节

ÌL<¤/3ãDOÏ

说明

Ì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

在线尝试


由于¤消耗数组,为什么要用/数组除以数组?是否“记住”最后弹出的值并在需要时使用它?
路易斯·门多

@LuisMendo:¤是少数不会从堆栈弹出和使用的命令之一。它在将列表保留在堆栈中的同时推入列表的最后一个元素。
Emigna



哦,当然!感谢您的解释
Luis Mendo

3

MATL,17个字节

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

在线尝试!

说明

该方法与其他答案相同:

  1. 生成array [0, 1/(n+1), 2/(n+1), ..., 1]n输入在哪里;
  2. 用这些值生成所有三元组;
  3. 只保留总和为的那些1

进一步来说:

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

水母37 33字节

感谢Zgarb节省了4个字节。

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

在线尝试!

就像我的Mathematica和Peter的CJam答案一样,这会生成一组候选元组,然后仅选择那些总和为1的元组。我对布局还不完全满意,我想知道是否可以用钩子或叉子保存一些字节,但我稍后必须调查。


1

的Perl 6:50 40个字节

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

返回(精确)有理数的三元素列表序列。

说明:

  • $_
    隐式声明的lambda参数。
  • 0, 1/($_ + 1) ... 1
    使用序列运算符...构造与可能的坐标值相对应的算术序列。
  • [X] EXPR xx 3
    取三个EXPR的笛卡尔乘积,即生成所有可能的三元组。
  • grep *.sum == 1, EXPR
    过滤总和为1的元组。

1

Ruby,62岁

如果对此无法改善,我会感到惊讶:

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

采取潜在的难题建议,这将基于第一个节点计算第二个节点选项,并通过减去前两个来计算第三个节点。



0

Python 3,106个字节

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

他们通过参数获取输入的函数,并将浮点列表列表打印到STDOUT。

Python不擅长笛卡尔积...

怎么运行的

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上尝试


0

实际上,15个字节

这使用的算法类似于TheBikingViking的Python answer中的算法。欢迎打高尔夫球。在线尝试!

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

取消高尔夫:

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字节

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

返回浮点数数组。编辑:通过直接计算第三个坐标保存7个字节。我试图消除if通过y直接计算范围来但是它花费了一个额外的字节:

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

最后,您写道[x/n,y/n/z/n],您是否忘记了逗号?
kamoroso94 '16

@ kamoroso94您说得对,我输入了最后一个逗号,谢谢您让我知道。
尼尔
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.