ค้นหาตัวหารที่เป็นบวก!


11

คำนิยาม

จำนวนเป็นบวกถ้ามันมากกว่าศูนย์

Number ( A) คือตัวหารของตัวเลขอื่น ( B) หากAสามารถหารBด้วยส่วนที่เหลือ

ตัวอย่างเช่น2เป็นตัวหาร6เพราะ2สามารถหาร6ด้วยส่วนที่เหลือ

เป้าหมาย

งานของคุณคือการเขียนโปรแกรม / ฟังก์ชั่นที่ใช้จำนวนบวกแล้วค้นหาตัวหารทั้งหมด

การ จำกัด

  • คุณอาจจะไม่ได้ใช้ใด ๆ ในตัวที่เกี่ยวข้องกับนายกรัฐมนตรี หรือ ตัวประกอบ
  • ความซับซ้อนของขั้นตอนวิธีการของคุณต้องไม่เกิน O (sqrt (n))

เสรีภาพ

  • รายการผลลัพธ์อาจมีรายการที่ซ้ำกัน
  • ไม่จำเป็นต้องเรียงรายการเอาท์พุท

เกณฑ์การให้คะแนน

นี่คือรหัสกอล์ฟทางออกที่สั้นที่สุดในหน่วยไบต์ชนะ

Testcases

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

คุณอาจจะหมายถึงตัวหารไม่ปัจจัย และฉันคิดว่าคุณต้องการความซับซ้อนของO(sqrt(n))เวลา
ข้อบกพร่อง

ความแตกต่างระหว่างตัวหารและปัจจัยคืออะไร?
Leun Nun

เราพูดถึงปัจจัยต่าง ๆ เช่นตัวเลขถ้าผลลัพธ์ของผลลัพธ์เหล่านี้เป็นตัวเลขดั้งเดิมอีกครั้ง แต่ตัวหารมักเป็นตัวเลขที่หารจำนวนดังกล่าวโดยไม่เหลือ
ข้อบกพร่อง

@flawr อัปเดตตามนั้น
Leun Nun

2
ควรมีตัวอย่างเพิ่มเติม 99 (1 3 9 11 33 99)
Brad Gilbert b2gills

คำตอบ:


4

PostgreSQL, 176 ไบต์

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

การป้อนข้อมูล: (SELECT ...v)

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

  • (SELECT ...v) - อินพุต
  • generate_series(1, sqrt(v)::int) - ตัวเลขตั้งแต่ 1 ถึง sqrt (n)
  • WHERE v%r=0 ตัวกรองตัวกรอง
  • ห่อด้วยนิพจน์ตารางทั่วไปเพื่ออ้างอิงสองครั้ง
  • SELECT r FROM c UNION SELECT v/r FROM c generete ส่วนที่เหลือของตัวหารและรวม
  • SELECT string_agg(r::text,',' ORDER BY r) สร้างผลลัพธ์ที่คั่นด้วยเครื่องหมายจุลภาคสุดท้าย

อินพุตเป็นตาราง:

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

เอาท์พุท:

╔═════╦════════════════╗
║ 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 ไบต์

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

อิงจากโซลูชัน C # ของ downrep_nation แต่เรียกซ้ำและเล่นกอล์ฟต่อไปโดยใช้คุณลักษณะใหม่จาก C # 6

อัลกอริทึมพื้นฐานเหมือนกับที่แสดงโดย downrep_nation for-loop ถูกเปลี่ยนเป็นการเรียกซ้ำดังนั้นพารามิเตอร์ที่สอง การเรียกซ้ำเกิดขึ้นโดยพารามิเตอร์เริ่มต้นดังนั้นฟังก์ชันจะถูกเรียกด้วยหมายเลขเริ่มต้นเดียวที่จำเป็นเพียงอย่างเดียว

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

เนื่องจากคำตอบส่วนใหญ่ที่นี่ (ยัง) ไม่เป็นไปตามรูปแบบผลลัพธ์ที่แน่นอนจากตัวอย่างฉันเก็บไว้เหมือนเดิม แต่เนื่องจากข้อเสียเปรียบฟังก์ชันจึงรวมเครื่องหมายจุลภาคต่อท้ายที่ผลลัพธ์


โพสต์แรกที่ดี!
Rɪᴋᴇʀ


2

Matlab, 48 ไบต์

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

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

นอกจากนี้คุณยังคิดค้นอัลกอริทึมที่ฉันนึกไม่ออก ... ว่าฉันโง่แค่ไหน
Leun Nun

ฉันพบsqrt(n)ตัวหารทั้งหมดแล้วใส่ตัวหารแต่ละตัวdและn/dในรายการของฉัน
ข้อบกพร่อง

เพิ่มกฎบางอย่าง อาจช่วยให้คุณประหยัดบางไบต์
Leun Nun

1
ฉันยังไม่ได้ทดสอบ แต่คุณไม่สามารถใช้b=~mod(n,a)บันทึก 1 ไบต์ได้หรือไม่
Luis Mendo

2

J, 26 ไบต์

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

คำอธิบาย

