Tìm khoảng thời gian tổng thể từ danh sách tần số


8

Lấy cảm hứng từ http://xkcd.com/1331/

Trong truyện tranh xkcd này, có một số gifs tất cả nhấp nháy với tần số khác nhau. Tôi muốn biết khoảng thời gian sẽ là bao nhiêu nếu chỉ là một GIF. Đưa ra một danh sách các số đại diện cho các tần số riêng lẻ, xuất ra khoảng thời gian của GIF tổng thể.

Định nghĩa chính thức

Đầu vào:

N
f1
f2
.
.
.
fN

Đầu ra:

P

Trong đó N là số tần số, fi là tần số thứ i và P là khoảng thời gian kết quả của tổng GIF.

Bạn có thể chọn sử dụng bất kỳ ký tự phân định nào bạn muốn (thay vì \ n) và bạn có thể loại trừ N nếu bạn muốn và nó sẽ được suy ra theo số lượng ký hiệu.

Một số chi tiết cụ thể

Các tần số là biểu diễn dấu phẩy động có độ chính xác kép gần nhất của các số được cung cấp làm đầu vào.

Thời gian xuất là một số nguyên không dấu 64 bit, được làm tròn (tăng 0,5) cho toàn bộ gần nhất. Bất kỳ đầu vào nào tạo ra khoảng thời gian lớn hơn 2 ^ 64-1 đều được coi là hành vi không xác định.

Tương tự, mọi đầu vào <= 0 đều được coi là hành vi không xác định.

Điều kiện thắng

Mã golf để mã ngắn nhất chiến thắng!


Spoiler có thể ... đây sẽ không phải là sản phẩm của các tần số nhất định?
danmcardle

@craenedgremlin Không phải vậy, nhưng bạn khá thân thiết.
Victor Stafusa

@craenedgremlin - Nếu A là 2s và B là 4s thì khoảng thời gian kết quả sẽ là 4s chứ không phải 8 giây.
Chấn thương kỹ thuật số

À, tôi hiểu rồi, cảm ơn. @Cruncher, chính xác ý bạn là gì bởi "tần số"? Lặp lại mỗi giây hoặc thời gian lặp lại mất? Tôi giả sử trước đây, vì đó thường là tần số có nghĩa là gì.
danmcardle

Có ít nhất 2 phương pháp cho việc này: Lấy tần số tổng thể làm GCD của tần số đầu vào và đảo ngược nó. Hoặc lấy tần số đầu vào, đảo ngược tất cả để lấy dấu chấm và lấy LCM làm khoảng thời gian tổng thể. Tôi đã lấy GCD. @DavidCarraher đã lấy LCM. Bạn chỉ cần đối phó với các số nguyên.
Victor Stafusa

Câu trả lời:


8

APL, 4

∧/∘÷

là cả LCM logic và số (với miền trên số nguyên, số float, số phức, số hữu tỷ, bất kỳ ngăn xếp số nào được hỗ trợ bởi việc triển khai APL), do đó ∧/giảm LCM hoặc tính LCM của một mảng.

Monadic ÷là số nghịch đảo. Vì vậy, thành phần ∧/∘÷là LCM của nghịch đảo của các số được cung cấp.

Công thức khác, nghịch đảo của GCD, sẽ là ÷∘(∨/), trong đó các dấu ngoặc đơn là cần thiết để sửa lỗi ưu tiên giữa /.

Bạn có thể dùng thử trực tuyến trên http://tryapl.com/

Ví dụ

      ∧/∘÷ .12 .02 3.9 .15 .99
100
      ∧/∘÷ (16÷5)(2÷3)(2.35)(1÷7)
420

Holy bananas!
Cruncher

3
@Cruncher đó sẽ là †))! trong APL.
Tobia

Bravo. Tôi nghĩ rằng chúng ta có một người chiến thắng.
Victor Stafusa

Đơn giản là tuyệt vời. Ngả mũ trước bạn.
DavidC

4

Toán học 43 28

Thử lần thứ hai

Nỗ lực đầu tiên của tôi là không chính xác, mặc dù nó đã có một số thành phần cần thiết (LCM, Rationalize). Giải pháp hoàn chỉnh đòi hỏi phải tính đến cả tử số và mẫu số của từng tần số (được biểu thị dưới dạng phân số chung).

l là danh sách tần số.

Hợp lý hóa 2.35 chuyển đổi nó thành phân số phổ biến 235/100.

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

Giả sử rằng tất cả các GIF bắn ở t = 0.

Cách tiếp cận sau đây không yêu cầu tần số được biểu thị là "số thực", nghĩa là. dưới dạng phân số thập phân. Chúng có thể là các loại phân số khác. Ví dụ dưới đây là trường hợp các phân số ở phần năm, phần ba, phần trăm và phần bảy.

