Bölen azaltma


21

N sayısının böleni, 1 ve n dahil olmak üzere n'yi eşit şekilde bölen herhangi bir sayıdır . Bölenlerin sayısı d (n) , bir sayının sahip olduğu bölen sayısıdır. İşte ilk çift için 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

Bölenlerin sayısını bir sayıdan tekrar tekrar çıkarabiliriz. Örneğin:

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

Bu durumda 0'a ulaşmak için 5 adım atıldı.


Negatif olmayan bir sayı verilmiş bir program veya fonksiyon yazın n bu bölenler sayısının tekrarlanan çıkarma tarafından 0 olarak azaltmak için gereken adımların sayısını döndürür.

Örnekler:

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

5
Zorunlu OEIS
Sp3000

Yanıtlar:



6

Python, 49 bayt

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

orlp bir bayt kurtarmaya yardımcı oldu! Sp3000 iki tane daha kazandı. Teşekkürler!


1
İçeri -~girerek n%-~kve aralığın alt sınırını kaldırarak işleri kısaltabilmelidir .
orlp

5

C, 52 bayt

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

4

Pyth, 10 bayt

tl.ulf%NTS

Test odası.

açıklama

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

Julia, 31 bayt

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

Basit yinelemeli uygulama.


2

MATL , 14 bayt

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

Çevrimiçi deneyin!

açıklama

`            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

JavaScript (ES6), 64 51 bayt

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

Neden gereksiz yere kuyruk özyinelemesi kullandığımı sorma.


2

Java, 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
Neden n=new Integer(100000)yerine n=100000?
user8397947

1

05AB1E, 12 10 bayt

Kod:

[Ð>#Ñg-¼]¾

Açıklama:

[           # 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

Çevrimiçi deneyin

Düzenleme: 2 bayt kaydedildi ve @Adnan sayesinde 0 girilen bir hata düzeltildi


Çok hoş! Ben golf biraz çalıştık ve 10 byte için aşağı var: [Ð>#Ñg-¼]¾. Yine de kısaltmanın bir yolu olmalı ...
Adnan

@LuisMendo Evet, çünkü D0Q#kısmı sayacın arttırılmasından sonra. [Ð>#Ñg-¼]¾Kod için çalışması gerektiğini 0rağmen :).
Adnan,

@Adnan: Tüm sayıları n'e kadar üretmeye ve dizinden dizine değere geçmeye ve saymaya dayanan bir sürüm denedim, ancak bu şekilde kısaltmayı başaramadım.
Emigna


1

Mathcad, [tbd] bayt

görüntü tanımını buraya girin


Mathcad byte denklik şeması henüz belirlenmedi. Bir kaba tuş vuruşu denkliğini kullanarak, program yaklaşık 39 "bayt" kullanır. Bu süre zarfında ve programlama operatörleri için her birine yalnızca bir klavye işlemi uygulayın (sırasıyla ctl-] ve ctl-shft- #) - aslında, yalnızca klavyeden bu şekilde girilebileceğini unutmayın.

Gördüğün tam olarak bir Mathcad çalışma sayfasına konan şey. Mathcad denklemleri / programları değerlendirir ve çıktıyı aynı sayfaya (örneğin, '=' değerlendirme operatöründen sonra veya arsa üzerine) koyar.


1

MATL, 13 bayt

tX`t:\ztt]Nq&

Çevrimiçi deneyin

Açıklama:

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 bayt

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

Eski güzelliği kullanmak DivisorSigma. @ MartinBüttner aşağıdaki alternatifleri belirtiyor:

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

1

Hoon , 93 76 bayt

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

Ungolfed:

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

Bir atom alan bir işlevi döndürür r,. Tüm geliştiricilerini içeren bir ara değer oluşturun r([1..n] listesini yapın, sadece (or ri) == 0) öğelerini saklayın. Eğer rsıfır dönüş sıfır, başka r eşit R- (uzunluk bölenler) ile recursing arttırılmış değerini döndürür.

Olduğu gibi kod, n = 100.000 için değerlendirme yapmak için aptalca bir zaman alır, çünkü tamamen büyük sayılar için geliştiriciler bulmak dev bir liste yapar ve üzerinde eşler. Bölenleri memoize etmek n = 10.000 için doğru çıktıyı alır, ancak 100.000 civarında beklemekten zahmet etmedim


