Tìm các ước số tích cực!


11

Định nghĩa

Một số là dương nếu nó lớn hơn 0.

Một số ( A) là ước của một số khác ( B) nếu Acó thể chia Bmà không có phần dư.

Ví dụ, 2là một ước của 62có thể chia 6mà không có phần dư.

Mục tiêu

Nhiệm vụ của bạn là viết một chương trình / hàm lấy số dương và sau đó tìm tất cả các ước của nó.

Sự hạn chế

  • Bạn không được sử dụng bất kỳ tích hợp nào liên quan đến nguyên tố hoặc nhân tố .
  • Độ phức tạp của thuật toán của bạn không được vượt quá O (sqrt (n)) .

Sự tự do

  • Danh sách đầu ra có thể chứa các bản sao.
  • Danh sách đầu ra không cần phải sắp xếp.

Chấm điểm

Đây là . Giải pháp ngắn nhất trong byte thắng.

Tủ thử

input    output
1        1
2        1,2
6        1,2,3,6
9        1,3,9

Bạn có thể có nghĩa là chia , không phải yếu tố . Và tôi đoán bạn muốn có một sự phức tạp về thời gianO(sqrt(n)) .
flawr

Sự khác biệt giữa ướcyếu tố là gì?
Nữ tu bị rò rỉ

Chúng ta nói về các yếu tố, ví dụ như một số, nếu tích của các kết quả này lại là số ban đầu, nhưng các ước số thường là các số chia số đó mà không có số dư.
flawr

@flawr Cập nhật tương ứng.
Nữ tu bị rò rỉ

2
Nên có nhiều ví dụ. 99 (1 3 9 11 33 99)
Brad Gilbert b2gills

Câu trả lời:


4

PostgreSQL, 176 byte

WITH c AS(SELECT * FROM(SELECT 6v)t,generate_series(1,sqrt(v)::int)s(r)WHERE v%r=0)
SELECT string_agg(r::text,',' ORDER BY r)
FROM(SELECT r FROM c UNION SELECT v/r FROM c)s

SqlFiddleDemo

Đầu vào: (SELECT ...v)

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

  • (SELECT ...v) - đầu vào
  • generate_series(1, sqrt(v)::int) - các số từ 1 đến sqrt (n)
  • WHERE v%r=0 ước số -filter
  • gói với biểu thức bảng chung để tham khảo hai lần
  • SELECT r FROM c UNION SELECT v/r FROM c phần còn lại của ước và kết hợp
  • SELECT string_agg(r::text,',' ORDER BY r) tạo kết quả cuối cùng được phân tách bằng dấu phẩy

Nhập vào dưới dạng bảng:

WITH c AS(SELECT * FROM i,generate_series(1,sqrt(v)::int)s(r)WHERE v%r=0)
SELECT v,string_agg(r::text,',' ORDER BY r)
FROM(SELECT v,r FROM c UNION SELECT v,v/r FROM c)s
GROUP BY v

SqlFiddleDemo

Đầu ra:

╔═════╦════════════════╗
║ v   ║   string_agg   ║
╠═════╬════════════════╣
║  1  ║ 1              ║
║  2  ║ 1,2            ║
║  6  ║ 1,2,3,6        ║
║  9  ║ 1,3,9          ║
║ 99  ║ 1,3,9,11,33,99 ║
╚═════╩════════════════╝

3

C # 6, 75 byte

string f(int r,int i=1)=>i*i>r?"":r%i==0?$"{i},{n(r,i+1)}{r/i},":n(r,i+1);

Dựa trên giải pháp C # của downrep_nation, nhưng đệ quy và đánh gôn tiếp tục sử dụng một số tính năng mới từ C # 6.

Thuật toán cơ bản giống như thuật toán được trình bày bởi downrep_nation. Vòng lặp for được chuyển thành đệ quy, do đó tham số thứ hai. bắt đầu đệ quy được thực hiện bởi tham số mặc định, do đó hàm được gọi với số bắt đầu duy nhất được yêu cầu.

  • sử dụng các hàm dựa trên biểu thức mà không có khối sẽ tránh câu lệnh return
  • nội suy chuỗi trong toán tử ternary cho phép tham gia nối chuỗi và điều kiện

