Ambil kisi 2 dimensi dan gambar sejumlah segmen garis di atasnya untuk mewakili cermin. Sekarang pilih titik untuk meletakkan laser teoretis dan sudut untuk menentukan arah yang ditunjuknya. Pertanyaannya adalah: jika Anda mengikuti jalur sinar laser untuk jarak tertentu, di titik koordinat manakah Anda?
Contoh:
Dalam gambar ini, L
adalah lokasi laser, t
adalah sudut itu (diukur dari sumbu X positif), M1
, M2
, dan M3
semua cermin segmen garis, dan E
adalah titik pada jalur sinar laser setelah D = d1 + d2 + d3 + d4
unit, mulai dari L
.
Tujuan
Menulis program terpendek (dalam byte) yang output E
yang diberikan L
, t
, D
, dan daftar cermin.
(Gunakan http://mothereff.in/byte-counter untuk menghitung byte.)
Masukkan format
Masukan akan datang dari stdin dalam format:
Lx Ly t D M1x1 M1y1 M1x2 M1y2 M2x1 M2y1 M2x2 M2y2 ...
- Semua nilai-nilai akan mengambang poin pencocokan regex ini:
[-+]?[0-9]*\.?[0-9]+
. - Selalu ada satu ruang di antara setiap angka.
- Membutuhkan kutipan di sekitar input diperbolehkan.
t
dalam derajat, tetapi tidak harus dalam[0, 360)
kisaran. (Jika Anda lebih suka menggunakan radian saja, katakan saja dalam jawaban Anda.)D
mungkin negatif, secara efektif memutar laser 180 derajat.D
mungkin juga 0.- Mungkin ada banyak mirror yang berubah-ubah (termasuk tidak sama sekali).
- Urutan cermin seharusnya tidak masalah.
- Anda dapat berasumsi bahwa input akan datang dalam kelipatan 4 angka. misalnya
Lx Ly t
atauLx Ly t D M1x1
tidak valid dan tidak akan diuji. Tidak ada input sama sekali juga tidak valid.
Tata letak di atas mungkin dimasukkan sebagai:
1 1 430 17 4.8 6.3 6.2 5.3 1.5 4.8 3.5 6 6.3 1.8 7.1 3
(Perhatikan bahwa gambar digambar secara bebas dan nilai-nilai ini hanya perkiraan. Nilai input Martin Büttner dari
1 1 430 17 4.8 5.3 6.2 4.3 1.5 4.8 3.5 6 6.3 1.8 7.1 3
akan memberikan lebih banyak tabrakan meskipun tidak cocok dengan sketsa.)
Format output
Output harus masuk ke stdout dalam format:
Ex Ey
Ini juga mengapung dan mungkin dalam bentuk eksponensial.
Catatan
- Cermin dapat saling berpotongan.
- Kedua sisi cermin bersifat reflektif.
- Sinar mungkin mengenai cermin yang sama beberapa kali.
- Sinar itu berlangsung selamanya.
Case yang tidak terdefinisi
Anda dapat mengasumsikan bahwa kasus-kasus itu ada di mana
- laser dimulai pada segmen garis cermin
- sinar laser menyentuh titik akhir cermin
- sinar laser menyentuh persimpangan antara dua cermin
tidak terdefinisi dan tidak akan diuji. Program Anda dapat melakukan apa saja jika ini terjadi, termasuk melempar kesalahan.
Bonus
Hanya untuk bersenang-senang, saya akan memberikan 200 poin hadiah untuk pengajuan dengan suara terbanyak yang menghasilkan representasi grafis dari masalah (Anda bahkan bisa menulis skrip interaktif). Pengajuan bonus ini tidak perlu di-golf dan bisa ringan dengan bagaimana input dan output ditangani. Mereka berbeda dari kiriman golf yang sebenarnya tetapi keduanya harus diajukan dalam jawaban yang sama .
Catatan: Hanya mengirimkan jawaban bonus baik-baik saja, Anda tidak akan menjadi jawaban yang diterima. Untuk dapat diterima, Anda harus benar-benar mengikuti spesifikasi input / output (mis. Output hanya melibatkan Ex Ey
, bukan gambar), dan menjadi yang terpendek.
Jawaban:
Ruby, 327 byte
(gulir ke bawah)
Mathematica, jawaban bonus
Saya hanya akan mengajukan pengajuan grafis sekarang. Saya mungkin port ini ke Ruby nanti dan golf jika saya suka.
Anda bisa menyebutnya seperti
Itu akan memberi Anda animasi di Mathematica dan juga mengekspor GIF (yang ada di atas untuk input ini). Saya telah sedikit memperluas contoh OP untuk ini, untuk membuatnya sedikit lebih menarik.
Lebih banyak contoh
Sebuah tabung dengan dinding yang agak menyimpang tetapi ujungnya tertutup:
Segitiga sama sisi dan arah awal yang hampir sejajar dengan salah satu sisi.
Satu lagi:
Ruby, jawaban golf
Ini pada dasarnya adalah terjemahan langsung dari solusi Mathematica ke Ruby, ditambah beberapa bermain golf dan memastikan itu memenuhi kriteria I / O.
sumber
Python 3 (
421C 390C, 366C)Gunakan
builtin.complex
sebagai vektor 2d. BegituUntuk mengalahkan solusi Ruby 368C, saya telah menemukan metode yang cukup ringkas untuk menghitung titik refleksi di sepanjang cermin. Dan juga menggunakan beberapa aljabar kompleks untuk mengurangi lebih banyak karakter. Ini dapat dengan mudah ditemukan dalam kode yang tidak diserang.
Ini versi golfnya.
Tidak disatukan
Bonus: HTML, Coffeescript, Penyesuaian & Perhitungan Realtime
Ini, Anda menyeret titik akhir (atau lazer, mirros), lalu trek ditampilkan. Ini juga mendukung dua jenis input, yang dijelaskan dalam pertanyaan dan yang digunakan oleh @Martin Büttner.
Penskalaan juga disesuaikan secara otomatis.
Untuk saat ini tidak memiliki animasi. Mungkin saya akan memperbaikinya nanti. Namun, menyeret titik putih dan Anda dapat melihat jenis animasi lain. Cobalah sendiri di sini secara online , ini lucu!
Seluruh proyek dapat ditemukan di Sini
Memperbarui
Di sini saya memberikan kasus yang menarik:
Dan hasilnya adalah:
sumber
JavaScript HTML,
10.543,947889Saya memperbaiki bug dan memastikan hasilnya memenuhi spesifikasi pertanyaan. Halaman web di bawah ini memiliki versi golf dan juga versi bonus grafis. Saya juga memperbaiki bug yang ditunjukkan oleh @ Ray yang menyimpan 58 karakter. (Terima kasih Ray.) Anda juga dapat menjalankan kode golf di konsol JavaScript. (Sekarang saya menggunakan laser hijau 2mW.)
Kode Golf
Memasukkan
Keluaran
Anda dapat mengujinya di sini: http://goo.gl/wKgIKD
Penjelasan
Kode di halaman web dikomentari. Pada dasarnya saya menghitung persimpangan laser dengan setiap cermin dengan asumsi laser dan cermin panjangnya tak terhingga. Lalu saya memeriksa apakah persimpangan berada dalam jarak terbatas cermin dan laser. Lalu saya mengambil persimpangan terdekat, memindahkan laser ke titik itu, dan melanjutkan sampai laser melewatkan semua cermin.
Proyek yang sangat menyenangkan. Terima kasih telah mengajukan pertanyaan ini!
Kode yang bisa dibaca
sumber
0 0 0.4 100 1 1 1 -1 1 -1 -1 -1 -1 -1 -1 1 -1 1 1 1
.Python - 765
Tantangan bagus. Ini adalah solusi saya yang mendapat input dari stdin dan output ke stdout. Menggunakan contoh @Martin Büttner:
Ini kode golfnya:
Dan di sini adalah kode tanpa tanda dengan angka bonus
sumber
sys.argv
bukan stdin.Matlab (388)
Merencanakan
Konsep
Poin Refleksi
Untuk menghitung titik refleksi kita pada dasarnya harus memotong dua garis lurus. Satu dengan titik p0 dan vektor v, yang lainnya di antara dua titik p1, p2. Jadi persamaan yang harus dipecahkan adalah (s, t adalah parameter): p0 + t v = s p1 + (1-s) * p2.
Parameter s kemudian merupakan koordinat barycentric dari cermin jadi jika 0
Mirroring
Mirroring dari v cukup sederhana. Mari kita asumsikan bahwa || v || = || n || = 1 di mana n adalah vektor normal dari cermin saat ini. Maka Anda bisa menggunakan rumus v: = v-2 ** n di mana <,> adalah produk titik.
Validitas langkah
Saat menghitung cermin 'valid' terdekat, kami harus mempertimbangkan beberapa kriteria yang membuatnya valid. Pertama, titik intersepsi cermin harus terletak di antara dua titik akhir, jadi itu harus 0
Program
Golf sedikit (388)
sumber