两个向量的线性组合


11

执行摘要

给定代表两个向量及其各自“权重”的输入,则产生的输出也代表这些向量的加权总和。

挑战

输入将包含以下字符的一行或多行:

  • 正好出现一次数字0,它表示二维平面中的原点;
  • 正好是另外两个数字(1-9;可以是或可以不是相同的数字),它们相对于原点的位置代表矢量,并且其值代表这些矢量的权重;
  • 一些“背景字符”。求解器可以选择特定的背景字符;例如,我将选择“。” (主要是为了人类可读性)。或者,背景字符可以是任何看起来像空白的东西。

(求解器可以选择输入是单个多行字符串还是单行字符串数组。)

例如,输入

....2
.0...
...3.

表示权重为2的坐标(3,1)处的向量,权重为3的坐标(2,-1)处的向量。

输出应与输入几乎相同,并进行以下更改:

  • 由求解器选择的“结果字符”,将被添加到由输入矢量的加权和指定的位置(等效地,在输入矢量的适当线性组合的位置);
  • 在同一张图片中,需要多少背景字符以适合原点,两个输入向量和输出向量。如果需要,可以包含额外的背景字符;唯一的限制是,如果背景字符是可见字符,则整个输出的形状必须是矩形,并且每个不代表矢量的字符都必须是背景字符。(如果将空格用作背景字符,则无需强制执行这些约束。)

(通常,如果我们有一个权重为a的向量(v,w)和权重为b的第二向量(x,y),则它们的加权总和为a(v,w)+ b(x,y)=(av + bx,aw + by)。)

在前面的示例中,适当的线性组合为2 *(3,1)+ 3 *(2,-1)=(12,-1)。如果我们使用“ X”作为结果字符,那么输出看起来像

....2.........
.0............
...3.........X

要么

................
...2............
0...............
..3.........X...
................
................

通常的评分:最短的答案(以字节为单位)获胜。

输入和输出示例

如果使用空格,则上面的输入看起来像

    2
 0
   3

和输出看起来像

    2
 0
   3         X

前导/尾随空格字符/行无关。如果读者看不见它们,那很好。(话虽如此,在其余示例中,我将回过头使用“。”作为背景字符,以使其更易于阅读。)

如果两个向量的权重均为1,则结果将看起来像平行四边形:输入

.1.
...
1.0

导致输出

X.1.
....
.1.0

请注意,如果输入向量是共线的,则此平行四边形可以退化:

0.1..1

导致输出

0.1..1.X

结果向量有可能等于输入向量之一或原点。在这种情况下,它只会覆盖输入字符。例如,输入

..2.0.1...

产生输出

..X.0.1...

(在输入和/或输出中,前导和尾随期间可以删除)。输入

.....3
......
...0..
......
......
2.....

产生输出

.....3
......
...X..
......
......
2.....

最后,输入

90
.8

产生输出

........90
.........8
..........
..........
..........
..........
..........
..........
X.........

1
欢迎来到PPCG!不错的第一个挑战。
AdmBorkBork '16

@TimmyD感谢您的欢迎和鼓励:)
Greg Martin

1
最后,由于我敢肯定其他人会提出来,因此这很接近变色龙挑战,因为相当多的代码将只是解析输入,而这并不是挑战的主要目的。
AdmBorkBork '16

输入或正确输出中的行/列数是否有限制?
Sparr

@TimmyD我为加权总和添加了通用公式,并且还阐明了两种输入格式都可以。我同意这接近变色龙的挑战(尽管我希望某些语言可能具有直接在董事会上“行走”以解决问题的能力);但是,有关Sandbox的反馈适度多于消极,因此我决定采用它。
格雷格·马丁

Answers:


7

MATL,48个字节

tZyyX:UX>*Yat48-tt0>*3#fbbhb~2#fh-*s7M+'X'wZ}4$(

背景字符是空格。输入是2D字符数组,行之间用分号分隔。因此,测试用例具有各自的输入:

['    2'; ' 0   '; '   3 ']
[' 1 '; '   '; '1 0']
['0 1  1']
['  2 0 1   ']
['     3'; '      '; '   0  '; '      '; '      '; '2     ']
['90'; ' 8']

