제수 감소


21

숫자 n 의 제수는 1과 n 자체를 포함하여 n 을 균등하게 나누는 임의의 숫자입니다 . 제수의 수 d (n) 는 숫자의 제수 입니다. 첫 커플 n에 대한 d (n) 은 다음과 같습니다 .

n    divisors    d(n)
1    1           1
2    1, 2        2
3    1, 3        2
4    1, 2, 4     3
5    1, 5        2
6    1, 2, 3, 6  4

숫자에서 제수를 반복적으로 뺄 수 있습니다. 예를 들면 다음과 같습니다.

16                  = 16
16 - d(16) = 16 - 5 = 11
11 - d(11) = 11 - 2 = 9
 9 - d( 9) =  9 - 3 = 6
 6 - d( 6) =  6 - 4 = 2
 2 - d( 2) =  2 - 2 = 0

이 경우 0에 도달하는 데 5 단계가 걸렸습니다.


음수가 아닌 n 을 주면 프로그램이나 함수를 쓰면 제수의 수를 반복해서 빼서 0으로 줄이는 단계 수를 반환합니다.

예 :

0, 0
1, 1
6, 2
16, 5
100, 19
100000, 7534

5
의무적 OEIS 링크 : A155043
Sp3000

답변:



6

파이썬, 49 바이트

f=lambda n:n and-~f(sum(n%~x<0for x in range(n)))

orlp는 바이트를 절약하는 데 도움이되었습니다! Sp3000은 두 가지를 더 절약했습니다. 감사!


1
이동에 의해 일을 단축 할 수 있어야 -~로를 n%-~k하고,이 범위의 하한 제거.
orlp

5

C, 52 바이트

g,o;l(f){for(g=o=f;o;f%o--||--g);return f?1+l(g):0;}

4

Pyth, 10 바이트

tl.ulf%NTS

테스트 스위트.

설명

tl.ulf%NTS
tl.ulf%NTSNQ  implicit variables at the end
           Q  obtain the input number
  .u      N   repeat the following until result no longer unique:
         S        generate range from 1 to N
     f            filter for:
      %NT             T in that range, which N%T is truthy (not zero)
    l             length of that list
                  that means, we found the number of "non-divisors" of N
tl            number of iterations, minus 1.

3

줄리아, 31 바이트

f(n)=n<1?0:f(sum(n%(1:n).>0))+1

간단한 재귀 구현.


2

MATL , 14 바이트

`t~?x@q.]t:\zT

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

설명

`            T  % Infinite loop
 t~?    ]       % Duplicate number. Is it non-zero?
    x@q.        % If so: delete number, push iteration index minus 1, break loop
         t:\    % Duplicate, range, modulo (remainder). Divisors give a 0 remainder
            z   % Number of non-zero elements; that is, of non-divisors

2

자바 스크립트 (ES6), 64 51 바이트

f=n=>n&&[...Array(m=n)].map((_,i)=>m-=n%++i<1)|f(m)+1

왜 꼬리 재귀를 불필요하게 사용했는지 묻지 마십시오.


2

자바, 147 93

a->{int k,i,n=new Integer(a),l=0;for(;n!=0;n-=k)for(l+=k=i=1;i<n;)if(n%i++==0)++k;return l;}

3
n=new Integer(100000)대신에 n=100000?
user8397947

1

05AB1E, 12 10 바이트

암호:

