Bagaimana Anda mengatur kursi Anda?


20

Anda mengajar kelas siswa dengan preferensi menarik tentang bagaimana kursi mereka diatur. Ada 3 persyaratan sangat spesifik yang mereka miliki untuk mengatur kursi:

  1. Mereka paling diatur dalam persegi panjang, bahkan jika itu berarti beberapa kursi kosong.

  2. Harus ada kursi kosong sesedikit mungkin.

  3. Mereka harus selebar mungkin. Kuadrat ditentukan oleh jarak antara lebar dan tinggi persegi panjang, lebih rendah lebih baik. Sebagai contoh, sebuah persegi panjang yang 4x7memiliki 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

1x13tidak 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.

2x7tentu 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:


8

Jelly , 16 15 14 byte

÷RĊ,Rµạ/+PỤḢịZ

Cobalah online! atau verifikasi semua kasus uji .

Bagaimana itu bekerja

÷RĊ,Rµạ/+PỤḢịZ  Main link. Argument: n

 R              Range; yield [1, ..., n].
÷               Divide n by each k in [1, ..., n].
  Ċ             Ceil; round the quotients up to the nearest integer.
    R           Range; yield [1, ..., n].
   ,            Pair; yield A := [[ ⌈n ÷ 1⌉, ..., ⌈n ÷ n⌉ ], [ 1, ..., n ]].
     µ          Begin a new, monadic chain. Argument: A
      ạ/        Reduce A by absolute difference.
                This yields [ |⌈n ÷ 1⌉ - 1|, ..., |⌈n ÷ n⌉ - n| ].
         P      Product; reduce A by multiplication.
                This yields [ ⌈n ÷ 1⌉ × 1, ..., ⌈n ÷ n⌉ × n].
       +        Add the results to left and right, element by element. This yields
                [ |⌈n ÷ 1⌉ - 1| + ⌈n ÷ 1⌉ × 1, ..., |⌈n ÷ n⌉ - n| + ⌈n ÷ n⌉ × n ].
          Ụ     Grade up; sort the indices of the list of sums by their values.
           Ḣ    Head; extract the first value, which corresponds to the smallest
                sum. Grading up is stable, so this selects the first index of all
                with the smallest sum in case of a tie. In this event, the first
                index will have the highest absolute difference of all indices
                with the smallest sum, meaning that it has the lowest product and,
                therefore, the lowest number of empty chairs.
             Z  Zip; transpose A's rows and columns.
                This yields [[ ⌈n ÷ 1⌉, 1 ], ..., [ ⌈n ÷ n⌉, n ]].
            ị   Retrieve the pair at that index.

4

Python 2, 68 byte

lambda n:min((abs(~i-n/~i)+n/~i*~i,i+1,0-n/~i)for i in range(n))[1:]

Setara dengan yang lebih "jelas":

lambda n:min([(i+1,0-n/~i)for i in range(n)],key=lambda(p,q):abs(p-q)+p*q)

Anda dapat menyimpan tiga byte dengan mengulangi range(-n,0), seperti yang saya lakukan dalam jawaban saya . Suite uji.
Dennis

3

Haskell, 65 byte

f x=snd$minimum[((a*b+a-b,a*b),(b,a))|a<-[1..x],b<-[1..a],a*b>=x]

Contoh penggunaan: map f [1..5]-> [(1,1),(1,2),(2,2),(2,2),(2,3)].

Melalui loop luar adari 1ke x(x -> jumlah siswa) dan loop dalam bdari 1ke a. Menyimpan semua di (b,a)mana a*b>=xdan membangun pasangan ((arrangement points,seats left), (b,a))yang mengikuti urutan leksikografis kita perlu menemukan minimum. Catatan: aselalu lebih besar dari pada b, jadi kita tidak perlu absuntuk squareyness. Tidak perlu mengurangi xdari skor "kursi kiri", karena hanya urutan relatif yang penting. Akhirnya kami menghapus pasangan skor dengan snd.


Mengapa tidak adil (a + ab, (b, a))? Jika Anda meminimalkan skor, tentu saja Anda meminimalkan a , atau apakah saya melewatkan sesuatu?
justinpc

@ jpcooper: a*b(jumlah kursi gratis) adalah tie breaker jika skor utamanya sama. Misalnya n=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.
nimi

