ขั้นตอนนี้ใช้เวลากี่ขั้นตอนจาก n ถึง 1 โดยการลบตัวหารที่ยิ่งใหญ่ที่สุดออกไป


50

แรงบันดาลใจจากคำถามนี้มากกว่าที่คณิตศาสตร์


ปัญหา

ให้เป็นจำนวนธรรมชาติn ≥ 2ใช้ตัวหารที่ใหญ่ที่สุดของn- ซึ่งจะแตกต่างจากnตัวเอง - nและลบได้จาก 1ทำซ้ำจนกว่าคุณจะได้รับ

คำถาม

มันไม่กี่ขั้นตอนใช้เวลาไปถึงจำนวนที่กำหนด1n ≥ 2

ตัวอย่างโดยละเอียด

n = 30ให้

ตัวหารที่ยิ่งใหญ่ที่สุดของ:

1.   30 is 15  -->  30 - 15 = 15
2.   15 is  5  -->  15 -  5 = 10
3.   10 is  5  -->  10 -  5 =  5
4.    5 is  1  -->   5 -  1 =  4
5.    4 is  2  -->   4 -  2 =  2
6.    2 is  1  -->   2 -  1 =  1

มันต้องใช้เวลา6 ขั้นตอน1ในการเข้าถึง

อินพุต

  • การป้อนข้อมูลเป็นจำนวนเต็มที่nn ≥ 2
  • โปรแกรมของคุณควรรองรับการป้อนข้อมูลจนถึงค่าจำนวนเต็มสูงสุดของภาษา

เอาท์พุต

  • 6เพียงแค่การส่งออกจำนวนของขั้นตอนเช่น
  • ช่องว่างนำหน้า / ต่อท้ายหรือขึ้นบรรทัดใหม่นั้นใช้ได้

ตัวอย่าง

f(5)        --> 3
f(30)       --> 6
f(31)       --> 7
f(32)       --> 5
f(100)      --> 8
f(200)      --> 9
f(2016^155) --> 2015

ความต้องการ

  • คุณสามารถรับอินพุตจากSTDINอาร์กิวเมนต์บรรทัดคำสั่งเป็นพารามิเตอร์ฟังก์ชันหรือจากค่าที่ใกล้เคียงที่สุด
  • คุณสามารถเขียนโปรแกรมหรือฟังก์ชั่น หากเป็นฟังก์ชันที่ไม่ระบุตัวตนโปรดระบุตัวอย่างของวิธีการเรียกใช้
  • นี่คือดังนั้นคำตอบที่สั้นที่สุดในจำนวนไบต์ชนะ
  • ช่องโหว่มาตรฐานไม่ได้รับอนุญาต

ชุดนี้สามารถพบได้ใน OEIS เช่นกัน: A064097

กึ่งลอการิทึม inductively กำหนดโดยa(1) = 0และa(p) = 1 + a(p-1)ถ้าpเป็นนายกรัฐมนตรีและถ้าa(n*m) = a(n) + a(m)m,n > 1


ชี้แจงข้อกำหนดในการป้อนข้อมูลในภาษาที่มีจำนวนเต็มความแม่นยำพื้นเมือง?
Sparr

อย่างน้อย @Sparr 2^32 - 1ผมจะบอกว่าคุณควรจะรองรับได้ถึง ส่วนที่เหลือขึ้นอยู่กับคุณและระบบของคุณ หวังว่านี่คือสิ่งที่คุณหมายถึงกับคำถามของคุณ
insertusernamehere

3
ฉันชอบชื่อที่รวบรวมได้ทั้งหมด
Luis Mendo

คำตอบ:


20

เยลลี่ขนาด 9 ไบต์

ÆṪÐĿÆFL€S

ลองออนไลน์! หรือตรวจสอบกรณีทดสอบทั้งหมด

พื้นหลัง

ความหมายของลำดับA064097มีความหมายว่า

คำนิยาม

โดยสูตรผลิตภัณฑ์ของออยเลอร์

สูตรผลิตภัณฑ์ของออยเลอร์

