Swingers anggur Olimpiade melakukan rutinitas mereka di pohon standar. Secara khusus, Pohon Standar n
memiliki simpul untuk 0
naik n-1
dan ujung-ujungnya menghubungkan setiap simpul bukan nol a
ke simpul n % a
di bawahnya. Jadi, misalnya, Standard Tree 5 terlihat seperti ini:
3
|
2 4
\ /
1
|
0
karena sisa ketika 5 dibagi 3 adalah 2, sisanya ketika 5 dibagi 2 atau 4 adalah 1, dan sisanya ketika 5 dibagi 1 adalah 0.
Tahun ini, Tarzan akan mempertahankan emasnya dengan rutinitas baru, yang masing-masing dimulai pada titik n - 1
, berayun ke titik n - 2
, terus ke titik n - 3
, dll, sampai akhirnya ia turun ke titik 0
.
Skor untuk rutin adalah jumlah skor untuk setiap ayunan (termasuk turun), dan skor untuk ayunan adalah jarak di dalam pohon antara titik awal dan titik akhir. Dengan demikian, rutinitas Tarzan di Standard Tree 5 memiliki skor 6:
- ayunan dari
4
ke3
skor tiga poin (bawah, atas, atas), - ayunan dari
3
ke2
skor satu poin (bawah), - ayunan dari
2
ke1
skor satu poin (bawah), dan - turun dari
1
ke0
skor satu poin (turun).
Tulis program atau fungsi yang, dengan bilangan bulat positif n
, menghitung skor rutin Tarzan di Pohon Standar n
. Input dan output sampel:
1 -> 0
2 -> 1
3 -> 2
4 -> 6
5 -> 6
6 -> 12
7 -> 12
8 -> 18
9 -> 22
10 -> 32
11 -> 24
12 -> 34
13 -> 34
14 -> 36
15 -> 44
16 -> 58
17 -> 50
18 -> 64
19 -> 60
20 -> 66
21 -> 78
22 -> 88
23 -> 68
24 -> 82
Aturan dan penilaian kode seperti biasa untuk golf kode .
sumber
Jawaban:
C,
9897 byteIni menghitung jarak antara setiap pasangan poin dengan rumus berikut:
Ini memiliki keuntungan bahwa ketika diterapkan ke semua pasangan, itu sama dengan:
Untuk membuat logikanya lebih sederhana, kita asumsikan kita beralih dari simpul 0 ke simpul n-1, daripada n-1 ke 0 seperti yang dinyatakan oleh pertanyaan. Jarak dari simpul akar ke simpul 0 jelas 0 (mereka sama). Dan kita dapat melihat bahwa untuk sebagian besar pohon, jarak dari simpul terakhir ke root adalah 2:
Ini berarti kami memiliki beberapa kasus khusus (n <2) tetapi kami dapat menjelaskannya dengan cukup mudah.
Kerusakan:
Terima kasih @feersum untuk 1 byte disimpan
Bonus: Pohon!
Saya menulis program cepat dan kotor untuk melihat seperti apa pohon-pohon ini. Inilah beberapa hasilnya:
19:
sumber
Python 2, 85 byte
sumber
Perl,
65595554 byteTermasuk +2 untuk
-ap
Jalankan dengan ukuran pohon di STDIN:
vines.pl
:Penjelasan
Jika Anda menulis ulang pohon itu
ke satu tempat setiap node berisi himpunan semua leluhur dan dirinya sendiri:
Kemudian kita bisa menggambarkan misalnya semua node path dari 4 ke 3 sebagai:
Jumlah tepi adalah satu kurang dari jumlah node sehingga kita dapat menggunakannya untuk mengabaikan titik bergabung, sehingga jumlah tepi pada jalur dari 4 ke 3 adalah 3 karena:
Perhatikan bahwa ini juga berfungsi untuk jalur yang langsung turun ke targetnya, misalnya untuk jalur dari 3 ke 2 jumlah tepi adalah 1 karena:
Kami kemudian dapat menjumlahkan semua kombinasi ini.
Jika Anda melihat hanya sebuah simpul, misalnya simpul 2 dengan leluhur yang ditetapkan
{2,3}
. Node ini akan berkontribusi sekali ketika memproses path2 to 1
karena mengandung 2 tetapi tidak 1. Tidak akan memberikan kontribusi apa pun untuk path3 to 2
karena memiliki 2 dan 3, tetapi akan berkontribusi sekali ketika memproses path4 to 3
karena memiliki 3 tetapi no 4. Secara umum angka dalam set leluhur dari sebuah simpul akan berkontribusi satu untuk setiap tetangga (satu lebih rendah dari yang lebih tinggi) yang tidak ada dalam set. Kecuali untuk elemen maksimum (4 dalam hal ini) yang hanya berkontribusi untuk tetangga rendah 3 karena tidak ada jalan5 to 4
. Simular 0 adalah satu sisi, tetapi karena 0 selalu di akar pohon dan berisi semua angka (itu adalah gabungan akhir dan kami tidak menghitung bergabung) tidak pernah ada kontribusi dari 0 sehingga lebih mudah untuk meninggalkan simpul 0 sama sekali.Jadi kita juga bisa menyelesaikan masalah dengan melihat set leluhur untuk setiap node, menghitung kontribusi dan menjumlahkan semua node.
Untuk dengan mudah memproses tetangga saya akan mewakili set leluhur sebagai string ruang dan 1 di mana masing-masing 1 pada posisi p menyatakan bahwa n-1-p adalah leluhur. Jadi misalnya dalam kasus kami
n=5
1 pada posisi 0 menunjukkan 4 adalah leluhur. Saya akan meninggalkan ruang trailing. Jadi representasi sebenarnya dari pohon yang akan saya bangun adalah:Perhatikan bahwa saya meninggalkan simpul 0 yang akan diwakili oleh
"11111"
karena saya akan mengabaikan simpul 0 (tidak pernah berkontribusi).Nenek moyang tanpa tetangga yang lebih rendah sekarang diwakili oleh akhir dari urutan 1. Nenek moyang tanpa tetangga yang lebih tinggi sekarang diwakili oleh permulaan urutan 1, tetapi kita harus mengabaikan permulaan urutan pada awal string karena ini akan mewakili jalur
5 to 4
yang tidak ada. Kombinasi ini sangat cocok dengan regex/.\b/
.Membangun string leluhur dilakukan dengan memproses semua node dalam urutan
n-1 .. 1
dan ada yang menetapkan 1 di posisi untuk node itu sendiri dan melakukan "atau" ke dalam keturunan.Dengan semua itu, program ini cukup mudah dimengerti:
Perhatikan bahwa mengganti
/.\b/
dengan/\b/
menyelesaikan versi bolak-balik dari masalah ini di mana tarzan juga mengambil jalannya0 to n-1
Beberapa contoh bagaimana string leluhur terlihat (diberikan secara berurutan
n-1 .. 1
):sumber
Mathematica,
113103102 byte-10 byte terima kasih kepada @feersum; -1 byte terima kasih kepada @MartinEnder
Berikut ini jauh lebih cepat (tapi lebih lama, sayangnya, pada 158 byte ):
sumber
With
. Juga sepertinya setiap kaliRange
digunakan,a
adalah argumen, sehingga bisa diperhitungkan.r=Range[a=#-1]
menghemat satu byte.J, 37 byte
Pemakaian:
Cobalah online di sini.
sumber
JavaScript (ES6),
118116 byteKurangnya fungsi perbedaan set benar-benar menyakitkan, tetapi beberapa rekursi kreatif mengurangi jumlah byte sedikit. Sunting: Disimpan 2 byte dengan menghapus parameter yang tidak perlu.
sumber