(],%)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 ไบต์

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

ไม่ค่อยมีประสิทธิภาพ แต่ใช้งานได้! ตัวอย่างด้านล่าง:

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>


ยินดีต้อนรับสู่ PPCG!
Laikoni

O(n)

1

MATLขนาด 12 ไบต์

tX^:\~ftGw/h

วิธีการคล้ายกับว่าใน@ flawr ของคำตอบ

ลองออนไลน์!

คำอธิบาย

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

ฉันมักจะสงสัยว่ารหัสที่รวมกันของโปรแกรมที่เขียนใน MATL จะทำให้ RNG ดีขึ้นหรือไม่
ข้อบกพร่อง

@flawr ที่อาจนำไปใช้กับทุกภาษาสวยกอล์ฟรหัส :-)
หลุยส์ Mendo

1

05AB1E , 14 12 ไบต์

รหัส:

ÐtLDŠÖÏDŠ/ï«

คำอธิบาย:

Ð             # 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.

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


สนใจที่จะให้คำอธิบาย?
Leun Nun

@KennyLau เพิ่ม
Adnan

1

Python 2, 64 ไบต์

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

ฟังก์ชั่นที่ไม่ระบุชื่อนี้แสดงรายการตัวหาร หารคำนวณโดยแบ่งการทดลองของจำนวนเต็มในช่วงซึ่งเป็น[1, ceil(sqrt(n))] O(sqrt(n))ถ้าn % x == 0(เทียบเท่าn%x<1) จากนั้นทั้งสองxและเป็นตัวหารของn/xn

ลองออนไลน์


1

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

½Rḍ³Tµ³:;

ในฐานะที่เป็นคำตอบอื่น ๆ นี้เป็นO (√n)ถ้าเราทำ (เท็จ) สมมติฐานที่ว่าแบ่งจำนวนเต็มคือO (1)

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

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

ลองออนไลน์!


ขอให้เรายังคงอภิปรายนี้ในการแชท
เดนนิส


0

Mathematica ขนาด 50 ไบต์

คล้ายกับของ @ flawr วิธีการแก้ปัญหา

ดำเนินการทางแผนกxตั้งแต่วันที่ 1 ถึงรากที่สองของnและถ้าหารประหยัดในรายการเป็นxและn / x

(#2/#)~Join~#&@@{Cases[Range@Sqrt@#,x_/;x∣#],#}&
  • โปรดทราบว่าต้องมี 3 ไบต์เพื่อแสดงใน UTF-8 ทำให้สตริงอักขระ 48 ตัวต้องใช้ 50 ไบต์ในการแสดง UTF-8

การใช้

  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}

ดีก็ต้องมี 3 ไบต์ ...
รั่วนูน

@KennyLau ใช่ฉันเป็นคนผิดควรมีสองตรวจสอบ
ไมล์

0

JavaScript (ES6), 66 62 ไบต์

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

ฉันคิดว่าฉันจะเขียนเวอร์ชันที่ส่งกลับรายการที่ซ้ำซ้อนที่เรียงลำดับและที่จริงแล้วกลับเป็น 4 ไบต์ที่สั้นกว่า ...


0

C #, 87 ไบต์


แข็งแรงเล่นกอล์ฟ

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

Ungolfed

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

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

    o += "," + v;

    return o;
}

รหัสเต็ม

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;
        }
    }
}

ข่าว

  • v1.0 - 87 bytes- โซลูชั่นเริ่มต้น

หมายเหตุ

  • ในรหัส Golfedฉันใช้var's และint' s แทนString'และInt32' s เพื่อทำให้รหัสสั้นลงในขณะที่ในรหัส Ungolfedและรหัสเต็มฉันใช้StringและInt32เพื่อทำให้รหัสอ่านง่ายขึ้น

ผมเคยได้ยินว่าเป็นเรื่องปกติดีกว่าfor while
Leun Nun

วิธีการแก้ปัญหาของคุณมีความซับซ้อนของ O (n) แทน O (sqrt (n)) ...
Leaky Nun

@KennyLau ขึ้นอยู่กับสถานการณ์ในกรณีนี้การforวนซ้ำจะมีความยาวเท่ากับการwhileวนซ้ำ ในกรณีนี้มันไม่เกี่ยวข้องกับการมีหรือมีอื่น ๆ
auhmaan

แต่ในกรณีนี้มันสามารถช่วยคุณประหยัดไบต์ได้ ...
Leaky Nun

0

Lua, 83 ไบต์

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

ฉันไม่สามารถทำได้ดีกว่านี้โชคไม่ดี


1. ยินดีต้อนรับสู่ PPCG หวังว่าคุณจะสนุกกับเว็บไซต์นี้! 2. คุณสามารถเปลี่ยน == 0 เป็น <1 เพื่อบันทึกบางไบต์ 3. คุณสามารถใช้โครงสร้างประกอบไปด้วยแทนที่จะสิ้นสุดแล้ว แต่ฉันไม่รู้ว่ามันจะบันทึกไบต์ใด ๆ 4. ความซับซ้อนของอัลกอริทึมของคุณคือ O (n) ซึ่งไม่เป็นไปตามข้อกำหนด
Leun Nun

