การลดตัวหาร


21

ตัวหารของตัวเลขnคือตัวเลขใด ๆ ที่แบ่งnเท่า ๆ กันรวมถึง 1 และnเอง จำนวนตัวหารd (n)คือจำนวนตัวหารจำนวนที่มี นี่คือd (n)สำหรับคู่แรก 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

ในกรณีนี้ใช้เวลา 5 ขั้นตอนในการไปถึง 0


เขียนโปรแกรมหรือฟังก์ชั่นที่ได้รับหมายเลขที่ไม่ติดลบnส่งคืนจำนวนขั้นตอนที่ต้องใช้เพื่อลดให้เป็น 0 โดยการลบจำนวนตัวหารซ้ำ

ตัวอย่าง:

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

5
หน้าที่เชื่อมโยง OEIS: A155043
Sp3000

คำตอบ:


1

เยลลี่, 10 9 ไบต์

1 ไบต์ขอบคุณที่เดนนิส♦

ท่าเรือคำตอบของฉันใน Pyth

ÆDLạµÐĿL’

ลองออนไลน์!

ชุดทดสอบ

คำอธิบาย

_ÆDL$$ÐĿL’
      ÐĿ    Repeat the following until result no longer unique:
 ÆD             Yield the array of the divisors
   L            Yield the length of the array
_               Subtract that from the number
        L   Number of iterations
         ’  Minus one.

6

Python ขนาด 49 ไบต์

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

orlp ช่วยประหยัด byte! และ Sp3000 ช่วยชีวิตอีกสองคน ขอบคุณ!


1
ควรจะสั้นลงสิ่งต่าง ๆ โดยการย้าย-~เข้าn%-~kและลบขอบเขตล่างของช่วง
orlp


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

JavaScript (ES6), 64 51 ไบต์

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

อย่าถามฉันว่าทำไมฉันถึงต้องใช้การเรียกหางซ้ำโดยไม่จำเป็น



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 ไบต์และแก้ไขข้อบกพร่องด้วยอินพุต 0 ขอบคุณ @Adnan


ดีมาก! ผมพยายามที่จะเล่นกอล์ฟมันเล็กน้อยและได้รับมันลงไป 10 [Ð>#Ñg-¼]¾ไบต์: จะต้องมีวิธีการที่จะทำให้มันสั้นลง ...
Adnan

@ LuisMendo ใช่นั่นเป็นเพราะD0Q#ส่วนหนึ่งเป็นเพราะการเพิ่มขึ้นของตัวนับ [Ð>#Ñg-¼]¾รหัสควรจะทำงานสำหรับ0แม้ว่า :)
Adnan

@Adnan: ฉันลองรุ่นที่สร้างจากการนับทั้งหมดจนถึง n และเปลี่ยนจากดัชนีเป็นค่าที่ดัชนีและนับ แต่ไม่ได้จัดการให้สั้นลงด้วยวิธีนั้น
Emigna


1

Mathcad, [tbd] ไบต์

ป้อนคำอธิบายรูปภาพที่นี่


แบบแผนความเท่าเทียมกันของไบต์ Mathcad ยังไม่ได้กำหนด การใช้การกดแป้นพิมพ์แบบคร่าว ๆ โปรแกรมใช้ประมาณ 39 "ไบต์" โปรดทราบว่าตัวดำเนินการในขณะที่และสำหรับการเขียนโปรแกรมใช้การดำเนินการของแป้นพิมพ์เดียวเท่านั้นในการป้อนข้อมูล (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

ฮุน , 93 76 ไบต์

|=
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 -))))

ส่งคืนฟังก์ชันที่ใช้อะตอม rผลตอบแทนที่ได้ฟังก์ชั่นที่ใช้อะตอม,สร้างค่ากลางที่มี devisors ทั้งหมดของr(Make list [1..n], เก็บเฉพาะองค์ประกอบที่ (mod ri) ​​== 0) ถ้าrเป็นศูนย์ส่งคืนศูนย์มิฉะนั้นส่งคืนค่าที่เพิ่มขึ้นของการเรียกซ้ำด้วย r เท่ากับ r- (ตัวหารความยาว)

