Giả hành


39

Có một con số khá tò mò đôi khi xuất hiện trong các bài toán hoặc câu đố toán học. Pseudofactorial (N) là bội số chung nhỏ nhất (tức là thấp nhất) của các số từ 1 đến N; nói cách khác, đó là số thấp nhất có tất cả các số từ 1 đến N là các yếu tố.

Ví dụ pseudofactorial (7) = 3 * 4 * 5 * 7, tương tự như 7! ngoại trừ 2 và 6 đã bị xóa vì chúng được chứa trong các điều khoản khác.

Viết chương trình tính pseudofactorial (N) và như mọi khi, mã ngắn nhất sẽ thắng.

Đây là một danh sách ngắn để sử dụng của bạn. Nhiều trường hợp thử nghiệm có thể được tìm thấy trong OEIS theo A003418 .

Yếu tố:

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

Giả hành:

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

6
Tôi không chắc tại sao tôi hiểu 26bị xóa khỏi danh sách bội số. Bạn có thể vui lòng làm rõ các quy tắc?
Maltysen

2
@Mattysen, psuedofactorial (N) là số nhỏ nhất có các số từ 1 đến N là các yếu tố (bội số chung nhỏ nhất của các số đó). Đó là định nghĩa kỹ thuật, nhưng cách tôi viết nó có phần gợi ý rằng nó tương tự như một nhân tố.
Tony Ruth


4
Chào mừng bạn đến với Câu đố lập trình & Code Golf! Đây là một thử thách đầu tiên tốt đẹp!
Alex A.

1
Thử thách đầu tiên của bạn đã đạt đến đỉnh HNQ. Tốt đẹp!
Daniel M.

Câu trả lời:




8

C (với x86), 52 byte

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

Kiểm tra các số từ 1 trở lên. Đối với mỗi số, chia nó cho tất cả các số từ n xuống 1 và tính tổng số còn lại. Dừng khi tổng bằng 0.

Sử dụng:

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

Không rõ ràng làm thế nào nó trả về một giá trị (không có returntuyên bố).

Quy ước gọi cho x86 nói rằng hàm phải trả về giá trị của nó trong thanh eaxghi. Thuận tiện, hướng dẫn phân chia idivdự kiến ​​đầu vào của nó eaxvà đưa ra kết quả trong eax(thương số) và edx(phần còn lại). Lặp lại cuối cùng chia kcho 1, vì vậy eaxsẽ chứa giá trị đúng khi hàm thoát.

Điều này chỉ hoạt động với tối ưu hóa trên (trong chế độ gỡ lỗi, nó xuất ra 421).


Làm thế nào để bạn thoát khỏi việc không khai báo loại n, k, b và t?
Tony Ruth

C có quy tắc int-default - tất cả các loại bị bỏ qua inttheo mặc định (bao gồm cả giá trị trả về). Nó hoạt động cho các đối số hàm nếu chúng được khai báo bằng cú pháp "kiểu cũ". Tuyên bố với các loại được xác định rõ ràng sẽ làint d(n,k,b,t) int n,k,b,t; {...}
anatolyg

nếu bạn đang tận dụng lợi thế của một quy ước gọi thì điều này thực sự nên được đánh dấu là "C (cdecl)" thay vì chỉ "C"
Steve Cox

@SteveCox Cả hai cdeclstdcallsử dụng cùng một phương thức cho giá trị trả về, vì vậy tôi đoán x86là đủ
anatolyg

7

Haskell, 20 byte

f x=foldr1 lcm[1..x]

Ví dụ sử dụng: map f [1..7]-> [1,2,6,12,60,60,420].

Thủ lcmthuật trong Haskell.


6

Python + SymPy, 45 byte

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

Khá tự giải thích.


Python 2, 57 54 byte

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

Kiểm tra nó trên Ideone .

Làm thế nào nó hoạt động

Đầu vào được lưu trữ trong các biến ir .

execthực thi mã r lần sau.

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

Trong khi i thay đổi từ r thành 1 , chúng tôi thêm giá trị ban đầu của r (được lưu trữ trong t ) nhiều lần nếu cần thiết để tự tạo r để tạo bội số của i . Kết quả là, rõ ràng là bội số của t .

Do đó, giá trị cuối cùng của r là bội số của tất cả các số nguyên trong phạm vi [1, ..., n] , trong đó n là đầu vào.


1
Không sử dụng các thư viện hoặc execthủ thuật của bên thứ ba, có một giải pháp 78 byte: from fractions import*;lambda n:reduce(lambda x,y:x*y/gcd(x,y),range(1,n+1),1) Sử dụng thực tế là như vậy lcm(x,y) = x*y/gcd(x,y).
Bakuriu

6

Python, 46 byte

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

Tìm kiếm nhiều ccủa g(n-1)trực tiếp. Mặc dù trước đây tôi đã có phương pháp này sẽ tìm nhầm 0 là bội số của bất cứ thứ gì, nhưng orngắn mạch hoặc (c%n<1)*ccũng sẽ bỏ qua c==0vì 0 là Falsey.


50 byte:

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

Giống như giải pháp của Dennis , nhưng là một hàm đệ quy. Có tính g(n-1), ngoại hình cho nhiều nhỏ nhất i*ncủa nđó cũng là một bội số của g(n-1). Thực sự chậm.

Cảm ơn Dennis cho 4 byte bằng cách xem bội số nthay vì g(n-1).


5

J, 9 byte

