Ketika Fibonacci bertemu Ratu

18

(Terinspirasi oleh respons Helka terhadap pemasangan acak tag "catur" dan "Fibonacci" dalam obrolan)


Fibonacci

The angka Fibonacci adalah salah satu urutan lebih terkenal dalam matematika, di mana setiap nomor terdiri dengan menambahkan dua angka sebelumnya bersama-sama. Di bawah ini adalah definisi dari urutan tanpa indeks:

f(0) = 0
f(1) = 1
f(n) = f(n-1) + f(n-2)

Ini menghasilkan urutan 0, 1, 1, 2, 3, 5, 8, 13, 21, ...( tautan OEIS ). Dalam tantangan ini, kami hanya akan berfokus pada nilai-nilai yang benar-benar positif (jadi 1, 1, 2, 3, ...), dan Anda dapat memilih pengindeksan-nol atau pengindeksan-tunggal, tetapi harap sebutkan yang mana dalam kiriman Anda.

Angka-angka Fibonacci dapat digunakan untuk ubin bidang, dengan menggunakan kotak yang berturut-turut f(n)dalam ukuran, dan meluruskan ujungnya bersama-sama. Ubin dilakukan secara berlawanan arah jarum jam, dengan menempatkan kotak dalam pola "kanan-kiri-bawah" dari kotak saat ini. Contoh ubin parsial ini untuk f(8)=21, dengan kuadrat awal disorot dengan warna biru, adalah sebagai berikut:
Kotak Fibonacci

Anda dapat melihat f(1)=1sebagai kotak awal (disorot dengan warna biru), f(2)=1kotak ditempatkan di sebelah kanannya , f(3)=2kotak ditempatkan di atas sana, f(4)=3kotak ditempatkan di kiri dan seterusnya. Kotak berikutnya adalah f(9)=21+13=34dan akan ditempatkan di bagian bawah. Ini adalah metode ubin parsial yang akan kami gunakan dalam tantangan ini.


Para ratu

Dalam permainan catur , bagian yang paling kuat adalah ratu karena ia dapat memindahkan sejumlah ruang secara horizontal, vertikal, atau diagonal. Dalam diagram papan di bawah ini, kotak dengan lingkaran hitam menunjukkan tempat ratu dapat bergerak:
Ratu bergerak dalam Catur

Kami akan mendefinisikan istilah cakupan sebagai

Persentase kuadrat yang dapat dipindahkan oleh ratu dibandingkan dengan jumlah kuadrat, mengingat posisi khusus ratu di papan kosong, dan termasuk posisi awal ratu sendiri.

Sebagai contoh bergerak di atas, cakupan ratu adalah 28/64 = 43.75%. Jika ratu berada di h8alun - alun kanan atas , cakupannya akan 22/64 = 34.375%. Jika sang ratu ada di dalam e7, cakupan akan 24/64 = 37.5%.


Tantangan

Kami akan menggunakan ubin Fibonacci yang ditunjukkan di atas sebagai papan catur kami untuk tantangan ini. Anda akan diberi dua bilangan bulat positif sebagai input, ndan x:

  • Ini nmewakili seberapa besar ubin itu. Contoh ubin di atas, dengan 21kotak di sebelah kiri, adalah papan ukuran n = 8sejak f(8) = 21(ketika nol-diindeks).
  • Yang xmewakili kuadrat Fibonacci yang digunakan untuk penempatan ratu, untuk menghitung cakupan. Ratu ditempatkan satu per satu pada setiap kotak di kotak persegi Fibonacci tertentu, dan cakupan total adalah penjumlahan dari cakupan individu (unik).

Sebagai contoh, berikut adalah gambar dari n = 8(ubin yang sama seperti di atas) dan x = 4(sesuai dengan f(4) = 3kotak, biru yang diarsir). Dengan menempatkan seorang ratu satu per satu ke masing-masing sembilan kotak biru itu, para ratu dapat (digabungkan) menutupi setiap kotak yang berwarna oranye. Karenanya, cakupan total dalam contoh ini 309/714 = 43.28%.

n = 8, x = 4

