유사 요인


39

수학 문제 나 수수께끼에 때때로 나타나는 호기심 많은 숫자가 있습니다. 의사 팩토리얼 (N)은 숫자 1 내지 N의 최소 (즉, 가장 낮은) 공통 배수이며; 다시 말해, 그것은 1에서 N까지의 모든 숫자를 인자로 갖는 가장 낮은 숫자입니다.

예를 들어 pseudofactorial (7) = 3 * 4 * 5 * 7은 7과 같습니다! 단, 2와 6은 다른 용어로 포함되어 있기 때문에 제거되었습니다.

pseudofactorial (N)을 계산하는 프로그램을 작성하면 항상 가장 짧은 코드가 승리합니다.

다음은 사용하기위한 간단한 목록입니다. 더 많은 테스트 사례는 OEIS의 A003418에 있습니다.

계승:

  1. 1
  2. 2
  3. 6
  4. 24
  5. 120
  6. 720
  7. 5040

유사 요인 :

  1. 1
  2. 2
  3. 6
  4. 12
  5. 60
  6. 60
  7. 420

6
나는 확실히 나는 이유를 이해 아니에요 26배수의 목록에서 제거되었습니다. 규칙을 명확하게 설명해 주시겠습니까?
Maltysen

2
@Mattysen, psuedofactorial (N)은 1부터 N까지의 숫자를 인자로 갖는 가장 작은 수입니다 (해당 숫자의 최소 공배수). 그것은 기술적 정의이지만, 제가 쓴 방식은 그것이 계승과 비슷하다는 것을 암시했습니다.
Tony Ruth


4
프로그래밍 퍼즐 및 코드 골프에 오신 것을 환영합니다! 이것은 좋은 첫 번째 도전입니다!
Alex A.

1
첫 번째 도전은 HNQ의 정상에 도달했습니다. 좋은!
Daniel M.

답변:




8

C (x86 포함), 52 바이트

d(n,k,b,t){for(b=k=1;b;++k)for(t=n,b=0;t;b+=k%t--);}

1부터 숫자를 확인합니다. 각 숫자에 대해 n에서 1까지의 모든 숫자로 나누고 나머지를 합산합니다. 합계가 0 일 때 정지합니다.

용법:

main()
{
    printf("%d\n", d(7)); // outputs 420
}

값을 어떻게 반환하는지는 명확하지 않습니다 ( return구문 이 없습니다 ).

x86의 호출 규칙은 함수가 eax레지스터에 값을 반환해야한다고 말합니다 . 편리하게, 나누기 명령어 idiv는의 입력을 기대하고 eax결과를 eax(몫) 및 edx(나머지)로 출력합니다 . 마지막 반복 분할 k로는 1, 그래서 eax함수가 종료되면 올바른 값이 포함됩니다.

이것은 디버그 최적화에서만 작동합니다 (디버그 모드에서는 출력 421).


n, k, b 및 t의 유형을 선언하지 않고 어떻게 벗어날 수 있습니까?
Tony Ruth

C는 기본 -int 규칙을 가지고 있습니다. 생략 된 모든 유형은 int기본적으로 반환 값을 포함합니다. 소위 "구식"구문을 사용하여 선언 된 함수 인수에 대해 작동합니다. 명시 적으로 정의 된 타입을 가진 선언은 다음과 int d(n,k,b,t) int n,k,b,t; {...}
같습니다

당신이 전화 컨벤션을 이용하고 있다면 이것은 단지 "C"가 아닌 "C (cdecl)"로 표시되어야합니다
Steve Cox

@SteveCox는 모두 cdeclstdcall것 같아요, 그래서 리턴 값에 대해 동일한 방법을 사용 x86충분하다
anatolyg가

7

하스켈, 20 바이트

f x=foldr1 lcm[1..x]

사용 예 : map f [1..7]-> [1,2,6,12,60,60,420].

lcm하스켈 의 비결.


6

Python + SymPy, 45 바이트

import sympy
lambda n:sympy.lcm(range(1,n+1))

상당히 자명하다.


파이썬 2, 57 54 바이트

i=r=input();exec't=r\nwhile r%i:r+=t\ni-=1;'*r;print r

Ideone에서 테스트하십시오 .

작동 원리

입력 값은 변수 ir에 저장됩니다 .

exec다음 코드를 r 번 실행합니다 .

t=r
while r%i:r+=t
i-=1

하지만 다르다 R1 , 우리는의 초기 값을 추가 R (저장된 t 필요에 따라)만큼을 R 의 배수로 만들기 위해 자체 I를 . 결과는 분명히 t 의 배수입니다 .

r 의 최종 값은 [1, ..., n] 범위의 모든 정수의 배수이며 , 여기서 n 은 입력입니다.


1
타사 라이브러리 또는 exec트릭을 사용하지 않으면 78 바이트 솔루션 from fractions import*;lambda n:reduce(lambda x,y:x*y/gcd(x,y),range(1,n+1),1)lcm(x,y) = x*y/gcd(x,y)있습니다.
Bakuriu 2016 년