Nếu hai hoặc nhiều tần số không tương xứng (trong trường hợp đó ít nhất một tần số phải là số vô tỷ) thì không có giải pháp. Nói cách khác, sẽ không có thời điểm nào, t> 0, tại đó tất cả các thành phần đều bắn cùng một lúc.

Ví dụ 1

f[{50, 10}]

1/10


Ví dụ 2

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

420

Nếu chúng ta nhân khoảng thời gian tổng thể nhỏ nhất với mỗi tần số, chúng ta sẽ tìm thấy toàn bộ số chu kỳ trong mỗi trường hợp:

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

{1344, 280, 987., 60}

(1344 bước nhảy của 16/5 đơn vị) hạ cánh tại 420. (280 bước nhảy của 2/3 đơn vị) hạ cánh tại 420. (987 bước nhảy của 2,35 đơn vị) hạ cánh tại 420. (60 bước nhảy của 7 đơn vị) hạ cánh tại 420.


Công cụ phù hợp cho công việc phù hợp.
Victor Stafusa

Tôi không chắc tôi hiểu. Nếu các đầu vào là tần số, f [{50,10}] có nghĩa là chu kỳ chung của tín hiệu phát 50 lần mỗi giây và một chu kỳ tập tin 10 lần mỗi giây? Câu trả lời đúng sẽ là 1/10 giây, nhưng f [{50, 10}] trả về 1. Trên thực tế, rất nhiều điều ngẫu nhiên trả về câu trả lời là 1. f [{345345, h}] trả về 1.
Michael Stern

Cách tiếp cận ban đầu của tôi không đầy đủ (và do đó không chính xác). Tôi đã sửa đổi nó theo cách để giải quyết sự quan sát của bạn. Giải pháp hiện tại cũng có ý nghĩa về mặt hình học (sử dụng các phân đoạn dòng so với dòng thực).
DavidC

Tôi đã đến để đăng một giải pháp như vậy, nhưng bạn đánh bại tôi với nó. Rất đẹp.
Jonathan Van Matre

@Jonathan. Vâng, cách tiếp cận của bạn gần giống với tôi. Nhưng tôi không thấy sự cần thiết của Vòng. Sẽ không Rationalize và LCM đảm bảo rằng kết quả là số nguyên?
DavidC

2

Javascript: 191 ký tự

Định dạng đầu vào mà tôi đã chọn (trong các quy tắc) là các số tần số được phân tách bằng dấu phẩy. Không có không gian cho phép và không có dòng mới. N ban đầu không được đưa ra. Mỗi số phải chỉ là một serie gồm ít nhất một chữ số [0-9] với một dấu chấm tùy chọn ở đâu đó bên trong. Nếu đầu vào không đúng định dạng, hành vi không được xác định.

Làm thế nào nó hoạt động:

Chu kỳ của một số số nguyên là GCD của các số này. Nếu các số đã cho không phải là số nguyên, nó sẽ nhân chúng lên 10 cho đến khi nó nhận được mọi thứ dưới dạng số nguyên (điều này khai thác thực tế là các số không nguyên được đưa ra trong cơ sở 10). Sau khi tính toán GCD, nó chia kết quả cho công suất của mười được sử dụng để nhân các số đầu vào và do đó có được tần số chung. Đảo ngược điều này, chúng tôi nhận được thời gian.
Lưu ý: Tôi khá chắc chắn rằng bây giờ tôi đã đưa ra câu trả lời này, ai đó sẽ viết mã giống nhau trong APL hoặc J và đánh bại nó. :

Mật mã:

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)

Kiểm tra nó:

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.

GCD? Đó là ước số chung lớn nhất, vì vậy nó sẽ luôn nhỏ hơn tần số. Tôi nghĩ bạn có nghĩa là LCM (bội số chung ít nhất).
Justin

@Quincunx Không, đó là GCD. Tổng thời gian là LCM của các thời kỳ riêng lẻ, không phải tần số riêng lẻ.
Victor Stafusa

1
Đây là APL:(⊃x÷z)×∨/z←{⍵×10}⍣{⍵≡⌈⍵}x←⎕
bến tàu

Bạn sẽ chạy một trường hợp thử nghiệm với số hữu tỷ hoặc "số thực" (theo nghĩa khoa học máy tính của thuật ngữ này)? Tôi không nghĩ rằng một cách tiếp cận dựa trên GCD sẽ hoạt động.
DavidC

@DavidCarraher Tôi nhầm tần số với thời gian, nhưng bây giờ tôi đã sửa. Chỉ cần thay đổi g/dthành d/g. Tôi sẽ thêm một số trường hợp thử nghiệm.
Victor Stafusa
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.