연속 정수의 합


27

누군가가 비슷 하고 비슷한 것을 말하기 전에 . 그러나 이것은 속임수가 아닙니다.


일부 양의 정수는 두 개 이상의 연속 양의 정수의 합으로 쓸 수 있습니다. 예를 들면 다음과 같습니다 9=2+3+4=4+5. 양의 정수를 입력으로 사용하고 그에 비례하는 연속적인 양의 정수를 증가시키는 가장 긴 시퀀스를 출력으로 인쇄하는 함수를 작성 하십시오 ( +위의 그림과 같이 출력이 증가하는 시퀀스 인 경우 -5 바이트가 허용되지만 모든 형식은 허용 가능합니다) 이러한 순서가 없으면 번호 자체를 인쇄해야합니다.

이것은 코드 골프입니다. 표준 규칙이 적용됩니다. 바이트 단위의 최단 코드가 이깁니다.


샘플 (형식이 다름)

Input:   9
Output:  2,3,4

Input:   8
Output:  8

Input:   25
Output:  [3,4,5,6,7]

2
출력되는 숫자가 특정 순서 (예 : 증가) 여야합니까?
xnor December

2
숫자가> 0이어야합니다 : 6 = 0 + 1 + 2 + 3 또는 6 = 1 + 2 + 3
Damien

5
부수적으로, 밀접하게 관련된 도전이 있다면, "이것은 속임수가 아니다"라고 말하는 것이 사람들이 그것이 속임수라고 생각한다면 그것을 설득하는 데 거의 도움이되지 않을 것입니다. 왜 그렇지 않다고 생각하는지 설명하면 더 도움이 될 것입니다.
Martin Ender

1
@Damien "positive"는 일반적으로> 0을 의미합니다. 0이 포함 된 경우 "음이 아닌"이라고합니다.
Martin Ender

3
cc @Vixen ^ (또한 음수가 허용되는 경우 최적의 솔루션은 항상 -n+1~ 사이입니다 n)
Martin Ender

답변:


11

파이썬, 67 바이트

f=lambda n,R=[1]:n-sum(R)and f(n,[R+[R[-1]+1],R[1:]][sum(R)>n])or R

이상하게 간단한 전략 : 올바른 합으로 구간 R을 검색하십시오.

  • 합이 너무 작 으면 다음으로 높은 숫자를 추가하여 구간의 오른쪽 끝점을 위로 이동하십시오.
  • 합이 너무 큰 경우 가장 작은 요소를 제거하여 왼쪽 끝점을 위로 이동하십시오.
  • 합이 정확하면 R을 출력하십시오.

간격의 하단이 증가하기 때문에 짧은 간격보다 긴 간격이 발견됩니다.


이상하게도 효율적입니다. 재귀 스택은 결국 오버플로됩니다 (예 : n = 8192).
primo December

7

Pyth, 12 10 바이트

j\+hfqsTQ}M^SQ2

코드 길이 는 15 바이트 이며 -5 바이트 보너스를받을 수 있습니다. Pyth Compiler 에서 온라인으로 사용해보십시오 .

2 바이트를 깎아 낸 @Jakube에게 감사드립니다!

작동 원리

j\+hfqsTQ}M^SQ2    (implicit) Store evaluated input in Q.

            S      Compute [1, ..., Q].
           ^  2    Get all pairs of elements of [1, ..., Q].
         }M        Reduce each pair by inclusive range. Maps [a, b] to [a, ..., b].
    f              Filter; for each pair T:
      sT             Add the integers in T.
     q  Q            Check if the sum equals Q.
                   Keep the pair if it does.
   h               Retrieve the first match.
                   Since the ranges [a, ..., b] are sorted by the value of a,
                   the first will be the longest, in ascending order.
j\+                Join, using '+' as separator.

1
Pyth 지역에 계몽되지 않은 사람들을 위해 설명을 추가해 주시겠습니까? :)
ETHproductions

내 답변을 편집했습니다.
Dennis

정말 고마워요! 나는 당신의 기술을 좋아합니다.
ETHproductions

1
입력 1000 : 30 분 및 계산 ...
primo

3

매스 매 티카, 73 68 65 56 43 바이트

