Temukan periode keseluruhan dari daftar frekuensi

8

Terinspirasi oleh http://xkcd.com/1331/

Dalam komik xkcd ini, ada beberapa gif yang semuanya berkedip dengan frekuensi berbeda. Saya ingin tahu bagaimana periode jika semua GIF tunggal. Diberikan daftar angka yang mewakili frekuensi individu, mengeluarkan periode GIF keseluruhan.

Definisi Resmi

Memasukkan:

N
f1
f2
.
.
.
fN

Keluaran:

P

Di mana N adalah jumlah frekuensi, fi adalah frekuensi ke-i, dan P adalah periode yang dihasilkan dari total GIF.

Anda dapat memilih untuk menggunakan karakter pembatas yang Anda inginkan (bukan \ n), dan Anda dapat mengecualikan N jika Anda mau, dan itu akan disimpulkan dengan jumlah pembatas.

Beberapa spesifik

Frekuensi adalah representasi titik mengambang presisi ganda terdekat dari angka-angka yang disediakan sebagai input.

Periode yang dikeluarkan adalah bilangan bulat bertanda 64-bit, dibulatkan (naik pada 0,5) ke keseluruhan terdekat. Setiap input yang akan menghasilkan periode yang lebih besar dari 2 ^ 64-1 dianggap perilaku tidak terdefinisi.

Demikian juga setiap input <= 0 dianggap perilaku tidak terdefinisi.

Kondisi menang

Golf kode sehingga kode terpendek menang!

Cruncher
sumber
Kemungkinan spoiler ... bukankah ini hanya produk dari frekuensi yang diberikan?
danmcardle
@crazedgremlin Tidak, tapi Anda cukup dekat.
Victor Stafusa
@crazedgremlin - Jika A adalah 2s dan B adalah 4s, maka periode yang dihasilkan adalah 4s, bukan 8s.
Digital Trauma
Ah, begitu, terima kasih. @Cruncher, apa sebenarnya yang Anda maksud dengan "frekuensi"? Pengulangan per detik atau jumlah waktu yang dibutuhkan pengulangan? Saya berasumsi yang pertama, karena biasanya itu yang dimaksud dengan frekuensi.
danmcardle
Setidaknya ada 2 metode untuk ini: Ambil frekuensi keseluruhan sebagai GCD dari frekuensi input dan balikkan. Atau ambil frekuensi input, balikkan semuanya untuk mendapatkan periode dan ambil LCM sebagai periode keseluruhan. Saya mengambil GCD. @DavidCarraher mengambil LCM. Anda hanya perlu mengatasi non-integer.
Victor Stafusa

Jawaban:

8

APL, 4

∧/∘÷

keduanya logis DAN dan numerik LCM (dengan domain lebih dari bilangan bulat, mengapung, kompleks, rasional, apa pun tumpukan angka didukung oleh implementasi APL) jadi ∧/ juga pengurangan oleh LCM, atau menghitung LCM dari sebuah array.

Monadic ÷adalah pembalikan angka. Jadi komposisinya ∧/∘÷adalah LCM dari angka terbalik yang disediakan.

Rumus lain, kebalikan dari GCD, adalah ÷∘(∨/), di mana tanda kurung diperlukan untuk memperbaiki diutamakan antara dan /.

Anda dapat mencobanya online di http://tryapl.com/

Contohnya

      ∧/∘÷ .12 .02 3.9 .15 .99
100
      ∧/∘÷ (16÷5)(2÷3)(2.35)(1÷7)
420
Tobia
sumber
Holy bananas!
Cruncher
3
@Cruncher itu †))! dalam APL.
Tobia
Bravo. Saya pikir kita punya pemenang.
Victor Stafusa
Sangat menakjubkan. Angkat topi untukmu.
DavidC
4

Mathematica 43 28

Percobaan kedua

Upaya pertama saya tidak benar, meskipun ia memang memiliki beberapa bahan yang diperlukan (LCM, Rasionalisasi). Solusi lengkap membutuhkan memperhitungkan baik pembilang dan penyebut masing-masing frekuensi (dinyatakan sebagai fraksi umum).

l adalah daftar frekuensi.

Merasionalisasi 2,35 mengubahnya menjadi fraksi umum 235/100.

f@l_:=LCM@@(1/Rationalize@l)

Asumsikan bahwa semua GIF menyala pada t = 0.

Pendekatan berikut ini tidak mengharuskan frekuensi dinyatakan sebagai "bilangan real", yaitu. sebagai pecahan desimal. Mereka mungkin jenis fraksi lain. Contoh di bawah ini adalah kasus di mana fraksi berada di perlima, pertiga, seperseratus dan ketujuh.

Jika dua atau lebih frekuensi tidak sepadan (dalam hal ini setidaknya satu harus menjadi bilangan irasional) maka tidak ada solusi. Dengan kata lain, tidak akan ada titik waktu, t> 0, di mana semua komponen menyala secara bersamaan.

Contoh 1

f[{50, 10}]

1/10


Contoh 2

f[{16/5, 2/3, 2.35, 1/7}]

420

Jika kami mengalikan periode keseluruhan paling sedikit dengan masing-masing frekuensi, kami menemukan seluruh siklus dalam setiap kasus:

420*{16/5, 2/3, 2.35, 1/7}

