Pseudofactorial


39

มีจำนวนที่ค่อนข้างอยากรู้อยากเห็นซึ่งบางครั้งก็ปรากฏขึ้นในปัญหาทางคณิตศาสตร์หรือปริศนา pseudofactorial (N) เป็นพหุคูณสามัญน้อยที่สุด (เช่นต่ำสุด) ของตัวเลข 1 ถึง N; มันคือจำนวนต่ำสุดซึ่งมีตัวเลขทั้งหมดตั้งแต่ 1 ถึง N เป็นปัจจัย

เช่น pseudofactorial (7) = 3 * 4 * 5 * 7 ซึ่งเหมือนกับ 7! ยกเว้นว่ามีการลบ 2 และ 6 ออกเนื่องจากมีอยู่ในข้อกำหนดอื่น

เขียนโปรแกรมเพื่อคำนวณ pseudofactorial (N) และเช่นเคยรหัสสั้นที่สุดชนะ

นี่คือรายการสั้น ๆ สำหรับการใช้งานของคุณ เพิ่มเติมกรณีทดสอบที่สามารถพบได้ใน OEIS ภายใต้A003418

factorial:

  1. 1
  2. 2
  3. 6
  4. 24
  5. 120
  6. 720
  7. 5040

Pseudofactorial:

  1. 1
  2. 2
  3. 6
  4. 12
  5. 60
  6. 60
  7. 420

6
ฉันไม่แน่ใจว่าฉันเข้าใจว่าทำไม2และ6ถูกลบออกจากรายการทวีคูณ คุณช่วยอธิบายกฎให้ชัดเจนขึ้นได้ไหม?
Maltysen

2
@ Mattysen, psuedofactorial (N) เป็นตัวเลขที่เล็กที่สุดซึ่งมีตัวเลข 1 ถึง N เป็นปัจจัย (ตัวคูณร่วมที่น้อยที่สุดของตัวเลขเหล่านั้น) นั่นคือคำจำกัดความทางเทคนิค แต่วิธีที่ฉันเขียนมันค่อนข้างมีนัยที่ว่ามันคล้ายกับแฟคทอเรียล
Tony Ruth


4
ยินดีต้อนรับสู่การเขียนโปรแกรมปริศนา & รหัสกอล์ฟ! นี่เป็นความท้าทายครั้งแรกที่ดี!
Alex A.

1
ความท้าทายแรกของคุณคือการก้าวขึ้นสู่จุดสูงสุดของ HNQ ดี!
Daniel M.

คำตอบ:


19

Dyalog APLขนาด 3 ไบต์

∧/⍳

APL beats Jelly

1 แม้ว่าการโต้แย้ง

∧/ LCM ข้าม


10
Interrobang นั้นเซ็กซี่มาก
shooqie

1
โอคนที่คุณเอาชนะเดนนิส ...
Mama Fun Roll

1
น่าประทับใจ แต่ 3 ไบต์เหล่านี้เป็นอย่างไร
หยุดหมุนนาฬิกาใน



8

C (กับ x86), 52 ไบต์

d(n,k,b,t){for(b=k=1;b;++k)for(t=n,b=0;t;b+=k%t--);}

ตรวจสอบตัวเลขตั้งแต่ 1 ขึ้นไป สำหรับแต่ละหมายเลขให้หารด้วยตัวเลขทั้งหมดจาก n ลงเหลือ 1 แล้วนำจำนวนที่เหลือ หยุดเมื่อผลรวมเป็น 0

การใช้งาน:

main()
{
    printf("%d\n", d(7)); // outputs 420
}

ไม่ชัดเจนว่าจะส่งคืนค่าreturnได้อย่างไร