Cases[Range~Array~{#,#},i_/;Tr@i==#,{2},1]&

1
+1 어젯밤에 비슷한 솔루션으로 끝났지 만 인터넷이 다운되었습니다. 또한 당신은 Tuples비문 식을 만들 수 있습니다 .
LegionMammal978

3

하스켈, 49 48 바이트

f n=[[a..b]|a<-[1..n],b<-[a..n],sum[a..b]==n]!!0

1
1 바이트 저장 : [...]!!0대신 사용하십시오 head[...].
nimi

2

MATLAB, 87 79 바이트

MATLAB 답변이 이미 있음을 알고 있지만 접근 방식이 크게 다릅니다.

x=input('');m=1:x;n=.5-m/2+x./m;l=max(find(~mod(n(n>0),1)));disp(m(1:l)+n(l)-1)

이것은 Octave 에서도 작동합니다 . 여기서 온라인으로 시도 할 수 있습니다 . 이미 consecutiveSum.m연결된 작업 공간에 코드를 추가 했으므로 consecutiveSum명령 프롬프트에 입력 한 다음 값을 입력하십시오 (예 : 25).

나는 여전히 그것을 줄이기 위해 노력하고 있습니다 (아마도 방정식을 조금 사용하여 조정). 기본적으로 정수 인 가장 큰 값 n을 찾은 m다음로 m시작 하는 첫 번째 숫자 를 표시합니다 n.

왜 이것이 작동합니까? 기본적으로 모든 숫자를 지배하는 수학 방정식이 있습니다. 그것들이 모두 연속적이라고 생각하고 어느 시점에서 시작한다면 기본적으로 다음과 같이 말할 수 있습니다.

n+(n+1)+(n+2)+(n+3)+...+(n+p)=x

이제 이것으로부터 시퀀스는 기본적으로 첫 번째 p삼각형 숫자 (0을 포함하여)이며 p+1많은에 추가됩니다 n. 이제 m=p+1우리가하자면 말할 수 있습니다.

m*(n+(m-1)/2)==x

이것은 실제로 상당히 해결할 수 있습니다. 나는 아직도 그것을하는 가장 짧은 코드 방법을 찾고 있습니다. 위의 코드를 시도하고 줄이기위한 아이디어가 있습니다.


입력 25의 경우 출력은 다음과 같습니다.

3     4     5     6     7

2
삼각형 숫자에 대한 요점과 관련 하여이 과제는 본질적으로 입력의 양의 차이로 삼각형 숫자를 찾으려고 노력하여 시퀀스의 삼각형 숫자의 인덱스 1,3,6,10,...가 최대화됩니다.
Arcturus

1

파이썬 2, 94 바이트

n=input()
r=int((2*n)**.5)
while r:
 if~r%2*r/2==n%r:print range(n/r-~-r/2,n/r-~r/2);r=1
 r-=1

입력은 stdin에서 가져옵니다. 이 솔루션은 매우 큰 입력에 적합합니다.

이 가능한 솔루션 길이로 반복 R 갖는 R ≤ √ (2N) 명시 적 솔루션 및 확인. 해가 존재하려면 r 이 홀수이면 n mod r 은 0이어야하고 r 이 짝수이면 n mod rr / 2 이어야합니다 .


샘플 사용법

$ echo 8192 | python sum-con-int.py
[8192]

$ echo 1000002 | python sum-con-int.py
[83328, 83329, 83330, 83331, 83332, 83333, 83334, 83335, 83336, 83337, 83338, 83339]

$ echo 1000000006 | python sum-con-int.py
[250000000, 250000001, 250000002, 250000003]

상대적으로 작은 출력을 가진 예제를 고의적으로 선택했습니다.


1

옥타브, 89 바이트

이것이 옥타브에서 할 수있는 최선입니다. 알고리즘은 xnor와 동일합니다.

x=input('');k=i=1;while x;s=sum(k:i);if s<x;i++;elseif s>x;k++;else;x=0;end;end;disp(k:1)

MATLAB에서 이것은 95 바이트입니다.

x=input('');k=1;i=1;while x;s=sum(k:i);if s<x;i=i+1;elseif s>x;k=k+1;else x=0;end;end;disp(k:i)

MATLAB에서는 입력에 대해 약 0.1 초 동안 실행됩니다 2000000 11000002 .


1

awk, 51 바이트

{while($0!=s+=s<$0?++j:-++i);while(++i-j)r=r i"+"}$0=r j

코드는 출력 형식으로 56 바이트에서 5 바이트를 뺀 값입니다. 해당 형식을 생성하기 위해 4 바이트를 추가로 사용해야했기 때문에 실제로 1 바이트를 절약했습니다. 만세! ;)

실제로 합계가 입력보다 클 때까지 1부터 시작하여 어려운 작업을 수행하고 있습니다. 그런 다음 1부터 시작하여 숫자가 입력보다 작을 때까지 숫자 빼기를 시작합니다. 결과를 찾을 때까지 시작과 끝 번호를 계속 변경하여 인쇄합니다.

사용 예

echo 303 | awk '{while($0!=s+=s<$0?++j:-++i);while(++i-j)r=r i"+"}$0=r j'

예제 출력

48 + 49 + 50 + 51 + 52 + 53

입력을 위해 이것을 시도 1e12했으며 464562+...+1488562거의 즉시 올바른 결과 ( )를 얻었습니다 . 물론 인쇄하는 데 시간이 걸렸지 만 ...


Awk 접근 방식을 좋아하십시오. 바인딩에서 우선 순위를 결정하는 데 문제가 있습니다. 좀 더 명확하게하기 위해 더 많은 괄호가 추가 된 버전을 포함시켜 주시겠습니까? :)
와일드 카드

