Розмежування реципрок


21

Враховуючи число n> 77 , напишіть програму або функцію, яка знаходить набір чітких додатних цілих чисел, таких, що сума множини дорівнює n , а сума зворотних множини дорівнює 1.

Приклад для 80:

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

Ваша програма або функція повинна (теоретично) працювати для будь-якого n <2 32 , і не виправдовується помилками округлення плаваючої точки. Зауважте, що рішення існують для всіх n> 77 .


Виграє найкоротший код у байтах.

Існує заохочувальний бонус: я присуджую суму за найменше рішення, яке працює для будь-якого n та веде журнал (n) . Для малих n він повинен бути швидким (визначається на мій розсуд). Так, це можливо.


3
Чи завжди гарантується таке розкладання? Будь-яка теоретична цифра, яка запевняє це?
Луїс Мендо

Здається, що існує для всіх n> 77. (Я не перевіряв кожну деталь.) Це повинно було бути в описі вашого виклику ...
недолік

1
@flawr, я припускаю, що він не включив цю посилання, оскільки це дає O(log n)алгоритм.
Пітер Тейлор

1
Ще він повинен був зазначити, що ця множина існує для даної n. (І я знайшов, що папір на першій сторінці, коли гуглити заголовок.)
помилка

1
@flawr, мені знадобилося близько 10 хвилин, щоб знайти його. Я дістався до нього через сторінку про єгипетські фракції, і ти ніндзя за 10 секунд.
Пітер Тейлор

Відповіді:


3

Математика, 54 байти

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

Настільки ж неефективним, як це стає, але це вирішується n = 78приблизно за 9 секунд.

Результат повертається у вигляді списку, загорнутого в одиночний список, наприклад:

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

Цікаво, чи працює він на дуже великих російських.
njpipeorgan

@njpipeorgan Дано достатньо пам’яті та часу, так.
Мартін Ендер

Я знайшов оцінку довжини IntegerPartition [n], яка є в порядку exp (sqrt (n)), ~ 10 ^ 10 ^ 4.5 для n = 2 ^ 30. Я дійсно не вірю, що математика (або навіть будь-яка архітектура) здатна вмістити масив.
njpipeorgan

@njpipeorgan У виклику прямо вказано, що алгоритм повинен працювати до 2 ^ 32 теоретично , а не практично (як це зазвичай прийнято вважати для гольфу з кодом, якщо виклик прямо не вимагає, щоб програма фактично закінчувала всі входи в розумну кількість часу та пам'яті ).
Мартін Ендер

4

Пітон 3, 7306, 1995 байт

Це рішення працює у log (n) складності (наскільки я можу сказати).

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]

Ви можете протестувати, який f(2**32 - 1)працює майже миттєво

Цей документ я використав для методу його обчислення. За допомогою цього методу існує величезна частина даних за заздалегідь визначеними значеннями для n від 78 до 334 без парних чисел після 168. Я хотів перетворити ці дані в щось невелике, і я не знав жодних хороших алгоритмів стиснення, тому я зробив своє.

Те, як я стиснув це, склав список правил заміни рядків. Я створив метод, який знайшов правило заміни рядка, яке дозволило б скоротити найбільше вмісту за всіма, беручи до уваги визначення правила. Потім я рекурсивно застосовував це, поки не зміг створити більше правил (я використав символи gz та AZ). Рядок, який я зробив для заміни, являв собою список, розділених комами, шістнадцяткових значень для кожного з чисел. З ретроспективою перетворення їх на шістнадцяткові значення, можливо, не було наймудрішим вибором, можливо, було б коротше залишити їх у десятковій формі, оскільки наявність шестигранника дозволить заощадити лише для тризначних чисел, але додасть 0 для одноцифрових чисел.

У рядку, де я встановив c, ви можете побачити список правил заміни та текст, на якому він працює. Правила потрібно застосовувати і в зворотному порядку, оскільки деякі правила включають символи, створені з інших правил.

У цьому коді також є численні місця, де я, ймовірно, міг би скоротити синтаксис, наприклад перетворення списків у єдиний список, а потім використання іншого методу для доступу до правил для заміни тексту на


1
n=218Результати [2]- це очікуване ??
officialaimm

1
Ні, я зрозумію, чому це відбувається трохи пізніше. Мої вибачення. Можливо, буде помилка в даних, які я стискав спочатку.
Камерон Авік

1

Haskell, 93 байти

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

Жахливо повільно 1, але він працює в постійній пам'яті. Тривіальне рішення: перевірити всі [2..n]підсумки на суму та суму зворотних запитів.

Повернення всіх рішень замість одного на 3 байти коротше: просто видаліть !!0(будьте обережні: час роботи завжди буде поза графіком).


1 Час виконання залежить від того, наскільки рано результат відображається у списку підрядів. Лінь Хаскелла зупиняє пошук, якщо знайдено першу відповідність. Коли компілюється, p 89(результат [3,4,6,9,18,21,28]:) працює на моєму (чотирирічному) ноутбуці у 35-і роки. Інші значення, навіть менші, можуть зайняти години.


0

Джулія, 77 байт

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

Це неефективна лямбда-функція, яка приймає ціле число і повертає цілий масив. Щоб викликати його, призначте його змінній.

Ми отримуємо розділи цілого числа, використовуючи partitions. Потім ми фільтруємо набір розділів лише до тих, що мають унікальні елементи, реципрок яких дорівнює 1. Щоб уникнути помилки округлення, ми використовуємо Rationalтип Джулії для побудови реципрок. filterповертає ітератор, тому ми маємо collectйого в масив. Це дає нам масив масивів (лише з одним елементом), тому ми можемо отримати перше використання [1].

Зараз, коли я кажу неефективно, я маю на увазі це. Запуск цього за n = 80 займає 39.113 секунд на моєму комп’ютері та виділяє 13.759 ГБ пам'яті.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.