Pertanyaan ini didasarkan pada Menara puzzle penempatan angka (juga dikenal sebagai Pencakar Langit), yang dapat Anda mainkan online . Tujuan Anda adalah untuk mengambil solusi untuk teka-teki dan menentukan petunjuk - jumlah menara terlihat di sepanjang setiap baris dan kolom. Ini adalah kode golf, byte paling sedikit menang.
Bagaimana Towers bekerja
Solusi untuk teka-teki Towers adalah kotak Latin - n*n
kotak di mana setiap baris dan kolom berisi permutasi angka yang 1
dilewati n
. Contoh untuk n=5
adalah:
4 3 5 2 1
5 4 1 3 2
1 5 2 4 3
2 1 3 5 4
3 2 4 1 5
Setiap baris dan kolom diberi label dengan petunjuk di setiap ujungnya seperti:
2 3 1 4 5
v v v v v
2 > 4 3 5 2 1 < 3
1 > 5 4 1 3 2 < 4
2 > 1 5 2 4 3 < 3
3 > 2 1 3 5 4 < 2
3 > 3 2 4 1 5 < 1
^ ^ ^ ^ ^
2 2 2 2 1
Setiap petunjuk adalah angka dari 1
ke n
yang memberitahu Anda berapa banyak menara yang Anda "lihat" melihat sepanjang baris / kolom dari arah itu, jika angka-angka diperlakukan sebagai menara dengan ketinggian itu. Setiap menara memblokir menara yang lebih pendek di belakangnya. Dengan kata lain, menara yang Anda lihat adalah menara yang lebih tinggi dari menara mana pun sebelumnya.
Sebagai contoh, mari kita lihat baris pertama.
2 > 4 3 5 2 1 < 3
Ini memiliki petunjuk dari 2
kiri karena Anda dapat melihat 4
dan 5
. The 4
blok 3
dari pandangan dan 5
blok segala sesuatu yang lain. Dari kanan, Anda dapat melihat 3
menara: 1
, 2
, dan 5
.
Persyaratan program
Tulis program atau fungsi yang menggunakan kotak angka dan keluaran atau cetak petunjuk, searah jarum jam dari kiri atas.
Memasukkan
Kotak n*n
Latin dengan 2<=n<=9
.
Formatnya fleksibel. Anda dapat menggunakan struktur data apa pun yang mewakili kisi atau daftar yang berisi angka atau karakter digit. Anda mungkin memerlukan pemisah antara baris atau tidak ada pemisah sama sekali. Beberapa kemungkinan adalah daftar, daftar daftar, matriks, string yang dipisahkan dengan token seperti
43521 54132 15243 21354 32415,
atau string tanpa spasi.
Anda tidak diberikan n
sebagai bagian dari input.
Keluaran
Kembalikan atau cetak petunjuk mulai dari kiri atas dan searah jarum jam. Jadi, pertama membaca petunjuk atas ke kanan, kemudian petunjuk kanan membaca ke bawah, lalu petunjuk bawah membaca ke kiri, petunjuk kiri membaca ke atas.
Ini akan menjadi 23145 34321 12222 33212
contoh sebelumnya
2 3 1 4 5
v v v v v
2 > 4 3 5 2 1 < 3
1 > 5 4 1 3 2 < 4
2 > 1 5 2 4 3 < 3
3 > 2 1 3 5 4 < 2
3 > 3 2 4 1 5 < 1
^ ^ ^ ^ ^
2 2 2 2 1
Sama seperti untuk input, Anda dapat menggunakan daftar, string, atau struktur yang dipesan. Keempat "kelompok" dapat dipisahkan atau tidak, dalam struktur bersarang atau datar. Tapi, formatnya harus sama untuk setiap grup.
Contoh kasus uji:
(Format input / output Anda tidak harus sama dengan ini.)
>> [[1 2] [2 1]]
[2 1]
[1 2]
[2 1]
[1 2]
>> [[3 1 2] [2 3 1] [1 2 3]]
[1 2 2]
[2 2 1]
[1 2 3]
[3 2 1]
>> [[4 3 5 2 1] [5 4 1 3 2] [1 5 2 4 3] [2 1 3 5 4] [3 2 4 1 5]]
[2 3 1 4 5]
[3 4 3 2 1]
[1 2 2 2 2]
[3 3 2 1 2]
>> [[2 6 4 1 3 7 5 8 9] [7 2 9 6 8 3 1 4 5] [5 9 7 4 6 1 8 2 3] [6 1 8 5 7 2 9 3 4] [1 5 3 9 2 6 4 7 8] [3 7 5 2 4 8 6 9 1] [8 3 1 7 9 4 2 5 6] [9 4 2 8 1 5 3 6 7] [4 8 6 3 5 9 7 1 2]]
[4 2 2 3 3 3 3 2 1]
[1 3 3 2 2 2 2 3 3]
[4 3 2 1 2 3 3 2 2]
[3 1 2 4 3 3 2 2 5]
Untuk kenyamanan Anda, berikut adalah kasus uji yang sama dalam format string datar.
>> 1221
21
12
21
12
>> 312231123
122
221
123
321
>> 4352154132152432135432415
23145
34321
12222
33212
>> 264137589729683145597461823618572934153926478375248691831794256942815367486359712
422333321
133222233
432123322
312433225
≢¨∪¨↓⌈\(⍉⍪⌽⍪⍉∘⌽∘⊖⍪⊖)
Python 2, 115 byte
Ada banyak sekali daftar membalik terjadi di sana.
Mengambil input sebagai daftar bersarang (mis. Panggilan dengan
T([[4,3,5,2,1],[5,4,1,3,2],[1,5,2,4,3],[2,1,3,5,4],[3,2,4,1,5]])
). Output adalah daftar datar tunggal.Tidak Terkumpul:
Alternatif 115:
Saya tidak tahu mengapa ini bekerja dengan daftar pemahaman, tetapi chuck
NameError
dengan pemahaman ...Agak terlalu lama, tetapi jika ada yang tertarik - ya, ini bisa menjadi lambda!
Pyth , 25 byte
Port Pyth wajib.
Masukkan daftar melalui STDIN, mis
[[4, 3, 5, 2, 1], [5, 4, 1, 3, 2], [1, 5, 2, 4, 3], [2, 1, 3, 5, 4], [3, 2, 4, 1, 5]]
.Coba online ... adalah apa yang akan saya katakan tetapi sayangnya, untuk alasan keamanan, penerjemah online melarang penggunaan eval pada kurung bersarang. Coba kode penyelesaiannya
JcQ5V4=J_CJ~Yml{meS<dhkUd_J)Y
, dan masukan seperti daftar rata seperti[4, 3, 5, 2, 1, 5, 4, 1, 3, 2, 1, 5, 2, 4, 3, 2, 1, 3, 5, 4, 3, 2, 4, 1, 5]
.(Terima kasih kepada @isaacg yang membantu bermain golf beberapa byte)
sumber
<
dan>
merupakan operator slice satu sisi, sehingga:d0hk
dapat diubah menjadi<dhk
.U
pada input pengumpulan sama denganUl
, jadiUld
bisa diubah menjadiUd
.CJam,
2927 byteMasukan seperti
Output seperti
Bagaimana itu bekerja
Ide dasarnya adalah membuat kode bekerja di sepanjang baris dan memutar grid berlawanan arah jarum jam 4 kali. Untuk menghitung menara, saya menaikkan setiap menara sejauh itu tidak membuat "perbedaan visual" (yaitu, jangan mengubahnya jika terlihat, atau menariknya ke ketinggian yang sama dengan menara di depan itu), dan kemudian saya menghitung ketinggian yang berbeda.
sumber
APL, 44
Diuji di sini.
sumber
J, 35 karakter
Contoh:
Coba di sini.
sumber
Haskell, 113
sumber
Mathematica,
230.120.116.113110 bytePemakaian:
sumber
a[[y]][[x]]
adalaha[[y,x]]
. Dan menggunakanArray
mungkin lebih pendek dariTable
.JavaScript,
335264256213Mengevaluasi di konsol JavaScript browser (saya menggunakan Firefox 34.0, sepertinya tidak berfungsi di Chrome 39 ??) Uji dengan:
Inilah inkarnasi kode yang tidak dikenali saat ini - semakin sulit untuk diikuti:
Saya sengaja tidak melihat jawaban lain, saya ingin melihat apakah saya bisa mengerjakan sesuatu sendiri. Pendekatan saya adalah untuk meratakan array input ke array satu dimensi dan precompute offset ke baris dari keempat arah. Kemudian saya menggunakan shift kanan untuk menguji apakah menara berikutnya salah dan jika itu, maka menambah penghitung untuk setiap baris.
Saya berharap ada banyak cara untuk meningkatkan ini, mungkin tidak menghitung ulang offset, melainkan menggunakan semacam overflow / modulo pada array input 1D? Dan mungkin menggabungkan loop saya, dapatkan lebih fungsional, deduplicate.
Setiap saran akan dihargai!
Pembaruan # 1 : Kemajuan, kami memiliki teknologi! Saya dapat menyingkirkan offset yang telah dihitung dan melakukannya sesuai dengan operator ternary yang dirangkai. Juga bisa menyingkirkan pernyataan if saya dan mengubah loop for menjadi whiles.
Pembaruan # 2 : Ini cukup membuat frustrasi; tidak ada pesta pizza untuk saya. Saya pikir fungsional dan menggunakan rekursi akan mengurangi banyak byte, tetapi beberapa percobaan pertama saya akhirnya menjadi lebih besar sebanyak 100 karakter! Dalam keputus-asaan, saya pergi menggunakan babi seluruh fungsi lemak ES6 untuk benar-benar pare itu. Kemudian saya mengambil untuk mengganti operator boolean dengan yang aritmatika dan menghapus parens, semi-titik dua dan spasi di mana pun saya bisa. Saya bahkan berhenti mendeklarasikan vars saya dan mencemari namespace global dengan simbol lokal saya. Kotor, kotor. Setelah semua upaya itu, saya mengalahkan skor Pembaruan # 1 saya dengan 8 karakter kekalahan, ke 256. Blargh!
Jika saya menerapkan optimasi kejam yang sama dan trik ES6 ke fungsi Pembaruan # 1 saya, saya akan mengalahkan skor ini dengan satu mil. Saya dapat melakukan Pembaruan # 3 hanya untuk melihat seperti apa nantinya.
Pembaruan # 3 : Ternyata pendekatan rekursif panah lemak punya lebih banyak kehidupan di dalamnya, saya hanya perlu bekerja dengan input 2 dimensi secara langsung daripada meratakannya dan menjadi lebih baik tentang memanfaatkan lingkup penutupan. Saya menulis ulang perhitungan offset array dalam dua kali dan mendapatkan skor yang sama, jadi pendekatan ini mungkin hampir habis!
sumber
Java, hanya
352350325 byte ...Masukan seperti
43521 54132 15243 21354 32415
Output seperti:
23145343211222233212
Bertakuk:
Setiap tips akan sangat dihargai!
sumber
for
loopfor(;i<n;i++)
kefor(;++i<n;)
dan menginisialisasii
ke-1
. Kemudian gunakan ini untuk melakukan hal-hal. Anda dapat melakukan hal yang sama dengan loop lainnya juga.a[i].charAt(j)-'0'
alih-alih penguraian eksplisit. Ini juga tidak memerlukan pembatas dalam input (membuat format input lebih seperti format output).for
-loops, Anda selalu dapat memasukkan sesuatu yang bermanfaat ke bagian "loop increment". Ini membuat kode lebih tidak jelas dan menghapus satu titik koma. Sebagai contoh:for(j=n;j-->0;System.out.print(c))
.Python 2 - 204 byte
Ini mungkin golf yang sangat buruk. Saya pikir masalahnya menarik, jadi saya memutuskan untuk mengatasinya tanpa melihat solusi orang lain. Saat saya mengetik kalimat ini, saya belum melihat jawaban atas pertanyaan ini. Saya tidak akan terkejut jika orang lain telah melakukan program Python yang lebih pendek;)
Contoh I / O
Anda dapat memasukkan spasi putih dalam input. Cukup banyak di mana saja, jujur. Selama Anda bisa
eval()
, itu akan berhasil.Penjelasan
Satu-satunya bagian yang menarik dari program ini adalah baris pertama. Ini mendefinisikan fungsi
f(l)
yang memberitahu Anda berapa banyak menara yang dapat dilihat secara berturut-turut, dan program lainnya hanya menerapkan fungsi itu untuk setiap posisi yang memungkinkan.Saat dipanggil, ia menemukan panjang
l
dan menyimpannya dalam variabeln
. Kemudian ia menciptakan variabel baruk
dengan pemahaman daftar yang cukup mengerikan ini:Tidak terlalu buruk ketika Anda memecahnya. Karena
n==len(l)
, segala sesuatu sebelum yangif
adil mewakilil
. Namun, menggunakanif
kami dapat menghapus beberapa elemen dari daftar. Kami membuat daftar dengan([0]+list(l))
, yang hanya "l
dengan0
menambahkan ke awal" (abaikan panggilan kelist()
, itu hanya ada karena kadangl
- kadang generator dan kami perlu memastikan itu sebenarnya daftar di sini).l[c]
hanya dimasukkan ke dalam daftar akhir jika lebih besar dari([0]+list(l))[c]
. Ini melakukan dua hal:l[c]
menjadic+1
. Kami secara efektif membandingkan setiap elemen dengan elemen di sebelah kiri. Jika lebih besar, itu terlihat. Kalau tidak, itu tersembunyi dan dihapus dari daftar.[0]+
omong kosong dan hanya dibandingkanl[c]
denganl[c-1]
, Python akan membandingkan menara pertama dengan yang terakhir (Anda dapat mengindeks ke dalam daftar dari akhir dengan-1
,-2
, dll), jadi jika menara terakhir adalah lebih tinggi daripada pertama kita akan mendapatkan hasil yang salah.Ketika semua dikatakan dan dilakukan,
l
berisi beberapa menara dank
berisi masing-masing menara yang tidak lebih pendek dari tetangga terdekatnya ke kiri. Jika tidak ada dari mereka (misalnya untukf([1,2,3,4,5])
), makal == k
. Kami tahu tidak ada yang tersisa untuk dilakukan dan dikembalikann
(panjang daftar). Jikal != k
, itu berarti setidaknya satu dari menara telah dihapus kali ini dan mungkin ada lebih banyak yang harus dilakukan. Jadi kita kembalif(k)
. Ya Tuhan, aku suka rekursi. Menariknya,f
selalu berulang satu tingkat lebih dalam daripada yang benar-benar "diperlukan". Ketika daftar yang akan dihasilkan dihasilkan, fungsi tidak memiliki cara untuk mengetahui hal itu pada awalnya.Ketika saya mulai menulis penjelasan ini, program ini panjangnya 223 byte. Sambil menjelaskan hal-hal yang saya sadari bahwa ada cara untuk menyelamatkan karakter, jadi saya senang saya mengetik ini! Contoh terbesar adalah yang
f(l)
awalnya diimplementasikan sebagai loop tak terbatas yang pecah ketika perhitungan dilakukan, sebelum saya menyadari rekursi akan bekerja. Itu hanya menunjukkan bahwa solusi pertama yang Anda pikirkan tidak akan selalu menjadi yang terbaik. :)sumber
Matlab,
(123)(119)digunakan seperti ini:
C #, turun ke 354 ...
Pendekatan yang berbeda dari yang digunakan TheBestOne.
sumber
\n
alih-alih baris baru, saya hanya menggantinya dengan spasi, jadi kode langsung berjalan saat seseorang menyalinnya. Dan saya membiarkan diri saya untuk menghapus yang terakhirend
(yang menutup fungsi, yang tidak perlu) yang menyimpan tambahan 4 karakter, saya harap itu ok =)end
, thx :)