Phân số điên cuồng!


9

EDIT: Tôi nhận được rất nhiều ý kiến ​​về việc không chấm dứt - Tôi sẽ đưa thẻ "câu trả lời đúng" cho người đầu tiên đưa cho tôi FF(3)(như cung cấp nó trong câu trả lời của họ) hoặc chứng minh rằng điều FF(3)đó thực sự nổ tung vô thời hạn.

Bài tập:

Nhiệm vụ của bạn là làm cho chương trình nhỏ nhất có thể tạo ra danh sách các đối ứng của hàm Fraction Frenzy ( FF(n)) với một số nguyên dương n.

Giới thiệu:

Trước khi tôi có thể giới thiệu hàm FF, trước tiên tôi phải giải thích các phân số của Ai Cập.

Phân số Ai Cập:

Phân số Ai Cập là một cách để biểu thị phân số là tổng của các phân số đơn vị riêng biệt - vì vậy một cách để biểu thị phân số 5/81/2 + 1/8. Nó không phải là một khoản tiền nhỏ như

1/4 + 1/4 + 1/8
1/2 + 1/16 + 1/16

bởi vì không phải tất cả các phân số của chúng là khác biệt ( 1/4được lặp lại trong ví dụ đầu tiên và 1/16trong lần thứ hai).

Theo định nghĩa của chúng tôi về phân số Ai Cập, chúng tôi cũng bao gồm việc sử dụng mẫu số âm trong phân số đơn vị.

Hàm FF:

Hàm FF (Fraction Frenzy) được mô tả như vậy:

FF(1)là phần Ai Cập 1/2 + 1/3 + 1/5 + 1/-30.

FF(2)bằng FF(1)"nhân" của chính nó ( FF(1)"bình phương"):

  (1/2 + 1/3 + 1/5 + 1/-30)(1/2 + 1/3 + 1/5 + 1/-30)
= 1/4 + 1/6 + 1/10 + 1/-60 + 1/6 + 1/9 + 1/15 + 1/-90 +
  1/10 + 1/15 + 1/25 + 1/-150 + 1/-60 + 1/-90 + 1/-150 + 1/900

Đây không phải là một phần Ai Cập giảm hoàn toàn, bởi vì có "lặp lại" trong phân số. Để giảm bớt chúng, thủ tục sau đây được thực hiện:

  1. Tổng tất cả các phân số đơn vị "thích" lại với nhau.
  2. Giảm các khoản tiền thành các hình thức đơn giản nhất của chúng - vì vậy, ví dụ, nếu một khoản tiền từ bước 12/6, có thể giảm xuống 1/3.
  3. Lặp lại 1 và 2 cho đến khi tất cả các mẫu số là khác biệt: ví dụ, 1/2 + 2/3 + 1/5trái ngược với 1/2 + 1/3 + 1/3mẫu số có mẫu số lặp lại 3.
  4. Nếu có một cặp một phần dương và một phần âm có giá trị tuyệt đối bằng nhau, hãy loại bỏ cả hai phần này (ví dụ 1/-51/5cả hai phải được loại bỏ).
  5. Nếu phân số không phải là đơn vị và không thể giảm thêm nữa, hãy chia nó thành các phân số đơn vị có mẫu số bằng nhau và giữ một phân số như hiện tại. Với những cái khác, nhân chúng với FF(1): (1/2 + 1/3 + 1/5 + 1/-30).
  6. Lặp lại các bước 1-5 cho đến khi tổng phân số cuối cùng là phân số Ai Cập hợp lệ - tức là tất cả các phân số đều khác biệt với nhau và chúng đều là các phân số đơn vị.

Đây là giảm FF(2):

  1/4 + 1/6 + 1/10 + 1/-60 + 1/6 + 1/9 + 1/15 + 1/-90 +
  1/10 + 1/15 + 1/25 + 1/-150 + 1/-60 + 1/-90 + 1/-150 + 1/900
