Pengurangan pembagi


21

Pembagi angka n adalah angka yang membagi n secara merata , termasuk 1 dan n itu sendiri. Jumlah pembagi d (n) adalah berapa banyak pembagi yang dimiliki suatu angka. Inilah d (n) untuk pasangan pertama 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

Kami berulang kali dapat mengurangi jumlah pembagi dari suatu angka. Sebagai contoh:

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

Dalam hal ini dibutuhkan 5 langkah untuk mencapai 0.


Tulis program atau fungsi yang diberi nomor nonnegatif n kembalikan jumlah langkah yang diperlukan untuk menguranginya menjadi 0 dengan pengurangan berulang dari jumlah pembagi.

Contoh:

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

5
Tautan OEIS yang wajib: A155043
Sp3000

Jawaban:



6

Python, 49 byte

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

orlp membantu menghemat satu byte! Dan Sp3000 menyimpan dua lagi. Terima kasih!


1
Seharusnya bisa mempersingkat hal dengan memindahkan ke -~dalam n%-~k, dan menghapus batas bawah rentang.
orlp

5

C, 52 byte

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

4

Pyth, 10 byte

tl.ulf%NTS

Suite uji.

Penjelasan

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 byte

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

Implementasi rekursif langsung.


2

MATL , 14 byte

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

Cobalah online!

Penjelasan

`            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 byte

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

Jangan tanya kenapa saya tidak perlu menggunakan rekursi ekor.


2

Jawa, 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
Kenapa n=new Integer(100000)bukannya n=100000?
user8397947

1

05AB1E, 12 10 byte

Kode:

[Ð>#Ñg-¼]¾

Penjelasan:

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

Cobalah online

Sunting: 2 byte disimpan dan bug dengan input 0 diperbaiki berkat @Adnan


Sangat bagus! Saya mencoba untuk golf itu sedikit, dan mendapatkannya ke 10 bytes: [Ð>#Ñg-¼]¾. Harus ada cara untuk membuatnya lebih pendek ...
Adnan

@LuisMendo Ya, itu karena D0Q#bagiannya adalah setelah kenaikan counter. The [Ð>#Ñg-¼]¾kode harus bekerja untuk 0meskipun :).
Adnan

@ Adnan: Saya mencoba versi berdasarkan menghasilkan semua jumlah upto n dan pergi dari indeks ke nilai di indeks dan menghitung, tetapi tidak berhasil membuatnya lebih pendek seperti itu.
Emigna


1

Mathcad, [tbd] byte

masukkan deskripsi gambar di sini


Skema ekivalensi byte Mathcad belum ditentukan. Menggunakan kesetaraan keystroke kasar, program ini menggunakan sekitar 39 "byte". Perhatikan bahwa sementara dan untuk operator pemrograman masing-masing hanya mengambil satu operasi keyboard untuk memasukkan (ctl-] dan ctl-shft- #, masing-masing) - memang, mereka hanya dapat dimasukkan dengan cara ini dari keyboard.

Apa yang Anda lihat adalah persis apa yang akan diletakkan di lembar kerja Mathcad. Mathcad mengevaluasi persamaan / program dan menempatkan output pada lembar yang sama (misalnya, setelah operator evaluasi '=' atau di plot).


1

MATL, 13 byte

tX`t:\ztt]Nq&

Cobalah online

Penjelasan:

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 byte

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

Memanfaatkan yang baik tua DivisorSigma. @ MartinBüttner mencatat alternatif berikut:

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

1

Hoon , 93 76 byte

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

Tidak Disatukan:

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

Mengembalikan fungsi yang mengambil atom r,. Buat nilai menengah yang berisi semua devisors dari r(Buat daftar [1..n], simpan hanya elemen di mana (mod ri) ​​== 0). Jika rnol, kembalikan nol, jika tidak kembalikan nilai berulang dari pengulangan dengan r sama dengan r- (pembagi panjang).

