Bendera Amerika Serikat berisi, di kantonnya, 50 bintang, yang mewakili 50 negara bagian.
Di masa lalu, ketika ada lebih sedikit negara, tentu saja ada lebih sedikit bintang, dan mereka diatur secara berbeda. Misalnya, dari tahun 1912-1959 (setelah masuk New Mexico dan Arizona tetapi sebelum Alaska), ada 48 bintang dalam susunan persegi panjang 6 × 8.
Bendera 37-bintang yang digunakan dari 1867-1877 (setelah masuk Nebraska tetapi sebelum Colorado) memiliki pola bintang asimetris.
Jika negara bagian 51 ditambahkan di masa depan, Army Institute of Heraldry telah mengembangkan desain awal untuk bendera baru.
Tapi tidak ada algoritma umum untuk mengatur bintang-bintang, jadi mari kita buat satu!
Tantangan
Tulis sebuah program yang akan, untuk sejumlah bintang tertentu untuk ditempatkan di kanton (bagian biru) dari bendera AS, menghasilkan koordinat optimal tempat meletakkan bintang-bintang itu. Sistem koordinat didefinisikan dengan kanton [ bukan bendera secara keseluruhan] dengan 0≤x≤W dan 0≤y≤H.
Untuk tujuan tantangan ini, pengaturan "optimal" didefinisikan sebagai pengaturan yang meminimalkan jarak rata-rata (Euclidean) antara titik di kanton dan pusat bintang terdekat.
Algoritma langsung (jika mungkin suboptimal) untuk memperkirakan nilai ini adalah:
def mean_distance_to_nearest_star(stars, width, height, point_density=100):
"""
Approximate the mean distance between a point in the rectangle
0 < x < width and 0 < y < height, and the nearest point in stars.
stars -- list of (x, y) points
width, height -- dimensions of the canton
"""
total = 0.0
nx = round(width * point_density)
ny = round(height * point_density)
for ix in range(nx):
x = (ix + 0.5) * width / nx
for iy in range(ny):
y = (iy + 0.5) * width / ny
min_dist = float('inf')
for sx, sy in stars:
min_dist = min(min_dist, math.hypot(x - sx, y - sy))
total += min_dist
return total / (nx * ny)
Program Anda akan mengambil tiga argumen baris perintah (tidak termasuk nama program itu sendiri):
- Jumlah bintang untuk dimasukkan ke dalam kanton.
- Lebar kanton. (Harus menerima nilai floating-point.)
- Ketinggian kanton. (Harus menerima nilai floating-point.)
(Jika bahasa pemrograman pilihan Anda tidak mendukung argumen baris perintah, lakukan sesuatu yang setara, dan dokumentasikan dalam jawaban Anda.)
Output harus terdiri dari nilai X dan Y yang dipisahkan koma, satu ke satu baris. (Urutan poin tidak masalah.)
Sebagai contoh:
~$ flagstar 5 1.4 1.0
0.20,0.20
0.20,0.80
0.70,0.50
1.20,0.20
1.20,0.80
Aturan & catatan tambahan
- Saya memiliki hak untuk menutup celah dalam aturan kapan saja.
Batas waktu untuk jawaban adalah Jumat, 4 Juli pukul 24:00 CDT (UTC-05: 00).Karena kurangnya jawaban, batas waktu telah diperpanjang. TBA.- Sertakan dalam jawaban Anda:
- Kode program Anda
- Penjelasan tentang cara kerjanya
- Keluarannya dengan argumen baris perintah
50 1.4 1.0
- Program Anda harus berjalan dalam jumlah waktu yang wajar: Paling lama 5 menit pada PC biasa. Saya tidak akan terlalu ketat tentang ini, tetapi akan mendiskualifikasi program Anda jika perlu berjam - jam .
- Program Anda harus deterministik, yaitu selalu memberikan hasil yang persis sama untuk argumen yang sama. Jadi, jangan bergantung pada
time()
ataurand()
. Metode Monte Carlo baik-baik saja selama Anda menggulung PRNG Anda sendiri. - Hanya titik pusat bintang yang penting. Jangan khawatir tentang mencoba untuk menghindari tumpang tindih atau semacamnya.
Mencetak gol
- Minimalkan jarak rata-rata dari titik di kanton ke bintang terdekat. (Lihat di atas.)
- Anda dapat dinilai berdasarkan bendera AS historis, antara 13 dan 50 bintang. Algoritma yang tepat untuk menghitung skor menjadi satu peringkat akan dikirim kemudian.
- Dalam hal seri, pemenang akan dipilih berdasarkan jumlah upvote bersih.
- Saya mungkin akan memposting program saya sendiri, tetapi akan mengecualikan diri dari memenuhi syarat untuk tanda centang.
sumber
Jawaban:
Javascript - pindahkan bintang ke titik paling terpencil
(dengan animasi proses)
Pendekatannya sangat sederhana:
Proses ini diulangi berkali-kali, secara bertahap mengurangi jumlah perpindahan bintang. Ini mengurangi jarak maksimum dari satu titik ke bintang terdekat, secara tidak langsung mengurangi jarak rata-rata dari satu titik ke bintang terdekat.
Seperti yang dipersyaratkan oleh pertanyaan, ini tidak menggunakan fungsi acak bawaan , melainkan menggunakan xorshift .
Sebagian besar kode mencakup pengaturan dan animasi - bagian yang menerapkan algoritma adalah fungsinya
adjustStars
.Kode
Anda dapat menyaksikan proses yang sedang berlangsung di Cuplikan Stack di bawah ini.
Output untuk 50 bintang
(lebar = 1,4, tinggi = 1,0)
Perkiraan jarak rata-rata pada 0,0655106697162357.
Koordinat:
sumber
Ini contoh sederhana. Itu selalu mengatur bintang-bintang menjadi kotak persegi panjang, dan mengoptimalkannya dengan memilih faktorisasi di mana sel-sel grid sedekat mungkin dengan kotak. Ini bekerja dengan baik ketika jumlah bintang memiliki pembagi dekat dengan akar kuadratnya, dan pesimis ketika jumlah bintang adalah prima.
Output untuk 50 bintang
(lebar = 1,4, tinggi = 1,0)
Persegi panjang 10 × 5.
sumber
Javascript - pindahkan bintang secara acak jika jarak rata-rata dikurangi
(dengan animasi proses)
Ini tidak memberikan animasi yang sibuk seperti jawaban pertama saya, memiliki periode yang panjang tanpa gerakan karena pengaturan ulang potensial diuji dan ditolak. Namun, hasil akhir memiliki jarak rata-rata yang lebih rendah, sehingga metode ini merupakan peningkatan.
Pendekatannya masih sangat sederhana:
Proses ini diulangi berkali-kali, secara bertahap mengurangi jumlah perpindahan bintang. Pilihan acak jarak untuk bergerak bias ke arah jarak yang lebih kecil, sehingga kemajuan dalam perubahan kecil diselingi dengan lompatan sesekali yang lebih besar. Setiap langkah membutuhkan waktu lebih lama daripada jawaban pertama saya, karena mengukur jarak rata-rata adalah proses yang lambat yang membutuhkan pengambilan sampel seluruh wilayah.
Seperti yang dipersyaratkan oleh pertanyaan, ini tidak menggunakan fungsi acak bawaan , melainkan menggunakan xorshift .
Sebagian besar kode mencakup pengaturan dan animasi - bagian yang menerapkan algoritma adalah fungsinya
adjustStars
.Kode
Anda dapat menyaksikan proses yang sedang berlangsung di Cuplikan Stack di bawah ini.
Output untuk 50 bintang
(lebar = 1,4, tinggi = 1,0)
Perkiraan jarak rata-rata pada 0.06402754713808706.
Koordinat:
sumber