Phân vùng đối ứng


21

Cho một số n> 77 , hãy viết một chương trình hoặc hàm tìm một tập hợp các số nguyên dương riêng biệt sao cho tổng của tập hợp bằng n và tổng các nghịch đảo của tập hợp bằng 1.

Ví dụ cho 80:

80 = 2 + 4 + 10 + 15 + 21 + 28 1/2 + 1/4 + 1/10 + 1/15 + 1/21 + 1/28 = 1

Chương trình hoặc chức năng của bạn phải (về mặt lý thuyết) hoạt động cho mọi n <2 32 và không được miễn cho các lỗi làm tròn dấu phẩy động. Lưu ý rằng các giải pháp tồn tại cho tất cả n> 77 .


Mã ngắn nhất trong byte thắng.

Có một ưu đãi tiền thưởng: Tôi sẽ trao tiền thưởng cho giải pháp nhỏ nhất hoạt động cho mọi n và chạy log (n) . Đối với n nhỏ thì phải nhanh (xác định theo ý của tôi). Vâng, điều này là có thể.


3
Là sự phân hủy như vậy luôn luôn được đảm bảo để tồn tại? Bất kỳ định lý lý thuyết số đảm bảo rằng?
Luis Mendo

Dường như tất cả n> 77. (Tôi đã không kiểm tra từng chi tiết.) Điều đó đáng lẽ phải có trong phần mô tả về thử thách của bạn ...
flawr

1
@flawr, tôi cho rằng anh ta không bao gồm tài liệu tham khảo đó vì nó cho đi O(log n)thuật toán.
Peter Taylor

1
Tuy nhiên, anh ta nên đề cập rằng bộ này tồn tại cho n. (Và tôi đã tìm thấy tờ giấy đó trên trang đầu tiên khi lấy tiêu đề.)
flawr

1
@flawr, tôi mất khoảng 10 phút để tìm thấy nó. Tôi đã nhận được nó thông qua một trang về phân số Ai Cập, và bạn sẽ cho tôi 10 giây.
Peter Taylor

Câu trả lời:


3

Toán học, 54 byte