หลักการเรียกใช้สำหรับ x86 บอกว่าฟังก์ชันจะต้องส่งคืนค่าในeaxทะเบียน สะดวกในการเรียนการสอนการหารidivคาดว่าจะเข้าeaxและส่งออกผลลัพธ์ในeax(ฉลาด) และedx(ส่วนที่เหลือ) การวนซ้ำครั้งล่าสุดหารkด้วย1ดังนั้นeaxจะมีค่าที่ถูกต้องเมื่อออกจากฟังก์ชัน

ใช้งานได้กับการปรับให้เหมาะสมเท่านั้น (ในโหมดดีบักจะส่งสัญญาณออก421)


คุณจะไปโดยไม่ประกาศประเภท n, k, b และ t ได้อย่างไร
Tony Ruth

C มีกฎเริ่มต้น int - ประเภทที่ละเว้นทั้งหมดเป็นintค่าเริ่มต้น (รวมถึงค่าส่งคืน) มันจะทำงานสำหรับฟังก์ชั่นการขัดแย้งถ้าพวกเขาจะประกาศโดยใช้สิ่งที่เรียกว่า "แบบเก่า" ไวยากรณ์ การประกาศด้วยประเภทที่กำหนดไว้อย่างชัดเจนจะเป็นint d(n,k,b,t) int n,k,b,t; {...}
Anatolyg

หากคุณกำลังใช้ประโยชน์จากการประชุมทางโทรศัพท์นี่ควรทำเครื่องหมายว่า "C (cdecl)" ไม่ใช่แค่ "C"
Steve Cox

@SteveCox ทั้งคู่cdeclและstdcallใช้วิธีการเดียวกันสำหรับการส่งคืนค่าดังนั้นฉันเดาว่าx86เพียงพอ
Anatolyg

7

Haskell, 20 ไบต์

f x=foldr1 lcm[1..x]

ตัวอย่างการใช้งาน: ->map f [1..7][1,2,6,12,60,60,420]

lcmเคล็ดลับใน Haskell


6

Python + SymPy, 45 ไบต์

import sympy
lambda n:sympy.lcm(range(1,n+1))

ค่อนข้างอธิบายตนเอง


Python 2, 57 54 ไบต์

i=r=input();exec't=r\nwhile r%i:r+=t\ni-=1;'*r;print r

ทดสอบบนIdeone

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

การป้อนข้อมูลที่ถูกเก็บไว้ในตัวแปรฉันและR

execดำเนินการดังต่อไปนี้รหัสRครั้ง

t=r
while r%i:r+=t
i-=1

ในขณะที่ฉันแตกต่างจากRไป1เราเพิ่มค่าเริ่มต้นของR (เก็บไว้ในเสื้อ ) หลาย ๆ ครั้งตามความจำเป็นเพื่อRตัวเองเพื่อสร้างหลายของฉัน ผลที่ได้คือเห็นได้ชัดว่ามีหลายที

ค่าสุดท้ายของrจึงเป็นจำนวนเต็มของจำนวนเต็มทั้งหมดในช่วง[1, ... , n]โดยที่nคืออินพุต


1
โดยไม่ต้องใช้ห้องสมุดของบุคคลที่สามหรือexecเทคนิคมีวิธีการแก้ปัญหา 78 ไบต์: ใช้ความจริงที่ว่าfrom fractions import*;lambda n:reduce(lambda x,y:x*y/gcd(x,y),range(1,n+1),1) lcm(x,y) = x*y/gcd(x,y)
Bakuriu

6

Python ขนาด 46 ไบต์

g=lambda n,c=0:n<1or(c%n<1)*c or g(n,c+g(n-1))

มองหาหลายcของg(n-1)โดยตรง ฉันเคยคิดมาก่อนแล้วว่าวิธีนี้จะหาค่า 0 เป็นจำนวนเท่าของอะไรก็ได้ แต่การorลัดวงจรหรือ(c%n<1)*cจะข้ามc==0เช่นกันเพราะ 0 คือ Falsey


50 ไบต์:

g=lambda n,i=1:n<1or(i*n%g(n-1)<1)*i*n or g(n,i+1)