6

파이썬, 46 바이트

g=lambda n,c=0:n<1or(c%n<1)*c or g(n,c+g(n-1))

여러 개 cg(n-1)직접 찾으십시오 . 그 전에이 방법은 0을 여러 배수로 잘못 찾지 만 0은 Falsey이므로 or단락 또는 (c%n<1)*c건너 뛸 것 c==0입니다.


50 바이트 :

g=lambda n,i=1:n<1or(i*n%g(n-1)<1)*i*n or g(n,i+1)

마찬가지로 데니스의 솔루션 ,하지만 재귀 함수있다. 계산 갖는 g(n-1)가장 작은 여러에 대한, 외모 i*nn그 또한의 배수이다 g(n-1). 정말 느려.

n대신 에 배수를 확인하여 4 바이트의 Dennis에게 감사합니다 g(n-1).


5

J, 9 바이트

[:*./1+i.

직접적인 접근. 숫자 범위를 [0, ..., n-1]만든 다음 각각에 1을 더하고 LCM을 사용하여 줄입니다.

용법

   f =: [:*./1+i.
   f 7
420


4

수학, 13 바이트

LCM@@Range@#&

단지 구성이 동일하지 않습니다 LCMRange와 함께 @*?
Maltysen

1
LCM로 전달되는 목록에서 요소 단위로 작동합니다 Range. 즉, 1에서 n 사이의 x에 대한 lcm ( x ) 만 반환합니다 . 또한 익명 함수를 닫을 누락 이 있습니다. 13 바이트 와 같은 것이 작동합니다. &LCM@@Range@#&
마일



3

옥타브, 27 바이트

@(x)lcm(1,num2cell(1:x){:})

로 호출 할 수있는 익명 함수를 만듭니다 ans(N).

온라인 데모

설명

이 용액 사이의 모든 번호 목록 작성 1x( 1:x갖는 셀 어레이로) 변환을 num2cell. 그런 다음 {:}인덱싱은 lcm최소 공통 배수를 계산하기 위해 여러 입력 인수로 전달되는 쉼표로 구분 된 목록을 만듭니다 . 항상 두 개 이상의 입력 인수가 필요 하기 lcm때문에 1은 항상 첫 번째 인수로 전달됩니다 lcm.


1
그래서 lcm옥타브에 2 개 이상의 입력을 받아 들인다! 흥미로운
Luis Mendo

@LuisMendo Yup 2+
Suever

3

MATLAB, 49 바이트

@(x)find(~any(bsxfun(@rem,1:prod(1:x),(1:x)')),1)

bsxfun
flawr

3

펄 6 , 13 바이트

{[lcm] 1..$_}

1부터 입력 (포함)까지의 범위를 만든 익명 코드 블록을 사용하여 범위를 줄입니다 &infix:<lcm>.

예:

#! /usr/bin/env perl6
use v6.c;

my &postfix:<p!> = {[lcm] 1..$_}

say 1p!; # 1
say 2p!; # 2
say 3p!; # 6
say 4p!; # 12
say 5p!; # 60
say 6p!; # 60
say 7p!; # 420

say 10000p!; # 5793339670287642968692270879...
# the result from this is 4349 digits long


2

자바 스크립트 (ES6), 92 88 80 74 69 바이트 :

감사합니다 @ConorOBrien 및 @Neil

y=>(g=(a,b)=>b?g(b,a%b):a,[...Array(y)].map((_,i)=>y=y*++i/g(y,i)),y)

b?g(b,a%b):a바이트를 저장합니다.
Neil

y*++i/g(y,i)더 많은 바이트를 절약합니다.
Neil

1

05AB1E, 20 바이트

Lpvyi¹LÒN>¢àN>*ˆ}}¯P

설명

Lpv                    # for each item in isprime(range(1,N)): N=7 -> [0,1,1,0,1,0,1]
   yi                  # if prime
     ¹LÒN>¢            # count occurrences of the prime 
                         in the prime-factorization of range(1,N):
                         p=2 -> [0,1,0,2,0,1,0]
           àN>*ˆ       # add max occurrence of that prime multiplied by the prime 
                         to global array: N=7 -> [4,3,5,7]
                }}     # end if/loop
                  ¯P   # get product of global array

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


1

Minkolang 0.15 , 12 바이트

12 바이트 솔루션 이 2 개 있으며 둘 다 포함했습니다.

1n[i1+4$M]N.

여기 사용해보십시오!

설명

1               Push 1
 n              Take number from input
  [             For loop that repeats n times
   i1+          Push loop counter + 1
      4$M       Pop b, a and push lcm(a,b)
         ]      Close for loop
          N.    Output as number and stop.

얻을 수있는만큼 간단합니다.


11nLd[4$M]N.

여기 사용해보십시오!

설명

11              Push two 1s
  n             Take number from input
   L            Pop b, a and push range from a to b, inclusive
    d           Duplicate top of stack (n)
     [4$M]      Pop b, a and push lcm(a,b), n times
          N.    Output as number and stop.

세 번째 해결책은 이것에서 파생 될 수 있습니다 : a를 제거 하고 current 뒤에 a 1를 추가하십시오 . 두 경우 모두 for 루프가 너무 여러 번 실행되므로 더 적은 수의 시간이 필요하며 더 적은 시간으로 실행하려면 2 바이트 () 바로 앞이 필요 합니다.dd1-[


1

루비, 25 바이트

g=->n{(1..n).reduce :lcm}

루비, 25 바이트

g=->n{n<1?1:a[n-1].lcm n}

1
안녕하세요, PPCG에 오신 것을 환영합니다! 첫 번째 게시물! 함수 이름을 지정할 필요가 없으므로를 제거 할 수 있습니다 g=.
NoOneIsHere6

익명의 기능이 허용됩니다.
아웃 골퍼 에릭

1

GameMaker 언어, 60 바이트

for(b=k=1;b;++k){b=0for(t=argument0;t;b+=k mod t--)}return k

아나 톨릭의 답의 논리를 바탕으로합니다.


1

PHP, 61 52 48 바이트

@ user59178 덕분에 9 바이트를 절약하고 루프를 병합하여 4 바이트를 절약했습니다.

function핵심 단어 로 인해 PHP의 재귀가 커집니다 . 반복을 사용합니다.
그리고 "작은"몇 가지 트릭으로, 나는 심지어 Arnauld 's JS를 이겼 습니다 .

while(++$k%++$i?$i>$argv[1]?0:$i=1:$k--);echo$k;

명령 행 인수에서 입력을받습니다. 로 실행하십시오 -r.

고장

while(++$k%++$i?    # loop $i up; if it does not divide $k
    $i>$argv[1]?0       # break if $i (smallest non-divisor of $k) is larger than input
    :$i=1               # while not, reset $i and continue loop with incremented $k
    :$k--);         # undo increment while $i divides $k
echo$k;         # print $k

언 골프

그것은 실제로 하나에 두 개의 루프입니다.

while($i<=$argv[1]) # loop while $i (smallest non-divisor of $k) is not larger than input
    for($k++,       # loop $k up from 1
        $i=0;$k%++$i<1;);   # loop $i up from 1 while it divides $k
echo$k;             # print $k

참고 : 중복에 대한 답변에서 복사


1

AWK, 42 바이트

{for(x=n=1;n<=$1;)if(x%n++){x++;n=1}$0=x}1

명령 줄 사용법 :

awk '{for(x=n=2;n<=$1;)if(x%n++){x++;n=2}$0=x}1' <<< NUM

나는 AWK해결책을 찾지 못했고 질문의 사본이 어제 게시되었습니다. 그래서 이것을 함께 던질 것이라고 생각했습니다. 19내 상자 에서 다소 느리게 해결 되지만 작동합니다.




0

Hoon , 67 바이트

|*
*
(roll (gulf 1 +<) |=({a/@ b/_1} (div (mul a b) d:(egcd a b))))

목록을 작성하고 [1..n]lcm으로 목록을 접으십시오. 불행히도 Hoon stdlib에는 내가 사용할 수있는 사전 빌드가 없습니다 : /



0

QBIC , 35 32 바이트

이것은 나를 여기로 데려왔다.

:{p=0[a|~q%b|p=1]]~p=0|_Xq\q=q+1

설명:

:        Get cmd line param as number 'a'
{        Start an infinite DO loop
p=0      Sets a flag that shows if divisions failed
[a|      FOR (b=1; b<=a; b++)
~q%b     IF 'q' (which starts at 1 in QBIC) is not cleanly divisible by 'b'
|p=1     THEN Set the flag
]]   Close the FOR loop and the IF, leave the DO open
~p=0     IF 'q' didn't get flagged
|_Xq     THEN quit, printing 'q'
\q=q+1   ELSE raise 'q', redo
         [DO Loop implicitly closed by QBIC]

완전히 나누지 않았을 q때 테스트를 중단하는 버전이 b있습니다. 또한, 테스트의 순서 b의에 대한이 q높은 것을 전제로 반전 b(테이크들에 의해 더 열심히 분할하는 것 ' 2, 3, 4다음의 경우 예를 들어 %2=0, %4!0... 반대 순전히 부사장.).

:{p=0[a,2,-1|~q%b|p=1┘b=2]]~p=0|_Xq\q=q+1



0

8 번째 , 23 바이트

암호

1 ' lcm rot 2 swap loop

이 코드는 TOS에서 결과 의사 팩토리얼을 남깁니다.

사용법과 예

ok> 7 1 ' lcm rot 2 swap loop .
420

또는 더 명확하게

ok> : pseudofact 1 ' n:lcm rot 2 swap loop ;

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