รหัสตาม - ใช้เวลาโง่ประเมิน n = 100.000 ทั้งหมดเนื่องจากการค้นหา devisors สำหรับคนจำนวนมากทำให้รายการใหญ่และแผนที่เหนือ การจำตัวหารจะได้ผลลัพธ์ที่ถูกต้องสำหรับ n = 10.000 แต่ฉันไม่ต้องรอประมาณ 100,000


1

Haskell, 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])ล่ะ
ลินน์

โอ้และmin 1จริง ๆ แล้วหนึ่งไบต์สั้นกว่าsignumแม้
Lynn

1

PowerShell v2 +, 74 67 ไบต์

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

ดูเหมือนจะค่อนข้างยาวเมื่อเทียบกับคำตอบอื่น ๆ ...

จะเข้า$n, เข้าสู่forห่วงกับเงื่อนไขที่ว่ามีค่ามากกว่า$n 0แต่ละวงซ้ำเราตั้งผู้ช่วย$aแล้วห่วงผ่านจำนวนจากทุกขึ้นไป1 $nแต่ละวงด้านในเราตรวจสอบกับทุกหมายเลขเพื่อดูว่ามันเป็นตัวหารหรือไม่และถ้าเป็นเช่นนั้นเราจะเพิ่มผู้ช่วยของเรา$a(โดยใช้การปฏิเสธแบบบูลีน จากนั้นเราจะลบวิธีการหลายตัวหารที่เราได้พบและเพิ่มเคาน์เตอร์ของเรา$n-=$a สุดท้ายเราเอาท์พุท$o++$o

ใช้เวลานานในการดำเนินการเนื่องจากเป็นโครงสร้างที่สำคัญสำหรับลูป ตัวอย่างเช่นการรันn = 10,000บนเครื่องของฉัน (Core 1 i5 เก่า) ใช้เวลาเกือบ 3 นาที


1

แร็กเก็ต - 126 ไบต์ลดลงถึง 98 ไบต์ 91 ไบต์

ทางออกที่ไร้เดียงสาอย่างยิ่ง - อาจถูกลดทอนลงมากด้วยอัลกอริธึมที่เหมาะสมและลูกเล่นบางอย่างที่ฉันไม่รู้

(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: บันทึก 7 ไบต์โดยแทนที่(cdr(build-list x values))ด้วย(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 ฉันรักเสียงกระเพื่อม!)
NoOneIsHere ที่

@NoOneIsHere มีการแก้ไขใน
kronicmage

0

> <> , 52 + 2 = 54 ไบต์

ต้องป้อนหมายเลขอินพุตในสแต็กเมื่อเริ่มต้นโปรแกรมดังนั้นจึงมี +2 ไบต์สำหรับ-vแฟล็ก ลองออนไลน์!

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

4 ไบต์ที่น่ารำคาญที่สูญเสียไปกับปัญหาการจัดตำแหน่ง Bah

อันนี้ทำงานโดยการสร้างลำดับจากnถึง0ในกอง เมื่อถึง 0 แล้วให้นำออกมาแล้วดึงความยาวของสแต็กที่เหลือออกมา

มันวิ่งO(n^2)ตามเวลาดังนั้นฉันจะไม่ลองn = 100000...


-vคือหนึ่งไบต์ไม่ใช่สอง
NoOneIsHere ที่

0

> <> , 36 + 3 = 39 ไบต์

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

sum(n%k>0 for k in range(1,n-1))การดำเนินการค่อนข้างตรงไปตรงมาด้วยซ้ำแต่ละคน 3 ไบต์สำหรับ-vธงต่อเมตา

ลองออนไลน์!


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

Perl 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.