เหมือนโซลูชันของ Dennisแต่เป็นฟังก์ชั่นวนซ้ำ มีการคำนวณg(n-1)รูปลักษณ์สำหรับหลายที่เล็กที่สุดi*nของที่นี้ยังมีหลายn g(n-1)ช้าจริงๆ

ขอขอบคุณที่เดนนิส 4 ไบต์โดยดูที่หลายรายการแทนng(n-1)


5

J, 9 ไบต์

[:*./1+i.

วิธีการตรงไปข้างหน้า สร้างช่วงของตัวเลข[0, ..., n-1]จากนั้นบวกหนึ่งส่วนเข้าด้วยกันแล้วลดลงโดยใช้ LCM

การใช้

   f =: [:*./1+i.
   f 7
420


4

Mathematica ขนาด 13 ไบต์

LCM@@Range@#&

จะไม่เทียบเท่านี้เพียงแค่เขียนLCMและRangeด้วย@*?
Maltysen

1
LCMดำเนินองค์ประกอบที่ชาญฉลาดในรายการซึ่งจะถูกส่งผ่านไปตามRangeความหมายนี้ก็จะกลับ LCM ( x ) สำหรับxตั้งแต่ 1 ถึงn นอกจากนี้ยังมีการขาดหายไป&ที่จะปิดฟังก์ชั่นที่ไม่ระบุชื่อ สิ่งที่ชอบLCM@@Range@#&สำหรับ 13 ไบต์จะใช้งานได้
ไมล์


3

Pyth - 8 ไบต์

[1..N]ตรวจสอบตัวเลขทั้งหมดจนกว่าจะพบหนึ่งที่หารด้วย

f!s%LTSQ

Test Suite


3

ระดับเสียงคู่, 27 ไบต์

@(x)lcm(1,num2cell(1:x){:})

ans(N)สร้างฟังก์ชั่นที่ไม่ระบุชื่อที่สามารถเรียกว่าเป็น

การสาธิตออนไลน์

คำอธิบาย

การแก้ปัญหานี้สร้างรายชื่อของตัวเลขทั้งหมดระหว่าง1และx( 1:x) num2cellแปลงให้อาร์เรย์มือถือที่มี จากนั้นการ{:}จัดทำดัชนีจะสร้างรายการที่คั่นด้วยเครื่องหมายจุลภาคซึ่งส่งผ่านไปยังlcmอาร์กิวเมนต์ที่ป้อนเข้าหลายรายการเพื่อคำนวณหลายรายการที่พบได้น้อยที่สุด 1 จะถูกส่งเป็นอาร์กิวเมนต์แรกเสมอlcmเพราะlcmต้องป้อนอาร์กิวเมนต์อย่างน้อยสองรายการเสมอ


1
ดังนั้นlcmใน Octave จึงยอมรับมากกว่า 2 อินพุต! น่าสนใจ
หลุยส์เมนโดะ

@LuisMendo Yup 2+
Suever


3

Perl 6 , 13 ไบต์

{[lcm] 1..$_}

รหัสที่ไม่ระบุชื่อบล็อกที่สร้างในช่วงตั้งแต่ 1 กับอินพุต (รวม) &infix:<lcm>แล้วว่ามีการลด

ตัวอย่าง:

#! /usr/bin/env perl6
use v6.c;

my &postfix:<p!> = {[lcm] 1..$_}

say 1p!; # 1
say 2p!; # 2
say 3p!; # 6
say 4p!; # 12
say 5p!; # 60
say 6p!; # 60
say 7p!; # 420

say 10000p!; # 5793339670287642968692270879...
# the result from this is 4349 digits long


2

JavaScript (ES6), 92 88 80 74 69 ไบต์:

ขอบคุณ @ConorOBrien และ @Neil

y=>(g=(a,b)=>b?g(b,a%b):a,[...Array(y)].map((_,i)=>y=y*++i/g(y,i)),y)

b?g(b,a%b):aบันทึกเป็นไบต์
Neil

y*++i/g(y,i)บันทึกไบต์เพิ่มเติม
Neil

1

05AB1E, 20 ไบต์

Lpvyi¹LÒN>¢àN>*ˆ}}¯P