{1344, 280, 987., 60}

(1344 hop dari 16/5 unit) mendarat di 420. (280 hop dari 2/3 unit) mendarat di 420. (987 hop dari 2,35 unit) mendarat di 420. (60 hop 7 unit) mendarat di 420.

DavidC
sumber
Alat yang tepat untuk pekerjaan yang tepat.
Victor Stafusa
Saya tidak yakin saya mengerti. Jika input adalah frekuensi, f [{50,10}] akan berarti siklus umum sinyal yang menyala 50 kali per detik dan siklus yang file 10 kali per detik? Jawaban yang benar adalah 1/10 detik, tetapi f [{50, 10}] mengembalikan 1. Sebenarnya, banyak hal acak mengembalikan jawaban 1. f [{345345, h}] mengembalikan 1.
Michael Stern
Pendekatan asli saya tidak lengkap (dan karena itu salah). Saya telah mengubahnya sedemikian rupa untuk mengatasi pengamatan Anda. Solusi saat ini juga masuk akal secara geometris (menggunakan segmen garis terhadap garis nyata).
DavidC
Saya datang untuk memposting solusi seperti itu, tetapi Anda mengalahkan saya untuk itu. Sangat bagus.
Jonathan Van Matre
@ Jonathan. Ya, pendekatan Anda hampir identik dengan pendekatan saya. Tapi saya tidak melihat perlunya Round. Tidakkah Rasionalisasi dan LCM menjamin bahwa hasilnya bilangan bulat?
DavidC
2

Javascript: 191 karakter

Format input yang saya pilih (dalam aturan) adalah angka frekuensi yang dipisahkan oleh koma. Tidak ada ruang yang diizinkan dan tidak ada baris baru. N awal tidak boleh diberikan. Setiap angka harus hanya seri minimal satu [0-9] digit dengan titik opsional di suatu tempat di dalam. Jika input salah, perilaku tidak terdefinisi.

Bagaimana itu bekerja:

Periode beberapa angka frekuensi integer adalah GCD dari angka-angka ini. Jika angka-angka yang diberikan bukan bilangan bulat, itu berhasil mengalikannya dengan 10 sampai mendapatkan semuanya sebagai bilangan bulat (ini mengeksploitasi fakta bahwa angka-angka non-integer diberikan dalam basis 10). Setelah menghitung GCD, hasilnya dibagi dengan kekuatan sepuluh yang digunakan untuk mengalikan angka input, dan karenanya mendapatkan frekuensi keseluruhan. Menolak ini kita mendapatkan titik.
Catatan: Saya cukup yakin bahwa sekarang saya memberikan jawaban ini, seseorang akan kode yang sama di APL atau J dan mengalahkannya. :(

Kode:

d=1,s=prompt().split(",");for(a in s){s[a]=parseFloat(s[a]);while(s[a]*d%1>0)d*=10}g=s[0]*d;for(a in s){u=g;v=s[a]*=d;p=2;q=1;while(u>=p&v>=p)if(u%p|v%p)p++;else{u/=p;v/=p;q*=p}g=q}alert(d/g)

Mengujinya:

Input: 50,10
Output: 0.1
Interpretation: One GIF blinks 10 times per second (period = 0.1s) and the other 50 times (period = 0.02s). So a combined GIF would repeat itself in 0.1 seconds.

Input: 2.7,3.4
Output: 10
Interpretation: One blinking at 2.7 times per second will blink 27 times in 10 seconds. One blinking 3.4 times per second will blink 34 times in 10 seconds. So, 10 seconds is a period, and since GCD(27,34)=1, it is the smallest.

Input: 4.8,7.2
Output: 0.4166666666666667
Interpretation: One blinking at 4.8 times per second and the other at 7.2 times per second, gives a frequency of 2.4 times per second, which is a period 0.41666... seconds.

Input: 0.6,12,7.9,4.33
Output: 100
Interpretation: Similar to second case. 60, 1200, 790 and 433 times each 100 seconds. The GCD of these numbers is 1.

Input: 400,200,25,350
Output: 0.04
Interpretation: The slowest is the 25 times per second, which is the overall frequency. 25 times per second is a period of 0.04 seconds.

Input: 440,200,35,360
Output: 0.2
Interpretation: In 0.2 seconds, we have 88, 40, 7 and 72 blinks.
Victor Stafusa
sumber
GCD? Itu pembagi umum terbesar, sehingga akan selalu lebih kecil dari frekuensi. Saya pikir maksud Anda LCM (multiple paling umum).
Justin
@ Quincunx Tidak, ini adalah GCD. Total periode adalah LCM dari periode individual, bukan frekuensi individual.
Victor Stafusa
1
Inilah APL:(⊃x÷z)×∨/z←{⍵×10}⍣{⍵≡⌈⍵}x←⎕
marinus
Apakah Anda akan menjalankan test case dengan bilangan rasional atau "bilangan real" (dalam pengertian ilmu komputer istilah)? Saya tidak berpikir pendekatan berdasarkan GCD akan berhasil.
DavidC
@ DavidVarraher Saya mengacaukan frekuensi dengan titik, tapi sekarang saya sudah memperbaiki. Baru saja mengubah g/dke d/g. Saya akan menambahkan beberapa test case.
Victor Stafusa