Kombinasi linear dari dua vektor

11

Ringkasan bisnis plan

Input yang diberikan mewakili dua vektor dan "bobot" masing-masing, menghasilkan output yang juga mewakili jumlah tertimbang dari vektor tersebut.

Tantangan

Input akan terdiri dari satu atau lebih baris karakter berikut:

  • persis satu kemunculan digit 0, yang mewakili asal dalam bidang dua dimensi;
  • tepat dua digit lainnya (1-9; mungkin atau mungkin tidak digit yang sama), yang posisinya relatif terhadap titik asal mewakili vektor, dan yang nilainya mewakili bobot yang dilampirkan pada vektor vektor tersebut;
  • sejumlah "karakter latar belakang". Pemecah dapat memilih karakter latar belakang tertentu; misalnya, saya akan memilih "." (sebagian besar untuk keterbacaan manusia). Bergantian, karakter latar belakang bisa berupa apa saja yang terlihat seperti ruang kosong.

(Pemecah dapat memilih apakah input adalah string multi-line tunggal atau array string satu-baris.)

Misalnya input

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

mewakili vektor pada koordinat (3,1) dengan bobot 2, dan vektor pada koordinat (2, -1) dengan bobot 3.

Outputnya harus hampir sama dengan input, dengan perubahan berikut:

  • "karakter hasil", yang dipilih oleh solver, untuk ditambahkan pada posisi yang ditentukan oleh jumlah tertimbang dari vektor input (ekuivalen, pada posisi yang merupakan kombinasi linear yang sesuai dari vektor input);
  • sebanyak karakter latar belakang yang diperlukan agar sesuai dengan asal, dua vektor input, dan vektor output dalam gambar yang sama. Karakter latar belakang tambahan dapat dimasukkan jika diinginkan; satu-satunya kendala adalah bahwa, jika karakter latar belakang adalah karakter yang terlihat, maka seluruh output harus berbentuk persegi panjang dan setiap karakter yang tidak mewakili vektor harus menjadi karakter latar belakang. (Jika ruang kosong digunakan sebagai karakter latar belakang, maka batasan ini tidak perlu ditegakkan.)

(Secara umum, jika kita memiliki satu vektor (v, w) dengan bobot a dan vektor kedua (x, y) dengan berat b, jumlah tertimbangnya adalah (v, w) + b (x, y) = (av + bx, aw + oleh).)

Pada contoh sebelumnya, kombinasi linear yang sesuai adalah 2 * (3,1) + 3 * (2, -1) = (12, -1). Jika kita menggunakan "X" sebagai karakter hasil, maka hasilnya akan terlihat seperti

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

atau

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

Penilaian : jawaban terpendek, dalam byte, menang.

Contoh input dan output

Jika ruang kosong digunakan, input di atas akan terlihat seperti

    2
 0
   3

dan hasilnya akan terlihat seperti

    2
 0
   3         X

Karakter / garis spasi putih terkemuka / tidak relevan; jika mereka tidak terlihat oleh pembaca, tidak apa-apa. (Yang dikatakan, untuk sisa contoh saya akan kembali menggunakan "." Untuk karakter latar belakang, untuk membuatnya lebih mudah dibaca.)

Jika kedua vektor memiliki bobot 1, maka hasilnya akan terlihat seperti jajar genjang: input

.1.
...
1.0

mengarah ke output

X.1.
....
.1.0

Perhatikan bahwa jajar genjang ini dapat berdegenerasi jika vektor inputnya adalah linier: input

0.1..1

mengarah ke output

0.1..1.X

Dimungkinkan untuk vektor hasil untuk sama dengan salah satu vektor input atau asal; dalam hal ini, ia hanya akan menimpa karakter input. Misalnya input

..2.0.1...

menghasilkan output

..X.0.1...

(di mana dalam input dan / atau output, periode awal dan akhir dapat dihapus). Input

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

menghasilkan output

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

Akhirnya input

90
.8

menghasilkan output