Jelas sekali, kapan saja n = x, cakupannya akan menjadi 100%(misalnya, dengan n=8dan x=8, Anda dapat melihat bahwa setiap kotak di seluruh papan akan dibahas setidaknya satu kali). Sebaliknya, dengan cakupan yang cukup besar ndan x=1atau x=2, cakupan akan mendekati (tetapi tidak pernah mencapai) 0%(misalnya, dengan n=8dan x=1, cakupannya sangat kecil 88/714 = 12.32%).

Dengan dua nomor input seperti itu, Anda harus menampilkan persentase cakupan, akurat ke dua tempat desimal. Silakan tentukan bagaimana kode Anda menangani pembulatan.


Aturan

  • Input dan output dapat diberikan dalam format apa pun yang mudah , tetapi harus akurat untuk dua tempat desimal. Silakan tentukan bagaimana kode Anda menangani pembulatan.
  • Asumsikan tidak ada bagian lain di papan tulis atau mengganggu gerakan.
  • Program lengkap atau fungsi dapat diterima. Jika suatu fungsi, Anda dapat mengembalikan output daripada mencetaknya.
  • Jika memungkinkan, harap sertakan tautan ke lingkungan pengujian online agar orang lain dapat mencoba kode Anda!
  • Celah standar dilarang.
  • Ini adalah sehingga semua aturan golf biasa berlaku, dan kode terpendek (dalam byte) menang.

Contohnya

n = 8, x = 4
43.28

n = 8, x = 8
100 or 100.00

n = 8, x = 1
12.32

n = 4, x = 1
66.67

n = 4, x = 2
60 or 60.00

n = 5, x = 3
75 or 75.00

n = 5, x = 1
47.5 or 47.50
AdmBorkBork
sumber
Gambar profil saya semi-relevan
Stephen
"Kapan Fibonacci bertemu sang Ratu"? Atau "Fibonacci memenuhi Queens"?
Jonathan Allan
@JonathanAllan Judul sudah benar apa adanya. Ini hadir indikatif tegang seperti pada "ini yang terjadi ketika X terjadi." Bandingkan "Ketika Henry bertemu Sally untuk makan siang, mereka selalu makan hamburger."
AdmBorkBork
Ah, maksudmu "Ketika Fibonacci bertemu Ratu ..."!
Jonathan Allan

Jawaban:

2

VB.NET, (.NET 4.5), 1238 1229 byte

-9 byte terima kasih kepada @totallyhuman

Function A(n,x)
Dim g=New List(Of List(Of Long))
g.Add(New List(Of Long))
g(0).Add(1)
For i=2To n
Dim b=1
If i>2Then 
Dim w=0,y=1
b=w+y
For j=3To i
w=y
y=b
b=w+y
Next
End If
Select Case i Mod 4
Case 1
For j=1To b
Dim l=New List(Of Long)
For k=1To b
l.Add(i)
Next
g.Add(l)
Next
Case 2
For Each r In g
For j=1To b
r.Add(i)
Next
Next
Case 3
For j=1To b
g.Insert(0,New List(Of Long))
For k=1To b
g(0).Add(i)
Next
Next
Case 0
For Each r In g
For j=1To b
r.Insert(0,i)
Next
Next
End Select
Next
For i=0To g.Count-1
Dim c=g(i)
For j=0To c.Count-1
Dim e=c(j)
If e=x Then
For k=1To Math.Max(g.Count,g(0).Count)
If j-k>=0AndAlso c(j-k)<>x Then c(j-k)=0
If i-k>=0AndAlso g(i-k)(j)<>x Then g(i-k)(j)=0
If j+k<c.Count AndAlso c(j+k)<>x Then c(j+k)=0
If i+k<g.Count AndAlso g(i+k)(j)<>x Then g(i+k)(j)=0
If i-k>=0AndAlso j-k>=0AndAlso g(i-k)(j-k)<>x Then g(i-k)(j-k)=0
If i-k>=0AndAlso j+k<c.Count AndAlso g(i-k)(j+k)<>x Then g(i-k)(j+k)=0
If i+k<g.Count AndAlso j-k>=0AndAlso g(i+k)(j-k)<>x Then g(i+k)(j-k)=0
If i+k<g.Count AndAlso j+k<c.Count AndAlso g(i+k)(j+k)<>x Then g(i+k)(j+k)=0
Next
End If
Next
Next
Dim hits=0
For Each r In g
For Each c In r
If c=x Or c=0Then hits+=1
Next
Next
Return Math.Round(hits*100/(g.Count*g(0).Count),2)
End Function