Vì hầu hết các câu trả lời ở đây (chưa) không tuân theo định dạng đầu ra chính xác từ các ví dụ, tôi giữ nguyên như vậy, nhưng vì một nhược điểm nên hàm bao gồm một dấu phẩy duy nhất ở kết quả.


Bài đăng đầu tiên rất hay!
Rɪᴋᴇʀ


2

Matlab, 48 byte

n=input('');a=1:n^.5;b=mod(n,a)<1;[a(b),n./a(b)]

Cái này hoạt động ra sao?
Nữ tu bị rò rỉ

Ngoài ra, bạn đã nghĩ ra một thuật toán mà tôi không thể nghĩ ra ... Tôi thật ngu ngốc.
Nữ tu bị rò rỉ

Tôi tìm thấy tất cả các divisos lên sqrt(n)và sau đó đặt từng ước dn/dtrong danh sách của tôi.
flawr

Đã thêm một số quy tắc. Có lẽ có thể giúp bạn tiết kiệm một số byte.
Leaky Nun

1
Tôi chưa thử nghiệm, nhưng bạn không thể sử dụng b=~mod(n,a)để lưu 1 byte?
Luis Mendo

2

J, 26 byte

(],%)1+[:I.0=]|~1+i.@<.@%:

Giải trình

(],%)1+[:I.0=]|~1+i.@<.@%:  Input: n
                        %:  Sqrt(n)
                     <.@    Floor(Sqrt(n))
                  i.@       Get the range from 0 to Floor(Sqrt(n)), exclusive
                1+          Add 1 to each
             ]              Get n
              |~            Get the modulo of each in the range by n
           0=               Which values are equal to 0 (divisible by n), 1 if true else 0
       [:I.                 Get the indices of ones
     1+                     Add one to each to get the divisors of n less than sqrt(n)
   %                        Divide n by each divisor
 ]                          Get the divisors
  ,                         Concatenate them and return

2

JavaScript (ES6) - 48 byte

f=n=>[...Array(n+1).keys()].filter(x=>x&&!(n%x))

Không hiệu quả lắm nhưng hoạt động! Ví dụ dưới đây:

let f=n=>[...Array(n+1).keys()].filter(x=>x&&!(n%x));
document.querySelector("input").addEventListener("change", function() {
  document.querySelector("output").value = f(Number(this.value)).join(", ");
});
Divisors of <input type="number" min=0 step=1> are: <output></output>


Chào mừng đến với PPCG!
Laikoni

O(n)

1

MATL , 12 byte

tX^:\~ftGw/h

Cách tiếp cận tương tự như trong câu trả lời của @ flawr .

Hãy thử trực tuyến!

Giải trình

t      % take input N. Duplicate.
X^:    % Generate range from 1 to sqrt(N)
\      % modulo (remainder of division)
~f     % indices of zero values: array of divisors up to sqrt(N)
tGw/   % element-wise divide input by those divisors, to produce rest of divisors
h      % concatenate both arrays horizontally

Tôi thường tự hỏi liệu mã kết hợp của các chương trình được viết bằng MATL có tạo ra một RNG tốt hay không.
flawr

@flawr Điều đó có thể áp dụng cho mọi ngôn ngữ golf mã đẹp :-)
Luis Mendo

1

05AB1E , 14 12 byte

Mã số:

ÐtLDŠÖÏDŠ/ï«

Giải trình:

Ð             # Triplicate input.
 tL           # Push the list [1, ..., sqrt(input)].
   D          # Duplicate that list.
    Š         # Pop a,b,c and push c,a,b.
     Ö        # Check for each if a % b == 0.
      Ï       # Only keep the truthy elements.
       D      # Duplicate the list.
        Š     # Pop a,b,c and push c,a,b
         /ï   # Integer divide
           «  # Concatenate to the initial array and implicitly print.

Sử dụng mã hóa CP-1252 . Hãy thử trực tuyến! .


Quan tâm để cung cấp một lời giải thích?
Nữ tu bị rò rỉ

@KennyLau Đã thêm
Adnan

1

Python 2, 64 byte

lambda n:sum([[x,n/x]for x in range(1,int(n**.5+1))if n%x<1],[])