........90
.........8
..........
..........
..........
..........
..........
..........
X.........
Greg Martin
sumber
1
Selamat datang di PPCG! Tantangan pertama yang bagus.
AdmBorkBork
@TimmyD Terima kasih atas sambutan dan dorongannya :)
Greg Martin
1
Akhirnya, karena saya yakin orang lain akan memunculkannya, ini sangat dekat dengan tantangan bunglon karena sepotong kode yang cukup besar akan hanya mengurai input, ketika itu sebenarnya bukan dorongan utama dari tantangan.
AdmBorkBork
apakah ada batasan jumlah baris / kolom dalam input atau output yang benar?
Sparr
@TimmyD Saya telah menambahkan rumus umum untuk jumlah tertimbang, dan juga menjelaskan bahwa format input baik-baik saja. Saya setuju bahwa ini dekat dengan tantangan bunglon (meskipun saya berharap bahwa beberapa bahasa mungkin memiliki kemampuan "berjalan" langsung di papan tulis untuk menyelesaikan masalah); namun umpan balik pada Sandbox sedikit lebih positif daripada negatif, jadi saya memutuskan untuk menggunakannya.
Greg Martin

Jawaban:

7

MATL , 48 byte

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

Karakter latar belakang adalah ruang. Input adalah array char 2D dengan baris yang dipisahkan oleh titik koma. Jadi kasus tes memiliki input masing-masing:

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

Outputnya termasuk sejumlah besar ruang putih padding.

Cobalah online!

Luis Mendo
sumber
2

Python 3, 374 355 byte

Tidak terlalu halus solusi python yang sangat murah hati dengan padding (menggunakan jarak papan catur maksimum). Input adalah satu baris di mana baris dipisahkan dengan pipa | (walaupun algoritme dapat dengan mudah menggunakan apa pun yang bukan alfanumerik yang bukan baris baru atau EOF). Apa pun yang bukan alfanumerik atau | berfungsi untuk input padding, output padding menggunakan titik. Umpan balik dan peningkatan dari pegolf python yang lebih berpengalaman sangat dihargai.

Sunting: Beberapa peningkatan berkat @TheBikingViking. Juga menambahkan lebih banyak margin karena saya tidak cukup murah hati dengan bantalan.

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))
algmyr
sumber
Jawaban bagus! Lihatlah tip Python . Beberapa petunjuk: 1. Ada baiknya Anda menentukan apakah Anda menggunakan Python 2/3, karena beberapa fitur berbeda. 2.You dapat melakukan [a,b][condition]alih - alih b if condition else cpada jalur 2. sortedmengambil iterator apa pun, termasuk pernyataan generator, sehingga Anda dapat menjatuhkan pasangan luar tanda kurung kotak. 3. zip(p)harus bekerja p[0] for p in P.
TheBikingViking
4. Anda dapat melakukan P+=[stuff]alih - alih P.append([stuff])pada jalur 7. 5. Lakukan ["."]alih-alih list("."). (3. seharusnya zip(p)[0].)
TheBikingViking
Maaf, harus modal Pdi zip.
TheBikingViking
5. Anda harus dapat melakukannya S=[stuff]*2*Ldi jalur 10.
TheBikingViking
[1] Poin bagus, akan menambahkan versi python. [2] Pola yang bagus, tetapi tidak berfungsi index(kesalahan tidak ditemukan). Akan bekerja dengan baik find. [Kembali. diurutkan] Terima kasih, tidak dapat menghapusnya saat menambahkan sorted. [3] zip (* P) ​​[0] tidak berfungsi di python 3 (objek zip tidak dapat diindeks). [4] P + = [barang] tidak akan berfungsi, meskipun P + = [[barang]] akan berhasil. [5] Terima kasih. [5 lainnya] Tidak berfungsi. Saya perlu daftar baru, bukan referensi.
algmyr
2

JavaScript, 534 528 502 bytes

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

Perhatikan bahwa bantalan optimal. Program ini mengasumsikan bahwa saya berisi string mentah, dengan garis yang dipisahkan oleh \nkarakter. Padding dilakukan dengan spasi, dan karakter hasilnya adalah huruf kecil x.

Ini adalah upaya pertama saya di golf kode.

Hal-hal teknis: - Ukuran program kira-kira dua kali lipat (dan kompleksitasnya naik secara dramatis) untuk hanya memperhitungkan karakter hasil, terutama karena string JavaScript tidak dapat diubah.


Penjelasan baris demi baris:

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

Saya sering menggunakannya, jadi menyimpannya dalam string menghemat ruang. Anda dapat melihat di bawah bahwa untuk splitfungsi, saya hanya membuat alias; ini karena saya hanya butuh satu argumen, yang lain konstan. Namun untuk indexOfdan join, itu akan lebih lama.

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

Tidak ada yang rumit di sini, saya membaca lebar dan tinggi array awal. Perhatikan penggunaan i[n]untuk mengakses indexOf, sementara splitditangani secara berbeda.

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

