2つのベクトルの線形結合


11

エグゼクティブサマリー

2つのベクトルを表す入力とそれぞれの「重み」を指定すると、それらのベクトルの加重和も表す出力が生成されます。

チャレンジ

入力は、次の文字の1つ以上の行で構成されます。

  • 2次元平面の原点を表す数字0の正確な1回の出現。
  • 正確に他の2桁(1から9。同じ数字である場合とそうでない場合がある)、その原点に対する位置はベクトルを表し、その値はこれらのベクトルに付加された重みを表します。
  • いくつかの「背景文字」。ソルバーは特定の背景文字を選択できます。たとえば、「。」を選択します (主に人間が読みやすいように)。または、背景文字は空白のように見えるものであれば何でもかまいません。

(ソルバーは、入力が単一の複数行文字列であるか、1行文字列の配列であるかを選択できます。)

たとえば、入力

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

重み2の座標(3,1)のベクトルと、重み3の座標(2、-1)のベクトルを表します。

出力は入力とほぼ同じで、次の変更が必要です。

  • ソルバーによって選択され、入力ベクトルの加重和によって指定された位置に(追加的に、入力ベクトルの適切な線形結合である位置に)追加される「結果文字」。
  • 原点、2つの入力ベクトル、および出力ベクトルを同じ画像に収めるために必要な数の背景文字。必要に応じて、追加の背景文字を含めることができます。唯一の制約は、背景文字が可視文字である場合、出力全体の形状が長方形でなければならず、ベクトルを表さないすべての文字が背景文字でなければならないということです。(空白文字が背景文字として使用される場合、これらの制約を実施する必要はありません。)

(一般に、重みaの1つのベクトル(v、w)と重みbの2番目のベクトル(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

結果ベクトルは、入力ベクトルの1つまたは原点に等しくなる可能性があります。この場合、単に入力文字を上書きします。たとえば、入力

..2.0.1...

出力を生成します

..X.0.1...

(入力および/または出力では、先行および後続の期間を削除できます)。入力

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

出力を生成します

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

最後に、入力

90
.8

出力を生成します

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

1
PPCGへようこそ!素敵な最初の挑戦。
AdmBorkBork

@TimmyD歓迎と励ましをありがとう:)
グレッグマーティン

1
最後に、他の人がそれをもたらすと確信しているので、かなり大きなコードのチャンクが単純に入力を解析するので、これはカメレオンの挑戦にふざけています。
-AdmBorkBork

入力または正しい出力の行/列の数に制限はありますか?
スパー

@TimmyD加重和の一般式を追加し、どちらの入力形式でも問題ないことを明確にしました。これはカメレオンの課題に近いことに同意します(ただし、一部の言語には、問題を解決するためにボード上で直接「歩く」機能があることを望んでいました)。ただし、Sandboxのフィードバックはネガティブよりも適度にポジティブであったため、私はそれを採用することにしました。
グレッグマーティン

回答:


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.行2の[a,b][condition]代わりに行うことができますb if condition else csortedジェネレーターステートメントを含む任意のイテレーターを使用するため、角括弧の外側のペアを削除できます。3.のzip(p)代わりに動作するはずですp[0] for p in P
TheBikingViking

4. 7行目のP+=[stuff]代わりに行うことができますP.append([stuff])。5 .の["."]代わりに行いlist(".")ます。(3.あったはずzip(p)[0]です。)
TheBikingViking

申し訳ありませんが、大文字Pである必要がありzipます。
TheBikingViking

5. S=[stuff]*2*L10行目でできるはずです
。– TheBikingViking

[1]良い点は、Pythonバージョンを追加することです。[2]パターンは良好ですが、動作しませんindex(何も見つからない場合のエラー)。でも動作しfindます。[Re。並べ替え]を追加するときにそれらを削除できなかったことに感謝しますsorted。[3] zip(* P)[0]はPython 3では機能しません(zipオブジェクトはインデックス化できません)。[4] P + = [[stuff]]は機能しますが、P + = [stuff]は機能しません。[5]ありがとう。[その他5]動作しません。参照ではなく、新しいリストが必要です。
アルグミー

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

パディングが最適であることに注意してください。このプログラムは、iが文字で区切られた生の文字列を含むと仮定します\n。パディングはスペースで行われ、結果の文字は小文字xです。

これは、コードゴルフの私の最初の試みです。

技術的なもの:-主にJavaScript文字列が不変であるため、結果の文字を考慮するだけでプログラムのサイズが約2倍になり(そしてその複雑さが劇的に上がりました)。


行ごとの説明:

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

私はそれらをよく使うので、文字列に保存することでスペースを節約できました。split関数については、以下に示すように、エイリアスを作成しただけです。これは、引数が1つだけ必要で、もう1つは定数であるためです。とのためindexOfjoin、しかし、それはもっと長かったでしょう。

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

ここでは複雑なことは何もありません。最初の配列の幅と高さを読んでいます。i[n]to の使用に注意してください。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演算子ですが~-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

同様のことが最初の文字に対して行われ、次に列に対して行われます。ここには多くの因数分解があり、1つの関数のみを使用できます。最後のパラメーターに注意してください。前者の場合、C[0]後で各行の先頭に追加した列の数を知ることができるように書き込みたいです。これにより、結果の文字の最終位置を取得できます。ただし、元の行の後に追加された列は気にしません。これが、使用されていないGジャンクセルへの2番目の呼び出しの理由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))

これは上記の2行とまったく同じです。唯一の違いは、C[1]この時間に書き込むことと、区切り文字N+Oとを使用することO+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関数が初期行ごとに1回呼び出されたためです。

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

最後に、配列内の新しい文字列を置き換えて、再び文字列に結合します。やったー!

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.