Kamu benar. Seharusnya saya membaca deskripsi dengan lebih baik.
justinpc

@ jpcooper: tunggu sebentar ... jika saya melepas tie breaker 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 sini b) kecil. Tetapi selama saya tidak punya bukti resmi, saya tidak ingin menggunakan fakta ini. Mari kita lihat apakah saya menemukannya.
nimi

Poin bagus. Tampaknya benar, dan seharusnya tidak terlalu sulit untuk menghasilkan bukti. Saya mulai bertanya-tanya apakah mungkin ada solusi linear untuk masalah ini.
justinpc

2

Ruby, 64 byte

->n{(1..n).map{|w|h=(n+w-1)/w;[(h-w).abs+h*w,w*h,w,h]}.min[2,3]}

Sebuah lambada yang mengambil jumlah orang sebagai argumen dan mengembalikan array dengan lebar dan tinggi dari solusi optimal.


Mengapa Anda perlu w*hsebagai elemen kedua dalam array Anda? Saya tidak berpikir itu terutama mengubah apa pun ketika Anda menelepon minkarena Anda meminimalkan skor alias elemen pertama.
Nilai Tinta

@ KevinLau-notKenny dari pertanyaan:In case of a tie, the optimal solution is the one with less empty chairs
MegaTom

2

MATL , 18 byte

:Gy/Xkvtd|yp+&X<Z)

Cobalah online!

Penjelasan

:      % Implicit input number N. Range [1 2 ... N]
G      % Push N again
y      % Duplicate second-from-top: push [1 2 ... N] again
/Xk    % Divide and round up
v      % Vertically concatenate. Gives 2×N array of rectangle sizes
td|    % Duplicate. Absolute difference of each column
y      % Duplicate second-from-top: push 2×N array again
p      % Product of each column
+      % Sum absolute differences and products
&X<    % Arg min
Z)     % Use as column index into the 2×N array. Implicitly display

2

Javascript, 98 byte

Golf kode pertama saya, jadi saya tetap memposting!

f=n=>{for(o=1/0,i=1;i<=n;i++)for(j=n;i*j>=n;j--)t=i*j-n+Math.abs(i-j),o>t&&(o=t,a=[i,j]);return a}

Awalnya saya oadalah objek kosong dan saya memeriksa apakah o.aitu kosong, jadi itu adalah kasus khusus di babak pertama. Tapi saya menemukan trik 1/0 dalam jawaban edc65 untuk menginisialisasi variabel ke Infinity.


Dan saya akan mencoba trik untuk menggunakan objek untuk menyimpan hasil sementara
edc65

1

Pyth, 24 22 21 byte

Sunting : pada kunci penyortiran, saya menyadari bahwa tidak perlu menemukan jumlah kursi kosong. Itu sama dengan skor jumlah kursi. Ini menyelamatkan saya 2 byte.

h.m_+B*FbaFbm,d.EcQdS

Cobalah online!


1

Matlab(174) (146)121

  function g(n),f=@(n,i)ceil(n/i);x=[];for i=1:n,x=[sortrows(x); f(n,i)*i-1/(f(n,i)*i)+abs(f(n,i)-i) i f(n,i)];end,x(1,2:3)
  • trik 1: saya menambahkan jumlahnya 1-1/length*widthsebagai tie-scoring

  • trik 2: saya menghitung number_students/lengthplafon untuk lebar persegi panjang, batas atas adalah kuadrat tetapi juga plafon

  • Saya yakin itu bisa bermain golf lebih lanjut ...

Cobalah


Sunting: dirujuk ke pernyataan @StewieGriffin.

Edit 2:

  • 1dan nkonstanta tidak perlu menambahkannya ke skor keseluruhan.
  • Suatu fungsi beberapa byte kurang dari program mandiri stdin.
  • Saya menggunakan teknik penyortiran ascendent menghemat terlalu banyak byte.

Sunting 3: tes kinerja.


@StewieGriffin yang bukan masalah besar, bisa diselesaikan menggunakanunique
Abr001am

1
Saya pikir saya setengah jalan ke beberapa terjemahan matematika yang bagus untuk masalah ini, tetapi masih tetap sebagai dugaan
Abr001am