[Ð>#Ñg-¼]¾

설명:

[           # start infinite loop
 Ð          # triplicate current number
  >#        # increase by 1 and break if true
    Ñg      # get number of divisors
      -     # subtract number of divisors from number
       ¼    # increase counter
        ]   # end loop
         ¾  # print counter

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

편집 : 2 바이트가 저장되고 @ Adnan 덕분에 입력 0이 수정 된 버그


아주 좋아요! 나는 약간의 골프를 시도했고 10 바이트로 줄 [Ð>#Ñg-¼]¾였습니다. 그래도 더 짧아 질 방법이 있어야합니다 ...
Adnan

@LuisMendo 예, D0Q#카운터가 증가한 이후 부분 이기 때문 입니다. [Ð>#Ñg-¼]¾코드가 작동해야 0하지만 :).
Adnan

@ Adnan : 나는 n까지의 모든 카운트를 생성하고 인덱스에서 인덱스에서 값으로 올라가고 카운트 업하는 것을 기반으로 버전을 시도했지만 그 방법으로 더 짧게 만들지는 못했습니다.
Emigna


1

Mathcad, [tbd] 바이트

여기에 이미지 설명을 입력하십시오


Mathcad 바이트 등가 체계는 아직 결정되지 않았습니다. 대략적인 키 스트로크 동등성을 사용하여 프로그램은 약 39 바이트를 사용합니다. while과 프로그래밍 연산자는 각각 하나의 키보드 조작 만 입력하고 (ctl-]와 ctl-shft- #) 각각 키보드를 통해서만 입력 할 수 있습니다.

당신이 보는 것은 정확하게 Mathcad 워크 시트에 내려 놓은 것입니다. Mathcad는 방정식 / 프로그램을 평가하고 동일한 시트에 출력을 넣습니다 (예 : '='평가 연산자 또는 플롯).


1

MATL, 13 바이트

tX`t:\ztt]Nq&

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

설명:

t               % Duplicate input
 X`      ]      % while loop, consumes 1 input
   t:\z         % calculates n-d(n), by counting number non-divisors
       tt       % dupe twice, for while loop condition, next iteration and to keep in stack
          Nq&   % get stack size, decrement, display that value

1

Mathematica, 35 바이트

If[#<1,0,#0[#-0~DivisorSigma~#]+1]&

좋은 옛날을 사용 DivisorSigma합니다. @ MartinBüttner는 다음 대안을 참고합니다.

If[#<1,0,#0[#-DivisorSum[#,1&]]+1]&
f@0=0;f@n_:=f[n-DivisorSum[n,1&]]+1

1

Hoon , 93 76 바이트

|=
r/@
?~
r
0
+($(r (sub r (lent (skim (gulf 1^r) |=(@ =(0 (mod r +<))))))))

언 골프 드 :

|=  r/@
?~  r
  0
=+  (skim (gulf 1^r) |=(@ =(0 (mod r +<))))
+($(r (sub r (lent -))))

아톰을 취하는 함수를 반환합니다 r. r( 만약 목록 [1..n] 의 모든 고안자를 포함하는 중간 값을 작성하십시오 ((mod ri) ​​== 0 인 요소 만 유지)). r0이 0 이면 , 그렇지 않으면 r이 동일한 r- (길이 제수)로 되풀이되는 증분 값을 반환합니다.

코드는있는 그대로 n = 100.000을 평가하는 데 시간이 오래 걸린다. 큰 숫자에 대한 생성자를 찾는 것은 거대한 목록을 만들고 그 위에 매핑하기 때문이다. 제수를 메모하면 n = 10.000에 대한 올바른 출력을 얻지 만 100.000을 기다리는 것을 귀찮게하지 않았습니다.


1

하스켈, 43 40 39 바이트

g 0=0;g n=1+g(sum$min 1.mod n<$>[1..n])

간단한 재귀 접근. 사용 예 : g 16-> 5.

편집 : @Lynn은 3 4 바이트를 저장했습니다 . 감사!


어때요 g(sum$signum.mod n<$>[1..n])?
Lynn

아, 그리고이 min 1실제로 이상의 바이트 짧은 signum도,

1

PowerShell v2 +, 74 67 바이트

param($n)for($o=0;$n-gt0){$a=0;1..$n|%{$a+=!($n%$_)};$n-=$a;$o++}$o

다른 답변에 비해 꽤 긴 것 같습니다 ...

입력 을 받고 보다 큰 조건 $nfor루프를 시작합니다 . 우리가 helper를 설정 한 각 루프 반복 은 모든 숫자를 반복 합니다 . 각 내부 루프는 모든 숫자를 검사하여 제수인지 확인하고, 그렇다면 부울 부정과 암시 적 캐스트 투 인트를 사용하여 도우미를 증가시킵니다 . 그런 다음 찾은 약수를 빼고 카운터를 증가시킵니다 . 마지막으로을 출력 합니다.$n0$a1$n$a$n-=$a$o++$o

중요한 for-loop 구문이므로 실행 하는 시간 이 오래 걸립니다 . 예를 들어 n = 10,000내 컴퓨터 (1 년 된 Core i5) 에서 실행 하는 데 거의 3 분이 걸립니다.


1

라켓 -126 바이트 이하 98 바이트 91 바이트

매우 순진한 솔루션-아마도 알 수없는 괜찮은 알고리즘과 lips 트릭으로 많이 줄일 수 있습니다.

(define(g x[c 0][d 0][i 2])(cond[(= x 0)c][(= i x)(g d(+ 1 c))][(=(modulo x i)0)(g x c d(+ 1 i))][else(g x c(+ 1 d)(+ 1 i))]))

편집 : 요청에 의한 설명. 내가 말했듯이, 이것은 매우 순진한 재귀 솔루션이며 훨씬 짧을 수 있습니다.

(define (g x [c 0] [d 0] [i 2]) ;g is the name of the function - arguments are x (input), c (counter for steps), d (non-divisor counter), i (iterator)
  (cond
    [(= x 0) c] ;once x gets to 0 c is outputted
    [(= i x) (g d (+ 1 c))] ;if iterator reaches x then we recurse with d as input and add 1 to c
    [(= (modulo x i) 0) (g x c d (+ 1 i))] ;checks if iterator is non divisor, then adds it to d and increments iterator
    [else(g x c (+ 1 d) (+ 1 i))])) ;otherwise just increments iterator

편집 2 : 덜 멍청한 알고리즘으로 98 바이트 버전 (아직 꽤 멍청하지만 짧을 수 있음)

(define(g x)(if(< x 1)0(+ 1(g(length(filter(λ(y)(>(modulo x y)0))(cdr(build-list x values))))))))

설명:

(define (g x) ;function name g, input x
  (if (< x 1)
      0 ;returns 0 if x < 1 (base case)
      (+ 1 ;simple recursion - adds 1 to output for each time we're looping
         (g (length ;the input we're passing is the length of... 
              (filter (λ (y) (> (modulo x y) 0)) ;the list where all numbers which are 0 modulo x are 0 are filtered out from...
                             (cdr (build-list x values)))))))) ;the list of all integers up to x, not including 0

편집 3 :로 대체 (cdr(build-list x values))하여 7 바이트 저장(build-list x add1)

(define(g x)(if(< x 1)0(+ 1(g(length(filter(λ(y)(>(modulo x y)0))(build-list x add1)))))))

안녕하세요, PPCG에 오신 것을 환영합니다! 좋은 포스트! 솔루션을 설명해 주시겠습니까? (PS I Lisp를 좋아합니다!)
NoOneIsHere5

@NoOneIsHere 편집 시간
kronicmage 2016 년

0

> <> , 52 + 2 = 54 바이트

프로그램 시작시 입력 번호가 스택에 있어야하므로 -v플래그에 +2 바이트가 있습니다. 온라인으로 사용해보십시오!

:0)?v~ln;>~$-]
03[}\::
@@:$<    v?=0:-1}+{~$?@@01%@:

정렬 문제로 인해 4 개의 성가신 바이트가 낭비됩니다. 바.

이 사람은에서 순서를 구축하여 작동 n0스택에. 0에 도달하면 팝하고 나머지 스택의 길이를 출력합니다.

그건 그렇고, 그것은 제 O(n^2)시간에 달려서 시도하지 않을 것입니다 n = 100000...


-v2가 아닌 1 바이트입니다.
NoOneIsHere 여기


0

루비, 42 바이트

f=->n{n<1?0:1+f[n-(1..n).count{|i|n%i<1}]}

가장 큰 테스트 사례에는 스택 오버플로 오류가 100000있으므로 49 바이트 내의 반복 버전이 있습니다 . 그러나 O(N^2)복잡성을 고려하면 시간이 걸립니다 .

->n{c=0;c+=1 while 0<n-=(1..n).count{|i|n%i<1};c}

0

펄 5, 40 바이트

sub f{@_?(1,f((1)x grep@_%$_,1..@_)):()}

입력 및 출력은 필요한 사본 수의 목록입니다 1.



0

실제로 17 바이트

";╗R`╜%`░l;"£╬klD

온라인으로 사용해보십시오! (참고 : TIO에서 마지막 테스트 케이스 시간 초과)

설명:

";╗R`╜%`░l;"£╬klD
"          "£╬     while top of stack is truthy, call the function:
 ;╗                  push a copy of n to reg0
   R                 range(1,n+1) ([1,n])
    `  `░l             push the number of values where the following is truthy:
     ╜%                  k mod n
                       (this computes the number of non-divisors of n)
          ;            make a copy
              klD  push entire stack as list, count number of items, subtract 1
                   (the result is the number of times the function was called)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.