1
희망이 도움이되기를 바랍니다 : {while($0!=s)s+=(s<$0) ? (++j) : -(++i); while(++i<j)r=r i"+"}$0=r j 항상 체인의 시작에서 뺀 마지막 정수이고, j 는 항상 체인의 끝에 추가 된 마지막 정수입니다
Cabbie407

0

Japt , 33 바이트

이것은 상당히 길지만 Dennis의 Pyth 기술을 사용합니다 ...

1oU à2 £W=Xg o1+Xg1¹x ¥U©W} rª ªU

온라인으로 사용해보십시오! 경고 : 더 큰 입력 (<= 20)의 경우 완료하는 데 시간이 걸리고 완료 될 때까지 브라우저를 정지시킵니다.

언 골프와 설명

1oU à2 £    W=Xg o1+Xg1¹ x ¥ U© W} rª  ª U
1oU à2 mXYZ{W=Xg o1+Xg1) x ==U&&W} r|| ||U

          // Implicit: U = input integer
1oU à2    // Generate a range from 1 to U, and take all combinations of length 2.
mXYZ{     // Map each item X in this range to:
W=Xg o    //  Set variable W to the range of integers starting at the first item in X,
1+Xg1)    //  and ending at 1 + the second item in X.
x ==U&&W  //  If the sum of this range equals U, return W; otherwise, return false.
r||       // Reduce the result with the || operator, returning the first non-false value.
||U       // If this is still false, there are no consecutive ranges that sum to U,
          // so resort to U itself.
          // Implicit: output last expression

보너스 적립 버전 : (38 바이트-5 = 33)

1oU à2 £W=Xg o1+Xg1¹x ¥U©W} rª ªU² q'+

0

줄리아, 92 바이트

x->(t=filter(i->all(j->j==1,diff(sort(i))),partitions(x));collect(t)[indmax(map(length,t))])

이것은 정수를 받아들이고 배열을 반환하는 익명 함수입니다. 호출하려면 이름을 지정하십시오 (예 :) f=x->....

언 골프 드 :

function f(x::Integer)
    # Get all arrays of integers that sum to x
    p = partitions(x)

    # Filter these down to only consecutive runs by checking whether
    # all differences are 1
    t = filter(i -> all(j -> j == 1, diff(sort(i))), p)

    # Find the index of the longest element of t
    i = indmax(map(length, t))

    return collect(t)[i]
end

0

루비, 94 바이트

->n{([*1..n].permutation(2).map{|i,j|[*i..j]if(i..j).reduce(:+)==n}-[p]).max_by{|k|k.size}||n}

언 골프 드 :

-> n {
  ([*1..n].permutation(2).map { |i,j|   # Finds all the possible sets of size 2
     [*i..j] if(i..j).reduce(:+) == n   # Adds a set to an array if sum of the set is n.
   }-[p]                                # Removes nil from the array
  ).max_by { |k|                        # Finds the longest sequence
    k.size
  } || n                                # Returns n if no sequence found.
}

용법:

->n{([*1..n].permutation(2).map{|i,j|[*i..j]if(i..j).reduce(:+)==n}-[p]).max_by{|k|k.size}||n}[25]
=> [3, 4, 5, 6, 7]

