파티션 나누기


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에 대해 작동 하고 log (n)을 실행 하는 가장 작은 솔루션에 현상금을 수여합니다 . 작은 n의 경우 속도빠릅니다 (내 재량에 따라 결정). 예, 가능합니다.


3
그러한 분해가 항상 존재합니까? 그것을 보장하는 어떤 수 이론 정리?
Luis Mendo 2016 년

것 같다 모든 N> 77. (나는 모든 세부 사항을 확인하지 않았습니다.) 그것은 당신의 도전에 대한 설명에
있었을

1
@flawr, 나는 O(log n)알고리즘을 포기하기 때문에 그 참조를 포함하지 않았다고 가정합니다 .
Peter Taylor

1
여전히 그는이 집합이 주어진 n에 대해 존재한다고 언급 했어야했다. (그리고 제목을 인터넷 검색 할 때 첫 페이지에서 그 논문을 찾았습니다.)
flawr

1
@flawr, 그것을 찾는 데 약 10 분이 걸렸습니다. 나는 이집트 분수에 대한 페이지를 통해 그것을 얻었고, 당신은 10 초 닌자를했습니다.
Peter Taylor

답변:


3

수학, 54 바이트

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

비효율적이지만 n = 78약 9 초 안에 해결 됩니다.

결과는 다음과 같이 단일 목록으로 래핑 된 목록으로 반환됩니다.

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

그것이 매우 큰 n에서 작동하는지 궁금합니다.
njpipeorgan

@njpipeorgan 메모리와 시간이 충분하다면, 그렇습니다.
Martin Ender 2016 년

n = 2 ^ 30의 경우 exp (sqrt (n)) ~ 10 ^ 10 ^ 4.5의 순서로 IntegerPartition [n]의 길이를 추정했습니다. 나는 수학 (또는 어떤 아키텍처)도 배열을 유지할 수 있다고 믿지 않습니다.
njpipeorgan

@njpipeorgan이 과제는 알고리즘이 이론적 으로 실제적 으로 2 ^ 32까지 작동해야 한다고 명시 적으로 명시하고 있습니다. ).
Martin Ender

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)거의 즉시 실행되는 테스트를 할 수 있습니다

나는 이 논문 을 그것을 계산하는 방법에 사용했다. 이 방법을 사용하면 168 이후의 짝수없이 78에서 334 사이의 n에 대해 미리 결정된 값에 대한 대량의 데이터 청크가 있습니다. 나는이 데이터를 작은 것으로 바꾸고 싶었고 좋은 압축 알고리즘을 알지 못했습니다. 내 자신을 만들었습니다.

압축 방식은 문자열 교체 규칙 목록을 갖는 것입니다. 규칙을 정의하는 것을 고려하여 모든 내용을 가장 많이 줄이는 문자열 바꾸기 규칙을 찾은 방법을 만들었습니다. 그런 다음 더 이상 규칙을 만들 수 없을 때까지이 문자를 재귀 적으로 적용했습니다 (문자 gz 및 AZ 사용). 내가 바꾸려고 한 문자열은 각 숫자에 대한 쉼표로 구분 된 16 진수 값 목록이었습니다. 돌이켜 보면 16 진수 값으로 변환하는 것이 가장 현명한 선택이 아닐 수 있습니다. 16 진수를 사용하면 3 자리 숫자 만 저장하고 한 자리 숫자에는 0을 추가하므로 10 진수로 두는 것이 더 짧을 수 있습니다.

내가 c를 설정 한 줄에는 교체 규칙 목록과 규칙이 실행되는 텍스트가 표시됩니다. 일부 규칙에는 다른 규칙에서 생성 된 문자가 포함되므로 규칙을 반대로 적용해야합니다.

이 코드에는 목록 목록을 단일 목록으로 바꾸고 다른 방법을 사용하여 텍스트를 바꾸는 규칙에 액세스하는 등 구문을 줄일 수있는 많은 장소가 있습니다.


1
n=218출력 [2]이 예상됩니다 ??
officialaimm

1
아니요, 왜 그런 일이 나중에 발생하는지 보겠습니다. 사과드립니다. 처음 압축 한 데이터에 오류가있을 수 있습니다.
Cameron Aavik 2012 년

1

하스켈, 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]상호의 합과 합에 대한 모든 하위 순서를 확인하십시오 .

1 대신에 모든 솔루션을 반환하는 것은 3 바이트 더 짧 !!0습니다.


1 실행 시간은 결과가 서브 시퀀스 목록에 얼마나 빨리 나타나는지에 따라 다릅니다. Haskell의 게으름은 첫 번째 일치 항목이 발견되면 검색을 중지합니다. 컴파일 할 때 p 89(결과 [3,4,6,9,18,21,28]:)는 35 세의 내 (4 세) 랩톱에서 실행됩니다. 더 작은 값이라도 다른 값은 몇 시간이 걸릴 수 있습니다.


0

줄리아, 77 바이트

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

이것은 정수를 받아들이고 정수 배열을 반환하는 비효율적 인 람다 함수입니다. 호출하려면 변수에 지정하십시오.

를 사용하여 정수의 파티션을 얻습니다 partitions. 그런 다음 왕복 세트의 합이 1 인 고유 요소를 가진 파티션으로 만 파티션 세트를 필터링합니다. 반올림 오류가 발생하지 않도록하기 위해 Julia의 Rational유형을 사용 하여 왕복을 구성합니다. filter반복자를 반환하므로 collect배열에 반복자를 배치해야합니다 . 이것은 하나의 요소로 된 배열의 배열을 제공하므로 첫 번째를 사용할 수 있습니다 [1].

이제 비효율적이라고 말하면 의미합니다. n = 80 동안 이것을 실행하면 컴퓨터에서 39.113 초가 걸리고 13.759 GB의 메모리가 할당됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.