주요 요인 뿌리


14

디지털 근에서 영감을 얻은 숫자의 소인수 근은 숫자의 소인수를 취하여 더한 다음 결과 숫자에 대해 프로세스를 반복하여 소수로 끝날 때까지 나타나는 숫자입니다 ( 그것은 그 자신의 유일한 주요 요인으로, 따라서 자신의 주요 요인 루트입니다). 4의 소인수 근은 4이며, 2 * 2 = 2 + 2이며, 1보다 큰 정수 (프라임 팩터가 없기 때문에 또 다른 특수한 경우)의 비 프라임 소인수 근입니다. 소인수 근에 의해 형성된 OEIS 서열은 A029908 입니다.

예를 들어, 24의 주요 요인 루트는 다음과 같습니다.

24=2*2*2*3

2+2+2+3=9=3*3

3+3=6=2*3

2+3=5, and the only prime factor of 5 is 5.  Therefore, the prime factoral root of 24 is 5.  

당신의 작업 :

입력 정수의 소인수 근을 찾는 프로그램 또는 함수를 작성하십시오.

입력:

귀하의 언어가 지원할 2에서 가장 큰 정수 사이의 적절한 방법을 통해 입력되는 정수. 최대 정수 크기가 부적절하게 낮은 언어를 구체적으로 선택하는 것은 허용되지 않습니다 (또한 이 표준 허점을 위반 함 )

산출:

입력의 주요 요인 루트 인 정수입니다.

테스트 사례 :

4   -> 4
24  -> 5
11  -> 11
250 -> 17

채점 :

이것은 이며 바이트 단위의 최저 점수입니다!


3
4예외이므로 답변을 테스트하는 동안 잊어 버리기 때문에 테스트 사례 를 추가 할 수 있습니까 ?
scottinet

1을 1로 출력해야합니까?
내 대명사는 monicareinstate

연결된 OEIS 시퀀스에 따라 @someone, 1에 대해 0을 출력해야합니다
scottinet

2
@someone 도전은 입력이 2 이상이 될 것이라고 말합니다.
Martin Ender

@someone 잠시만 기다려 주셔서 죄송합니다. Martin이 말했듯이, 과제는 입력이 1보다 클 것이므로 입력이 1 일 때의 동작은 정의되지 않는다고 말합니다.
그리폰

답변:



14

하스켈 , 61 바이트

import Data.Numbers.Primes
until=<<((==)=<<)$sum.primeFactors

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

설명

until=<<((==)=<<)함수 소요 f입력에 적용 x즉, 수정 지점에 도달 할 때까지 f x같음 x. primeFactors숫자의 소인수 목록을 반환하고 sum숫자 목록의 합계를 산출합니다.

하지만 잠깐, 왜 until=<<((==)=<<) 일이 그렇게 이상해 보입니까?

우리가 가정하면 f=sum.primeFactors,보다 자연스러운 정의는 것 until(\x->f x==x)f때문에, until술어 (부울을 반환하는 함수), 동일한 입력 및 반환 유형 (예를 들어,이 함수 소요 Int -> Int이러한 유형의) 가치를 한 다음에 함수를 적용 술어가 이행 될 때까지 값.

until(\x->f x==x)f와 동일하고 until(\x->(==)(f x)x)f, 보유하고있는 g (h x) x것처럼 (g=<<h)x우리는 얻는다 until(\x->((==)=<<f)x)f. Eta 변환 후이 됩니다 until((==)=<<f)f. 그러나 이제 우리 (==)=<<가에 적용되는 함수로 취급 하면 , 그리고 와 함께 형식 f임을 until(((==)=<<)f)f다시 알 수 있으므로 다시 쓸 수 있습니다 . 연산자를 사용하여 외부 괄호를 제거하고 대체 하면 위의 솔루션 이 생성됩니다.g (h x) xg=untilh=((==)=<<)x=f(until=<<((==)=<<))f$fsum.primeFactors


4
=<<((==)=<<)$으아 아아아
완전히 인간적인

2
@icrieverytim 설명을 추가했습니다. 이 마법이 어떻게 작용하는지에 대한 추가 질문이 있으시면 하스켈 대화방 에 문의하십시오 .
Laikoni



4

파이썬 2 , 84 바이트

f=lambda n,d=2:n>1and(n%d and f(n,d+1)or d+f(n/d))
i=input()
exec'i=f(i);'*i
print i

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