เอาล่ะ รายการจะต้องมีการสั่งซื้อหรือจัดรูปแบบที่เหมาะสม?
user6245072

"รายการเอาท์พุทอาจมีรายการที่ซ้ำกันรายการเอาท์พุทไม่จำเป็นต้องเรียงลำดับ"
Leun Nun

ถูกต้องแล้ว และฉันต้องพิมพ์ผลลัพธ์หรืออาร์เรย์ที่มีค่าเพียงพอหรือไม่?
user6245072

อย่างใดอย่างหนึ่งที่คุณพิมพ์หรือคุณกลับ (ภายในฟังก์ชั่น)
Leun Nun

0

Perl 6 , 40 ไบต์

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

คำอธิบาย:

{
  # 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
  )
}

การใช้งาน:

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 ไบต์

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

ฉันไม่ทราบว่าวิธีนี้ใช้ได้กับทุกหมายเลขหรือไม่

แต่ความซับซ้อนนั้นถูกต้องแล้วก็มีบางอย่างที่ไม่ได้เป็นเช่นนั้น



0

รหัสเครื่อง IA-32 ขนาด 27 ไบต์

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

รหัสที่มา (ไวยากรณ์ 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;

First พารามิเตอร์ ( ecx) เป็นตัวชี้ไปยังผลลัพธ์พารามิเตอร์ที่สอง (edx ) คือตัวเลข มันไม่ได้ทำเครื่องหมายจุดสิ้นสุดของเอาต์พุตในทางใด หนึ่งควรเติมอาร์เรย์เอาต์พุตด้วยศูนย์เพื่อหาจุดสิ้นสุดของรายการ

โปรแกรม C ++ เต็มรูปแบบที่ใช้รหัสนี้:

#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';
}

เอาต์พุตมีข้อบกพร่องบางอย่างแม้ว่าจะเป็นไปตามข้อมูลจำเพาะ (ไม่จำเป็นต้องเรียงลำดับ; ไม่จำเป็นต้องมีเอกลักษณ์)


อินพุต: 69

เอาท์พุท:

69
1
23
3

ตัวหารอยู่ในคู่


อินพุต: 100

เอาท์พุท:

100
1
50
2
25
4
20
5
10
10

สำหรับสี่เหลี่ยมที่สมบูรณ์แบบตัวหารสุดท้ายจะถูกส่งออกสองครั้ง (เป็นคู่กับตัวเอง)


อินพุต: 30

เอาท์พุท:

30
1
15
2
10
3
6
5
5
6

หากอินพุตอยู่ใกล้กับสี่เหลี่ยมจัตุรัสที่สมบูรณ์แบบคู่สุดท้ายจะถูกส่งออกสองครั้ง เป็นเพราะลำดับการตรวจสอบในลูป: อันดับแรกตรวจสอบ "เหลือ = 0" และเอาท์พุทและจากนั้นจะตรวจสอบ "quotient <ตัวหาร" เพื่อออกจากลูป


0

SmileBASIC ขนาด 49 ไบต์

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

ใช้ความจริงที่D>N/D= D>sqrt(N)สำหรับจำนวนบวก


0

C, 87 81 ไบต์

ปรับปรุงโดย@ceilingcat , 81 ไบต์:

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

ลองออนไลน์!


คำตอบเดิมของฉัน 87 ไบต์:

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

รวบรวมและทำงานกับgcc div.c -o div -lm./div <n>


โบนัส:ตัวแปรที่สั้นกว่าซึ่งมีความซับซ้อนของเวลา O (n) และฮาร์ดโค้ดn(46 ไบต์ + ความยาวn):

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

แก้ไข: ขอบคุณ @Sriotchilism O'Zaic สำหรับการชี้ให้เห็นว่าอินพุตไม่ควร hardcoded ฉันปรับเปลี่ยนการส่งหลักเพื่อรับอินพุตผ่าน argv


1
เป็นnอินพุตหรือไม่ การใส่อินพุตในตัวแปรไม่ใช่วิธีที่ยอมรับในการป้อนข้อมูลที่นี่ด้วยเหตุผลหลายประการ ท่านสามารถดูรายละเอียดเพิ่มเติมเกี่ยวกับการเข้าและส่งออกในรูปแบบที่ได้รับการยอมรับและไม่ได้รับการยอมรับของเราที่นี่: codegolf.meta.stackexchange.com/questions/2447/... และถ้าคุณอยากรู้เกี่ยวกับภาษาเฉพาะ (เช่น C) คุณสามารถดูที่นี่: codegolf.meta.stackexchange.com/questions/11924/...
Ad Hoc Garf Hunter

@ SriotchilismO'Zaic ใช่nเป็นอินพุต ฉันจะลองแก้ไขมันเพื่อให้อินพุทเป็นวิธีอื่น ขอบคุณสำหรับข้อมูล!
OverclockedSanic

0

APL (NARS), 22 ตัวอักษร, 44 ไบต์

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

ทดสอบ:

  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 

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