ที่φหมายถึงฟังก์ชัน totient ของออยเลอร์และpแตกต่างกันไปตามจำนวนเฉพาะเท่านั้น

เมื่อรวมทั้งสองอย่างเข้าด้วยกันเราอนุมานคุณสมบัติ

คุณสมบัติแรก

ที่ωหมายถึงจำนวนของปัจจัยสำคัญที่แตกต่างกันของn

การใช้สูตรผลลัพธ์k + 1ครั้งโดยที่kมีขนาดใหญ่พอดังนั้นφ k + 1 (n) = 1เราจะได้

คุณสมบัติที่สอง

จากคุณสมบัตินี้เราจะได้รับสูตร

สูตร

ที่เท่าเทียมกันที่ผ่านมาถือเพราะω (1) = 0

มันทำงานอย่างไร

ÆṪÐĿÆFL€S  Main link. Argument: n

  ÐĿ       Repeatedly apply the link to the left until the results are no longer
           unique, and return the list of unique results.
ÆṪ           Apply Euler's totient function.
           Since φ(1) = 1, This computes φ-towers until 1 is reached.
    ÆF     Break each resulting integer into [prime, exponent] pairs.
      L€   Compute the length of each list.
           This counts the number of distinct prime factors.
        S  Add the results.

ตอนนี้เป็นวิธีที่ฉลาดมาก!
Abr001am

15

05AB1E , 13 11 ไบต์

รหัส:

[DÒ¦P-¼D#]¾

คำอธิบาย:

[        ]   # An infinite loop and...
       D#        break out of the loop when the value is equal to 1.
 D           # Duplicate top of the stack (or in the beginning: duplicate input).
  Ò          # Get the prime factors, in the form [2, 3, 5]
   ¦         # Remove the first prime factor (the smallest one), in order to get 
               the largest product.
    P        # Take the product, [3, 5] -> 15, [] -> 1.
     -       # Substract from the current value.
      ¼      # Add one to the counting variable.
          ¾  # Push the counting variable and implicitly print that value.

ใช้การเข้ารหัสCP-1252 ลองออนไลน์! .


13
ลบปัจจัยหลักแรก (เล็กที่สุด) เพื่อให้ได้ผลิตภัณฑ์ที่ใหญ่ที่สุดช่างฉลาดแค่ไหน! :-)
Luis Mendo

ฉันเห็นคุณเป็นผู้พัฒนาภาษา
Sarge Borsch

@SargeBorsch ใช่ถูกต้องแล้ว :)
Adnan

[¼Ñü-¤ÄD#]¾- ฉันเข้าใกล้การโกนไบต์ด้วยเข็มคู่โอ้ดี ...
Magic Octopus Urn

ไบต์ [Ð#Ò¦P-¼]¾-1: จะดีกว่าÐ DD
Grimmy

11

Pyth, 11 ไบต์

fq1=-Q/QhPQ

ชุดทดสอบ

วนซ้ำอย่างต่อเนื่องตรงไปตรงมา

คำอธิบาย:

fq1=-Q/QhPQ
               Implicit: Q = eval(input())
f              Apply the following function until it is truthy,
               incrementing T each time starting at 1:
         PQ    Take the prime factorization of Q
        h      Take its first element, the smallest factor of Q
      /Q       Divide Q by that, giving Q's largest factor
    -Q         Subtract the result from Q
   =           Assign Q to that value
 q1            Check if Q is now 1.

นั่นเป็นกลอุบายที่ดีมากกับfilter
Maltysen

3
ฉันไม่เข้าใจว่าทำไมสิ่งนี้ถึงส่งผลให้จำนวนครั้งที่ฟังก์ชั่นทำงาน นี่เป็นคุณสมบัติที่ไม่มีเอกสารfหรือไม่
corsiKa

@corsiKa fโดยไม่มีอาร์กิวเมนต์ที่สองจะวนซ้ำจำนวนเต็มบวกทั้งหมดที่เริ่มต้น1และส่งกลับค่าแรกที่ให้ค่าจริงในคำสั่งด้านใน ค่านี้ไม่ได้ใช้ในโปรแกรมนี้ดังนั้นจึงส่งคืนจำนวนครั้งที่รัน ไม่ได้ไม่มีเอกสารเพียงแหกคอก :) หากช่วยคุณสามารถคิดว่านี่เป็นforวงดังนี้:for(int i=1; some_condition_unrelated_to_i; i++) { change_stuff_that_affects_condition_but_not_i;}
FryAmTheEggman

@corsiKa เอกสารนี้มีการอ้างอิงอักขระที่ด้านขวาของล่ามออนไลน์ มีเพียงหนึ่งอาร์กิวเมนต์ ( f <l:T> <none>) fเป็นแรกอินพุทที่A(_)เป็น truthy [1, 2, 3, 4...]มากกว่า
Dennis

อ่าฉันเข้าใจแล้ว โดยจะใช้การป้อนข้อมูล แต่ไม่เคยใช้การป้อนข้อมูลในการคำนวณ ที่อธิบายถึงความคิดเห็น @Maltysen ของ "นั่นเป็นเคล็ดลับที่ดีจริงๆ" เพราะคุณสนใจเฉพาะการนับซ้ำที่ไม่ได้ใช้การนับที่ใดก็ได้ในตัวกรองของคุณ ฉันรักช่วงเวลา ah-ha เหล่านั้น!
:)