Select[IntegerPartitions@#,Unequal@@#&&Tr[1/#]==1&,1]&

Về hiệu quả như nó được, nhưng nó sẽ giải quyết n = 78trong khoảng 9 giây.

Kết quả được trả về dưới dạng danh sách được bọc trong danh sách đơn, ví dụ:

{{45, 12, 9, 5, 4, 3}}

Tôi tự hỏi nếu nó hoạt động cho n rất lớn.
njpipe tổ chức

@njpipeorgan Cho đủ bộ nhớ và thời gian, vâng.
Martin Ender

Tôi đã tìm thấy một ước tính về độ dài của IntegerPartition [n], theo thứ tự exp (sqrt (n)), ~ 10 ^ 10 ^ 4.5 cho n = 2 ^ 30. Tôi thực sự không tin rằng mathicala (hoặc thậm chí bất kỳ kiến ​​trúc nào) có thể giữ được mảng.
njpipe tổ chức

@njpipe Organ Thách thức nói rõ rằng thuật toán phải hoạt động tối đa 2 ^ 32 về mặt lý thuyết , không thực tế (như thường được giả định cho môn đánh gôn, trừ khi thử thách yêu cầu chương trình thực sự kết thúc cho tất cả các đầu vào trong một khoảng thời gian và bộ nhớ hợp lý ).
Martin Ender

4

Python 3, 7306 1995 Byte

Giải pháp này chạy trong độ phức tạp log (n) (theo như tôi có thể nói).

def i(s,t):
 for n in s[::-1]:t=t.replace(*n)
 return [[]]*78+[list(bytearray.fromhex(a))for a in t.split(",")]
def f(n):
 g,h=lambda c,n:c+[[[2],[3,7,78,91]][n[len(c)]%2]+[i*2for i in c[-1]]],lambda n:[]if n<78 else h((n-[2,179][n%2])//2)+[n]
 v=h(n);c=[i([['g',',03040'],['h',',,0306080'],['i',',020'],['j','b0c1'],['k','21'],['l','60'],['m','30'],['n','141'],['o','k24'],['p',',g'],['q','618'],['r','0c0'],['s','1e'],['t',',0ml'],['u','283c'],['v','e0f1'],['w','2a38'],['x','80'],['y','a0'],['z','01'],['A','50'],['B','24'],['C','i40'],['D','plb1'],['E','gl'],['F','48'],['G','bre1'],['H','28'],['I','6k'],['J','416s'],['K',',040Al'],['L','90'],['M','2a'],['N','54'],['O','k6o'],['P','3c'],['Q','il'],['R','18'],['S','px'],['T','im'],['U','70'],['V','b1'],['W','23'],['X','pj'],['Y','hj'],['Z','0n']],'020lxycHTaRHCyf1517CyfneC91k51cCLdneQU912MCyf0dBiALyf2dClfPEyfneT9s2dELdneEjIgmLydHg5rd14BKLardsE3n8sQ9rd1517Q9rdneplmdRBgUmcRMC5sPEyf102bgA6sPE91z2miAj41IQmc0dRBQUen7spl31z82bT9RFT3wE7neMgmyf0dRBgUmaHMELc1b36EUdBMQLyfs2d,C710M2bgLardRHT3BFQ9rf0dPQ7rdBMQm9Rs2d,0mAl9100d142bE710M2bQmc0fRPtxarfn8sEc1k4sBTfnePExcwtxarf1k8BExcuT3kkT91663C51964,0mAl71k4BMELe12NTcRwQjOT820ltmarf1z8mExeRNCqBFtmyjIHKLa100ds2bQU91bM36garf1k4sBTcRBFgxarfwE91keB2dtUxcn8sME9nbs36gm9rduC5R78,0mAUyf0d14BME91kbB36QLc12AB2dgyjqkHEUeMNT9157eQU9RMFT8s78C8neuixLc1zk4AtUxc1z8Mmt8re0fn8sWhLyc1bH36pl8neu,Kxycsw,iAxc1420l,K8ren8NS9n81bs36hc0vz8WmYzqkmhyv2WBHhyVOHXkJoSjIwSjIuSvz4WASVZIAXZ6skmSj6oFXzOmplvcsW46D61csk46plv8WBFDqoF,tarvk8WBH,tyjkqoHhGqkN,tmvZ8sWmhVZqskmpc0vZ8WAXZqkAplbnImASbn6skwSbn6skuSVOwSVOupGONSbn6soFpyVkJk5aSj6sk78YJkuDkIP5aYOuhvzk4WBAhVzk416oA,tyjkJ265a,,0mxyjk41q53sYzIHmPXkqowXkqouhyVqoHFYz6omFhb0e1zqkmNSyVIP78YJ20klpyVOHwYk620olpc0vz8WBmFXzqomFpG61ckH38PhyjIP78Yz620kmlDkImLDzINUhGIuNDzIA78hb0e1ZIANYkqk366chG6oFNXkJkP5ahVZ6somFSb0e1620kNlhVk41qomADzIFLXkqso78pGqoFNXzkImP5a,tyjk620oHlhG620kNlXzqskm78,tjZqskHmPYqouFD6sku78YzqkNU,tjZqsomF')[v[0]]]
 for o in range(len(v)-1):c=g(c,v)
 return c[-1]

Bạn có thể kiểm tra f(2**32 - 1)chạy gần như ngay lập tức

Tôi đã sử dụng bài báo này về một phương pháp để tính toán nó. Với phương pháp này, có một khối dữ liệu khổng lồ cho các giá trị được xác định trước cho n từ 78 đến 334 mà không có số chẵn sau 168. Tôi muốn biến dữ liệu này thành một số nhỏ và tôi không biết bất kỳ thuật toán nén tốt nào nên tôi làm của riêng tôi.

Cách tôi nén nó là bằng cách có một danh sách các quy tắc thay thế chuỗi. Tôi đã tạo ra một phương thức tìm thấy quy tắc thay thế chuỗi sẽ cắt giảm hầu hết nội dung trên tất cả có tính đến việc xác định quy tắc. Sau đó tôi đã áp dụng đệ quy này cho đến khi tôi không thể tạo thêm quy tắc nào nữa (tôi đã sử dụng các ký tự gz và AZ). Chuỗi tôi tạo để thay thế là một danh sách các giá trị hex được phân tách bằng dấu phẩy cho mỗi số. Nhìn lại, chuyển đổi chúng thành các giá trị hex của chúng có thể không phải là lựa chọn khôn ngoan nhất, có lẽ sẽ ngắn hơn nếu để chúng ở dạng thập phân, vì có hex sẽ chỉ lưu cho các số có 3 chữ số nhưng sẽ thêm 0 cho các số có một chữ số.

Dòng nơi tôi đặt c bạn có thể thấy danh sách các quy tắc thay thế và văn bản mà nó chạy trên đó. Các quy tắc cũng cần được áp dụng ngược lại vì một số quy tắc bao gồm các ký tự được tạo từ các quy tắc khác.

Cũng có nhiều vị trí trong mã này, nơi tôi có thể cắt giảm cú pháp, chẳng hạn như biến danh sách danh sách thành một danh sách và sau đó sử dụng một phương pháp khác để truy cập các quy tắc để thay thế văn bản bằng


1
n=218đầu ra [2]là dự kiến ​​??
chính thức tuyên bố

1
Không, tôi sẽ thấy tại sao điều đó xảy ra muộn hơn một chút. Lời xin lỗi của tôi. Có thể là một lỗi trong dữ liệu tôi nén ban đầu.
Cameron Aasta

1

Haskell, 93 byte

import Data.List
import Data.Ratio
p n=[x|x<-subsequences[2..n],sum x==n,1==sum(map(1%)x)]!!0

Kinh khủng 1 chậm nhưng nó chạy trong bộ nhớ liên tục. Giải pháp tầm thường: kiểm tra tất cả các phần sau của [2..n]tổng và tổng của các đối ứng.

Trả về tất cả các giải pháp thay vì một giải pháp ngắn hơn 3 byte: chỉ cần loại bỏ !!0(coi chừng: thời gian chạy sẽ luôn bị tắt khỏi biểu đồ).


1 Thời gian chạy tùy thuộc vào kết quả xuất hiện sớm như thế nào trong danh sách các chuỗi. Sự lười biếng của Haskell dừng tìm kiếm nếu trận đấu đầu tiên được tìm thấy. Khi được biên dịch, p 89(kết quả [3,4,6,9,18,21,28]:) chạy trên máy tính xách tay (4 tuổi) của tôi trong 35s. Các giá trị khác, thậm chí nhỏ hơn, có thể mất nhiều giờ.


0

Julia, 77 byte

n->collect(filter(i->i==∪(i)&&sum(j->Rational(1,j),i)==1,partitions(n)))[1]

Đây là một hàm lambda không hiệu quả, chấp nhận một số nguyên và trả về một mảng số nguyên. Để gọi nó, gán nó cho một biến.

Chúng tôi nhận được các phân vùng của số nguyên bằng cách sử dụng partitions. Sau đó, chúng tôi lọc tập hợp các phân vùng thành chỉ các phần tử có các phần tử duy nhất có tổng số tương ứng là 1. Để đảm bảo không xảy ra lỗi vòng, chúng tôi sử dụng Rationalloại của Julia để xây dựng các đối ứng. filtertrả về một iterator, vì vậy chúng ta phải đưa collectnó vào một mảng. Điều này cung cấp cho chúng tôi một mảng các mảng (chỉ có một phần tử duy nhất), vì vậy chúng tôi có thể nhận được phần đầu tiên bằng cách sử dụng [1].

Bây giờ, khi tôi nói không hiệu quả, tôi có nghĩa là nó. Chạy cái này trong n = 80 mất 39.113 giây trên máy tính của tôi và phân bổ bộ nhớ 13.759 GB.

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.