Pikirkan juga tentang ini. Lihat contoh julia.
mschauer

1

Python 2, 64 byte

lambda n:max((~-i*~min(i,n/i),0-n/i,-i)for i in range(-n,0))[1:]

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 .


1

Julia, 61 59 55 53 52 byte

/ =cld
n->[m=indmax([~i*~-max(i,n/i)for i=1:n]),n/m]

Cobalah online!

Bagaimana itu bekerja

Kode ini setara dengan versi ungolfed berikut ini, di mana cldadalah pembagian plafon.

function chairs(n)
    m = indmin([(i + 1) * (max(i, cld(n, i)) - 1) for i in 1:n])
    return [m, cld(n, m)]
end

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/ indmaxmemberikan 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).


1

JavaScript (ES6) 74 78

Edit menjaga hasil temp sebagai array bukan 2 vars, dipinjam dari jawaban Thiht

n=>(z=>{for(x=0;y=-~(~-n/++x),x<=y;)(s=y-x+x*y-n)>=z||(z=s,r=[x,y])})()||r

Kurang golf

n=>{
  z = 1/0
  for (x=0; y=(n-1)/++x+1|0, x <= y; )
  {
    s = y-x+x*y-n;
    if (s<z)
      z=s, r=[x,y]
  }
  return r
}

Uji

f=n=>(z=>{for(x=0;y=-~(~-n/++x),x<=y;)(s=y-x+x*y-n)>=z||(z=s,r=[x,y])})()||r

out=x=>O.textContent+=x+'\n'

for(i=1;i<=100;i++)out(i+' :( '+f(i)+' )')
<pre id=O></pre>


1

PHP, 129 byte

function f($i){$s=INF;for($x=1;$x<$i;$x++){if($s>$t=(abs($x-$e=ceil($i/$x))-$i+($e*$x))){$s=$t;$d[0]=$x;$d[1]=$e;}}var_dump($d);}

Tidak Terkumpul:

function f ($i){
    $s=INF;
    for($x=1; $x<$i; $x++){ // for every number less than the input
        if( $s > $t=( abs($x-$e=ceil($i/$x))-$i+($e*$x) ) ){ 
            // determine the other dimension, the score, and compare to the minimum score
            $s=$t;
            $d[0]=$x;
            $d[1]=$e;
        }
    }
    var_dump($d);
}

1

PHP, 104 byte

Algoritma yang memecahkan masalah ini sederhana dan mungkin digunakan oleh jawaban lain dalam bahasa yang mirip dengan PHP (JavaScript, fe):

  • mulai dengan nilai besar untuk skor awal; ncukup besar (di mana nnilai input); skor pengaturan yang dihitung pada iterasi pertama ( 1, n) adalah (n-1)+0;
  • beralih untuk semua nilai lebar antara 1dan n; hitung ketinggian minimum sebagai ceil(n/width), hitung skor pengaturan menggunakan rumus yang disediakan dalam pertanyaan (yaitu abs(width - height) + (width * height - n)); jika skor lebih baik dari skor terbaik sebelumnya maka ingat lebar, tinggi dan skor terbaik baru; pada ikatan menggunakan nilai width * height - npengaturan saat ini dan pengaturan terbaik sebelumnya untuk mendeteksi pengaturan terbaik baru;
  • itu saja.

Setelah bermain golf, algoritma ini menghasilkan sesuatu seperti ini (dibungkus di sini untuk dibaca):

