숫자가 연속적인 정수의 곱인지 확인


18

6, 12, 20, 30, 42, 56, 60, 90, 120 등과 같은 일부 숫자는 아래와 같이 연속 정수의 곱으로 표현할 수 있습니다.

6   = 2 * 3  
12  = 3 * 4  
30  = 5 * 6
60  = 3 * 4 * 5  
90  = 9 * 10  
120 = 4 * 5 * 6  

제품이 지정된 숫자와 동일한 연속 정수 목록을 출력하는 프로그램 또는 함수를 작성하십시오.

이 논리에 적합하지 않은 숫자의 예는 다음과 같습니다.

99  = 9 * 11  (Product of non-consecutive numbers)
121 = 11 * 11 (Same numbers)
2   = 1 * 2   (Product of itself and 1)
13  = 13      (Product of only one number)

의 경우에는 2 = 2 * 11을 곱한 정수가 동일한 결과를 제공하므로 유효한 결과로 간주하지 않습니다. 이 질문에서는 제품에서 정수> = 2 만 고려합니다.

입력

유효한 32 비트 양의 정수 표준 입력, 함수 인수 등이 될 수 있습니다.

산출

연속 정수>> 2의 목록 (오름차순 또는 내림차순). 연속 정수의 여러 조합이있는 경우 하나의 인스턴스 만 제공하십시오 . 더 많이 제공하면 괜찮습니다.

제한 사항

모든 유효한 입력 (양수 32 비트 정수) 에 대해 표준 컴퓨터 에서 실행하려면 코드가 적당한 시간 (<5 분)이 소요 됩니다. 연속적인 정수 곱이있는 경우 코드는 제한 시간 내에 하나 이상을 출력해야합니다. 그렇지 않으면 코드는 제한 시간 내에 출력없이 종료되어야합니다.

이것은 코드 골프이므로 바이트 단위의 가장 짧은 코드가 이깁니다.


1
언급 한 바와 같이이 퍼즐은이 사이트 형식에 적합하지 않습니다. 이 사이트는 우승자를 결정하는 좋은 방법 (예 : 가장 짧은 코드, 가장 빠른 코드, 대부분의 투표 등)이있는 컨테스트를위한 사이트입니다. 귀하는 그러한 방법을 제공하지 않았습니다.
Chris Jester-Young

2
이것을 코드 골프 (가장 짧은 코드)로 만드는 것이 좋습니다.하지만 약간의 제한을 두어야합니다. 예 : 숫자 0-1000000, 최대 실행 시간 10 초 등
Level River St

이 질문을 구하기 위해 편집하려고했습니다. 하지만 이전에 질문 한 적이 없으므로 표시되는 내용이 있으면 수정하십시오.
벡터화

@bitpwner 오타 몇 개를 제외하고는 괜찮아 보입니다. 다시 열기로 투표
seequ

5
나는 당신이 의미하는 것 같아요 30=5*6.
Kyle Kanos

답변:


8

자바-124

String f(int t){int s=2,h=3,p=s,i;String o="";for(;p!=t&&s*s<t;p=p<t?p*h++:p/s++);if(p==t)for(i=s;i<h;o+++=i+" ");return o;}

2에서 시작하면 시작 번호가 대상의 제곱근> 또는 대상에 정확하게 도달 할 때까지 반복됩니다. 제품이 낮 으면 높은 수를 곱하여 증가시킵니다. 높으면 시작 번호로 나누고 증가시킵니다.

예를 들어 30의 경우 다음을 확인합니다.

2*3     = 6 (too low, multiply)
2*3*4   = 24 (too low, multiply)
2*3*4*5 = 120 (too high, divide)
3*4*5   = 60 (too high, divide)
4*5     = 20 (too low, multiply)
4*5*6   = 120 (too high, divide)
5*6     = 30 (bingo!)

공백으로 구분 된 요인 문자열을 오름차순으로 출력합니다.

줄 바꿈으로 :