0

진지하게, 53-5 = 48 바이트

,;;;╝`;u@n╟(D;)`n(XXk`iu@u@x;Σ╛=[])Ii`╗`ñ╜M`M;░p@X'+j

육각 덤프

2c3b3b3bbc603b75406ec728443b29606e2858586b60697540754
0783be4be3d5b5d29496960bb60a4bd4d604d3bb0704058272b6a

온라인으로 사용해보십시오!

Dennis 's Pyth와 비슷한 무차별 대입 방식입니다.

모든 것은 레지스터 1에 k입력 n을 읽은 다음 [[1],[2,2],[3,3,3],[4,4,4,4],...]최대 목록을 만듭니다 n n.

다음 비트까지 는 레지스터 0에 저장된 함수로, 한 쌍을 취하여 두 요소를 증가시키고, 범위로 변환하고, 범위의 합을 찾고, 그 합이 레지스터 1의 값인지 여부를 확인합니다. 해당 범위를 반환하고 그렇지 않으면 빈 목록을 반환합니다.

마지막 발생까지의 부분 M은 위에서 설명한 멋진 목록 목록에 enumerate함수를 매핑하고 각 목록에서 수행 한 다음 저장된 함수를 그 위에 매핑합니다. 완료되면 각각 비어있는 목록 또는 합산되는 범위의 목록이 있습니다.n 있습니다.

;░빈 목록을 제거합니다. p@X남아있는 첫 번째 목록을 가져옵니다 ( 0@E작동합니다). 보너스를 위해 목록을 문자열로 변환 할 때 각 숫자 사이에 '+j넣습니다 +.


0

ES6, 72 바이트

n=>{for(l=u=1;n;)n>0?n-=u++:n+=l++;return[...Array(u).keys()].slice(l);}

@ Cabbie407의 awk 솔루션의 직선 포트이지만 여기에 형벌이 있기 때문에 서식 보너스가 없습니다.


0

파이썬 3 239 236 215 203 바이트

이것은 약간 성가시다. 나중에 골프를 치러야합니다.

def x(n):
 r=[n]
 for i in range(2,n):
  t=[]
  if i%2*(n%i<1):t=[j+n//i-i//2for j in range(i)]
  elif i%2<1and n%i==i//2:t=[j+n//i-i//2+1for j in range(i)]
  if t[:1]>[0]*(sum(t)==n):r+=t,
 return r[-1]

k당신이 선택하면 때문이다 t[0]빈에 t, 파이썬은 당신을 무례 소리를한다. 다시, 이것은 골프가 필요하다. 덕분에 t[:1]더 이상 무례한 소음이 없습니다! 다른 배열에 대해서만 확인하면됩니다.


0

젤리 , 8 바이트 (비경쟁)

ẆS⁼¥Ðf⁸Ṫ

온라인으로 사용해보십시오!

올바르게 이해하면 (11-5 = 6) 바이트 버전이 될 수 있습니다.

ẆS⁼¥Ðf⁸Ṫj”+

이해를 돕기 위해 벡터화 등식에 대해 비 벡터화 등식을 바꾸고 왼쪽 인수를 첫 번째 인수 또는 항등으로 변경하고 같지 않고 필터 인과 같음 벡터화 및 비 벡터화를위한 필터 아웃. : O
HyperNeutrino

가장 적합한 것을 게시했지만 속도 최적화를 사용한다고 가정 해 봅시다.
Outgolfer Erik


0

PHP, 70 바이트

while(fmod($q=sqrt(2*$argn+(++$p-.5)**2)-.5,1));print_r(range($p,$q));

파이프로 실행 -nR또는 온라인으로 시도 .

단위는 p가에 대한 정수 솔루션을 찾을 때까지 argument==(p+q)*(q-p+1)/2,
다음의 범위 인쇄 p로를 q.


0

Excel VBA, 119-5 = 114 바이트

Subn예상되는 유형의 정수를 입력 하고 셀에 합산되는 가장 긴 연속 숫자 시퀀스를 출력하는 루틴[A1]

Sub a(n)
For i=1To n
s=0
For j=i To n
s=s+j
If s=n Then:For k=i To j-1:r=r &k &"+":Next:[A1]=r &j:End
Next
Next
End Sub
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.