输出中包含大量的填充空白。

在线尝试!


2

Python 3中,374个 355字节

不太精巧的python解决方案,非常适合填充(使用最大棋盘距离)。输入是单行,其中行用管道分隔。(尽管该算法可以轻松使用非字母数字,不是换行符或EOF的任何东西)。非字母数字或| 适用于输入填充,输出填充使用句点。感谢经验丰富的Python高尔夫球手的反馈和改进。

编辑:感谢@TheBikingViking。还增加了更多的边距,因为我对填充的使用不够慷慨。

s=input()
l=[len(s),1+s.find('|')]['|'in s]
P=sorted([int(c),i%l,i//l]for i,c in enumerate(s)if c.isalnum())
L=X=Y=0
P[0][0]=-sum(p[0]for p in P)
for w,x,y in P:L=max(abs(x),abs(y),L);X+=x*w;Y+=y*w
P+=[['X',P[0][1]+X,P[0][2]+Y]]
P[0][0]=0
L=2*max(abs(X),abs(Y),L)
S=[2*L*["."]for _ in[0]*2*L]
for w,x,y in P:S[L+y][L+x]=str(w)
for s in S:print(''.join(s))

好答案!看一下Python技巧。一些提示:1.由于某些功能不同,因此最好指定是否使用Python 2/3。2.您可以[a,b][condition]代替b if condition else c第2行执行操作,而是使用sorted任何迭代器(包括generator语句),因此可以放下外部的一对方括号。3. zip(p)应该代替p[0] for p in P
TheBikingViking

4.您可以P+=[stuff]代替P.append([stuff])第7行执行操作。5. ["."]代替代替list(".")。(3.应该是zip(p)[0]。)
TheBikingViking

对不起,应该是资金Pzip
TheBikingViking '16

5.您应该可以S=[stuff]*2*L在第10行上进行
。– TheBikingViking

[1]好点,将添加python版本。[2]良好的模式,但无法使用index(错误提示:找不到任何内容)。将与find虽然。[回覆。排序]谢谢,错过了在添加时将其删除的问题sorted。[3] zip(* P)[0]在python 3中不起作用(zip对象不可索引)。[4] P + = [stuff]无效,尽管P + = [[stuff]]有效。[5]谢谢。[其他5]不起作用。我需要新列表,而不是引用。
algmyr '16

2

JavaScript中,534个 528 502字节

n="indexOf"
J="join"
B=X=>X.split(O)
O='\n'
w=i[n](O)+1
h=B(i).length
Z=(X,Y,R)=>{C[R]+=X-1;return Array(X)[J](Y)}
C=[0,0,0]
G=(X,E,T,U,R)=>X>0&E>=0?Z(X+E+1+T,U,R):""
o=i[n]("0")
L=X=>Math.floor(X/(w-1))
l=L(o)
c=o%w
x=y=0
j=i
for(z="1";z<="9";z++){while(p=~j[n](z)){j=j.replace(z," ")
x+=~p%w-l
y+=L(~p)-c}}
I=B(i).map(X=>G(-x,-l,0," ",0)+X+G(x,l-w+2,0," ",2))
N=Z(I[0].length+1," ",2)
A=B(G(-y,-c,0,N+O,1)+I[J](O)+G(y,c-h,1,O+N,2))
M=y+c+C[1]
O=""
m=B(A[M])
m[x+l+C[0]/h]="x"
A[M]=m[J]("")
A[J]("\n")

请注意,填充是最佳的。该程序假定我包含原始字符串,且各行用\n字符分隔。用空格填充,结果字符为小写x

这是我第一次尝试代码编程。

技术资料:-该程序的大小大约增加了一倍(并且其复杂性急剧增加),仅考虑结果字符,主要是因为JavaScript字符串是不可变的。


逐行说明:

n="indexOf"
J="join"
B=X=>X.split(O)

我经常使用它们,因此将它们存储在字符串中可以节省一些空间。您可以在下面看到该split函数,我只是创建了一个别名;这是因为我只需要一个参数,另一个则是常数。对于indexOfjoin,它将更长。

O='\n'
w=i[n](O)+1
h=B(i).length

这里没有什么复杂的,我正在读取初始数组的宽度和高度。注意,这里使用的i[n]访问indexOf,而split不同的方式处理。

Z=(X,Y,R)=>{C[R]+=X-1;return Array(X)[J](Y)}

这变得越来越有趣。此函数基本上将字符串X的连接数J-1创建并返回。这用于生成用于填充的空格字符串。

C=[0,0,0]

该数组将包含通过填充添加的行数和列数(在第一种情况下,偏移量为系数h)。最后一个单元格是一个垃圾单元格,它使我无法在下面的函数中添加其他参数。

G=(X,E,T,U,R)=>X>0&E>=0?Z(X+E+1+T,U,R):""

仅此功能处理填充(行和列);它根据结果向量(X)的坐标以及要生成的行数/列数(E)来确定是否有必要创建一个。的X+E+1+T只是一招节省一些空间,U是填充字符串(列的空间,而对于线整条生产线),我们会回来的R。对于一行,此函数基本上返回在该行的开头或末尾所需的填充,对于一行,则返回原始行之前或之后所需的填充行。

o=i[n]("0")
L=X=>Math.floor(X/(w-1))
l=L(o)
c=o%w

在这里,我们读取原点的位置,并获取其坐标。L是将索引转换为行号的功能。

x=y=0
j=i
for(z="1";z<="9";z++){
    while(p=~j[n](z)){
        j=j.replace(z," ")
        x+=~p%w-l
        y+=L(~p)-c
    }
}

我添加了一些空格以使其更易于阅读。这里发生的是,对于每个可能的数字,我们一直在原始字符串中寻找它。这个~技巧在Javascript中相对常见。它是按位的NOT运算符,但这里最重要的是that ~-1==0,它允许我测试循环的结尾。然后,我删除了字符串中的字符(这就是我进行复制的原因),这使我可以根据需要继续搜索。然后(x, y),我使用简单的减法将向量的坐标添加到。

I=B(i).map(X=>G(-x,-l,0," ",0)+X+G(x,l-w+2,0," ",2))

我在这里将原始字符串分成几行,对于每一行,我都会调用G它将在行之前和之后生成填充。在l-w+2等来自一个简单的指数计算,让我来测试我是否需要添加填充与否。例如,如果x>0x+l-w+1>0,则(x+l-w+1)+1必须在该行之后添加空格。的+x删除是因为它是第一个参数,并且已X+E+1+T在的定义中使用G

对于第一个字符,然后对列,执行类似的操作。这里有很多分解,只允许我使用一个函数。注意最后一个参数;在第一种情况下,我想写信以便C[0]稍后知道在每一行的开头添加了多少列;这使我可以检索结果字符的最终位置。但是,我不在乎原始行之后添加的列,这就是为什么第二次调用G写入C[2]未使用的垃圾单元的原因。

N=Z(I[0].length+1," ",2)

在这里,我简单地阅读了这些行的新长度,并从中创建了一行空格。这将用于创建垂直填充。

A=B(G(-y,-c,0,N+O,1)+I[J](O)+G(y,c-h,1,O+N,2))

这与上面的两行完全相同。唯一的区别是编写C[1]时间,并使用分隔符N+OO+N。请记住,这O是一个换行符,并且N是一行空格。然后B,我将结果应用于再次拆分(我需要检索包含结果字符的行以对其进行编辑)。

M=y+c+C[1]

这是结果字符的垂直索引。

O=""
m=B(A[M])
m[x+l+C[0]/h]="x"

在这里,我被迫修改O以能够将适当的行拆分为字符数组。这是因为JavaScript字符串是不可变的。编辑字符串的唯一方法是将其转换为数组(这就是我在这里所做的事情),在正确的位置进行编辑,然后再次连接字符串。另请注意h因素,这是因为该G函数在每个初始行中被调用一次。

A[M]=m[J]("")
A[J]("\n")

最后,我替换了数组中的新字符串,然后将其再次连接到字符串中。oo!

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.