이것은 꽤 바보 같은 질문 일지 모르지만 어떻게 f=lambda n,d=2:n>1and(n%d and f(n,d+1)or d+f(n/d))작동합니까? Python (주로 Java 및 C #)으로 프로그래밍 한 적이 없으므로이 함수의 결과가 무엇인지 확실하지 않습니다. 이 함수는 입력을 수정하여 n나중에 반환 합니까 , 아니면 n>1and(n%d and f(n,d+1)or d+f(n/d))0 또는 1 또는 0 또는 n다른 부울과 비슷 합니까? Java / C # 에서이 포트가 어떻게 보이는지 시각화하려고하지만 일반적으로 이와 같은 Python 람다를 이해하지 못하기 때문에 불가능합니다.
Kevin Cruijssen

1
@KevinCruijssen 이것은와 동일합니다 n>1 ? (n%d!=0 ? f(n, d+1) : d+f(n/d)) : n>1. 일반적으로 용어 x and yx ? y : x입니다. 대부분의 경우 x and y or z와 같습니다 x ? y : z.
ovs

1
@KevinCruijssen Java 포트는 다음과 같습니다 f=(n,d=2)->n>1?n%d>0?f(n,d+1):d+f(n/d):0.
ovs

그래. 설명 주셔서 감사합니다, 이제 훨씬 더 의미가 있습니다. 그리고 기억 x and y되고 x ? y : x아니라 자바 스크립트에서. 감사!
Kevin Cruijssen

4

자바 (8) 175 144 142 141 바이트

n->{for(int i,t=n,x;;n=t){for(i=2;i<t;t=t%i++<1?0:t);if(t>1|n<5)return n;for(t=0,i=1;i++<n;)for(;n%i<1;n/=i,t+=x)for(x=i;x>9;x/=10)t+=x%10;}}

@Nevay 덕분에 -1 바이트 .

일부 골프 언어의 단일 바이트와 달리 Java는 소수 검사, 소수, 자릿수 등으로 매우 장황하므로 200 미만이면 너무 초라하지 않습니다.
루프를 결합 하고 숫자 합에 대해 분리 된 재귀 방법을 사용하지 않으면 여전히 골프를 칠 수 있습니다 .

설명:

여기에서 시도하십시오.

n->{                // Method with integer as both parameter and return-type
  for(int i,        //  Index-integer `i`
          t=n,      //  Temp integer `t`, starting at the input `n`
          x;        //  Temp integer `x`
      ;             //  Loop (1) indefinitely
      n=t){         //    After every iteration, replace `n` with the value `t`
    for(i=2;        //   Reset `i` to 2
        i<t;        //   Inner loop (2) from 2 to `t` (exclusive)
        t=t%i++<1?  //    If `t` is divisible by `i`:
           0        //     Set `t` to 0
          :         //    Else:
           t        //     Leave `t` the same
    );              //   End of inner loop (2)
    if(t>1          //   If `t` is not 0 (it means it's a prime),
       |n<5)        //   or if `n` is below 5 (for edge-cases `4` and 'prime' `1`)
      return n;     //    Return `n` as result
    for(t=0,        //   Reset `t` to 0
        i=1;        //   Reset `i` to 1
        i++<n;)     //   Inner loop (3) from 2 to `n` (inclusive)
      for(;n%i<1;   //    Inner loop (4) as long as `n` is divisible by `i`
          n/=i,     //      After every iteration: Divide `n` by `i`,
          t+=x)     //      and increase `t` by `x`
        for(x=i;    //     Reset `x` to `i`
            x>9;    //     Inner loop (5) as long as `x` contains more than 1 digit
            x/=10)  //       After every iteration, remove the trailing digit
          t+=n%10;  //      Increase `t` with the trailing digit of `n`
                    //     End of inner loop (5) (implicit / single-line body)
                    //    End of inner loop (4) (implicit / single-line body)
                    //   End of inner loop (3) (implicit / single-line body)
  }                 //  End of loop (1)
}                   // End of method

6
이것이 골프 언어 인 것처럼 장황하게 설명을 작성하는 것을 귀찮게하여 +1.
내 대명사는 monicareinstate

@ 누군가 감사합니다! 누군가 과거에 한 번 Java 답변에 대한 설명을 요청했기 때문에 모든 답변에 추가했습니다. :)
Kevin Cruijssen

i,t=n,x그것은 파이썬에 속해있는 것 같습니다, haha
ETHproductions

@ETHproductions Hehe, 너무 나쁘다 int (Python과 달리) 여전히 선두를 추가해야합니다 . ;)
Kevin Cruijssen

i++<n대신 사용할 수 있습니다 ++i<=n.
Nevay