Ini semakin menarik. Fungsi ini pada dasarnya menciptakan gabungan J-1 kali string X dan mengembalikannya. Ini digunakan untuk menghasilkan string ruang untuk padding.

C=[0,0,0]

Array ini akan berisi jumlah baris dan kolom yang ditambahkan oleh padding (dinonaktifkan oleh faktor h dalam kasus pertama). Sel terakhir adalah sampah, dan mencegah saya dari memiliki argumen tambahan dalam fungsi di bawah ini.

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

Fungsi ini sendiri menangani bantalan (baik garis dan kolom); itu menentukan, berdasarkan pada koordinat vektor hasil (X), dan jumlah baris / kolom untuk menghasilkan (E), apakah perlu untuk membuat satu. yang X+E+1+Thanya trik untuk menghemat ruang, Uadalah string mengisi (ruang untuk kolom, dan seluruh baris untuk baris), dan kami akan kembali ke R. Fungsi ini pada dasarnya mengembalikan, dalam kasus garis, padding diperlukan di awal atau akhir baris tersebut, dan, dalam kasus kolom, ia mengembalikan garis padding yang diperlukan baik sebelum atau setelah garis asli.

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

Di sini kita membaca posisi asal, dan kita mengambil koordinatnya. L adalah fungsi untuk mengubah indeks menjadi nomor baris.

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

Saya menambahkan beberapa spasi putih untuk membuatnya lebih mudah dibaca. Apa yang terjadi di sini adalah bahwa untuk setiap angka yang mungkin, kami terus mencarinya di string asli. The ~Caranya relatif umum di Javascript; itu bukan operator bitwise, tapi yang penting di sini adalah itu ~-1==0, yang memungkinkan saya untuk menguji akhir dari loop. Saya kemudian menghapus karakter dalam string (itulah sebabnya saya membuat salinan), ini memungkinkan saya untuk melanjutkan pencarian selama diperlukan. Saya kemudian menambahkan koordinat vektor (x, y), menggunakan substraksi sederhana.

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

Saya di sini membagi string asli menjadi garis-garis, dan untuk setiap baris, saya sebut Gmana yang akan menghasilkan padding sebelum dan sesudah baris. The l-w+2dan sebagainya berasal dari perhitungan indeks sederhana yang memungkinkan saya untuk menguji apakah saya perlu menambahkan bantalan atau tidak. Misalnya, jika x>0dan x+l-w+1>0, maka (x+l-w+1)+1spasi harus ditambahkan setelah baris. The +xsedang dihapus karena itu menjadi parameter pertama, dan X+E+1+Tdigunakan dalam definisi G.

Hal serupa dilakukan untuk karakter pertama, dan kemudian untuk kolom. Ada banyak faktorisasi di sini yang memungkinkan saya untuk menggunakan hanya satu fungsi. Perhatikan parameter terakhir; dalam kasus pertama, saya ingin menulis C[0]agar dapat mengetahui nanti berapa banyak kolom yang saya tambahkan di awal setiap baris; ini memungkinkan saya untuk mengambil posisi akhir dari karakter hasil. Namun saya tidak peduli dengan kolom yang ditambahkan setelah baris asli, itulah sebabnya panggilan kedua untuk Gmenulis ke sel sampah C[2]yang tidak digunakan.

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

Di sini saya cukup membaca panjang baru dari garis, dan membuat garis spasi dari itu. Ini akan digunakan untuk membuat padding vertikal.

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

Ini persis sama dengan dua baris di atas. Satu-satunya perbedaan adalah menulis untuk C[1]saat ini, dan menggunakan pemisah N+Odan O+N. Ingat itu Oadalah baris baru, dan Ngaris ruang. Saya kemudian menerapkan Bpada hasil untuk membaginya lagi (saya perlu mengambil baris yang berisi karakter hasil untuk mengeditnya).

M=y+c+C[1]

Ini adalah indeks vertikal dari karakter yang dihasilkan.

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

Di sini saya dipaksa untuk memodifikasi Oagar dapat membagi baris yang sesuai menjadi array karakter. Ini karena string JavaScript tidak dapat diubah; satu-satunya cara untuk mengedit string adalah mengubahnya menjadi array (yang saya lakukan di sini), mengedit di posisi yang tepat, dan bergabung dengan string lagi. Perhatikan juga hfaktornya, yang karena Gfungsinya dipanggil sekali per baris awal.

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

Saya akhirnya mengganti string baru dalam array, dan bergabung kembali menjadi string. Woo hoo!

pie3636
sumber