= 1/4 + 2/6 + 1/9 + 2/10 + 2/15 + 1/25 + 2/-60 + 2/-90 + 2/-150 + 1/900 (step 1)
= 1/4 + 1/3 + 1/9 + 1/5 + 2/15 + 1/25 + 1/-30 + 1/-45 + 1/-75 + 1/900   (step 2)
= 1/3 + 1/4 + 1/5 + 1/9 + 1/15 + 1/15(1/2 + 1/3 + 1/5 + 1/-30) +        (step 5)
  1/25 + 1/-30 + 1/-45 + 1/-75 + 1/900
= 1/3 + 1/4 + 1/5 + 1/9 + 1/15 + 1/30 + 1/45 + 1/75 + 1/-450 +
  1/25 + 1/-30 + 1/-45 + 1/-75 + 1/900
= 1/3 + 1/4 + 1/5 + 1/9 + 1/15 + 1/25 + 1/-450 + 1/900                  (step 4)

Đối với tất cả n(ngoại trừ 1), FF(n)được định nghĩa bằng "bình phương" FF(n-1).

Đầu vào và đầu ra:

Cho một số nguyên n, bạn phải xuất ra một danh sách tất cả các đối ứng của FF(n), được sắp xếp theo thứ tự tăng dần của các giá trị tuyệt đối của chúng:

1 -> [2, 3, 5, -30]
# 1/2 + 1/3 + 1/5 + 1/-30 = FF(1), reciprocals = [2, 3, 5, -30]

2 -> [3, 4, 5, 9, 15, 25, -450, 900]

Bạn được phép sử dụng một chuỗi với bất kỳ dấu phân cách hoặc giải thích danh sách ngôn ngữ của bạn, vì vậy những đầu ra này đều được chấp nhận với đầu vào 1:

2 3 5 -30   (Space-delimited)
2,3,5,-30   (Comma-delimited)
[2 3 5 -30] (Lisp-like lists)
etc. etc.

Thông số kỹ thuật:

  • Bạn phải xuất kết quả của FF(n)hàm chính xác như được chỉ định ở trên.
  • Bạn được đảm bảo rằng đầu vào sẽ là một số nguyên dương - nó sẽ không bao giờ dưới 0 và nó sẽ không bao giờ là số thập phân (hoặc phân số).

Đây là , vì vậy mã ngắn nhất tính bằng byte sẽ thắng!


4
Vì tò mò, điều này có đảm bảo chấm dứt?
Martin Ender


Tôi xác nhận rằng FF (3) dường như sẽ nổ tung. Bạn đã không kiểm tra điều này lên đến khoảng FF (10) trước khi đăng lên hộp cát?
Peter Taylor


2
Phân số Ai Cập không có giá trị âm trong đó, vì vậy nó không thực sự là một phần của Ai Cập.
mbomb007

Câu trả lời:


1

Haskell , 365 byte

import Data.Function;import Data.List;import Data.Ratio;n=numerator;d=denominator
r=until=<<((==)=<<)$filter(/=0).map(sum).groupBy((==)`on`d).sortBy(compare`on`d)
p s=let(o,q)=span((<2).abs.n)s in case q of []->o;(a:b)->let j=a-1%d a*signum a in p.r$o++[a-j]++map(*j)e++b
s s=(*)<$>s<*>s;e=(1%)<$>[2,3,5,-30];f=iterate(p.r.s)e;o i=[abs(d q)*signum(n q)|q<-f!!(i-1)]

Hãy thử trực tuyến!


Hmmio tôi chạy vào một vòng lặp rõ ràng vô hạn khi tách đơn vị lớn nhất và kiểm tra lại tại một thời điểm như đã trình bày và đã làm như vậy khi tách đơn vị nhỏ nhất theo chiều ngược lại hoặc toàn cầu không phải đơn vị trước khi kiểm tra lại nhưng có lẽ tôi nên không thất bại trong việc chọn các đơn vị không ở giữa, liệu người ta có thể hủy bỏ đủ số người khác để đạt được FF hữu hạn (3) không?
Roman Czyborra

Sử dụng (1%)<$>[2,4,6,12]như 1 chỉ đơn thuần là trì hoãn sự hủy diệt từ FF (3) đến FF (4)
Roman Czyborra

(1%)<$>[2,3,10,15]hoặc (1%)<$>[3,4,6,8,12,24]không mang lại sự cải thiện nào cả 🤔
Roman Czyborra
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.