Kode as-is membutuhkan jumlah waktu yang bodoh untuk mengevaluasi n = 100.000, seluruhnya karena menemukan pembagi angka besar membuat daftar raksasa dan memetakannya. Memoizing para pembagi mendapat hasil yang benar untuk n = 10.000, tapi saya tidak repot menunggu sekitar 100.000


1

Haskell, 43 40 39 byte

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

Pendekatan rekursif sederhana. Contoh penggunaan: g 16-> 5.

Sunting: @ Lynn disimpan 3 4 byte. Terima kasih!


Bagaimana dengan g(sum$signum.mod n<$>[1..n])?
Lynn

Oh, dan min 1sebenarnya satu byte lebih pendek dari signum, bahkan
Lynn

1

PowerShell v2 +, 74 67 byte

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

Tampaknya cukup panjang dibandingkan dengan beberapa jawaban lain ...

Mengambil input $n, memasuki forlingkaran dengan kondisi yang $nlebih besar dari 0. Setiap iterasi loop kami atur helper $a, lalu loop melalui setiap angka dari 1hingga $n. Setiap loop batin kami memeriksa setiap angka untuk melihat apakah itu pembagi, dan jika demikian kami menambah pembantu kami $a(menggunakan negasi Boolean dan implisit cast-to-int). Lalu, kita kurangi berapa banyak pembagi yang kita temukan $n-=$adan tambahkan penghitung kita $o++. Akhirnya, kami output $o.

Butuh waktu lama untuk dieksekusi, karena ini adalah konstruksi for-loop yang signifikan. Misalnya, menjalankan n = 10,000komputer saya (Core 1 i5 lama) membutuhkan waktu hampir 3 menit.


1

Racket - 126 byte Turun ke 98 byte 91 byte

Solusi yang sangat naif - mungkin bisa ditebang dengan algoritma yang layak dan beberapa trik lisp yang saya tidak tahu

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

Edit: penjelasan dengan permintaan. Seperti yang saya katakan, ini adalah solusi rekursif yang sangat naif dan bisa jauh lebih pendek.

(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

Sunting versi 2: 98 byte dengan algoritme yang kurang bodoh (masih sangat bodoh dan bisa lebih pendek)

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

Penjelasan:

(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

Sunting 3: Disimpan 7 byte dengan menggantinya (cdr(build-list x values))dengan(build-list x add1)

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

Halo, dan selamat datang di PPCG! Pos yang bagus! Bisakah Anda jelaskan solusinya? (PS I love Lisp!)
NoOneIsHere

@NoOneIsHere Diedit dalam
kronicmage

0

> <> , 52 + 2 = 54 byte

Nomor input harus ada pada stack pada awal program, jadi ada +2 byte untuk -vflag. Cobalah online!

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

4 byte yang mengganggu terbuang untuk masalah perataan. Bah

Yang ini bekerja dengan membangun urutan dari nke 0di tumpukan. Setelah 0 tercapai, letakan dan ouput panjang tumpukan yang tersisa.

Ngomong-ngomong, ini berjalan O(n^2)tepat waktu, jadi saya tidak akan mencoba n = 100000...


-vadalah satu byte, bukan dua.
NoOneIsHere

0

> <> , 36 + 3 = 39 byte

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

Implementasi relatif mudah, dengan setiap iterasi menjadi sum(n%k>0 for k in range(1,n-1)) . +3 byte untuk -vbendera, per meta .

Cobalah online!


0

Ruby, 42 byte

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

Ada kesalahan stack overflow pada case uji terbesar 100000, jadi inilah versi berulang dalam 49 byte . Butuh beberapa saat, mengingat O(N^2)kompleksitasnya.

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

0

Perl 5, 40 byte

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

Input dan output adalah sebagai daftar jumlah salinan yang diperlukan 1.


0

C #, 63 byte

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

0

Sebenarnya, 17 byte

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

Cobalah online! (catatan: waktu uji kasus terakhir habis pada TIO)

Penjelasan:

";╗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)
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.