for($s=$h=$j=$n=$argv[$w=$i=1];$i<=$j;$j=ceil($n/++$i)
{$c=$j-$i+$i*$j-$n;if($c<$s||$c==$s&&$i*$j<$w*$h){$w=$i;$h=$j;$s=$c;}}
echo"$w,$h";

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.

  • tidak perlu mengulang lebar dari 1ke $n; untuk kecepatan, lebar ( $i) harus beralih antara 1dan floor(sqrt($n))tetapi ini membuat kode lebih panjang daripada memperpendeknya; tetapi jika lebarnya tidak melebihi sqrt($n), tinggi minimum ( $j) akan selalu lebih besar dari sqrt($n)(paling tidak produk mereka $n);
  • pernyataan sebelumnya memungkinkan penggunaan $i <= $j(lebar <= tinggi) sebagai kondisi terminasi untuk loop; dengan cara ini, lebar akan beralih dari 1ke floor(sqrt($n))dan ketinggian akan mendapatkan nilai mulai dari $ndan turun ke ceil(sqrt($n))(tidak harus semuanya);
  • mengetahui bahwa lebar selalu lebih kecil dari atau sama dengan ketinggian, beri tahu kami bahwa abs(width - height)selalu height - width( $j-$i); 5 byte disimpan dengan cara ini;
  • nilai input $ndigunakan dalam perhitungan skor (jumlah kursi yang tidak dihuni adalah width * height - n) tetapi tidak diperlukan; skor tidak perlu ditampilkan, itu dihitung hanya untuk perbandingan pengaturan; dengan menghapus - ndari rumus skor kami menyimpan 3 byte lainnya (kode PHP -$n) tanpa kehilangan apa pun;
  • diberikan dua pernyataan terakhir, rumus skor menjadi height - width + width * height( $j-$i+$i*$j);
  • on ties (skor pengaturan saat ini sama dengan skor terbaik sebelumnya), aturan mengatakan untuk menggunakan pengaturan dengan kursi yang lebih bebas; karena lebar selalu bertambah dan tinggi selalu menurun, height - widthbagian dari skor berkurang pada setiap langkah;
  • jika skor saat ini sama dengan skor terbaik sebelumnya, pernyataan sebelumnya memberi tahu kita bahwa jumlah kursi gratis dari pengaturan saat ini lebih besar daripada yang ada pada pengaturan terbaik sebelumnya; ini berarti pengaturan terbaik sebelumnya memenangkan dasi;
  • karena ikatan selalu dimenangkan oleh pengaturan terbaik sebelumnya, pengaturan baru menjadi pengaturan terbaik baru hanya ketika nilainya lebih kecil dari yang terbaik sebelumnya; kode yang memeriksa ikatan tidak berguna dan dapat dihapus ( ||$c==$s&&$i*$j<$w*$h- banyak byte);
  • karena penghapusan dari -$nrumus skor, skor untuk pengaturan pertama ( 1x$n) adalah $n-1+1*$n(yaitu 2*$n-1); nilai awal dari skor terbaik ( $s) dapat berupa nilai yang lebih besar atau sama dengan 2*$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:

for($s=2*$j=$n=$argv[$i=1];$i<=$j;$j=ceil($n/++$i))
if($s>$c=$j-$i+$i*$j){$w=$i;$h=$j;$s=$c;}echo"$w,$h";

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 (katakanlah arrange-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:

$ php arrange-your-chairs.php 1001
28,36

Solusi lain (116 byte)

Solusi lain yang menggunakan algoritma berbeda:

for($n=$argv[1];++$j<=$n;)for($i=0;++$i<=$j;)
if($n<=$k=$i*$j)$a["$i,$j"]=($j-$i+$k-$n)*$n+$k;asort($a);echo key($a);

Ini menempatkan semua kombinasi dari setidaknya $nkursi 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)

foreach(range(1,$m=$n=$argv[1])as$i)
if(($d=ceil($n/$i))<=$i&&$m>=$s=$i*$d-$n+$i-$d){$m=$s;$w=$d;$h=$i;}echo"$w,$h";

Ini adalah versi PHP dari jawaban @ Neil (JavaScript / ES6, 85 byte).

Ada beberapa perbedaan nyata karena fitur masing-masing bahasa:

  • jawaban JS menghasilkan array nnilai (tidak terdefinisi) kemudian menggunakan kuncinya untuk beralih dari 0ke n-1; itu menambah i( d=(n+i++)/i|0) untuk membuatnya iterate dari 1to n; solusi PHP tidak perlu bertambah; digunakan range()untuk menghasilkan array kemudian menggunakan nilai yang dihasilkan ( 1untuk n) untuk beralih;
  • jawaban JS menggunakan (n+i)/ilalu mengonversi nilai menjadi integer menggunakan |0untuk mendapatkan bilangan bulat terkecil lebih besar dari n/i; jawaban PHP memecahkan masalah ini dengan mudah dengan fungsi PHP ceil(); JavaScript juga menyediakan Math.ceil()tetapi menggunakan 5 byte lebih dari solusi yang ditemukan oleh Neil;
  • PHP menyediakan fungsi array_map()yang mirip dengan JS Array.map()tetapi tidak membantu di sini; sintaksnya adalah verbose, foreachmenghasilkan kode yang lebih pendek; itu lebih besar dari kode JS, meskipun;
  • menggabungkan penugasan ke dalam kondisi menggunakan ||tidak dimungkinkan dalam PHP karena tidak memiliki operator koma; Saya menerjemahkan a||b||cke dalam if(!a&&!b)c, karena adan bperbandingan, saya meniadakan operator mereka (diganti <dengan >=); ini juga menghasilkan kode yang lebih besar daripada versi JS;
  • 23 byte lainnya harus ditambahkan hanya karena nama-nama variabel dalam PHP harus diawali oleh $.

Versi ungolfed dari semua solusi dan test suite dapat ditemukan di Github .


1
Ini adalah jawaban kode-golf paling menyeluruh yang pernah saya lihat.
DJMcMayhem

0

JavaSCript (ES6), 83 byte

n=>[...Array(m=n)].map((_,i)=>(d=(n+i++)/i|0)>i||(s=i*d-n+i-d)>m||(m=s,r=[d,i]))&&r

Mungkin Anda bisa menerapkan trik saya (untuk menyimpan 2 byte)
Leaky Nun

@ KennyLau saya tidak berpikir itu membantu; Saya harus menambah mkompensasi.
Neil

0

Julia, 87

Saya pikir ini adalah satu langkah ke arah mencari fungsi ajaib untuk masalah:

f(i)=(i+n)÷(i+1)|>j->(j*i<n)+j
_=indmin([sqrt(n)<=i?i-f(i)*(1-i):2n for i=1:n])
_,f(_)

Hanya terlihat berpasangan (i, j=(i+n)/(i+1))atau(i, j+1)


tolong jelaskan lebih lanjut bagaimana cara kerjanya, Anda membuat saya penasaran dengan fungsi Anda
Abr001am

2
Saya tidak yakin bagaimana ini seharusnya bekerja. Anda tidak mendefinisikan di nmana pun, dan Anda tampaknya tidak mengambil input.
Dennis

Ah, maaf, saya hanya mengambil nmasukan. Seseorang harus membungkusnya n->.... Bagus bahwa Anda bisa membuatnya bekerja.
mschauer

0

Oracle SQL 11.2, 173 byte

SELECT MIN(x||','||y)KEEP(DENSE_RANK FIRST ORDER BY y-x+(y*x-:1))FROM(SELECT CEIL(LEVEL/:1)x,CEIL(MOD(LEVEL+.1,:1))y FROM DUAL CONNECT BY LEVEL<=:1*:1)WHERE x<=y AND:1<=x*y;

Tidak bermain golf

SELECT MIN(x||','||y)KEEP(DENSE_RANK FIRST ORDER BY y-x+(y*x-:1))  -- Keeps the minimal score
FROM   (SELECT CEIL(LEVEL/:1)x,CEIL(MOD(LEVEL+.1,:1))y FROM DUAL CONNECT BY LEVEL<=:1*:1) -- Generate x,y combinations 
WHERE  x<=y AND :1<=x*y  -- Filters out wrong combinations

0

Q 58 Bytes

{c@d?&/d:+/(-/;*/)@\:+c:{((b<a)?1b)#+(b:-_-x%a;a:1+!x)}x}

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

{..}'1+!100

di mana {..} adalah lambda. Baca sebagai "berlaku lambda untuk setiap nilai 1 + 100 int pertama" (dengan kata lain untuk setiap nilai 1..100)

Menghasilkan

1 1
2 1
2 2
2 2
3 2
3 2
3 3
3 3
3 3
5 2
4 3
4 3
4 4
4 4
4 4
4 4
6 3
6 3
5 4
5 4
7 3
5 5
..

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 kiri

a: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%aberlaku 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?xmengembalikan posisi pertama item x dalam urutan s. Dengan (b<a)?1bKami mencari 1b (nilai sebenarnya) secara berurutan sebagai hasil dari membandingkan b dan a, dan mendapatkan posisi pertama di mana b

n#sDibutuhkan 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 (-/;*/)@\:+cadalah 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. Dengan d?&/dkami 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 benar

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.