Anda mengajar kelas siswa dengan preferensi menarik tentang bagaimana kursi mereka diatur. Ada 3 persyaratan sangat spesifik yang mereka miliki untuk mengatur kursi:
Mereka paling diatur dalam persegi panjang, bahkan jika itu berarti beberapa kursi kosong.
Harus ada kursi kosong sesedikit mungkin.
Mereka harus selebar mungkin. Kuadrat ditentukan oleh jarak antara lebar dan tinggi persegi panjang, lebih rendah lebih baik. Sebagai contoh, sebuah persegi panjang yang
4x7
memiliki segi 3 dari 3.
Untuk lebih spesifik, "skor" dari suatu pengaturan adalah jarak antara lebar dan tinggi ditambah jumlah kursi yang akan kosong.
Mari kita ambil contoh. Katakanlah Anda memiliki 13 siswa. Anda dapat mengatur kursi dengan salah satu dari cara berikut:
1x13
2x7
3x5
4x4
1x13
tidak terlalu persegi. Faktanya, 1 dan 13 terpisah 12, jadi kami memberikan pengaturan ini 12 poin. Ini juga memiliki 0 kursi kosong, jadi kami menambahkan 0 poin, memberikan skor 12. pengaturan ini tidak terlalu bagus.
2x7
tentu lebih baik. 2 dan 7 hanya 5 terpisah, jadi kami memberikan pengaturan ini 5 poin. Namun, jika Anda benar-benar mengatur 2 baris tujuh kursi, itu akan membutuhkan 14 kursi, artinya satu kursi akan kosong. Jadi kami menambahkan satu poin, memberikan pengaturan ini skor 6.
Kita juga bisa melakukannya 3x5
. 3 dan 5 terpisah 2, jadi +2 poin. Dibutuhkan 15 kursi, artinya kita akan memiliki dua kursi tambahan, jadi +2 poin lagi, untuk skor 4.
Opsi terakhir 4x4
,. 4 dan 4 terpisah 0, jadi kami memberikan ini +0 poin. 4x4 membutuhkan 16 kursi, jadi 3 kursi kosong, dengan skor total 3. Ini adalah solusi optimal.
Dalam kasus dasi, solusi optimal adalah dengan kursi yang kurang kosong.
Tantangan
Anda harus menulis program atau fungsi yang membutuhkan bilangan bulat dan menampilkan pengaturan kursi yang optimal untuk jumlah siswa tersebut. IO dapat dalam format apa pun yang masuk akal. Berikut adalah contoh output untuk sejumlah siswa dari 1 hingga 100:
1: (1, 1)
2: (1, 2)
3: (2, 2)
4: (2, 2)
5: (2, 3)
6: (2, 3)
7: (3, 3)
8: (3, 3)
9: (3, 3)
10: (2, 5)
11: (3, 4)
12: (3, 4)
13: (4, 4)
14: (4, 4)
15: (4, 4)
16: (4, 4)
17: (3, 6)
18: (3, 6)
19: (4, 5)
20: (4, 5)
21: (3, 7)
22: (5, 5)
23: (5, 5)
24: (5, 5)
25: (5, 5)
26: (4, 7)
27: (4, 7)
28: (4, 7)
29: (5, 6)
30: (5, 6)
31: (4, 8)
32: (4, 8)
33: (6, 6)
34: (6, 6)
35: (6, 6)
36: (6, 6)
37: (5, 8)
38: (5, 8)
39: (5, 8)
40: (5, 8)
41: (6, 7)
42: (6, 7)
43: (5, 9)
44: (5, 9)
45: (5, 9)
46: (7, 7)
47: (7, 7)
48: (7, 7)
49: (7, 7)
50: (5, 10)
51: (6, 9)
52: (6, 9)
53: (6, 9)
54: (6, 9)
55: (7, 8)
56: (7, 8)
57: (6, 10)
58: (6, 10)
59: (6, 10)
60: (6, 10)
61: (8, 8)
62: (8, 8)
63: (8, 8)
64: (8, 8)
65: (6, 11)
66: (6, 11)
67: (7, 10)
68: (7, 10)
69: (7, 10)
70: (7, 10)
71: (8, 9)
72: (8, 9)
73: (7, 11)
74: (7, 11)
75: (7, 11)
76: (7, 11)
77: (7, 11)
78: (9, 9)
79: (9, 9)
80: (9, 9)
81: (9, 9)
82: (7, 12)
83: (7, 12)
84: (7, 12)
85: (8, 11)
86: (8, 11)
87: (8, 11)
88: (8, 11)
89: (9, 10)
90: (9, 10)
91: (7, 13)
92: (8, 12)
93: (8, 12)
94: (8, 12)
95: (8, 12)
96: (8, 12)
97: (10, 10)
98: (10, 10)
99: (10, 10)
100: (10, 10)
Seperti biasa, ini adalah kode-golf, sehingga celah standar berlaku, dan pemenangnya adalah jawaban terpendek dalam byte.
Jawaban:
Jelly ,
161514 byteCobalah online! atau verifikasi semua kasus uji .
Bagaimana itu bekerja
sumber
Python 2, 68 byte
Setara dengan yang lebih "jelas":
sumber
range(-n,0)
, seperti yang saya lakukan dalam jawaban saya . Suite uji.Haskell, 65 byte
Contoh penggunaan:
map f [1..5]
->[(1,1),(1,2),(2,2),(2,2),(2,3)]
.Melalui loop luar
a
dari1
kex
(x -> jumlah siswa) dan loop dalamb
dari1
kea
. Menyimpan semua di(b,a)
manaa*b>=x
dan membangun pasangan((arrangement points,seats left), (b,a))
yang mengikuti urutan leksikografis kita perlu menemukan minimum. Catatan:a
selalu lebih besar dari padab
, jadi kita tidak perluabs
untuk squareyness. Tidak perlu mengurangix
dari skor "kursi kiri", karena hanya urutan relatif yang penting. Akhirnya kami menghapus pasangan skor dengansnd
.sumber
a*b
(jumlah kursi gratis) adalah tie breaker jika skor utamanya sama. Misalnyan=43
: a)a=7, b=7
, skor:(49,49)
b)a=9, b=5
, skor:(49,45)
. Skor utama adalah sama, tie breaker memutuskan, b) menang.a*b
, angka itu sendiri(b,a)
yang harus saya bawa tetap bertindak sebagai tie breaker dan memberikan hasil yang sama untuk (setidaknya)n=1..300
. Suatu produk kecil jika salah satu faktor (di sinib
) kecil. Tetapi selama saya tidak punya bukti resmi, saya tidak ingin menggunakan fakta ini. Mari kita lihat apakah saya menemukannya.Ruby, 64 byte
Sebuah lambada yang mengambil jumlah orang sebagai argumen dan mengembalikan array dengan lebar dan tinggi dari solusi optimal.
sumber
w*h
sebagai elemen kedua dalam array Anda? Saya tidak berpikir itu terutama mengubah apa pun ketika Anda meneleponmin
karena Anda meminimalkan skor alias elemen pertama.In case of a tie, the optimal solution is the one with less empty chairs
MATL , 18 byte
Cobalah online!
Penjelasan
sumber
Javascript, 98 byte
Golf kode pertama saya, jadi saya tetap memposting!
Awalnya saya
o
adalah objek kosong dan saya memeriksa apakaho.a
itu kosong, jadi itu adalah kasus khusus di babak pertama. Tapi saya menemukan trik 1/0 dalam jawaban edc65 untuk menginisialisasi variabel ke Infinity.sumber
Pyth,
242221 byteSunting : pada kunci penyortiran, saya menyadari bahwa tidak perlu menemukan jumlah kursi kosong. Itu sama dengan skor jumlah kursi. Ini menyelamatkan saya 2 byte.
Cobalah online!
sumber
Matlab
(174) (146)121trik 1: saya menambahkan jumlahnya
1-1/length*width
sebagai tie-scoringtrik 2: saya menghitung
number_students/length
plafon untuk lebar persegi panjang,batas atas adalah kuadrat tetapi juga plafonSaya yakin itu bisa bermain golf lebih lanjut ...
Cobalah
Sunting: dirujuk ke pernyataan @StewieGriffin.
Edit 2:
1
dann
konstanta tidak perlu menambahkannya ke skor keseluruhan.Sunting 3: tes kinerja.
sumber
unique
Python 2, 64 byte
Ini adalah penggabungan dari jawaban Python @ Lynn (dari mana saya mengambil
max(...)[1:]
trik) dan algoritma dari jawaban Julia saya (yang memungkinkan implementasi yang sedikit lebih pendek).Uji di Ideone .
sumber
Julia,
6159555352 byteCobalah online!
Bagaimana itu bekerja
Kode ini setara dengan versi ungolfed berikut ini, di mana
cld
adalah pembagian plafon.Untuk menemukan pengaturan yang optimal, jelas cukup untuk memeriksa pasangan [i, j] , di mana 1 ≤ i ≤ n dan j = ⌈n / i⌉ .
Skor untuk pengaturan semacam itu adalah | j - i | + (ij - n) , di mana puncak kedua adalah jumlah kursi kosong. Alih-alih skor aktual, kita dapat membandingkan skor yang ditambah dengan konstanta, seperti ij + | j - i | + 1 .
Cukup untuk mempertimbangkan pasangan [i, j] di mana i ≤ j karena pengaturan [i, j] dan [j, i] sama-sama valid. Kami berurusan dengan pasangan yang benar-benar menurun dengan menetapkan j = max (⌈n / i⌉, i) sebagai gantinya, yang memastikan bahwa j ≥ i dan akan menghasilkan skor suboptimal jika ⌈n / i⌉ <i .
Sejak j - i ≥ 0 , kami memiliki ij + | j - i | + 1 = ij + j - i + 1 = (i + 1) × (j - 1) , yang dapat dihitung dalam lebih sedikit byte kode.
Akhirnya
indmin
/indmax
memberikan indeks m (dan dengan demikian nilai i ) dari pengaturan optimal, yaitu m oleh ⌈n / m⌉ . Ikatan rusak oleh kejadian pertama, yang sesuai dengan nilai terendah dari i , oleh karena itu nilai tertinggi dari j - i dan dengan demikian nilai terendah dari ij - n (kursi kosong).sumber
JavaScript (ES6) 74
78Edit menjaga hasil temp sebagai array bukan 2 vars, dipinjam dari jawaban Thiht
Kurang golf
Uji
sumber
PHP, 129 byte
Tidak Terkumpul:
sumber
PHP, 104 byte
Algoritma yang memecahkan masalah ini sederhana dan mungkin digunakan oleh jawaban lain dalam bahasa yang mirip dengan PHP (JavaScript, fe):
n
cukup besar (di manan
nilai input); skor pengaturan yang dihitung pada iterasi pertama (1, n
) adalah(n-1)+0
;1
dann
; hitung ketinggian minimum sebagaiceil(n/width)
, hitung skor pengaturan menggunakan rumus yang disediakan dalam pertanyaan (yaituabs(width - height) + (width * height - n)
); jika skor lebih baik dari skor terbaik sebelumnya maka ingat lebar, tinggi dan skor terbaik baru; pada ikatan menggunakan nilaiwidth * height - n
pengaturan saat ini dan pengaturan terbaik sebelumnya untuk mendeteksi pengaturan terbaik baru;Setelah bermain golf, algoritma ini menghasilkan sesuatu seperti ini (dibungkus di sini untuk dibaca):
Ini menggunakan 137 byte (ketika diletakkan pada satu baris) dan jauh dari 104 byte yang diiklankan dalam judul. Kode mungkin dapat dipersingkat oleh 2-3 byte tetapi sumber perbaikan besar adalah di tempat lain: dalam rincian algoritma.
Algoritma yang direvisi:
Ada beberapa tempat di mana algoritma dapat ditingkatkan dengan menghapus kode yang tidak berguna.
1
ke$n
; untuk kecepatan, lebar ($i
) harus beralih antara1
danfloor(sqrt($n))
tetapi ini membuat kode lebih panjang daripada memperpendeknya; tetapi jika lebarnya tidak melebihisqrt($n)
, tinggi minimum ($j
) akan selalu lebih besar darisqrt($n)
(paling tidak produk mereka$n
);$i <= $j
(lebar <= tinggi) sebagai kondisi terminasi untuk loop; dengan cara ini, lebar akan beralih dari1
kefloor(sqrt($n))
dan ketinggian akan mendapatkan nilai mulai dari$n
dan turun keceil(sqrt($n))
(tidak harus semuanya);abs(width - height)
selaluheight - width
($j-$i
); 5 byte disimpan dengan cara ini;$n
digunakan dalam perhitungan skor (jumlah kursi yang tidak dihuni adalahwidth * height - n
) tetapi tidak diperlukan; skor tidak perlu ditampilkan, itu dihitung hanya untuk perbandingan pengaturan; dengan menghapus- n
dari rumus skor kami menyimpan 3 byte lainnya (kode PHP-$n
) tanpa kehilangan apa pun;height - width + width * height
($j-$i+$i*$j
);height - width
bagian dari skor berkurang pada setiap langkah;||$c==$s&&$i*$j<$w*$h
- banyak byte);-$n
rumus skor, skor untuk pengaturan pertama (1x$n
) adalah$n-1+1*$n
(yaitu2*$n-1
); nilai awal dari skor terbaik ($s
) dapat berupa nilai yang lebih besar atau sama dengan2*$n
; iterasi pertama memiliki skor yang lebih baik dan itu menjadi pengaturan terbaik yang membiarkan algoritma berjalan tanpa masalah inisialisasi.Kode baru ( 104 byte ), setelah menerapkan peningkatan yang dijelaskan di atas adalah:
Itu dibungkus di sini untuk dibaca. Tambahkan kode di atas dengan penanda PHP
<?php
(secara teknis, ini bukan bagian dari kode), masukkan ke dalam file (katakanlaharrange-your-chairs.php
) dan jalankan dengan integer lebih besar dari nol sebagai argumen. Ini akan menampilkan lebar dan tinggi pengaturan yang dihitung, dipisahkan dengan koma:Solusi lain (116 byte)
Solusi lain yang menggunakan algoritma berbeda:
Ini menempatkan semua kombinasi dari setidaknya
$n
kursi ke dalam daftar asosiatif; kuncinya adalah representasi teks dari pengaturan, nilainya adalah skor pengaturan. Kemudian mengurutkan daftar (naik dengan nilai) dan mendapatkan kunci dari entri pertama.Satu lagi (115 byte)
Ini adalah versi PHP dari jawaban @ Neil (JavaScript / ES6, 85 byte).
Ada beberapa perbedaan nyata karena fitur masing-masing bahasa:
n
nilai (tidak terdefinisi) kemudian menggunakan kuncinya untuk beralih dari0
ken-1
; itu menambahi
(d=(n+i++)/i|0
) untuk membuatnya iterate dari1
ton
; solusi PHP tidak perlu bertambah; digunakanrange()
untuk menghasilkan array kemudian menggunakan nilai yang dihasilkan (1
untukn
) untuk beralih;(n+i)/i
lalu mengonversi nilai menjadi integer menggunakan|0
untuk mendapatkan bilangan bulat terkecil lebih besar darin/i
; jawaban PHP memecahkan masalah ini dengan mudah dengan fungsi PHPceil()
; JavaScript juga menyediakanMath.ceil()
tetapi menggunakan 5 byte lebih dari solusi yang ditemukan oleh Neil;array_map()
yang mirip dengan JSArray.map()
tetapi tidak membantu di sini; sintaksnya adalah verbose,foreach
menghasilkan kode yang lebih pendek; itu lebih besar dari kode JS, meskipun;||
tidak dimungkinkan dalam PHP karena tidak memiliki operator koma; Saya menerjemahkana||b||c
ke dalamif(!a&&!b)c
, karenaa
danb
perbandingan, saya meniadakan operator mereka (diganti<
dengan>=
); ini juga menghasilkan kode yang lebih besar daripada versi JS;$
.Versi ungolfed dari semua solusi dan test suite dapat ditemukan di Github .
sumber
JavaSCript (ES6), 83 byte
sumber
m
kompensasi.Julia, 87
Saya pikir ini adalah satu langkah ke arah mencari fungsi ajaib untuk masalah:
Hanya terlihat berpasangan
(i, j=(i+n)/(i+1))
atau(i, j+1)
sumber
n
mana pun, dan Anda tampaknya tidak mengambil input.n
masukan. Seseorang harus membungkusnyan->...
. Bagus bahwa Anda bisa membuatnya bekerja.Oracle SQL 11.2, 173 byte
Tidak bermain golf
sumber
Q 58 Bytes
Lamba yang menghitung biaya minimal untuk nilai yang diberikan (x) dan mengembalikan urutan dua nilai (lebar, tinggi)
Menambahkan nama ke lambda itu membutuhkan dua karakter lainnya (mis. F: {..} alih-alih {..})
Uji
di mana {..} adalah lambda. Baca sebagai "berlaku lambda untuk setiap nilai 1 + 100 int pertama" (dengan kata lain untuk setiap nilai 1..100)
Menghasilkan
Penjelasan
Lamdba bersarang
{((b<a)?1b)#+(b:-_-x%a;a:1+!x)}
menghasilkan semua pasangan kandidat (lebar, tinggi) untuk kursi x sebagai dua urutan (w1 w2 w3 ..; h1 h2 h3 ..) (lebar dan tinggi). Baca dari kiri ke kanan, tetapi evaluasi dari kanan ke kiria:1+!x
menghasilkan nilai 1..x dan menetapkan urutan itu ke a-_-
adalah negate floor negate, dan mengimplementasikan ceil (ceil bukan primitif bahasa)b:-_-x%a
berlaku ceil untuk setiap nilai x dibagi dengan setiap item im a, dan tetapkan urutan yang dihasilkan untuk b. Dengan kata lain, b adalah setiap masing-masing x dibagi dengan masing-masing 1..x+(b;a)
mengembalikan secuence yang terdiri dari seq a dan seq b, lalu membaliknya (hasilnya adalah urutan pasangan di mana i-pair mengandung elemen i dari a dan elemen i dari b)b<a
membandingkan item dengan item b dan a, dan menghasilkan secuence dari nilai-nilai logis (true = 1b untuk setiap indeks di mana b [i]s?x
mengembalikan posisi pertama item x dalam urutan s. Dengan(b<a)?1b
Kami mencari 1b (nilai sebenarnya) secara berurutan sebagai hasil dari membandingkan b dan a, dan mendapatkan posisi pertama di mana bn#s
Dibutuhkan n pertama n item dari seq s. Kami ingin membuang pasangan duplikat, jadi kami berhenti ketika item pertama dari pasangan <item kedua (mis. Pertimbangkan 13,1 tetapi tidak 1,13).Sebagai efek samping, setiap pasangan dari urutan yang dihasilkan adalah jarak yang menurun antara a dan b (ex (13 1; 7 2; 5 3; 4 4)
Pasangan kandidat yang dihasilkan oleh lambda bersarang ditugaskan untuk c. Kami kemudian membalik c (memperoleh b, a lagi) dan menerapkan dua fungsi untuk argumen itu:
*/
mengalikan, dan-/
mengurangi. Hasilnya(-/;*/)@\:+c
adalah perbedaan dan produk dari masing-masing pasangan.+/
dijumlahkan, dan menghitung biaya akhir. Biaya setiap patir ditugaskan untuk d& /
&/
adalah batas minimum , jadi d adalah biaya minimum. Dengand?&/d
kami menemukan kejadian pertama dari biaya minimum dalam d, dan dengan c @ .. kami mengambil pasangan pada posisi itu. Karena setiap pasangan mengurangi distante antara a dan n, minimum pertama yang ditemukan memiliki distante maksimum antara pasangan minimum lainnya, jadi kami menerapkan aturan dasi dengan benarsumber