Hàm ẩn danh này đưa ra một danh sách các ước số. Các ước số được tính bằng cách chia thử nghiệm các số nguyên trong phạm vi [1, ceil(sqrt(n))], đó là O(sqrt(n)). Nếu n % x == 0(tương đương n%x<1), thì cả hai xn/xlà ước của n.

Dùng thử trực tuyến


1

Thạch , 9 byte

½Rḍ³Tµ³:;

Như các câu trả lời khác, đây là O (n) nếu chúng ta đưa ra giả định (sai) rằng phép chia số nguyên là O (1) .

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

½Rḍ³Tµ³:;  Main link. Argument: n

½          Compute the square root of n.
 R         Construct the range from 1 to the square root.
  ḍ³       Test each integer of that range for divisibility by n.
    T      Get the indices of truthy elements.
     µ     Begin a new, monadic chain. Argument: A (list of divisors)
      ³:   Divide n by each divisor.
        ;  Concatenate the quotients with A.

Hãy thử trực tuyến!




0

Toán học, 50 byte

Tương tự như giải pháp của @ flawr .

Thực hiện phép chia đường cho x từ 1 đến căn bậc hai của n và nếu chia hết, lưu nó vào danh sách dưới dạng xn / x .

(#2/#)~Join~#&@@{Cases[Range@Sqrt@#,x_/;x∣#],#}&
  • Lưu ý rằng yêu cầu 3 byte để biểu diễn trong UTF-8, làm cho chuỗi 48 ký tự yêu cầu 50 byte trong biểu diễn UTF-8.

Sử dụng

  f = (#2/#)~Join~#&@@{Cases[Range@Sqrt@#,x_/;x∣#],#}&
  f[1]
{1, 1}
  f[2]
{2, 1}
  f[6]
{6, 3, 1, 2}
  f[9]
{9, 3, 1, 3}

Chà, nó đòi hỏi 3 byte ...
Leaky Nun

@KennyLau Vâng, tôi đã sai, nên có đôi kiểm tra
dặm

0

JavaScript (ES6), 66 62 byte

f=(n,d=1)=>d*d>n?[]:d*d-n?n%d?f(n,d+1):[d,...f(n,d+1),n/d]:[d]

Tôi nghĩ rằng tôi đã viết một phiên bản trả về một danh sách trùng lặp đã được sắp xếp và nó thực sự ngắn hơn 4 byte ...


0

C #, 87 byte


Chơi gôn

String m(int v){var o="1";int i=1;while(++i<=v/2)if(v%i==0)o+=","+i;o+=","+v;return o;}

Ung dung

String m( Int32 v ) {
    String o = "1";
    Int32 i = 1;

    while (++i <= v / 2)
        if (v % i == 0)
            o += "," + i;

    o += "," + v;

    return o;
}

Mã đầy đủ

using System;
using System.Collections.Generic;

namespace N {
    class P {
        static void Main( string[] args ) {
            List<Int32> li = new List<Int32>() {
                1, 2, 6, 9,
            };

            foreach (Int32 i in li) {
                Console.WriteLine( i + " »> " + m( i ) );
            }

            Console.ReadLine();
        }

        static String m( Int32 v ) {
            String o = "1";
            Int32 i = 1;

            while (++i <= v / 2)
                if (v % i == 0)
                    o += "," + i;

            o += "," + v;

            return o;
        }
    }
}

Phát hành

  • v1.0 - 87 bytes- Giải pháp ban đầu.

Ghi chú

  • Trong đang Golfed , tôi sử dụng var's và int' s thay vì String's và Int32' s để làm cho đoạn code ngắn hơn, trong khi ở Mã Ungolfedđầy đủ Mã tôi sử dụng String's và Int32' s để làm cho mã dễ đọc hơn.

Tôi đã nghe nói rằng fornói chung là tốt hơn while.
Nữ tu bị rò rỉ

Giải pháp của bạn có độ phức tạp là O (n) thay vì O (sqrt (n)) ...
Leaky Nun

@KennyLau nó phụ thuộc vào tình huống, trong trường hợp này có một forvòng lặp sẽ có cùng độ dài mà whilevòng lặp có. Trong trường hợp này, nó không liên quan hoặc có cái khác.
auhmaan

Nhưng trong trường hợp này, nó có thể giúp bạn tiết kiệm một byte ...
Leaky Nun

0

Lua, 83 byte

s=''x=io.read()for i=1,x do if x%i==0 then s=s..i..', 'end end print(s:sub(1,#s-2))

Thật không may, tôi không thể làm tốt hơn


1. chào mừng bạn đến với PPCG, hy vọng bạn sẽ thích trang web này! 2. bạn có thể thay đổi == 0 thành <1 để lưu một số byte. 3. bạn có thể sử dụng cấu trúc ternary thay vì nếu sau đó kết thúc, nhưng tôi không biết liệu nó có lưu bất kỳ byte nào không. 4. độ phức tạp của thuật toán của bạn là O (n) không đáp ứng yêu cầu.
Leaky Nun

Được rồi Danh sách cần phải được sắp xếp, hoặc định dạng thích hợp?
dùng6245072

"Danh sách đầu ra có thể chứa các bản sao. Danh sách đầu ra không cần phải sắp xếp."
Leaky Nun

Đúng rồi lol. Và tôi có cần in kết quả hoặc một mảng chứa nó là đủ không?
dùng6245072

Vâng, hoặc bạn in nó hoặc bạn trả lại nó (bên trong một chức năng).
Leaky Nun

0

Perl 6 , 40 byte

{|(my@a=grep $_%%*,^.sqrt+1),|($_ X/@a)}

Giải trình:

{
  # this block has an implicit parameter named $_

  # slip this list into outer list:
  |(

    my @a = grep
                 # Whatever lambda:
                 # checks if the block's parameter ($_)
                 # is divisible by (%%) this lambda's parameter (*)

                 $_ %% *,

                 # upto and exclude the sqrt of the argument
                 # then shift the Range up by one
                 ^.sqrt+1
                 # (0 ..^ $_.sqrt) + 1

                 # would be clearer if written as:
                 # 1 .. $_.sqrt+1
  ),
  # slip this list into outer list
  |(

    # take the argument and divide it by each value in @a
    $_ X/ @a

    # should use X[div] instead of X[/] so that it would return
    # Ints instead of Rats
  )
}

Sử dụng:

my &divisors = {|(my@a=grep $_%%*,^.sqrt+1),|($_ X/@a)}

.say for (1,2,6,9,10,50,99)».&divisors
(1 1)
(1 2 2 1)
(1 2 3 6 3 2)
(1 3 9 3)
(1 2 10 5)
(1 2 5 50 25 10)
(1 3 9 99 33 11)

0

c #, 87 byte

void f(int r){for(int i=1;i<=Math.Sqrt(r);i++){if(r%i==0)Console.WriteLine(i+" "+r/i);}

Tôi không biết nếu điều này làm việc cho tất cả các số, tôi nghi ngờ nó làm.

nhưng sự phức tạp là đúng, vì vậy đó đã là một cái gì đó không phải là nó



0

Mã máy IA-32, 27 byte

Hexdump:

60 33 db 8b f9 33 c0 92 43 50 f7 f3 85 d2 75 04
ab 93 ab 93 3b c3 5a 77 ec 61 c3

Mã nguồn (cú pháp MS Visual Studio):

    pushad;
    xor ebx, ebx;
    mov edi, ecx;
myloop:
    xor eax, eax;
    xchg eax, edx;
    inc ebx;
    push eax;
    div ebx;
    test edx, edx;
    jnz skip_output;
    stosd;
    xchg eax, ebx;
    stosd;
    xchg eax, ebx;
skip_output:
    cmp eax, ebx;
    pop edx;
    ja myloop;
    popad;
    ret;

Tham số đầu tiên ( ecx) là con trỏ tới đầu ra, tham số thứ hai ( edx) là số. Nó không đánh dấu sự kết thúc của đầu ra theo bất kỳ cách nào; người ta nên điền trước mảng đầu ra với các số không để tìm phần cuối của danh sách.

Một chương trình C ++ đầy đủ sử dụng mã này:

#include <cstdint>
#include <vector>
#include <iostream>
#include <sstream>
__declspec(naked) void _fastcall doit(uint32_t* d, uint32_t n) {
    _asm {
        pushad;
        xor ebx, ebx;
        mov edi, ecx;
    myloop:
        xor eax, eax;
        xchg eax, edx;
        inc ebx;
        push eax;
        div ebx;
        test edx, edx;
        jnz skip_output;
        stosd;
        xchg eax, ebx;
        stosd;
        xchg eax, ebx;
    skip_output:
        cmp eax, ebx;
        pop edx;
        ja myloop;
        popad;
        ret;
    }
}
int main(int argc, char* argv[]) {
    uint32_t n;
    std::stringstream(argv[1]) >> n;
    std::vector<uint32_t> list(2 * sqrt(n) + 3); // c++ initializes with zeros
    doit(list.data(), n);
    for (auto i = list.begin(); *i; ++i)
        std::cout << *i << '\n';
}

Đầu ra có một số trục trặc, mặc dù nó tuân theo thông số kỹ thuật (không cần sắp xếp; không cần sự độc đáo).


Đầu vào: 69

Đầu ra:

69
1
23
3

Các ước số là theo cặp.


Đầu vào: 100

Đầu ra:

100
1
50
2
25
4
20
5
10
10

Đối với hình vuông hoàn hảo, ước số cuối cùng được xuất hai lần (đó là một cặp với chính nó).


Đầu vào: 30

Đầu ra:

30
1
15
2
10
3
6
5
5
6

Nếu đầu vào gần với một hình vuông hoàn hảo, cặp cuối cùng là đầu ra hai lần. Đó là do thứ tự kiểm tra trong vòng lặp: đầu tiên, nó kiểm tra "phần còn lại = 0" và đầu ra, và chỉ sau đó nó kiểm tra "thương số <ước số" để thoát khỏi vòng lặp.


0

SmileBASIC, 49 byte

INPUT N
FOR D=1TO N/D
IF N MOD D<1THEN?D,N/D
NEXT

Sử dụng thực tế là D>N/D= D>sqrt(N)cho số dương


0

C, 87 81 byte

Được cải thiện bởi @ceilingcat , 81 byte:

i,j;main(n,b)int**b;{for(;j=sqrt(n=atoi(b[1]))/++i;n%i||printf("%u,%u,",i,n/i));}

Hãy thử trực tuyến!


Câu trả lời ban đầu của tôi, 87 byte:

i;main(int n,char**b){n=atoi(b[1]);for(;(int)sqrt(n)/++i;n%i?:printf("%u,%u,",i,n/i));}

Biên dịch với gcc div.c -o div -lm, và chạy với ./div <n>.


Phần thưởng: Một biến thể thậm chí ngắn hơn với độ phức tạp thời gian O (n) và mã hóa cứng n(46 byte + chiều dài n):

i,n=/*INSERT VALUE HERE*/;main(){for(;n/++i;n%i?:printf("%u,",i));}

Chỉnh sửa: Cảm ơn bạn @Sriotchilism O'Z cổ vì đã chỉ ra rằng các đầu vào không nên được mã hóa cứng, tôi đã sửa đổi trình chính để lấy đầu vào qua argv.


1
nđầu vào? Đặt đầu vào trong một biến không phải là một cách được chấp nhận để thực hiện đầu vào ở đây vì một số lý do. Bạn có thể xem thêm về các hình thức đầu vào và đầu ra được chấp nhận và không được chấp nhận của chúng tôi tại đây: codegolf.meta.stackexchange.com/questions/2447/ . Và nếu bạn tò mò về một ngôn ngữ cụ thể (ví dụ C), bạn có thể xem tại đây: codegolf.meta.stackexchange.com/questions/11924/ Lỗi .
Đăng Rock Garf Hunter

@ SriotchilismO'Z cổ Có, nlà đầu vào. Tôi sẽ thử sửa đổi nó để có một số cách khác. Cảm ơn bạn đã thông tin!
OverclockedSanic

0

APL (NARS), 22 ký tự, 44 byte

{v∪⍵÷v←k/⍨0=⍵∣⍨k←⍳⌊√⍵}

kiểm tra:

  f←{v∪⍵÷v←k/⍨0=⍵∣⍨k←⍳⌊√⍵}
  f 1
1 
  f 2
1 2 
  f 6
1 2 6 3 
  f 9
1 3 9 
  f 90
1 2 3 5 6 9 90 45 30 18 15 10 

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.