1

Haskell, 43 40 39 bayt

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

Basit özyinelemeli yaklaşım. Kullanım örneği: g 16-> 5.

Düzenleme: @Lynn 3 4 bayt kaydetti . Teşekkürler!


Ne dersiniz g(sum$signum.mod n<$>[1..n])?
Lynn,

Oh, ve min 1aslında bir bayt signum, hatta daha kısa
Lynn

1

PowerShell v2 +, 74 67 bayt

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

Diğer cevapların bazılarına kıyasla oldukça uzun görünüyor ...

Girdi alır $n, fordurumdan $ndaha büyük olan bir döngüye girer 0. Her döngü yineleme biz dizi yardımcı $a, her numarası üzerinden daha sonra döngü 1için yukarı $n. Her iç döngü bir bölen olup olmadığını görmek için her sayıya karşı kontrol ederiz ve öyleyse yardımcımızı artırırız $a(Boolean negatifi ve örtük cast-to-int kullanarak). Sonra kaç tane bölen bulduğumuzu çıkardık $n-=$ave sayacımızı artırdık $o++. Sonunda çıktı $o.

Bir Alır uzun bir önemli For döngüsü yapı olduğundan, çalışmasına zaman. Örneğin, n = 10,000makinemde çalışmak (1 yıl eski Core i5) yaklaşık 3 dakika sürüyor.


1

Raket - 126 bayt 98 bayttan aşağı 91 bayt

Son derece saf bir çözüm - muhtemelen düzgün bir algoritma ve bilmediğim bazı hileler ile çok daha fazla kesilebilir

(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))]))

Düzenleme: istek üzerine açıklama. Dediğim gibi, bu son derece saf bir özyinelemeli bir çözüm ve çok daha kısa olabilir.

(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

Daha az dilsiz bir algoritma ile 2: 98 bayt sürümünü düzenleyin (yine de oldukça dilsiz ve kısa olabilir)

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

Açıklama:

(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

Düzenleme 3: değiştirerek 7 bayt Kaydedilen (cdr(build-list x values))ile(build-list x add1)

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

Merhaba ve PPCG'ye hoş geldiniz! Harika yazı! Çözümünüzü açıklayabilir misiniz lütfen? (PS Lisp'i seviyorum!)
NoOneIsHere

@ NoOneIsHere Düzenlendi
kronicmage

0

> <> , 52 + 2 = 54 bayt

Giriş numarasının program başlangıcında yığında bulunması gerekir, bu nedenle -vbayrak için +2 bayt vardır . Çevrimiçi deneyin!

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

4 sinir bozucu bayt, uyum sorunlarını boşa harcıyor. Bah.

Bu, diziyi yığından başlayarak noluşturarak çalışır 0. 0'a ulaşıldıktan sonra, onu açın ve kalan yığının uzunluğunu çıkarın.

Bu arada, O(n^2)zamanla çalışıyor, bu yüzden denemem n = 100000...


-vbir bayt, iki değil.
NoOneIsHere

0

> <> , 36 + 3 = 39 bayt

:?v~ln; >~&
:}\0&
+&>1-:?!^:{:}$%0)&

Uygulama, her yineleme ile nispeten basit sum(n%k>0 for k in range(1,n-1)). -vBayrak başına meta için +3 bayt .

Çevrimiçi deneyin!


0

Ruby, 42 bayt

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

En büyük test durumunda yığın taşması hatası var, 100000işte 49 bayt içindeki yinelemeli bir sürüm . Yine de O(N^2)karmaşıklığı dikkate alarak biraz zaman alıyor .

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

0

Perl 5, 40 bayt

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

Giriş ve çıkış, istenen sayıda kopya listesidir 1.


0

C #, 63 bayt

int F(int n)=>n<1?0:F(Enumerable.Range(1,n).Count(i=>n%i>0))+1;

0

Aslında, 17 bayt

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

Çevrimiçi deneyin! (not: TIO'da son test durumu zaman aşımına uğradı)

Açıklama:

";╗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)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.