[:*./1+i.

Phương pháp tiếp cận thẳng. Tạo phạm vi số [0, ..., n-1], sau đó thêm một số cho từng số và giảm số đó bằng LCM.

Sử dụng

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


4

Toán học, 13 byte

LCM@@Range@#&

Điều này không tương đương với chỉ sáng tác LCMRangevới @*?
Maltysen

1
LCMvận hành phần tử khôn ngoan trên một danh sách, sẽ được thông qua Range, có nghĩa là điều này sẽ trả về lcm ( x ) cho x từ 1 đến n . Ngoài ra, còn thiếu một &chức năng ẩn danh. Một cái gì đó như LCM@@Range@#&cho 13 byte sẽ làm việc.
dặm



3

Octave, 27 byte

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

Tạo một hàm ẩn danh có thể được gọi là ans(N).

Demo trực tuyến

Giải trình

Giải pháp này tạo ra một danh sách tất cả các số giữa 1x( 1:x), chuyển đổi chúng thành một mảng ô với num2cell. Sau đó, việc {:}lập chỉ mục tạo ra một danh sách được phân tách bằng dấu phẩy được chuyển đến lcmdưới dạng nhiều đối số đầu vào để tính bội số chung nhỏ nhất. 1 luôn được truyền làm đối số đầu tiên lcmlcmluôn cần ít nhất hai đối số đầu vào.


1
Vì vậy, lcmtrong Octave chấp nhận nhiều hơn 2 đầu vào! Thú vị
Luis Mendo

@LuisMendo Yup 2+
Suever

3

MATLAB, 49 byte

@(x)find(~any(bsxfun(@rem,1:prod(1:x),(1:x)')),1)

+1 chobsxfun
flawr

3

Perl 6 , 13 byte

{[lcm] 1..$_}

Khối mã ẩn danh tạo Phạm vi từ 1 đến đầu vào (đã bao gồm), sau đó giảm số đó bằng &infix:<lcm>.

Thí dụ:

#! /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 byte:

Cảm ơn @ConorOBrien và @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):atiết kiệm một byte.
Neil

y*++i/g(y,i)tiết kiệm thêm một số byte.
Neil

1

05AB1E, 20 byte

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

Giải trình

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

Dùng thử trực tuyến


1

Chồn 0,15 , 12 byte

Tôi có hai giải pháp 12 byte và đã bao gồm cả hai.

1n[i1+4$M]N.

Hãy thử nó ở đây!

Giải trình

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.

Về đơn giản như nó được.


11nLd[4$M]N.

Hãy thử nó ở đây!

Giải trình

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.

Một giải pháp thứ ba có thể được bắt nguồn từ đây: loại bỏ a 1và thêm a dsau dòng điện d. Trong cả hai trường hợp, số phụ là cần thiết bởi vì vòng lặp for chạy quá nhiều lần và làm cho nó chạy ít hơn một lần mất hai byte ( 1-ngay trước số [).


1

Ruby, 25 byte

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

Ruby, 25 byte

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

1
Xin chào, và chào mừng đến với PPCG! Bài đăng đầu tiên tuyệt vời! Bạn không phải đặt tên cho chức năng của mình, vì vậy bạn có thể xóa g=.
NoOneIsHãy là

Chức năng ẩn danh được cho phép.
Erik the Outgolfer

1

Ngôn ngữ GameMaker, 60 byte

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

Dựa trên logic của câu trả lời của anatolyg.


1

PHP, 61 52 48 byte

đã lưu 9 byte nhờ @ user59178, 4 byte bằng cách hợp nhất các vòng lặp.

Đệ quy trong PHP là cồng kềnh do functiontừ khóa; vì vậy tôi sử dụng phép lặp.
Và với một vài thủ thuật "nhỏ", giờ tôi thậm chí còn đánh bại Arnauld hès JS .

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

lấy đầu vào từ đối số dòng lệnh. Chạy với -r.

phá vỡ

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

vô dụng

Đó thực sự là hai vòng lặp trong một:

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

Lưu ý: được sao chép từ câu trả lời của tôi trên bản sao




0

Hoon , 67 byte

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

Tạo danh sách [1..n], gấp lại danh sách với lcm. Thật không may, Hoon stdlib không có bản dựng sẵn mà tôi có thể sử dụng: /



0

AWK, 42 byte

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

Sử dụng dòng lệnh:

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

Tôi đã không thấy một AWKgiải pháp và một bản sao của câu hỏi vừa được đăng ngày hôm qua, vì vậy tôi nghĩ rằng tôi đã ném nó cùng nhau. Nó khá chậm giải quyết cho 19hoặc lớn hơn trên hộp của tôi, nhưng nó hoạt động.


0

QBIC , 35 32 byte

Điều này đã đưa tôi đến đây.

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

Giải trình:

:        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]

Đây là phiên bản dừng thử nghiệm qkhi bkhông phân chia rõ ràng. Ngoài ra, thứ tự của thử nghiệm b'chống lại s qđược đảo ngược trong giả định rằng cao b' s sẽ khó khăn hơn để chia cho (mất 2, 3, 4ví dụ: nếu %2=0, %4có thể là !0. Ngược lại không quá nhiều ...).

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



0

8 , 23 byte

1 ' lcm rot 2 swap loop

Mã này để lại kết quả giả trên ĐKDV

Cách sử dụng và ví dụ

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

Hay nói rõ hơn

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

ok> 7 pseudofact .
420
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.