7

Python 2, 50 49 ไบต์

f=lambda n,k=1:2/n or n%(n-k)and f(n,k+1)or-~f(k)

นี่จะไม่เสร็จสิ้นในกรณีทดสอบล่าสุดเมื่อใดก็ตามที่เร็ว ๆ นี้ ...

หรือนี่คือ 48- ไบต์ที่ส่งคืนTrueแทน1สำหรับn=2:

f=lambda n,k=1:n<3or n%(n-k)and f(n,k+1)or-~f(k)

6

เยลลี่ 10 ไบต์

ÆfḊPạµÐĿi2

ลองออนไลน์! หรือตรวจสอบกรณีทดสอบมากที่สุด กรณีทดสอบล่าสุดเสร็จสิ้นอย่างรวดเร็วในพื้นที่

มันทำงานอย่างไร

ÆfḊPạµÐĿi2  Main link. Argument: n (integer)

Æf          Factorize n, yielding a list of primes, [] for 1, or [0] for 0.
  Ḋ         Dequeue; remove the first (smallest) element.
   P        Take the product.
            This yields the largest proper divisor if n > 1, 1 if n < 2.
    ạ       Yield the abs. value of the difference of the divisor (or 1) and n.
     µ      Convert the chain to the left into a link.
      ÐĿ    Repeatedly execute the link until the results are no longer unique.
            Collect all intermediate results in a list.
            For each starting value of n, the last results are 2 -> 1 -> 0 (-> 1).
        i2  Compute the 1-based index of 2.

5

เรติน่า 12

  • บันทึก 14 ไบต์ขอบคุณ @ MartinBüttner
(1 +) (? = \ 1 + $)

สิ่งนี้จะถือว่าอินพุตที่ระบุเป็น unaryและเอาต์พุตที่กำหนดเป็นทศนิยม หากสิ่งนี้ไม่เป็นที่ยอมรับเราสามารถทำได้มากกว่า 6 ไบต์:

จอประสาทตา , 18

  • บันทึก 8 ไบต์ด้วย @ MartinBüttner
. +
$ *
(1 +) (? = \ 1 + $)

ลองออนไลน์ - เพิ่มบรรทัดที่ 1 เพื่อเรียกใช้การทดสอบทั้งหมดในครั้งเดียว

น่าเสียดายที่นี่ใช้การคำนวณแบบไม่รวมดังนั้นอินพุตของปี 2559 155จึงไม่เป็นประโยชน์

  • สเตจแรก (2 บรรทัด) จะแปลงค่าทศนิยมให้เป็น unary เป็นสตริงของ1s
  • ขั้นตอนที่สอง (1 บรรทัด) คำนวณปัจจัยที่ใหญ่ที่สุดของ n โดยใช้กลุ่มการจับคู่ regex และ lookbehinds และลบออกจาก n ได้อย่างมีประสิทธิภาพ regex นี้จะจับคู่หลาย ๆ ครั้งเท่าที่จำเป็นเพื่อลดจำนวนเท่าที่จะทำได้ จำนวนการจับคู่ regex จะเป็นจำนวนขั้นตอนและจะถูกส่งออกโดยขั้นตอนนี้