3

망막 , 30 바이트

{+`(\1|\b11+?\B)+$
$1;$#1$*
;

단항으로 입력 및 출력 .

온라인으로 사용해보십시오! 편의상 10 진수 / 단항 변환을 수행합니다.

설명

{+`(\1|\b11+?\B)+$
$1;$#1$*

{전체 과정이 고정 된 지점에 도달 할 때까지, 즉 문자열을 수정할 실패 할 때까지 지시합니다 망막 루프에서 전체 프로그램을 실행합니다. 결과적으로 프로그램 자체는 현재 값의 주요 요소를 합산하는 한 단계를 계산합니다.

이 단계 자체는 입력의 소인수 분해를 계산합니다. 은 +과 유사 {하지만 문자열을 변경 멈출 때까지에만이 단계를 반복합니다. 정규 표현식 1은 동일한 하위 문자열 (즉, 요인)을 반복적 으로 일치시켜 최종 실행을 일치시킵니다. 이 방법은 순방향 참조로 인해 약간 복잡 \1합니다. 첫 번째 반복에서 그룹 1은 아직 아무것도 캡처하지 않았으므로 \1무조건 실패합니다. 대신, \b11+?\B런의 시작 부분에서 시작하여 최소한 2 1개의을 포함하며 전체 런을 포함하지 않는 가장 작은 하위 문자열 인 일치해야 합니다. 이후 반복에서는로 인해이 대안을 다시 사용할 수 없습니다 \b. 따라서 모든 반복에서 우리는 일치합니다.\1즉, 동일한 하위 문자열을 반복해서 반복합니다. 이 과정은 $우리가 실제 제수를 캡처했는지 확인하기 위해 문자열의 끝 ( )을 정확하게 맞춰야 합니다. 이 다소 까다로운 접근 방식의 이점은 그룹 1이 정확히 n / d 시간, 즉 제수 d를 나눈 후에 남은 것 입니다.

이 일치를 d ( $1), 분리 ;n / d ( $#1$*, $#1사본 을 삽입합니다 ( 1여기서 $#1그룹이 캡처 한 수))로 바꿉니다 1.

이 프로세스는 문자열에서 최종 실행이 그 자체로 프라임 일 때 중지됩니다. 그러면 정규식이 더 이상 일치하지 않기 때문입니다.

;

소수를 합치기 위해해야 ​​할 일은 모든 구분 기호를 제거하는 것입니다.





1

젤리 , 6 바이트

이 답변은 Jelly의 여러 주요 인수 분해 기본 제공 중 하나를 사용하며 빠른 방법을 사용 repeat until the results are no longer unique합니다.

ÆfSµÐL

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


당신이 outgolfed 생각 하지만, 당신의 접근 방식, 그 대답이 작동하는지 확실하지 않습니다
caird coinheringaahing

@cairdcoinheringaahing 방금 그의 대답 (또는 파이썬과 동등한 것)을 1에서 100000까지 확인했으며 작동합니다. 필자 1는 필요한 단계 수가 같고 n( 1한 번만 실행하면 됨) 유일한 단계 라고 생각 합니다. 단계 수가 더 큰 경우는 없습니다 n(예 : 반례가없는 것 같습니다). 아 잘, 나는 outgolfed되었습니다 : D
Sherlock9

글쎄요. 나는이 문제봤을 때 생각 동일한 코드 인을위한 일이지만
케어 드 coinheringaahing

n의 소인수의 합은 항상 n보다 작거나 같으므로 n이 항상 충분하다는 것을 쉽게 증명할 수 있습니다.
Chris

1

MATL , 6 바이트

scottinet 가 필요 이상으로 반복하는 아이디어 를 사용 합니다. 실수를 지적한 Shaggy 에게도 감사드립니다 .

t:"Yfs

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

설명

t       % Take input (implicit). Duplicate
:"      % Do the following that many times
  Yf    %   Array of prime factors
  s     %   Sum of array
        % End (implicit). Display (implicit)

이것은 실패한 것 같습니다 4.
Shaggy

@Shaggy 감사합니다! 그 작업
Luis Mendo

@Shaggy 지금 해결
Luis Mendo

1

PowerShell , 124 바이트

function f($a){for($i=2;$a-gt1){if(!($a%$i)){$i;$a/=$i}else{$i++}}}
for($x=$args[0];$l-ne$x){$l=$x;$x=(f($x))-join'+'|iex}$x

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

PowerShell에는 소인수 분해 기능이 기본적으로 제공되지 않으므로 소인수 친구 에 대한 내 답변의 코드 (맨 위 줄)를 사용하여 인수 분해 계산을 수행합니다.

두 번째 줄은이 프로그램의 핵심입니다. 우리는에서 입력을 $args$x, 다음 for때까지 루프 $l입니다 -n하다며 eQUAL에 $x. (첫 번째 반복 $l$null$x 한 번에 적어도 그래서 우리는거야 루프, 정수).

루프 내부에서 루프 $l = $x끝에 도달했는지 여부를 결정하도록 설정했습니다 . 그리고 우리는의 요소를 얻을 수 $xf($x), -join함께 사람들을 +그리고 |iex그들 (줄여서 Invoke-Expression과 유사 eval). 에 다시 저장됩니다 $x. 따라서 소인수 분해가 합쳐진 "끝"에 도달했습니다. 그런 다음 $x파이프 라인에 배치 하면 출력이 암시 적으로 나타납니다.


0

Mathematica, 35 바이트

#//.x_:>Tr[1##&@@@FactorInteger@x]&

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

(Mathics는 지원하지 않습니다 Tr. 수동으로 구현해야합니다)


4
1##&에 대한 짧은 TimesFixedPoint거의 항상로 단축 할 수있다 //.:#//.x_:>Tr[1##&@@@FactorInteger@x]&
마틴 청산

@MartinEnder 감사합니다! 나는에 대해 이미 알고 Times있었지만 그 FixedPoint트릭에 대해서는 알지 못했습니다 .
user202729 년

코드는 Mathematica로 작성되었습니다. 이것은 수학 함수가 아닙니다. 언어 이름을 Mathematica로 변경하거나 Tr을 Total로 변경해야합니다.
J42161217

@ {no one} 죄송합니다. 언어 이름 (Mathics)이 실수입니다. {i cri evritime}에서 해결했습니다.
user202729


0

루비 , 63 바이트

->n{n.times{n=n.prime_division.map{|x|x.reduce:*}.sum};n}

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

Prime # prime_division-rprime 을 사용하기 위해 +6 바이트에 플래그를 사용합니다 .

prime_division[prime, exponent](예를 들어 24 개의 인자가 [2, 2, 2, 3]있으므로 24 개의 쌍을 반환 합니다. [[2, 3], [3, 1]]) 각 단계에서 해당 쌍의 멤버를 곱하고 결과를 합산합니다.


0

자바 스크립트 (ES6), 63 바이트

f=n=>(q=(p=(m,x)=>m<x?0:m%x?p(m,x+1):x+p(m/x,x))(n,2))^n?f(q):q
<input id=i type=number min=0 value=0 oninput="o.innerText=f(i.value)">
<p id=o></p>

언 골프 드 :

f=n=>(                  // Recursive function `f`
    p=(m,x=2)=>(        //   Recursive function `p`, used to sum prime factors
        m<x?            //     If m (the number to be factored) is less than x (the current
            0           //     iteration), return 0
        :m%x?           //     Else if m doesn't divide x
            p(m,x+1)    //     run the next iteration
        :               //     Else (if m divides x)
            x+p(m/x,x)  //     Divide m by x and repeat the current iteration
    ),
    q=p(n),             //   Set q to the sum of the prime factors of n
    q^n?                //   If q != n then
        f(q)            //     repeat f with q
    :                   //   else
        q               //     return q
)

0

자바 8, 101 바이트

n->{for(int i=n;i-->0;n=f(n,2));return n;}int f(int n,int d){return n>1?n%d>0?f(n,d+1):d+f(n/d,2):0;}

@ovs 포트 의 놀라운 Python 2 답변 .

설명:

여기에서 시도하십시오.

n->{                  // Method with integer as both parameter and return-type
  for(int i=n;i-->0;  //  Loop the input amount of times
    n=f(n,2)          //   And change `n` that many times with a separate method call
  );                  //  End of loop
  return n;           //  Then return the integer `n` as result
}                     // End of method

int f(int n,int d){   // Separated method with 2 integer parameters and integer return-type
                      // (`d` is 2 when we initially call this recursive-method)
  return n>1?         //  If input `n` is larger than 1:
    n%d>0?            //   And it's not divisible by `d`:
     f(n,d+1)         //    Do a recursive-call with `n, d+1`
    :                 //   Else:
     d                //    Sum `d` with
      +f(n/d,2)       //    a recursive call with `n/d, 2`
   :                  //  Else:
    0;                //   Simply return 0
}                     // End of separated method
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.