String p(int t){
    int s=2,h=3,p=s,i;
    String o="";
    for(;p!=t&&s*s<t;p=p<t?p*h++:p/s++);
    if(p==t)
        for(i=s;i<h;o+=i+" ");
    return o;
}

7

Python- 104 97 95 92 시도해보십시오

n=input()
s=i=2
c=1
while s<n:
 s*=i+c;c+=1
 if s==n:print range(i,i+c)
 if s/n:i+=1;s,c=i,1

n예를 들어 미리 120으로 설정되어 있으면 프로그램은 다음 두 가지 솔루션을 출력합니다.

[2, 3, 4, 5]
[4, 5, 6]

죄송합니다. 입력을 정의하는 것을 잊었습니다.
Falko

1
c = c + 1, i = i + 1을 c + = 1, i + = 1로
교체

1
예, 생각하지 않았습니다 +=. 그러나 나는 ++파이썬에서 그리워합니다 ...
Falko

1
if s>=n그리고 if s/n당신은 같은 수의 문자의 모든 솔루션을 제공 할 수 있도록 동일합니다.
isaacg

1
로 변경 s=s*(i+c)하여 세 문자를 저장할 수 있습니다 s*=i+c.
El'endia Starman

4

Clojure의 - 127 109 바이트

(defn f[x](first(for[r[range]y(r 2 x)v[(take-while #(<=(apply * %(r y %))x)(r y x))]:when(=(apply * v)x)]v)))

예:

(map f [6 12 30 60 90 120 1404816 99 121 2 13])
=> ((2 3) (3 4) (5 6) (3 4 5) (9 10) (2 3 4 5) (111 112 113) nil nil nil nil)

설명:

이것은 기본적이고 최적화되지 않은 기능적 접근 방식입니다. 나는 간단한 루프를 사용하여 모든 가능성의 게으른 목록을 만들고 (너무 큰 숫자를 제공하여 오버플로를 방지하는 모든 조합을 건너 뛰고) 첫 번째 옵션을 사용합니다. 가능성이 없으면 nil을 반환합니다.

http://tryclj.com/ 에서 테스트하기가 가장 쉽습니다 .


또한 모든 가능성을 반환 할 수 있음을 알았습니다 .120 바이트 102 바이트 이지만 결과를 중첩 목록으로 제공합니다.

(defn f[x](for[r[range]y(r 2 x)v[(take-while #(<=(apply * %(r y %))x)(r y x))]:when(=(apply * v)x)]v))

예:

(map f [6 12 30 60 90 120 1404816 99 121 2 13])
=> (((2 3)) ((3 4)) ((5 6)) ((3 4 5)) ((9 10)) ((2 3 4 5) (4 5 6)) ((111 112 113)) () () () ())

3

CJam, 31 바이트

q~:Qmq,A,m*{2f+~,f+_:*Q={p}*}%;

그것은 무차별 접근 방식이지만 공식 Java 인터프리터를 사용하면 실행 시간이 불과 몇 초 입니다.

온라인 인터프리터를 사용하여 코드를 테스트 하려면 입력을 합리적으로 낮게 유지해야합니다. 2 26 미만은 여전히 내 컴퓨터에서 작동합니다.

$ TIME="%e s"
$ time cjam product.cjam <<< 2
0.12 s
$ time cjam product.cjam <<< 6
[2 3]
0.10 s
$ time cjam product.cjam <<< 120
[2 3 4 5]
[4 5 6]
0.12 s
$ time cjam product.cjam <<< 479001600
[2 3 4 5 6 7 8 9 10 11 12]
0.68 s
$ time cjam product.cjam <<< 4294901760
[65535 65536]
1.48 s
$ time cjam product.cjam <<< 4294967295
1.40 s

작동 원리

q~:Q      " Read from STDIN, interpret the input and save the result in variable “Q”.     ";
mq,       " Push the array [ 0 1 2 … (Q ** 0.5 - 1) ].                                    ";
A,m*      " Push the array [ 0 1 2 … 9 ] and take the Cartesian product.                  ";
{         " For each pair in the Cartesian product:                                       ";
  2f+     " Add 2 to each component.                                                      ";
  ~       " Dump the array's elements on the stack.                                       ";
  ,       " Push the array [ 0 1 2 … n ], where “n” is the topmost integer on the stack.  ";
  f+      " Add “m” to each element, where “m” is the integer below the array.            ";
  _:*     " Duplicate the resulting array and push the product of its elements.           ";
  Q={p}*  " If the product is equal to “Q”, print.                                        ";
}%        " Collect the remaining results into an array.                                  ";
;         " Discard the array from the stack.                                             ";

2

자바, 162

정수 배열 또는 null연속 된 숫자가없는 경우 배열을 반환 합니다.

int[] e(int n){for(int i=1;i<n;i++){int h=i+1,c=1,s=i;while(s<n){c++;s*=h++;}if(s==n){int[] o=new int[c];for(int j=0;j<c;j++){o[j]=h-j-1;}return o;}}return null;}

언 골프 :

int[] execute(int input){
    for(int i=1; i<input; i++){
        int highest = i+1, count = 1, sum = i;
        while(sum < input){
            count++;
            sum *= highest++;
        }
        if(sum == input){
            int[] numbers = new int[count];
            for(int j=0; j<count; j++){
                numbers[j] = highest-j-1;
            }
            return numbers;
        }
    }
    return null;
}

2

C 105 (110)는 그것을 시도

n,k,l;main(i){for(scanf("%d",&n);++i<n;)for(k=1,l=i;k<n;)if(k*=l++,k==n)for(l=n;l/=i;)printf("%d ",i++);}

144 보너스 : 이것은 모든 수를 반복하고 일치하는 제품을 찾습니다.

main(i,j,k,l,m){for(scanf("%d",&m);++i<13;)for(j=0;++j<46341-i;){for(l=k=1;k<=i;)l*=j+k++;if(l==m)for(puts(""),k=0;k<i;)printf("%d ",j+k+++1);}}

멋지고 매우 간단하고 우아합니다! 내가 그것에 던진 작은 숫자 중 일부를 위해 확실히 일했습니다. 그런 다음 50815512 (7128 x 7129)를 주었고 무한 루프에 빠졌습니다. 7128 x 7129 x 7130 = 362314600560을 계산하려고 할 때 오버플로입니까?
Todd Lehman

감사! k < n때문에 상태 가 너무 높아지는 것 같습니다 k *= l++. 나는 오랫동안 서명을 오래 붙일 수는 없었지만 인생을 망칠 것입니다.
Bebe

2

PHP 258 문자, 201은 계승 함수를 계산하지 않습니다.

수학적으로 "번호를 동일 연속 요인"을 표현하는 가장 간단한 방법은 X!/Y!어디에서 X가장 많은 수이며, Y가장 낮은 마이너스입니다. 불행히도 나는 풀이를 배우기 전에 미적분 복용을 중단 Z = X!/Y!했으므로 조금 무차별해야했습니다.

지저분한, 골 판이없는 버전 :

<?php
// PHP does not define a factorial function, so I've kludged one in.
function fact($n) {
    $r = 1;
    for($i=$n; $i>1; $i--) {
        $r *= $i;
    }
    return $r;
}

$input = intval($argv[1]);

if( $input < 2 ) { die('invalid input'); }

printf("input: %s\n", $input);

$max=min(ceil(sqrt($input)),170); // integer breakdown for > 170!
$grid = array();
for( $x=1;$x<$max;$x++ ) {
    for( $y=$max;$y>=1;$y-- ) {
        if( $y >= $x ) { continue; } // Skip results that would be < 1
        $cur = fact($x)/fact($y);
        if( $cur > $input ) { // too large!
            echo "\n"; continue 2;
        }
        if( $cur == $input ) { //just right
            printf("%7d\n\nFound %s == %s\n", $cur, implode(' * ', range($y+1, $x)), $cur);
            break 2;
        }
        printf("%7d ", $cur);
    }
    echo "\n";
}
if($cur!=$input){printf("No consecutive factors produce %d\n", $input);}

출력 예 :

input: 518918400

  2
  3       6
  4      12      24
  5      20      60     120
  6      30     120     360     720
  7      42     210     840    2520    5040
  8      56     336    1680    6720   20160   40320
  9      72     504    3024   15120   60480  181440  362880
 10      90     720    5040   30240  151200  604800 1814400 3628800
 11     110     990    7920   55440  332640 1663200 6652800 19958400 39916800
 12     132    1320   11880   95040  665280 3991680 19958400 79833600 239500800 479001600
 13     156    1716   17160  154440 1235520 8648640 51891840 259459200
 14     182    2184   24024  240240 2162160 17297280 121080960
 15     210    2730   32760  360360 3603600 32432400 259459200
 16     240    3360   43680  524160 5765760 57657600 518918400

Found 9 * 10 * 11 * 12 * 13 * 14 * 15 * 16 == 518918400

골프 :

<? function f($n){$r=1;for($i=$n;$i>1;$i--)$r*=$i;return $r;}$i=$argv[1];$m=min(ceil(sqrt($i)),170);for($x=1;$x<$m;$x++){for($y=$m;$y>0;$y--){if($y>=$x)continue;$c=f($x)/f($y);if($c>$i)continue 2;if($c==$i){$y++;echo "$y $x";break 2;}}}if($c!=$i){echo 'No';}

산출:

[sammitch@vm ~/golf] time php consecutive_golf.php 518918400
9 16
real 0m0.019s
user 0m0.011s
sys  0m0.009s
[sammitch@vm ~/golf] time php consecutive_golf.php 518918401
No
real 0m0.027s
user 0m0.017s
sys  0m0.011s

나는 런타임이 꽤 빠를 것이라고 기대하지 않았다!


이 아이디어도 저의 생각에 떠 올랐고 매우 효율적으로 보이지만 "자격을 갖추기에는"충분히 단축 될 수있을 것 같습니다.
bebe

1
@bebe 그것은 258 자이며 PHP에는 그렇게 나쁘지 않습니다. 내가 게으르지 않고 완고하지 않았다면 실제 언어로 할 것입니다 . : P
Sammitch

X! / Y! Y는 N <= <X 인 정수 N의 곱이다. 그게 전혀 도움이 되나요?
trichoplax

2

피시스 , 35

JvwKr2 4W-ZJ~@KgJZ1=YurGHK=Zu*NTY)Y

참고 : 내 코드는 실제로 연속 정수> = 2의 표현으로 입력의 가장 짧은 표현을 발견하므로 유효하지 않은 입력에서는 1 요소 목록을 인쇄합니다. 아마도 오랜 시간이 지나면 가능합니다. 문제 설명에 입력이 유효하다고 표시되었으므로 이것이 정상이라고 가정합니다.

간단한 설명 :

기본적으로 프로그램은 범위의 상한 및 하한을 저장하고 감소를 사용하여 범위에있는 숫자의 곱을 계산하고 필요에 따라 끝점을 조정 한 다음 제품이 입력과 같아 질 때까지 반복합니다.

긴 설명 :

각 코드 스 니펫에 대해 더 자세한 설명과 추론뿐만 아니라 동등한 파이썬을 제공 할 것입니다.

Jvw => J=eval(input())

Pyth에서 입력을받는 표준 방법.

Kr2 4=> K=range(2,4)=>K=[2,3]

첫 번째 이상한 부분이 있습니다. 엔드 포인트를 별도의 변수로 저장하는 대신 목록의 요소로 저장합니다. 그 이유는 곧 분명해질 것입니다. 또한 Pyth에서 간단한 할당을 수행하는 대신 K[2 3)범위를 사용하여 문자를 저장합니다.

W-ZJ=> while Z-J=>while Z!=J

이 시점에서 "Z 란 무엇입니까? 아직 정의하지 않았습니다."라고 물을 수 있습니다. Pyth에서는 모든 변수가 사전 정의되어 있습니다. Z는 0으로 시작합니다. 그러나 Z는 나중에 제품 값으로 설정되므로 목록이 올바른 값에 도달하면 while 루프가 종료됩니다.

~@K>JZ1 => K[J>Z] += 1

여기에 별도의 변수가 아닌 목록에 값을 저장하는 이유가 있습니다. 제품이 현재 너무 높거나 낮은 지 여부에 따라 두 끝점 중 하나를 증가시키고 싶습니다. 엔드 포인트가 별도의 변수라면 목록 인덱싱의 마법으로 인해 짧아 질 수 있습니다. 또한이 확인은 제품보다 먼저 이루어지고 Z가 0으로 초기화된다는 사실은 K가 [2,4]제품을 처음 가져갈 때까지 올바른 엔드 포인트가되도록합니다.

=YurGHK=> Y=reduce(lambda G,H: range(G,H),K)=>Y=range(K[0],K[1])

이제 제품을 인수 할 실제 목록이 필요하며 성공하면 인쇄 될 것입니다. 분명히 범위 함수를 사용할 것입니다. 까다로운 점은 범위 기능에 대한 입력을 얻는 데 있습니다. 목록을 색인화하여이를 수행하는 확실한 방법은입니다 =Yr'K@K1. 그러나이 두 요소 목록에서 축소 기능을 사용하면 문자로 단축 할 수 있습니다.

=Zu*NTY => Z=reduce(lambda N,T: N*T,Y)

그리고 이제,이 사건의 모든 요점에서 목록의 제품을 찾기위한 축소 작업입니다.

) => 종료하는 동안

Y => print(Y)

성공하면 목록을 인쇄하십시오.

예제 실행 :

$ cat seq_prod 
JvwKr2 4W-ZJ~@K>JZ1=YurGHK=Zu*NTY)Y

$ cat seq_prod | python3 pyth.py
<debug stuff>
==================================================
[9, 10, 11, 12, 13, 14, 15, 16]

1

자바-115

void f(int i){for(int j=2;j<i;j++)for(int k=1,x=j;(x*=j+k)<i;k++);if(x==i)for(i=j;i<j+k;i++)System.out.println(i);}

약간 덜 골프 :

void f(int i) {
 for(int j=2; j<i; j++)
  for(int k=1, x=j; (x*=j+k) < i; k++);
   if(x == i)
    for(i=j; i<j+k; i++)
     System.out.println(i);
}

예, 함수를 작성하고 리턴 값을 인쇄했습니다. 전에는 여기서 본 적이 없습니다.
seequ

나는 아무것도 인쇄 할 수 없다 ... 그러나 그것이 나에게 약간의 출력을 줄 경우, 당신은 골프를 System.out.println밟을 수 System.out.print있고 끝의 세미콜론은 for(int k=1,x=j;(x*=j+k)<i;k++)불필요 할뿐만 아니라 오류를 일으킨다.
Qwix

이것은 나를 위해 작동하지 않습니다. x, j, k마지막에 범위를 벗어난 if/for때문에 블록 ;. 를 제거하면 ;아무것도 인쇄되지 않습니다.
Geobits

1
@Qwix로 변경하면 print숫자가 함께 실행되지 않도록 공백 문자를 추가해야합니다.
Geobits

1
@Geobits 좋은 지적! 아마 나에게 약간의 결과를 주었을 것입니다.
Qwix

1

MATLAB (88)

코드는 숫자가에 저장 x되고에 출력 될 것으로 예상 l합니다.

for n=2:12
r=ceil(x^(1/n))
for s=-3*n:n
l=r-s+(1:n)
if prod(l)==x
return 
end;end;l=x;end

이후 13! > 2^32에만 12 개까지 길이 2의 제품이 코드 검색이 코드는 주위의 0.001s의 지속적인 실행이 있습니다.


1

스칼라-86

def p(n:Int)=(2 to n).flatMap(i=>(i to n).map(i to _-1).find(_.product==n)).headOption

이 코드는 매우 비효율적이지만 최적화하면 몇 문자 만 추가됩니다. 기능적 접근 방식을 사용하여 가능한 모든 연속 시퀀스의 곱을 확인합니다. (연속적인 정수 시퀀스는 스칼라에서 Range 객체로 표시됩니다)

언 골프 :

def product(n: Int): Option[Range] = {
  def productStartingAt(start: Int): Option[Range] =
    (start to n-1).map(start to _).find(_.product == n)

  (2 to n).flatMap(i => productStartingAt(i)).headOption
}

1

CJam 계산 시간이 길어 은 현재 많은 수에서 작동하지 않습니다.

가장 짧은 CJam 코드입니다. http://cjam.aditsu.net/ 에서 테스트 하십시오 . 입력을 A로 정의; 0 내지 A-1의 모든 수의 어레이를 생성하는 단계; 발길질 0; 배열의 모든 숫자를 곱할 때까지 가장 작은 숫자를 차는 것은 A보다 크지 않습니다. 그것이 A보다 큰지 확인하는 단계; 그렇지 않으면 0에서 A-2까지 배열을 작성하십시오. 답을 찾을 때까지 반복합니다. 아무것도 발견되지 않으면 예외가 발생합니다. 나는 숫자 사이에 공백이 필요하다고 생각하지 않았으므로 32 자 길이의 두 번째 코드에 포함됩니다.

ri:A,{)\;,1{;(;_{*}*_A>}gA<}g

ri:A,{)\;,1{;(;_{*}*_A>}gA<}g" "*

귀하의 답변이 너무 느려서 유효하지 않습니다. 유효한 32 비트 정수에서 5 분 이내에 완료해야합니다. 3600060000 == 60000 * 60001에 얼마나 걸립니까?
isaacg

공정 포인트, 나는 그것을 재 작업하고 그것이 짧은 경우 게시합니다
kaine

다시 작업하려면 그때 까지이 답변을 삭제하거나 현재 유효하지 않은 것으로 표시하십시오.
isaacg

1

다트-102 자

이것은 느린 구현입니다. 더 빨라질 수 있지만 더 많은 문자가 필요합니다 (루프 만 할 때까지 i*i<n)

f(n,[i=2]){
  t(j,p,a)=>p<n?t(++j,p*j,a..add(j)):p>n?f(n,i+1):a;
  for(;i<n;i++)if(n%i<1)return t(i,i,[i]);
}

(102 개의 문자는 줄 바꿈과 선행 공백이 없습니다).

그것을 사용하려면 다음과 같이하십시오.

main() {
  print(f(123456789*123456790));
}

0

자바 스크립트, 88

골프 코드 :

function f(a){for(i=2;i<a;i++){b=[1];for(j=i;j>1;j--)if((b[0]*=b[i-j+1]=j)==a)alert(b)}}

보다 쉽게 ​​읽을 수있는 코드

function f(a){
    for(i=2;i<a;i++){
        b=[1];
        for(j=i;j>1;j--)
            if((b[0]*=b[i-j+1]=j)==a)
                alert(b);
    }
}

2에서 입력 숫자까지의 각 숫자에 대해 현재 숫자에서 다시 2까지의 연속 정수 곱을 찾습니다.이 곱이 입력 숫자와 같으면 원래 입력 숫자와 함께 일련의 연속 숫자가 출력됩니다. .

입력 번호와 제품이 입력 번호 인 연속 정수가 출력됩니다.

예를 들어 f (120)은 "120,5,4,3,2"텍스트로 경고를 생성 한 다음 "120,6,5,4"텍스트로 두 번째 경보를 생성합니다.

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