\bผมไม่คิดว่าคุณต้องการ
Martin Ender

คุณสามารถประหยัดได้มากขึ้นเช่นนี้แม้ว่าในทางเทคนิคแล้วและคุณไม่ต้องการขั้นตอนแรกเช่นกัน
Martin Ender

@ MartinBüttnerสุดยอด! สง่างามมาก - ขอบคุณ!
Digital Trauma

5

Pyth - 15 14 13 ไบต์

ปลอกพิเศษ1ฆ่าฉันจริงๆ

tl.u-N/Nh+PN2

ลองมันออนไลน์ได้ที่นี่

tl                One minus the length of
 .u               Cumulative fixed point operator implicitly on input
  -N              N -
   /N             N /
    h             Smallest prime factor
     +PN2         Prime factorization of lambda var, with two added to work with 1

1
สิ่งหนึ่งที่ฉันมักจะลืม .... กำลังดุร้ายมักจะเป็นวิธีตีกอล์ฟที่ดีที่สุด
Leaky Nun

คุณหมายถึงอะไรกับปลอกพิเศษ1?
Adnan

1
@Adnan ตัวประกอบที่สำคัญของการ1มีที่[]ซึ่งทำให้เกิดข้อผิดพลาดเมื่อผมใช้องค์ประกอบแรก ฉันต้องกรณีพิเศษเพื่อให้มันกลับมา1อีกครั้งดังนั้นจุด.uคงที่สิ้นสุด ฉันพบวิธีที่ดีกว่า.xลองยกเว้นซึ่งเป็นสิ่งที่ช่วยฉัน 2 ไบต์เหล่านั้น
Maltysen

จำเป็นต้องยอมรับตัวเลข> = 2 (> 1) เท่านั้น
โซโลมอน Ucko

@SolomonUcko คุณเข้าใจผิด.uจุดคงที่ในที่สุดก็จะเข้าถึง1ข้อมูลทั้งหมดในจุดที่จะต้องใส่กล่องพิเศษ
Maltysen

5

JavaScript (ES6), * 44 38

บันทึกการแก้ไข 6 ไบต์ขอบคุณ @ l4m2

(* 4 ขีดหยุดยังคงเป็น 4)

ฟังก์ชั่นวนซ้ำ

f=(n,d=n)=>n>1?n%--d?f(n,d):f(n-d)+1:0

น้อย golfed

f=(n, d=n-1)=>{
  if (n>1)
    if(n % d != 0)
      return f(n, d-1) // same number, try a smaller divisor
    else
      return f(n-d)+1  // reduce number, increment step, repeat
  else
    return 0
}

ทดสอบ

f=(n,d=n)=>n>1?n%--d?f(n,d):f(n-d)+1:0

console.log=x=>O.textContent+=x+'\n';

[5,30,31,32,100,200].forEach(x=>console.log(x+' -> '+f(x)))
<pre id=O></pre>


ดี แต่ฉันคิดว่าคุณควรใช้สองไบต์ที่จำเป็นในการสร้าง f (1) == 0
Neil

@ ไม่มีความคิดอีกครั้ง: ไม่ "ให้ n เป็นจำนวนธรรมชาติ≥ 2 ... "
edc65

ฉันต้องการแว่นตาใหม่
Neil

ทำไมไม่f=(n,d=n)=>n>1?n%--d?f(n,d):f(n-d)+1:0?
l4m2

@ l4m2 ถูกต้องทำไมล่ะ ขอบคุณ
edc65

4

Mathematica ขนาด 36 ไบต์

f@1=0;f@n_:=f[n-Divisors[n][[-2]]]+1

ฟังก์ชั่นที่ไม่มีชื่อใช้ไบต์เดียวกัน:

If[#<2,0,#0[#-Divisors[#][[-2]]]+1]&

นี่คือการใช้คำจำกัดความตรงไปตรงมาเป็นฟังก์ชั่นซ้ำ


4

อ็อกเทฟ, 59 58 55 ไบต์

function r=f(x)r=0;while(x-=x/factor(x)(1));r++;end;end

อัปเดตขอบคุณ Stewie Griffin ประหยัด 1 ไบต์

อัปเดตเพิ่มเติมประหยัดอีกสามไบต์โดยใช้ผลลัพธ์ของการแยกตัวประกอบในขณะตรวจสอบ

ตัวอย่างการวิ่ง:

octave:41> f(5)
ans =  3
octave:42> f(30)
ans =  6
octave:43> f(31)
ans =  7
octave:44> f(32)
ans =  5
octave:45> f(100)
ans =  8
octave:46> f(200)
ans =  9

สุดท้ายคือendสิ่งจำเป็นในระดับแปดเสียงหรือไม่
Abr001am

มันคือ. ฉันสังเกตเห็นว่าไม่ได้อยู่ใน matlab จากคำตอบของคุณ แต่ Octave คาดหวังไว้ (อย่างที่ฉันได้เรียนรู้จากการลองของคุณใน Octave)
dcsohl

4

Haskell, 59 ไบต์

f 1=0;f n=1+(f$n-(last$filter(\x->n`mod`x==0)[1..n`div`2]))

การใช้งาน:

Prelude> f 30
Prelude> 6

มันอาจจะไม่มีประสิทธิภาพเล็กน้อยสำหรับคนจำนวนมากเนื่องจากการสร้างรายการ


1
รายการความเข้าใจและ<1แทนที่จะ==0บันทึกไม่กี่ไบต์: f 1=0;f n=1+f(n-last[a|a<-[1..ndiv2],mod n a<1])
Angs

4

Julia, 56 50 45 39 ไบต์

f(n)=n>1&&f(n-n÷first(factor(n))[1])+1

นี่คือฟังก์ชันเรียกซ้ำที่ยอมรับจำนวนเต็มและส่งกลับจำนวนเต็ม

Ungolfed:

function f(n)
    if n < 2
        # No decrementing necessary
        return 0
    else
        # As Dennis showed in his Jelly answer, we don't need to
        # divide by the smallest prime factor; any prime factor
        # will do. Since `factor` returns a `Dict` which isn't
        # sorted, `first` doesn't always get the smallest, and
        # that's okay.
        return f(n - n ÷ first(factor(n))[1]) + 1
    end
end

ลองออนไลน์! (รวมถึงกรณีทดสอบทั้งหมด)

บันทึก 6 ไบต์ด้วย Martin Büttnerและ 11 ขอบคุณ Dennis!


3

PowerShell v2 +, 81 ไบต์

param($a)for(;$a-gt1){for($i=$a-1;$i-gt0;$i--){if(!($a%$i)){$j++;$a-=$i;$i=0}}}$j

โหดร้ายดุร้าย

จะเข้า$a, เข้าสู่forห่วงจนกว่าจะมีค่าน้อยกว่าหรือเท่ากับ$a 1แต่ละลูปที่เราไปถึงforลูปอื่นที่นับถอยหลัง$aจนกว่าเราจะเจอตัวหาร ( !($a%$i) ที่แย่ที่สุดเราจะพบ$i=1ว่าเป็นตัวหาร เมื่อเราเพิ่มเคาน์เตอร์ของเรา$jลบตัวหารของเรา$a-=$iและตั้งค่า$i=0ให้แยกวงด้านในออก ในที่สุดเราจะไปถึงเงื่อนไขที่วงรอบนอกเป็นเท็จ (เช่น$aได้มาถึง1) ดังนั้นเอาท์พุท$jและออก

ข้อควรระวัง : การดำเนินการนี้จะใช้เวลานานสำหรับจำนวนที่มากขึ้นโดยเฉพาะช่วงเวลา การป้อนข้อมูล 100,000,000 ใช้เวลา ~ 35 วินาทีบนแล็ปท็อป Core i5 ของฉัน แก้ไข - เพิ่งทดสอบด้วย[int]::MaxValue(2 ^ 32-1) และใช้เวลาประมาณ 27 นาที ไม่เลวเกินไปฉันคิดว่า



3

Japt 12 ไบต์ (ไม่ใช่การแข่งขัน)

@!(UµUk Å×}a

ทดสอบออนไลน์! ไม่แข่งขันเนื่องจากใช้คุณลักษณะหลายอย่างที่เพิ่มเข้ามาหลังจากการโพสต์ความท้าทาย

มันทำงานอย่างไร

@   !(Uµ Uk Å  ×   }a
XYZ{!(U-=Uk s1 r*1 }a
                       // Implicit: U = input integer
XYZ{               }a  // Return the smallest non-negative integer X which returns
                       // a truthy value when run through this function:
         Uk            //   Take the prime factorization of U.
            s1         //   Slice off the first item.
                       //   Now we have all but the smallest prime factor of U.
               r*1     //   Reduce the result by multiplication, starting at 1.
                       //   This takes the product of the array, which is the
                       //   largest divisor of U.
      U-=              //   Subtract the result from U.
    !(                 //   Return !U (which is basically U == 0).
                       //   Since we started at 0, U == 1 after 1 less iteration than
                       //   the desired result. U == 0 works because the smallest
                       //   divisor of 1 is 1, so the next term after 1 is 0.
                       // Implicit: output result of last expression

เทคนิคนี้ได้รับแรงบันดาลใจจากคำตอบ 05AB1E รุ่นก่อนหน้านี้ใช้งาน ²¤(ดัน 2 ออกจากสองรายการแรก) Åเพราะมันสั้นกว่าหนึ่งไบต์s1 (พื้นที่ส่วนท้ายโน้ต); ฉันเพิ่งรู้หลังจากความจริงที่ว่าเนื่องจากสิ่งนี้ผนวก 2 ถึงส่วนท้ายของอาร์เรย์และชิ้นจากจุดเริ่มต้นในความเป็นจริงมันล้มเหลวในจำนวนคอมโพสิตแปลก ๆ ใด ๆ แม้ว่ามันจะทำงานในทุกกรณีทดสอบที่กำหนด


2

Python 3, 75, 70 , 67 ไบต์

g=lambda x,y=0:y*(x<2)or[g(x-z,y+1)for z in range(1,x)if x%z<1][-1]

นี่เป็นวิธีแก้ปัญหาแบบเรียกซ้ำ ใช้เวลานานมากสำหรับกรณีทดสอบจำนวนมาก


2

> <>, 32 ไบต์

<\?=2:-$@:$/:
1-$:@@:@%?!\
;/ln

คาดว่าหมายเลขอินพุตn, บนสแต็ก

โปรแกรมนี้สร้างลำดับสมบูรณ์บนสแต็ก ในฐานะที่เป็นหมายเลขเดียวที่สามารถนำไปสู่การ1มี2การสร้างลำดับหยุดเมื่อ2ถึง สิ่งนี้ยังทำให้ขนาดของสแต็กเท่ากับจำนวนขั้นตอนมากกว่าจำนวนขั้นตอนที่ +1


2

Ruby, 43 ไบต์

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

พบจำนวนน้อยที่สุดiเช่นที่xแบ่งx-iและ recurse 1จนกว่าจะถึง


2

Haskell, 67 ไบต์

นี่คือรหัส:

a&b|b<2=0|a==b=1+2&(b-1)|mod b a<1=1+2&(b-div b a)|1<2=(a+1)&b
(2&)

และนี่คือเหตุผลหนึ่งว่าทำไม Haskell จึงยอดเยี่ยม:

f = (2&)

(-->) :: Eq a => a -> a -> Bool
(-->) = (==)

h=[f(5)        --> 3
  ,f(30)       --> 6
  ,f(31)       --> 7
  ,f(32)       --> 5
  ,f(100)      --> 8
  ,f(200)      --> 9
  ,f(2016^155) --> 2015
  ]

ใช่ใน Haskell คุณสามารถกำหนด-->ให้เทียบเท่า==ได้


2

Matlab, 107 ไบต์

a=input('');b=factor(a-isprime(a));c=log2(a);while(max(b)>1),b=max(factor(max(b)-1));c=c+1;end,disp(fix(c))
  • ไม่ใช่การแข่งขันนี่ไม่ใช่การแปลซ้ำของการส่งครั้งล่าสุดของฉันเพียงอีกวิธีพีชคณิตโดยตรงมันสรุปผลรวมไบนารีบันทึกทั้งหมดของปัจจัยสำคัญทั้งหมด kinda คลุมเครือเพื่อแสดงให้เห็น
  • ฉันจะตีกอล์ฟให้มากกว่านี้เมื่อฉันมีเวลา

2

MATL, 17 16 ไบต์

`tttYfl)/-tq]vnq

ลองออนไลน์

คำอธิบาย

        % Implicitly grab input
`       % Do while loop
    ttt % Make three copies of top stack element
    Yf  % Compute all prime factors
    l)  % Grab the smallest one
    /   % Divide by this to get the biggest divisor
    -   % Subtract the biggest divisor
    t   % Duplicate the result
    q   % Subtract one (causes loop to terminate when the value is 1). This
        % is functionally equivalent to doing 1> (since the input will always be positive) 
        % with fewer bytes
]       % End do...while loop
v       % Vertically concatenate stack contents (consumes entire stack)
n       % Determine length of the result
q       % Subtract 1 from the length
        % Implicitly display result

2

C99, 62 61 ไบต์

1 ไบต์ golfed off โดย @Alchymist

f(a,c,b)long*c,a,b;{for(*c=0,b=a;a^1;a%--b||(++*c,b=a-=b));}  

เรียกใช้เป็น f (x, & y) โดยที่ x คืออินพุตและ y คือเอาต์พุต


หากคุณทดสอบ a% - b คุณสามารถหลีกเลี่ยง b-- ได้ในตอนท้าย ประหยัดทั้งหนึ่งไบต์
เล่นแร่แปรธาตุ


2

Clojure, 116 104 ไบต์

(fn[n](loop[m n t 1](let[s(- m(last(filter #(=(rem m %)0)(range 1 m))))](if(< s 2)t(recur s (inc t))))))

-12 ไบต์โดยการกรองช่วงเพื่อค้นหาทวีคูณจากนั้นใช้lastอันใดอันหนึ่งเพื่อให้ได้ค่าที่มากที่สุด

วิธีการแก้ปัญหาแบบไร้เดียงสาที่เพียงแค่แก้ปัญหาตามที่อธิบายไว้โดย OP น่าเสียดายที่การค้นหาตัวหารที่ยิ่งใหญ่ที่สุดนั้นใช้เวลาเพียงครึ่งเดียวกับที่ใช้ อย่างน้อยฉันควรมีห้องมากมายให้เล่นกอล์ฟจากที่นี่

pregolfed และทดสอบ:

(defn great-divider [n]
  ; Filter a range to find multiples, then take the last one to get the largest
  (last
     (filter #(= (rem n %) 0)
             (range 1 n))))

(defn sub-great-divide [n]
  (loop [m n
         step 1]
    (let [g-d (great-divider m) ; Find greatest divisor of m
          diff (- m g-d)] ; Find the difference
      (println m " is " g-d " --> " m " - " g-d " = " diff)
      (if (< diff 2)
        step
        (recur diff (inc step))))))

(sub-great-divide 30)

30  is  15  -->  30  -  15  =  15
15  is  5  -->  15  -  5  =  10
10  is  5  -->  10  -  5  =  5
5  is  1  -->  5  -  1  =  4
4  is  2  -->  4  -  2  =  2
2  is  1  -->  2  -  1  =  1
6

1
@insertusernamehere ไม่น่าเสียดายเพราะนั่นคือตัวระบุที่ถูกต้องทั้งหมด ฉันได้ลบช่องว่างที่เป็นไปได้ทั้งหมดแล้ว ถ้าฉันต้องการตีกอล์ฟเพิ่มเติมฉันจะต้องทำใหม่อัลกอริทึม
Carcigenicate

2

Perl 6 , 35 ไบต์

{+({$_ -first $_%%*,[R,] ^$_}...1)}

ลองออนไลน์!

มันทำงานอย่างไร

{                                 }   # A bare block lambda.
                    [R,] ^$_          # Construct range from arg minus 1, down to 0.
        first $_%%*,                  # Get first element that is a divisor of the arg.
    $_ -                              # Subtract it from the arg.
   {                        }...1     # Do this iteratively, until 1 is reached.
 +(                              )    # Return the number of values generated this way.

1

Pyth, 17 16 ไบต์

L?tbhy-b*F+1tPb0

ลองออนไลน์! ( y.vที่ส่วนท้ายมีไว้สำหรับการเรียกใช้ฟังก์ชัน)


17 ไบต์ดั้งเดิม:

L?tb+1y-b*F+1tPb0

ลองออนไลน์! ( y.vที่ส่วนท้ายมีไว้สำหรับการเรียกใช้ฟังก์ชัน)

(ฉันตอบคำถามด้วยโปรแกรม Pyth นี้)


ฉันไม่ได้สนใจโปรแกรมของคุณ แต่ถ้าคุณใช้นิยามแบบเรียกซ้ำใน OP uอาจจะสั้นกว่าการเรียกซ้ำจริง
Maltysen

1

Pyke 11 ไบต์ (ไม่ใช่การแข่งขัน)

D3Phf-oRr;o

สิ่งนี้ใช้พฤติกรรมใหม่ที่หากมีข้อยกเว้นยกขึ้นหลังจาก goto ก็จะเรียกคืนสถานะจากก่อนหน้า goto (ยกเว้นคำจำกัดความของตัวแปร) และดำเนินการต่อ ในกรณีนี้มันเทียบเท่ากับรหัสหลามต่อไปนี้:

# Implicit input and variable setup
inp = input()
o = 0
# End implicit
try:
    while 1:
        inp -= factors(inp)[0] # If factors is called on the value 1, it returns an empty
                               # list which when the first element tries to be accessed
                               # raises an exception
        o += 1 # Using `o` returns the current value of `o` and increments it
except:
    print o # This in effect gets the number of times the loop went

ทั้งหมดนี้เป็นไปได้โดยใช้ Pyke โดยไม่ต้องใช้การก่อสร้างแบบวนลูป - ใช่แล้ว!

ลองที่นี่!


1

JavaScript (ES6), 70 54 ไบต์

f=(n,i=2)=>n<i?0:n%i?f(n,i+1):n>i?f(i)+f(n/i):1+f(n-1)

การใช้งานของสูตรแบบเรียกซ้ำที่ให้ไว้ แต่ตอนนี้ได้รับการปรับปรุงเพื่อใช้การเรียกซ้ำเพื่อค้นหาตัวหารด้วย


1

Perl, 57 + 1 ( -pตั้งค่าสถานะ) = 58 ไบต์

$n=$_;$n-=$n/(grep!($n%$_),2..$n/2,$n)[0],$\++while$n>1}{

การใช้งาน:

> echo 31 | perl -pe '$n=$_;$n-=$n/(grep!($n%$_),2..$n/2,$n)[0],$\++while$n>1}{'

Ungolfed:

while (<>) {
# code above added by -p
    # $_ has input value
    # $\ has undef (or 0)
    my $n = $_;
    while ($n > 1) {
        my $d = 1;
        for (2 .. ($n / 2)) {
            if ($n % $_ == 0) {
                $d = $n / $_;
                last;
            }
        }
        $n -= $d;
        $\++;
    }
} {
# code below added by -p
    print;  # prints $_ (undef here) and $\
}

1

Clojure 98 98ไบต์

#(loop[n % i -1](if n(recur(first(for[j(range(dec n)0 -1):when(=(mod n j)0)](- n j)))(inc i))i))

ใช้for :whenเพื่อค้นหาตัวหารที่ใหญ่ที่สุดวนซ้ำจนกว่าจะไม่พบค่าดังกล่าวที่ใหญ่กว่าค่าหนึ่ง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.