Simulasi pernyataan masalah. Saya mulai dengan membuat kisi, mengulang-ulang setiap nomor Fibonacci baru untuk meningkatkan ukuran kuadrat. Saya menyimpan indeks di setiap sel, sehingga mudah untuk menemukan ke mana ratu akan pergi pada langkah berikutnya.

Kemudian, saya menemukan setiap sel yang seharusnya memiliki ratu di dalamnya, dan menandai setiap kotak yang terancam dengan nol. Saya melewatkan sel di mana ratu berada sehingga saya tidak perlu khawatir tentang mundur.

Pada akhirnya, saya menghitung sel-sel yang dibersihkan, dan sel-sel dengan ratu, dan kemudian membaginya dengan jumlah total ruang. Kalikan dengan 100 untuk mendapatkan persen, dan bulatkan ke dua tempat desimal terdekat.

Brian J
sumber
Bisakah Anda tidak mengubah hitske nama variabel yang lebih pendek? Saya tidak tahu VB.NET, tapi saya berasumsi itu variabel.
totallyhuman
@totallyhuman ya, itu benar. Saya melewati dengan tangan dan pasti melewatkan yang itu. Terima kasih!
Brian J
2

Python 2 , 524 499 byte

def Q(n,x):
 global w,h,f;f,R,L=0,range,len
 for d in R(n):s=x-1==d;f=f or[[s]];w=L(f[0]);W,H=R(w),R(L(f));exec"for j in "+("W:f.append([s]*w)","f:\n\tfor k in H:j.append(s)","W:f.insert(0,[s]*w)","f:\n\tfor k in H:j.insert(0,s)","f:0")[d%4-(d==0)]
 w,h=L(f[0]),L(f);l=0,1,-1
 for Y in R(h):
	for X in R(w):exec("""def F(u,v,x,y):
 while(u==v==0)==0<=x<w!=0<=y<h:f[y][x]=1+(f[y][x]!=1);x+=u;y+=v
for s in l:
 for t in l:F(s,t,X,Y)""","")[f[Y][X]!=1]
 q=w*h;return(q-sum(j.count(0)for j in f))*100./q

Cobalah online!

Menentukan fungsi yang menggunakan ukuran ubin ndan nomor kuadrat Ratu ratu x. Persentase ouput dibulatkan dengan sempurna ke dua tempat desimal (dalam catatan kaki, tempat semua output berlangsung).

fadalah array dua dimensi yang berisi informasi papan yang diinisiasi 0. Kemudian, papan catur fibonacci dihitung dan diisi dengan ratu di mana ratu akan berada. Para ratu itu kemudian dipindahkan ke setiap tempat mereka dapat dipindahkan; semua posisi dihitung dan dicetak sebagai persentase dari seluruh papan.

Jonathan Frech
sumber
1

Mathematica 11.1, 336 byte, berbasis 1

R=Rectangle[#,+##]&;f=Fibonacci;o=Join@@Outer[##,1]&;r=RegionUnion;s=RegionMeasure;p[1]={0,0};p[i_]:=p[i-1]+{{-f@i,-f[i-2]},{0,-f@i},{f[i-1],0},{f[i-1]-f@i,f[i-1]}}[[i~Mod~4+1]];t[i_]:=r[R[p@#,f@#]&/@Range@i];k[n_,x_]:=Round[100s@RegionIntersection[r[R[#,f@x]&/@((#+p@x)&/@o[1##&,o[List,{-1,0,1},{-1,0,1}],Range[2f@n]])],t@i]/s@t@i,.01]

Penggunaan: k[n, x]. Perhatikan bahwa fungsi ini berbasis 1. Pembulatan dicapai olehRound[100x,0.01]

Pada dasarnya, p[i]adalah fungsi menentukan posisi setiap kotak. Dan daerah dihitung dengan-tingkat atas fungsi seperti RegionIntersection, RegionUnion,RegionMeasure

hasil

Keyu Gan
sumber