คำอธิบาย

Lpv                    # for each item in isprime(range(1,N)): N=7 -> [0,1,1,0,1,0,1]
   yi                  # if prime
     ¹LÒN>¢            # count occurrences of the prime 
                         in the prime-factorization of range(1,N):
                         p=2 -> [0,1,0,2,0,1,0]
           àN>*ˆ       # add max occurrence of that prime multiplied by the prime 
                         to global array: N=7 -> [4,3,5,7]
                }}     # end if/loop
                  ¯P   # get product of global array

ลองออนไลน์


1

Minkolang 0.15 , 12 ไบต์

ฉันมีโซลูชัน 12 ไบต์สองรายการและรวมไว้ด้วยกัน

1n[i1+4$M]N.

ลองที่นี่!

คำอธิบาย

1               Push 1
 n              Take number from input
  [             For loop that repeats n times
   i1+          Push loop counter + 1
      4$M       Pop b, a and push lcm(a,b)
         ]      Close for loop
          N.    Output as number and stop.

ตรงไปตรงมาเท่าที่จะได้รับ


11nLd[4$M]N.

ลองที่นี่!

คำอธิบาย

11              Push two 1s
  n             Take number from input
   L            Pop b, a and push range from a to b, inclusive
    d           Duplicate top of stack (n)
     [4$M]      Pop b, a and push lcm(a,b), n times
          N.    Output as number and stop.

