正の除数を見つけてください!


11

定義

ゼロより大きい場合、数値は正です。

数(A)は、別の数(の除数であるB場合)Aに分割することができBない残り。

たとえば、余りなしで除算できるため2、の除数です。626

ゴール

あなたの仕事は、正の数をとるプログラム/関数を作成し、その除数をすべて見つけることです。

制限

  • prime または factorizationに関連する組み込みは使用できません。
  • アルゴリズムの複雑さはO(sqrt(n))を超えてはなりませ

自由

  • 出力リストに重複が含まれている場合があります。
  • 出力リストをソートする必要はありません。

得点

これはです。バイト単位の最短ソリューションが勝ちです。

テストケース

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

あなたは、おそらく平均除数、ない要因。そして、私はあなたが持っているしたいと思い、時間の複雑さのをO(sqrt(n))
flawr

divisorfactorの違いは何ですか?
リーキー修道女

これらの積が再び元の数値になる場合、数値などの要因について説明しますが、除数は通常、その数値を剰余なしで除算する数値です。
flawr

@flawr適宜更新されました。
リーキー修道女

2
より多くの例があるはずです。99 (1 3 9 11 33 99)
ブラッドギルバートb2gills 16年

回答:


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 -フィルター除数
  • 共通テーブル式でラップして2回参照する
  • SELECT r FROM c UNION SELECT v/r FROM c 残りの除数と合成
  • 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);

downrep_nationのC#ソリューションに基づいていますが、再帰的であり、C#6のいくつかの新機能を使用してさらにダウンしています。

基本的なアルゴリズムは、downrep_nationで提示されるものと同じです。forループは再帰、つまり2番目のパラメーターになります。再帰開始はデフォルトのパラメーターによって行われるため、必要な単一の開始番号のみで関数が呼び出されます。

  • ブロックなしで式ベースの関数を使用すると、returnステートメントが回避されます
  • 三項演算子内の文字列補間により、文字列の連結と条件を結合できます

ここでのほとんどの回答は(まだ)例の正確な出力形式に従っていないので、そのままにしておきますが、欠点として、結果に単一の末尾コンマが含まれます。


素敵な最初の投稿!
Rɪᴋᴇʀ


2

Matlab、48バイト

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

これはどのように作動しますか?
リーキー修道女

また、あなたは私が考えることができなかったアルゴリズムを考案しました...私はどれほど愚かです。
リーキー修道女

これまでのすべての除数を見つけて、sqrt(n)各除数dn/dリストに入れます。
flawr

いくつかのルールを追加しました。たぶん数バイト節約できます。
リーキー修道女

1
私はテストしていませんが、b=~mod(n,a)1バイトを節約するために使用できませんか?
ルイスメンドー

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へようこそ!
ライコニ

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

@flawrそれはおそらく、ほぼすべてのコードのゴルフ言語に適用されます:-)
ルイスメンドー

1

05AB1E14 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エンコードを使用します。オンラインでお試しください!


説明を提供しますか?
リーキー修道女

追加された@KennyLau-
アドナン

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)、両方xn/xの除数ですn

オンラインで試す


1

ゼリー、9 バイト

½Rḍ³Tµ³:;

他の答えとして、整数除算がO(1)であるという(誤った)仮定を行う場合、これはO(√n)です。

使い方

½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∣#],#}&
  • UTF-8で表現するには3バイトが必要であり、48文字の文字列はUTF-8表現で50バイトを必要とすることに注意してください。

使用法

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

非ゴルフ

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コード、Iの使用varのとint'の代わりのよStringさんとInt32中ながら、コードを短くするのUngolfedコード完全なコード Iの使用StringのとInt32のコードを読みやすくします。

それforは一般的に優れていると聞きましたwhile
リーキー修道女

ソリューションには、O(sqrt(n))ではなくO(n)の複雑さがあります...
Leaky Nun

@KennyLauは状況に依存します。この場合、forループがあるとwhileループの長さが同じになります。この場合、onを持っているか、もう一方を持っているかは関係ありません。
auhmaan

しかし、この場合は1バイト節約できます...
リーキー修道女

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. if then endの代わりに三項構造を使用できますが、バイトが保存されるかどうかわかりません。4.アルゴリズムの複雑さはO(n)であり、要件を満たしていません。
リーキー修道女

大丈夫。リストを並べ替えたり、適切にフォーマットする必要がありますか?
user6245072

「出力リストに重複が含まれている可能性があります。出力リストをソートする必要はありません。」
Leaky Nun

そうだね そして、結果を印刷する必要がありますか、それを含む配列で十分ですか?
user6245072

まあ、それを印刷するか、(関数内で)返します。
リーキー修道女

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;

最初のパラメーター(ecx)は出力へのポインター、2番目のパラメーター(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

完全な正方形の場合、最後の除数は2回出力されます(それ自体とのペアです)。


入力:30

出力:

30
1
15
2
10
3
6
5
5
6

入力が完全な正方形に近い場合、最後のペアが2回出力されます。これは、ループ内のチェックの順序によるものです。まず、「剰余= 0」と出力をチェックしてから、「quotient <divisor」をチェックしてからループを終了します。


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に、入力をハードコーディングしてはならないことを指摘していただき、ありがとうございます。argvを介して入力を受け取るようにメイン送信を変更しました。


1
n入力はありますか?入力を変数に入れることは、いくつかの理由でここで入力を行う方法として受け入れられていません。承認済みおよび未承認の入力および出力フォームの詳細については、codegolf.meta.stackexchange.com / questions / 2447 / …をご覧ください。また、特定の言語(Cなど)に興味がある場合は、codegolf.meta.stackexchange.com / questions / 11924 / を参照してください
ポストロックガーフハンター

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