วิธีการแก้ปัญหาที่สามจะได้รับจากนี้ลบ1และเพิ่มหลังปัจจุบันd dในทั้งสองกรณีจำเป็นต้องมีหมายเลขพิเศษเนื่องจาก for loop ทำงานหนึ่งครั้งมากเกินไปและทำให้ใช้เวลาน้อยลงใช้เวลาน้อยกว่าสองไบต์ ( 1-ก่อนหน้า[)


1

ทับทิมขนาด 25 ไบต์

g=->n{(1..n).reduce :lcm}

ทับทิมขนาด 25 ไบต์

g=->n{n<1?1:a[n-1].lcm n}

1
สวัสดีและยินดีต้อนรับสู่ PPCG! โพสต์แรกสุดยอด! คุณไม่ต้องตั้งชื่อฟังก์ชั่นของคุณดังนั้นคุณสามารถลบg=ได้
NoOne อยู่ที่นี่

อนุญาตให้ใช้ฟังก์ชันที่ไม่ระบุชื่อ
Erik the Outgolfer

1

GameMaker Language ขนาด 60 ไบต์

for(b=k=1;b;++k){b=0for(t=argument0;t;b+=k mod t--)}return k

ขึ้นอยู่กับตรรกะของคำตอบของ Anatolyg


1

PHP, 61 52 48 ไบต์

บันทึก 9 ไบต์ด้วย @ user59178, 4 ไบต์โดยการรวมลูป

การเรียกซ้ำใน PHP มีขนาดใหญ่มากเนื่องจากfunctionคำสำคัญ ดังนั้นฉันจึงใช้การวนซ้ำ
และด้วยกลเม็ดเล็ก ๆ น้อย ๆ ตอนนี้ฉันก็เอาชนะArnauld's JSได้แล้ว

while(++$k%++$i?$i>$argv[1]?0:$i=1:$k--);echo$k;

รับอินพุตจากอาร์กิวเมนต์บรรทัดคำสั่ง -rทำงานด้วย

ชำรุด

while(++$k%++$i?    # loop $i up; if it does not divide $k
    $i>$argv[1]?0       # break if $i (smallest non-divisor of $k) is larger than input
    :$i=1               # while not, reset $i and continue loop with incremented $k
    :$k--);         # undo increment while $i divides $k
echo$k;         # print $k

ungolfed

อันที่จริงแล้วสองลูปในหนึ่งเดียว:

while($i<=$argv[1]) # loop while $i (smallest non-divisor of $k) is not larger than input
    for($k++,       # loop $k up from 1
        $i=0;$k%++$i<1;);   # loop $i up from 1 while it divides $k
echo$k;             # print $k

หมายเหตุ: คัดลอกมาจากคำตอบของฉันในรายการที่ซ้ำกัน


1

AWK, 42 ไบต์

{for(x=n=1;n<=$1;)if(x%n++){x++;n=1}$0=x}1

การใช้บรรทัดคำสั่ง:

awk '{for(x=n=2;n<=$1;)if(x%n++){x++;n=2}$0=x}1' <<< NUM

ฉันไม่เห็นAWKวิธีแก้ปัญหาและมีคำถามเพิ่งโพสต์เมื่อวานนี้ดังนั้นฉันคิดว่าฉันจะรวมมันเข้าด้วยกัน มันค่อนข้างช้าสำหรับการแก้ปัญหา19หรือใหญ่กว่าในกล่องของฉัน แต่มันใช้งานได้




0

ฮุน 67 ไบต์

|*
*
(roll (gulf 1 +<) |=({a/@ b/_1} (div (mul a b) d:(egcd a b))))

สร้างรายการ[1..n]พับรายการด้วย lcm น่าเสียดาย Hoon stdlib ไม่มี pre-built ที่ฉันสามารถใช้ได้: /



0

QBIC , 35 32 ไบต์

สิ่งนี้ทำให้ฉันมาที่นี่

:{p=0[a|~q%b|p=1]]~p=0|_Xq\q=q+1

คำอธิบาย:

:        Get cmd line param as number 'a'
{        Start an infinite DO loop
p=0      Sets a flag that shows if divisions failed
[a|      FOR (b=1; b<=a; b++)
~q%b     IF 'q' (which starts at 1 in QBIC) is not cleanly divisible by 'b'
|p=1     THEN Set the flag
]]   Close the FOR loop and the IF, leave the DO open
~p=0     IF 'q' didn't get flagged
|_Xq     THEN quit, printing 'q'
\q=q+1   ELSE raise 'q', redo
         [DO Loop implicitly closed by QBIC]

นี่คือรุ่นที่หยุดการทดสอบqเมื่อbไม่แบ่งอย่างเรียบร้อย นอกจากนี้คำสั่งของการทดสอบb's กับqเป็นสิ่งที่ตรงกันข้ามในสมมติฐานที่ว่าสูงb' s จะยากที่จะหารด้วย (ใช้เวลา2, 3, 4เช่น: ถ้า%2=0, %4อาจจะเป็น!0. ในทางกลับกันไม่มาก ... )

:{p=0[a,2,-1|~q%b|p=1┘b=2]]~p=0|_Xq\q=q+1

0

ความจริง 35 ไบต์

f(x)==reduce(lcm,[i for i in 1..x])

รหัสทดสอบและผลลัพธ์

(25) -> [[i,f(i)] for i in [1,6,19,22,30]]
   (25)  [[1,1],[6,60],[19,232792560],[22,232792560],[30,2329089562800]]
                                                  Type: List List Integer

ฉันแค่หาวิธี หาจำนวนเต็มบวกที่เล็กที่สุดซึ่งมีจำนวนเต็มทั้งหมดจาก 1 ถึง n เป็นปัจจัย เพราะคุณบอกว่ามันเป็น douplicate ฉันโพสต์ที่นี่



0

8th , 23 ไบต์

รหัส

1 ' lcm rot 2 swap loop

รหัสนี้จะส่งผลให้ pseudofactorial บน TOS

การใช้งานและตัวอย่าง

ok> 7 1 ' lcm rot 2 swap loop .
420

หรือชัดเจนขึ้น

ok> : pseudofact 1 ' n:lcm rot 2 swap loop ;

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