10進表現が2進数のように見える、指定された数の倍数を見つける


34

私が遭遇している問題に興味深いと思われるコードレビューサイトで。OPは間違っていると思いますが、確信が持てません...それでは彼のために解決しましょう!(関数/手順ではなくプログラムを書く)

入力(stdinまたは類似):

x10進表記の整数。1より大きく2 ^ 31未満です。

出力(stdoutまたは類似):

y10進表記の整数。x * y10進表記の製品には、数字0と1のみが含まれている必要があります。0より大きい最小の数字でなければなりません。

注:出力は制限されません-最小値yが約10 ^ 100の場合、プログラムは100桁すべてを出力する必要があります(2 ^ 64などの合理的な制限があるかどうかはわかりませんy-それを解決しませんでした) )。

プログラムは、すべてのx範囲で妥当な時間(1秒?1時間?-そのようなもの)で終了するはずです。

ボーナス:

あなたのプログラムは、(RAMを除く)入力の大きさに制限があり、そしてにより多項式の複雑さ、あなたのプログラムの乗算バイト数を持っていない場合は0.8ダウンとラウンド。


例:入力2; 出力5、2 * 5 = 10であるため

例:入力21; 48121 * 481 = 10101であるため、出力


免責事項:私はコードレビューサイトの質問に対して責任を負いません。矛盾がある場合は、上記の説明のみを適切な仕様と見なす必要があります。

OEIS A079339


6
常に解決可能である必要があります。10 ^ n mod x = qとなるような無限数のnが存在するように、少なくとも1つのqが存在する必要があることは明らかです。このようなnの値をx個取り、それぞれのべき乗10 ^ nを合計します。
feersum

1
9の倍数は、異常に高い結果を生成するようです。
SuperJedi224

1
関連プロジェクトオイラーの問題、この質問はおなじみのようだと思った他の人のために
-Sp3000

1
多項式の複雑さとは、入力の桁数の多項式、または入力の値の多項式を意味しますか?
レトコラディ

3
@anatolyg鉱山はブルートフォースではありません
-aditsu

回答:


8

Pyth、9バイト

f!-`*TQ10

デモンストレーション

各倍数について、文字列に変換し、数字を減算して10(この場合Pythの便利なintをstrキャストに使用)、結果を論理的に否定し、正しい倍数が見つかった場合にのみ検索を終了します。

ボーナスソリューション、10バイト:

f.xi`*TQ2Z

このソリューションは、実際に数値の文字列表現が2進数(i ... 2)として処理できるかどうかを確認し、この試行でエラーがスローされないときに終了します。


18

Python 2、効率的なソリューション、99

n=input()
d={n:0}
k=1
while min(d):[d.setdefault((x+k)%n,d[x]+k)for x in set(d)];k*=10
print d[0]/n

いくつかのゴルフのヒントをありがとう。

他のすべての人に、入力の結果を得るのにどれだけの時間がかかるか(自分の答えで)投稿するように挑戦します。72または99、それらが本当に速い場合は、79992次のようにします(ここでも1秒未満)。

説明:

(コードはかなり読みやすいので)これは必要ないと思ったのですが、リクエストがあったので、ここに行きます:

最初のアイデアは、2進法の数は1以上の10の累乗の合計であるということです。したがって、剰余0が得られるまでさまざまな方法で10の累乗を追加することができます。

これを単純に行うと、すべてのバイナリ形式の数値を生成してテストするのと同じことになります。しかし、残りの多くは同じです。より良い方法は、特定の剰余を与えた最小の数値のみを記録し、記録した数値に10の累乗を連続して追加することです。それがプログラムの動作です。

dキーは剰余であり、値はその剰余を含むバイナリ形式の数値である辞書/マップです。イニシャルn:0は特別なケースです:0:0パワーを追加できるようになっているはずですが、キー0を見つけるとアルゴリズムが停止するためn、代わりに使用しました。

次にk、既存のすべての数値に10の累乗(に格納)を追加し、残りを記録し始めます。kremaining:(x+k)%nとnumber:d[x]+kに追加し、それが新しい剰余である場合にのみ記録します:d.setdefault(…)、次のpower:に進み、k*=10キー0を取得するまで繰り返します:while min(d)

最後に、d[0]剰余0 modのバイナリに見える数を与えるnので、それを除算しnて解を得ます。

注:プログラムは、多数(10の累乗ではなく指数を記録し、以前の値からべき乗の剰余を計算する)を回避することでより効率的にすることができますが、コードゴルフです。

実際、ここでは、より高速なバージョンを作成しました。

n=input()
d={n:0}
k=1
b=0
while 0not in d:
 for x in list(d):d.setdefault((x+k)%n,b)
 k=(k*10)%n;b+=1
x=10**d[0]
while x%n:x+=10**d[n-x%n]
print x/n

1
私の答えも得られません。xD「Dangit、Java、BigIntegerをデフォルトで使用するよりもInteger.MAX_VALUEを選択するのは呪いだ!」-すべてのJavaプログラマー
Addison Crump

@VTCAKAVSMoACE Longを使用してみませんか?
-aditsu

うーん 余分なバイトですが、...価値があります。ありがとう!
アディソンクランプ

か否か。それは実際に真剣にそれを減らします。ありがとう!
アディソンクランプ

1
99を解くタイミング:aditsu:0.001秒; xnor:5時間以上、まだ完了していません。
-user193661

13

Python 2、47バイト

n=a=input()
while'1'<max(str(a)):a+=n
print a/n

入力番号nと現在の倍数を追跡しますaaバイナリのように見える場合、比率を出力しa/nます。数がで作られていることを確認するには0さんと1さん、我々はにその文字列表現で最大の文字を比較します'1'

で終わるlongを回避するためにのstr(a)代わりに使用`a`Lます。残念ながら、'L'はより大きいです'1'


12

Perl、27バイト

#!perl -p
1while($_*++$\)=~/[2-9]/}{

シバンを1つとしてカウントすると、入力はstdinから取得されます。

サンプルの使用法

$ echo 2 | perl dec-bin.pl
5

$ echo 21 | perl dec-bin.pl
481

$ echo 98 | perl dec-bin.pl
112245

Perl、25バイト

#!perl -p
eval'0b'.++$\*$_||redo}{

@skmrxによる 2バイトの改善。

正規表現をチェックするのではなく、代わりに製品をバイナリリテラルとして評価しようとします。失敗すると、次へと進みます。通常、このoct関数はこの目的に使用されますが、無効な数字を静かに削除しますが、これはこのチャレンジでは役に立ちません。


Perl、40バイト

#!perl -p
1while($b=sprintf"%b",++$i)%$_;$_=$b/$_

はるかに効率的なソリューション。バイナリ表現を反復処理し、それらを基数10として解釈してから、可分性をチェックします。100未満のすべての値の実行時間はごくわずかです。

サンプルの使用法

$ echo 72|perl dec-bin.pl
1543209875

$ echo 99|perl dec-bin.pl
1122334455667789

2
ニース:)今日の投稿からいくつかの新しいことを学びました!コードを読みながら、最初のコードから数バイトを削る方法を見つけましたeval"0b".$_*++$\||redo}{
。– svsd

しかしuse bigint、OPがサポートすることを義務付けている多数をサポートするために含める必要があると思います:(
svsd

1
@skmrnそれは素晴らしい。試しましたがoct'0b'.++$\*$_、無効な数字を静かに切り取ります。eval代わりに使うとは思わなかった。
プリモ

11

Javascript、43バイト

これは思ったよりもずっと短くなりました。基本的にはy1まで増加しますy * (input number) = (binary-looking number)。明らかに非効率的です。

for(x=prompt(y=0);!+('0b'+x*++y););alert(y)


Javascript(より効率的なソリューション)、53バイト

これはyまでバイナリで増加しますy / (input number) = (number without a remainder)。次に、出力します(number without a remainder)

for(x=prompt(y=1);(z=y.toString(2))%x;y++);alert(z/x)


Javascript(さらに効率的なソリューション)、76バイト

これは、上記の前の方法の両方を組み合わせたものです。yいずれかy * (input number) = (binary-looking number)(出力がであることを意味するy)またはy / (input number) = (number without a remainder)(出力がであることを意味する)まで増分をチェックします(number without a remainder)

for(x=prompt(y=a=0);!a;a=+('0b'+x*++y)?y:(z=y.toString(2))%x?0:z/x);alert(a)


可能な場合は1を指定する必要があります(入力例:1)
edc65

@ edc65修正済み-バイトカウントの変更なし!
ママファンロール

これにより、Safari 9.0がクラッシュします。ジュッセイイン。:)
アディソンクランプ

1
ただし、出力の小さな数値に制限されます。Javascriptの数値の精度は17桁で、OPはもっと大きな値を要求しています(モジュラー演算を使用して実行できます)
-edc65

ヒント:入力72を試行しないでください。Firefox41は15分間フリーズしてからクラッシュします。私はこれを難しい方法で発見しました。
ETHproductions

9

Haskell、72 70 64 60 58バイト

main=do x<-readLn;print$[y|y<-[1..],all(<'2')$show$x*y]!!0

編集:@Jan Dvorakは4バイトの節約に役立ちました。

編集:@BlackCapはdo表記に切り替えることで2バイトを節約しました。ありがとう!


main=print.f=<<readLn
ジョンドヴォルザーク

fをインライン化することにより、バイトを保存できますmain=readLn>>= \x->print$[y|y<-[1..],all(<'2')$show$x*y]!!0
。– BlackCap

2実際にはmain=do x<-readLn;print$[y|y<-[1..],all(<'2')$show$x*y]!!0
-BlackCap

@BlackCap:いいね!どうもありがとう!
-nimi

7

Python 2、67 65 63 60バイト

a=input();b=1
while set(`a*b`)&set('23456789'):b+=1
print b

2バイトのStatusと5バイトのShebangに感謝します!


1
初期化する必要があると思うb=1
-anatolyg

2
実行することで2バイトを削ることができますany(c in`a*b`for c in'23456789')
ステータス

1
これについてはわかりませんが、not c in`a*b`for c in'10'うまくいくでしょうか?
コール

2
while条件をに変更すると、6バイト節約できますset('a*b')&set('23456789')
ケイド

2
`Lforとlongを生成し'L'>'1'ます。
user193661

6

JavaScriptの(ES6)222 250

任意精度の数学を使用する(10進数の文字列を操作)

これはもう少し(完了)できますが、 JS標準の数値(精度の10進数17桁)に限定されておらず、高速であるという事実が気に入っています。

EcmaScript 6準拠のブラウザーで以下のスニペットを実行してテストします。時間は9998まで許容されます-9999を試さないで、999に我慢してください。

// As a complete program with I/O via popup  
for(n=+prompt(a=[0],q=[t=1]);t;){for(c=1,t=i=0;i<a.length;i++)a[i]=a[i]&c?0:a[i]|c?(c=0,t+=q[i],1):c=0;c&&(a[i]=c,t+=q[i]=q[i-1]*10%n);t%=n}a.reverse().map(a=>(z+=[a],d=z/n|0,z%=n,r||d?r+=d:0),r='',z=0);alert([r,a.join``])

// As a testable function
f=n=>{
  for(a=[0],q=[t=1];t;)
  {
    for(c=1,t=i=0;i<a.length;i++)
      a[i]=a[i]&c?0:a[i]|c?(c=0,t+=q[i],1):c=0
    c&&(a[i]=c,t+=q[i]=q[i-1]*10%n);
    t%=n
  }  
  a.reverse().map(a=>(z+=[a],d=z/n|0,z%=n,r||d?r+=d:0),r='',z=0)
  return [r,a.join``]
}

// Test and timing
out = x => O.innerHTML += x + '\n'

setTimeout(_=>{
;[1,2,10, 21, 23, 98, 72, 9, 99, 999]
.forEach((test,i) => { 
  var t0 = ~new Date  
  var result = f(test)
  out('n='+test+' '+result+' time(ms) ' + (t0-~new Date))
})},100)  
<pre id=O>Timing test cases ...
</pre>

より読みやすい

これは、分離された機能としてモジュラスと長い除算を持つ最初のバージョンです。

// function M - Modulus with arbitrary precision - a is a string of decimal digits
M = (a, b, q = 1, t = 0, j = a.length) => {
  while (j--) + a[j] ? t += q : 0, q = (q * 10) % b;
  return t % b
}

// function D - Long division with arbitrary precision - a is a string of decimal digits
D = (a, b, r = '', z = 0) => [...a].map(a => (z += a, d = z / b | 0, z %= b, r || d ? r += d : 0)) && r

// Testable function 
f = n => {
  for (i = 0; ++i < 1e7 && (z = M(v = i.toString(2), n)););
  return z ? ['big'] : [D(v, n), v]
}

Firefoxで動作するようにしましたが、たとえば999
aditsu

36秒で999を処理できる新しいバージョンがありますが、javascriptタイムアウトで9999に達する見込みはありません(追加される各「9」には終了時間の2 ^ 9(〜500)倍の時間が必要です)
edc65

JavaScriptでできることは@aditsuです(ただし、C#でもまったく同じです)。信じられないほどのアルゴリズムの説明をすぐに待っている
edc65

説明を追加しました
-aditsu



4

PHP、50バイト

while(preg_match('/[^01]/',$argv[1]*++$y));echo$y;

いくつかのテストケース

1 > 1
2 > 5
12 > 925
21 > 481

1
このようなものを作るつもりだった、これは私が思っていたよりも少し短い
-Martijn

4

CJam、19 17 16バイト

li:V!{)_V*sAs-}g

オンラインで試す

条件に一致するものが見つかるまで値を順番に試すブルートフォースソリューション。

最新バージョンは、使用して2つのバイトのおかげで節約Asの代わりに"01"文字列を構築する01@aditsuによって示唆されているように、。コメントで提案された完全なソリューションは、もう1バイト節約しますが、私のものとはかなり異なって見えるため、自分の名前で投稿したくありませんでした。

そして、@ Dennisによってさらに1バイトが保存されました。

説明:

li      Get input and convert to int.
:V      Save it in variable V.
!       Negate the value. Since we saved it in V, we don't need it on the stack anymore.
        But we need 0 on the stack as the start value for y. This conveniently
        accomplishes both with a single operator, since the input is guaranteed to be
        larger than 0.
{       Loop over y.
  )       Increment y.
  _       Copy it.
  V*      Multiply with input in variable V.
  s       Convert to string.
  As      Push the string "10", as the number 10 converted to a string .
  -       Remove 0 and 1 digits. This will result in an empty list if there were only
          0 and 1 digits. The empty list is falsy, and will terminate the loop.
}g      End loop.

3
16:li0{1$+_sAs-}g\/
aditsu

ありがとう、@ aditsu。私の名前でソリューション全体をコピーしたくありませんでした。それはAs非常にローカルな変更であるため、文字列を構築するために取りました。
レトコラディ

1
@RetoKoradi 16バイト、変更の少ない:li:V!{)_V*sAs-}gまた、0{)_easi*sAs-}g(15バイト)はJavaインタープリターとコマンドライン引数で動作します。
デニス

4

Pythonの3 2、101の 76バイト

@aditsuのおかげで-25バイト

@aditsuのソリューションとほぼ同じ効率

99 -> 0.436 Seconds
72 -> 0.007 Seconds
b,m,n=1,1,input()
while b%n:
 b=int("{0:b}".format(m))
 m+=1
print b/n

倍数を昇順でループしようとする代わりに、「バイナリ」形式で生成している製品をループしようとしています。


悪くありません:) 9999はどうですか?
aditsu

2
いくつかのゴルフのヒント:使用パイソン2( n=input())、(while b%n:初期化b1)、インデントなし
aditsu

@aditsuありがとう!9999うーん、数日かかるようです。元の図面に戻ります-_-
Rnet

1
bin(m)[2:]フォーマット文字列よりも短くする必要があります。ダブル割り当てをオンにb=m=1すると、数個も節約できます。
プリモ

4

Java、213バイト

import java.math.*;class P{public static void main(String[]a){BigInteger b=new java.util.Scanner(System.in).nextBigInteger(),c,d=c=b.ONE;while(!(b.multiply(c)+"").matches("[01]+"))c=c.add(d);System.out.print(c);}}

BigIntegersを使用し、それ自体が(すべての合理的な意図と目的のために)無制限の入力サイズを持ちます。ただし、複雑さについてはわかりません。これは、ここでの機能の成長率に依存します。

ほんの少しのバイト数を節約してくれたジオビットとypnypnに感謝します。


こんにちは、メインメソッドでこれをどのように呼び出しますか?試してみたが成功しなかった
ヤシンハジャイ

staticメソッドに修飾子を追加する必要があります。
SuperJedi224

1
質問は、ソリューションは単なる機能ではなく、完全なプログラムであるべきだと言っています。
raznagul

b.ONEandの!(b.multiply(c)+"")代わりにandで15をカットできtoString()ます。
ジオビット

@raznagul:修正。
SuperJedi224

4

C、3675バイト

Code Golfには長い...

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <assert.h>

#define min_n 1
#define max_n 10000

unsigned *mod_list; // list of mods to check
unsigned mod_list_length; // number of mods to check
char *graph; // for each mod, the power of 10 that gives it

void BuildGraph(unsigned n)
{
    unsigned mod10 = 10 % n;
    int pow = 1;

    memset(graph, 0, n);
    if (n == 1)
        return;
    mod_list[0] = 0; // mod 0 - no path coming to it yet
    mod_list[1] = 1; // mod 1 - 10^0 coming to it
    mod_list_length = 2;
    while (graph[0] == 0)
    {
        // We are going to change mod_list_length by adding new nodes.
        // This should not affect the set of nodes we check, so save its old value.
        unsigned mod_list_limit = mod_list_length;
        for (unsigned i = 0; i < mod_list_limit; ++i)
        {
            unsigned mod = mod_list[i] + mod10;
            if (mod >= n)
                mod -= n;
            if (graph[mod] == 0 && mod != 1) // new node?
            {
                graph[mod] = pow; // record the power of 10 with which we come to this node
                mod_list[mod_list_length++] = mod; // add it to the list of nodes
                if (mod == 0) // found the path to 0?
                    return; // stop calculating
            }
        }
        mod10 = (unsigned long long)mod10 * 10 % n; // go to next power of 10
        ++pow;
    }
}

void PrintPath(unsigned n, char *out)
{
    // Going to output powers of 10 in descending order
    unsigned mod = 0; // start at node 0
    int prev_pow = graph[mod] + 1; // happens to be an acceptable initialization
    do {
        int pow = graph[mod];
        while (--prev_pow > pow) // output the proper number of 0-digits
            *out++ = '0';
        *out++ = '1'; // output the digit 1, corresponding to current power of 10
        if (pow == 0)
            break;
        unsigned mod10 = 1;
        for (int p = 0; p < pow; ++p)
            mod10 = (unsigned long long)mod10 * 10 % n;
        mod = (mod + n - mod10 % n) % n; // go to the preceding node
    } while (mod != 0);
    while (--prev_pow >= 0) // output the proper number of 0-digits
        *out++ = '0';
    *out++ = 0;
}

// The long division algorithm
void DivideAndPrint(char *product, unsigned n, FILE* file)
{
    unsigned long long temp = 0;
    int print = 0;
    while (*product != '\0')
    {
        temp = temp * 10 + *product++ - '0';
        if (temp >= n)
            print = 1;
        if (print)
        {
            unsigned quotient = (unsigned)(temp / n);
            unsigned remainder = temp % n;
            fputc('0' + quotient, file);
            temp = remainder;
        }
    }
    fputc('\n', file);
    assert(temp == 0); // if not divisible, there is a bug somewhere
}

void Calc(unsigned n, FILE* file)
{
    char result[99];
    BuildGraph(n);
    PrintPath(n, result);
    DivideAndPrint(result, n, file);
}

int main(int argc, char* argv[])
{
    unsigned n;

    if (argv[1])
    {
        FILE* file = fopen(argv[1], "wt");
        mod_list = calloc(max_n, sizeof(int));
        graph = calloc(max_n, 1);
        clock_t before = clock();
        for (n = min_n; n <= max_n; ++n)
        {
            Calc(n, file);
        }
        clock_t after = clock();
        fprintf(stderr, "Time: %f\n", (after - before) / (double)CLOCKS_PER_SEC);
    }
    else
    {
        scanf("%u", &n);
        mod_list = calloc(n, sizeof(int));
        graph = calloc(n, 1);
        Calc(n, stdout);
    }
}

コマンドラインパラメータなしで実行します-から取得nstdin、結果をに出力しstdoutます。ファイル名で実行-結果をn = 1...10000そのファイルに書き込み、時間を測定します。

1 ... 10000のパフォーマンス:140ミリ秒

このコードは、速度のためにCで実装されたaditsuによって提案されアルゴリズムを使用します。私はそれをゴルフする努力をしなかったので、コードは読みやすいでしょう。

std::map検索結果を記録するためにC ++で最初に実装しましたが、かなり時間がかかりました。ただし、のキーmapは連続した整数modであるため(モジュロの数値を表すため、これらをs と呼びますn)、配列を使用するのが自然であるため、Cで書き直しました。

追加の最適化は、マッピングの値に関するものです。それぞれmodに大きな整数を格納することを避けるために、最大の10のべき乗のみを格納しmodます。したがって、配列は実際には検索ツリー/グラフです。検索がに到達するとmod = 0、ツリーのノードをルートまでトレースすると、10の累乗が降順になります。

通常、検索はかなり短時間で停止し、ノードのごく一部しかアクセスされないため、アクティブなノードのリストが必要です。mod_listlengthの配列として実装されmod_list_lengthます。

いくつかの実行時統計(nプログラム5nがメモリのバイトを割り当てるため、16 GB RAMを備えたマシンで、largeにとって重要と思われる):

  • 入力99999999-2秒
  • 入力-27 999999999秒(結果は、111111111222222222333333333444444444555555555666666666777777777888888889おそらく32ビット整数で可能な最大の結果です)
  • 入力-26 2147483647秒(結果は4661316525084584315813
  • 入力1999999998-52秒(おそらく、32ビット整数で可能な最長の実行時間)

2
私はあなたが恵み後にしていることを理解し、それでもこれは、コードゴルフ問題、およびサイトのルールを作るためにあなたを必要とし、いくつかのゴルフあなたのコードへの努力を。
ピーターテイラー

プログラムのサイズは3546バイトです。
-aditsu

@aditsu私はCR / LFのスタイルを使用するWindowsでのバイト数、測定
anatolyg

4

C ++ 11、多くのバイト、非常に高速、すごい(1999999998では1.5秒、1…10000では0.2秒)

(以下のゴルフPythonバージョン。)

まず、aditsuのソリューションにいくらか似た概念から始めます。この概念では、nステップで到達可能なモジュラー剰余のコレクションを誘導的に構築します。ただし、剰余0が見つかるまで待機する代わりに、a・10 ^ n + b = 0となるように、見つかった2つの剰余aおよびbをチェックします。大きな入力でははるかに高速で、使用するメモリははるかに少なくなります。

いくつかのベンチマーク:

$ echo 99999999 | \time ./decbin
1111111122222222333333334444444455555555666666667777777788888889
0.18user 0.01system 0:00.20elapsed 99%CPU (0avgtext+0avgdata 69360maxresident)k
0inputs+0outputs (0major+16276minor)pagefaults 0swaps
$ echo 999999999 | \time ./decbin
111111111222222222333333333444444444555555555666666666777777777888888889
1.22user 0.04system 0:01.27elapsed 100%CPU (0avgtext+0avgdata 434776maxresident)k
0inputs+0outputs (0major+37308minor)pagefaults 0swaps
$ echo 2147483647 | \time ./decbin
4661316525084584315813
0.00user 0.00system 0:00.01elapsed 72%CPU (0avgtext+0avgdata 5960maxresident)k
0inputs+0outputs (0major+1084minor)pagefaults 0swaps
$ echo 1999999998 | \time ./decbin
555555556111111111666666667222222222777777778333333333888888889444444445
1.42user 0.08system 0:01.50elapsed 100%CPU (0avgtext+0avgdata 544140maxresident)k
0inputs+0outputs (0major+38379minor)pagefaults 0swaps
$ \time ./decbin 10000.out
0.19user 0.00system 0:00.20elapsed 100%CPU (0avgtext+0avgdata 3324maxresident)k
0inputs+264outputs (0major+160minor)pagefaults 0swaps

コード:

#include <algorithm>
#include <boost/iterator/transform_iterator.hpp>
#include <fstream>
#include <list>
#include <iostream>
#include <string>
#include <utility>
#include <vector>

using namespace boost;
using namespace std;

static inline bool cmp_first_partnered(pair<int, pair<int, int>> a,
                                       pair<int, pair<int, int>> b) {
  return a.first < b.first;
}
static inline bool eq_first_partnered(pair<int, pair<int, int>> a,
                                      pair<int, pair<int, int>> b) {
  return a.first == b.first;
}

static pair<int, int> retrace(int modulus, int place, pair<int, int> state,
                              list<vector<int>>::iterator i,
                              list<vector<int>>::iterator j, string &ret) {
  if (i == j)
    return state;
  state = retrace(modulus, (place * 10LL) % modulus, state, next(i), j, ret);
  int remainder = state.first;
  long long k = state.second * 10LL;
  if (!binary_search(i->cbegin(), i->cend(), remainder)) {
    remainder = ((long long)remainder + modulus - place) % modulus;
    k += 1;
  }
  int digit = k / modulus;
  if (digit != 0 || ret.size())
    ret += '0' + digit;
  return make_pair(remainder, k % modulus);
}

static void mult(int modulus, int x, int y,
                 vector<pair<int, pair<int, int>>>::iterator i,
                 vector<pair<int, pair<int, int>>>::iterator j) {
  if (y - x == 1) {
    for (auto k = i; k != j; k++)
      k->first = (k->first * 10LL) % modulus;
    return;
  }

  int z = (x + y) / 2;
  vector<pair<int, pair<int, int>>>::iterator k = lower_bound(
      i, j, make_pair(int(((long long)modulus * z + 9) / 10), make_pair(0, 0)));
  mult(modulus, x, z, i, k);
  mult(modulus, z, y, k, j);
  inplace_merge(i, k, j,
                [](pair<int, pair<int, int>> a, pair<int, pair<int, int>> b) {
                  return make_pair(a.first, a.second.second) <
                         make_pair(b.first, b.second.second);
                });
}

static string go(int modulus) {
  if (modulus == 1)
    return "1";

  int sequence = 1;
  list<vector<int>> v = {{0}};
  vector<pair<int, pair<int, int>>> partnered;
  int place = 1;
  while (true) {
    v.emplace_back(v.rbegin()->size() * 2);
    vector<int> &previous = *next(v.rbegin()), &current = *v.rbegin();

    auto offset = [modulus, place, sequence](int a) {
      return (a + (long long)place) % modulus;
    };
    auto old_mid =
        lower_bound(previous.cbegin(), previous.cend(), modulus - place),
         new_mid = lower_bound(previous.cbegin(), previous.cend(), place);
    current.resize(
        set_union(new_mid, previous.cend(),
                  make_transform_iterator(previous.cbegin(), offset),
                  make_transform_iterator(old_mid, offset),
                  set_union(previous.cbegin(), new_mid,
                            make_transform_iterator(old_mid, offset),
                            make_transform_iterator(previous.cend(), offset),
                            current.begin())) -
        current.begin());

    int place2 = modulus - (long long)place * place % modulus;
    auto offset_partnered = [modulus, place, place2,
                             sequence](pair<int, pair<int, int>> a) {
      return make_pair((a.first + (long long)place2) % modulus,
                       make_pair((a.second.first + (long long)place) % modulus,
                                 sequence + a.second.second));
    };
    auto old_mid_partnered =
        lower_bound(partnered.cbegin(), partnered.cend(),
                    make_pair(modulus - place2, make_pair(0, 0))),
         new_mid_partnered = lower_bound(partnered.cbegin(), partnered.cend(),
                                         make_pair(place2, make_pair(0, 0)));
    vector<pair<int, pair<int, int>>> next_partnered(partnered.size() * 2 + 1);
    auto i =
        set_union(partnered.cbegin(), new_mid_partnered,
                  make_transform_iterator(old_mid_partnered, offset_partnered),
                  make_transform_iterator(partnered.cend(), offset_partnered),
                  next_partnered.begin(), cmp_first_partnered);
    if (new_mid_partnered == partnered.cend() ||
        new_mid_partnered->first != place2)
      *i++ = make_pair(place2, make_pair(place, sequence));
    next_partnered.resize(
        set_union(new_mid_partnered, partnered.cend(),
                  make_transform_iterator(partnered.cbegin(), offset_partnered),
                  make_transform_iterator(old_mid_partnered, offset_partnered),
                  i, cmp_first_partnered) -
        next_partnered.begin());
    partnered.swap(next_partnered);

    sequence += previous.size();

    place = (place * 10LL) % modulus;

    mult(modulus, 0, 10, partnered.begin(), partnered.end());
    partnered.resize(
        unique(partnered.begin(), partnered.end(), eq_first_partnered) -
        partnered.begin());

    auto with_first = [](int a) { return make_pair(a, make_pair(a, 0)); };

    vector<pair<int, pair<int, int>>> hits;
    set_intersection(partnered.cbegin(), partnered.cend(),
                     make_transform_iterator(current.cbegin(), with_first),
                     make_transform_iterator(current.cend(), with_first),
                     back_inserter(hits), cmp_first_partnered);

    if (hits.size()) {
      pair<int, pair<int, int>> best = *min_element(
          hits.begin(), hits.end(),
          [](pair<int, pair<int, int>> a, pair<int, pair<int, int>> b) {
            return a.second.second < b.second.second;
          });
      string ret = "";
      pair<int, int> state =
          retrace(modulus, 1, make_pair(best.second.first, 0), v.begin(),
                  prev(v.end()), ret);
      retrace(modulus, 1, make_pair(best.first, state.second), v.begin(),
              prev(v.end()), ret);
      return ret;
    }
  }
}

int main(int argc, const char *argv[]) {
  ios_base::sync_with_stdio(false);
  if (argc >= 2) {
    ofstream ofs(argv[1]);
    for (int modulus = 1; modulus <= 10000; modulus++)
      ofs << go(modulus) << '\n';
  } else {
    int modulus;
    cin >> modulus;
    cout << go(modulus) << '\n';
  }
  return 0;
}

Python、280バイト(PyPyを使用した1999999998では8.6秒)

n=input()
if n<2:print 1;exit()
d={0:0}
l=[]
k=1
b=x=y=0
while 1:
 for a in[0]+l:
  m=(a+k)%n
  if m not in d:l.append(m);d[m]=b
 k=(k*10)%n;b+=1
 for a in l:
  if(-k*a)%n in d:
   while(a-x)%n:x+=10**d[(a-x)%n]
   while(-y-k*a)%n:y+=10**d[(-y-k*a)%n]
   print(10**b*x+y)/n;exit()

2
私はあなたが恵み後にしていることを理解し、それでもこれは、コードゴルフ問題、およびサイトのルールを作るためにあなたを必要とし、いくつかのゴルフあなたのコードへの努力を。
ピーターテイラー

1
@PeterTaylor、非常によく、私はPythonでゴルフバージョンを追加しました。
アンデルスカセオルグ

3

Mathematica 115バイト

p=Drop[Union[FromDigits/@Flatten[Table[Tuples[{0,1},{k}],{k,2,12}],1]],2];
i=Input[];FirstCase[p,x_/;Divisible[x,i]]

3

Java 156バイト

public class P{public static void main(String[]a){long x=Long.valueOf(a[0]),y;for(y=2;!(""+x*y).replaceAll("1|0","").isEmpty();y++);System.out.println(y);}}

aditsuに感謝します:)


あなたは後にスペースを必要としない[]yすることができlongますが、忘れてしまった、あまりにもx*y+""、第二のプログラムで使用するトリックをisEmpty代わりに長さを確認し、使用;の代わりに{}
aditsu

とにかく、コードゴルフへようこそ:)
aditsu

私は感銘を受けましたが、y longを作成してもコードが短くなることはありません
Joba

はい、そうなりますlong x=…,y;
。– aditsu

y1から開始する必要があります。宣言で初期化できます。クラスをパブリックにする必要はなくy++x*yパート(x*y++)に移動できます
-aditsu

2

Pyth- 12 11バイト

filterを数値引数とともに使用して、述語を満たす最初の自然数を取得します。デフォルトは1で、これが必要です。Setwise diffは、0と1のみをチェックします。

f!-j*QT10U2

テストスイート


文字列に変換して削除し"01ます。1文字を保存します。
寂部

2

R、45バイト

x=scan();y=2;while(grepl("[2-9]",x*y))y=y+1;y

使用法:

> x=scan();y=2;while(grepl("[2-9]",x*y))y=y+1;y
1: 2
2: 
Read 1 item
[1] 5
> x=scan();y=2;while(grepl("[2-9]",x*y))y=y+1;y
1: 21
2: 
Read 1 item
[1] 481
> x=scan();y=2;while(grepl("[2-9]",x*y))y=y+1;y
1: 42
2: 
Read 1 item
[1] 2405

2

Java(登録商標)、198の 193 181バイト

5バイトを削減し、テスト可能な数字の範囲を広げてくれた@aditsuに感謝します!

Javaが整数を解析する方法が原因で、一部の値が負にループすることに注意してください。これはBigIntegerによって回避できますが、ボーナスはそれほど価値がありませんでした。

私は勝つつもりはないことを知っていますが、これが他の短い答えを刺激することを願っています。

クラスA {public static void main(String [] a){for(long i = 1 ;; i ++){try {long b = Long.parseLong(a [0]); if(b * i <0)break; Long.parseLong(b * i + ""、2); System.out.println(i);} catch(Exception e){}}}}

洗練されていない:

クラスA {
   public static void main(String [] a){
      for(long i = 1 ;; i ++){// 1から始まる無限ループ
         try {//バイナリとして解析しようとしてエラーがスローされた場合、iに1を追加しながら再起動する
            long b = Long.parseLong(a [0]); //後で-宣言する方が2回使用するよりも短い
            if(b * i <0)break; //ループした場合はプログラムを中断します。
            Long.parseLong(b * i + ""、2); //乗算して、それが2進数として通過可能かどうかを確認します。そうでない場合は、エラーをスローしてループの先頭に戻ります
            System.out.println(b); // 印刷する
         } catch(Exception e){} // catchでは何もしません
      }
   }
}

2
:) Longより短いのは面白いですInteger
アナトリグ

3
最も文字通り皮肉があります。
アディソンクランプ

2

C、107 101バイト(32ビットの105 99バイト)

コードゴルフのCには明確な答えがありません。実際、Cは可能な限り最小のプログラムを作成するための最良の選択ではありませんが、それほど悪くはありません。

main(d,b){char s[9];gets(s);for(b=atoi(s);sprintf(s,"%d",b*d),strspn(s,"01")[s];d++);printf("%d",d);}

#includesなしでも実行できますが、すべての関数定義は暗黙的になります。主な欠点は、これがすべての関数がintを返すという仮定を引き起こすことです。これは、実際にポインターを返す関数の64ビットマシンの問題です。32ビットマシンを使用している場合、上記のソリューションから2バイトを削ることができます。

main(d,b){char s[9];for(b=atoi(gets(s));sprintf(s,"%d",b*d),strspn(s,"01")[s];d++);printf("%d",d);}

やや読みやすいバージョン:

int main()
{
  char s[9];
  gets(s);
  int d = 1;
  int b = atoi(s);
  for (; sprintf(s, "%d", b * d), strspn(s, "01")[s]; d++);
  printf("%d", d);
}

2

5秒に近いC#時間(1〜10000)

要求されたとおり、ここに元の課題に答えるゴルフC#プログラムがあります。コマンドライン引数として入力し、コンソールに出力します。

using System;using System.Collections.Generic;using System.Numerics;using System.Linq;
class P{static void Main(string[] a){int m,n=int.Parse(a[0]);var d=new Dictionary<int,long>();long b;int h;
for(d[n]=0,b=h=1;;b*=2,h=(h*10)%n)foreach(int k in d.Keys.Reverse())if(!d.ContainsKey(m=(h+k)%n)){
var w=d[k]|b;if(m==0){Console.Write(BigInteger.Parse(Convert.ToString(w,2))/n);return;}d.Add(m,w);}}}

それから、賞金に関しては、賞金はaditsuに行くべきです。なぜなら、彼のアルゴリズムはパフォーマンスの点では勝てないと思うからです。しかし、アナトリグの自己回答も驚くべきものです。

C#での高速実装を次に示します。C ++ではもっと速くなると思います(たぶん2倍)。Visual Studio 2010、.NET framework 4、64ビットでコンパイルおよびテストし、出力をnulにリダイレクトします。時間:00:00:05.2604315

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Numerics;
using System.Diagnostics;

class Program
{
   static BigInteger Find(int n)
   {
      var d = new Dictionary<int, long>();
      long kb;
      int km;
      d[n] = 0;
      for (kb = km = 1; ; kb *= 2, km = (km * 10) % n)
      {
         foreach (int key in d.Keys.Reverse())
         {
            int m = (km + key) % n;
            if (!d.ContainsKey(m))
            {
               long w = d[key] | kb;
               if (m == 0)
               {
                  return BigInteger.Parse(Convert.ToString(w, 2));
               }
               d.Add(m, w);
            }
         }
      }
   }

   static void Exec(int n, out string sq, out string sa)
   {
      var v = Find(n);
      sq = (v/n).ToString();
      sa = v.ToString();
   }  

   static void Main(string[] args)
   {
      // string n = Console.ReadLine();
      int limit = int.Parse(args[0]);
      string q ="", a = "";
      Stopwatch x = new Stopwatch();
      x.Start();
      for (int n = 1; n <= limit; n++)
      {
         Exec(n, out q, out a);
         Console.WriteLine("{0} {1} {2}", n, q, a);
      }
      x.Stop();
      Console.Error.WriteLine("{0}", x.Elapsed);
   }
}

Times 4.1s。バウンティのミススポーク。PyPyの最新バージョンでは、aditsuの高速バージョンの時間は約8秒なので、これは2倍高速です。
プリモ

私はあなたが恵み後にしていることを理解し、それでもこれは、コードゴルフ問題、およびサイトのルールを作るためにあなたを必要とし、いくつかのゴルフあなたのコードへの努力を。
ピーターテイラー

私は賞金を求めているのではなく、単なる実装の例です。しかし、あなたは正しいです、私はゴルフバージョンを追加します。
edc65

@PeterTaylorは今行くことができますか?
edc65

ところで、なぜKeys.Reverse?順序は重要ですか?並行性の問題を回避するだけの場合ToListは、より短くなります。
ピーターテイラー

2

GMPを使用したC(621バイト、高速)

私は速くて短くしようとしましたが、速く支持されました。この実装では、aditsuの回答に関するコメントで言及した数論的高速化のわずかに改善されたバージョンを使用します

として保存しpseudobinary.c、でコンパイルしgcc pseudobinary.c -lgmp -o pseudobinaryます。これにより、大きな入力に大量のメモリが割り当てられるため、64ビットプラットフォーム用にコンパイルする必要があります。

#include <gmp.h>
int main(int y,char*z[]){int i,n,b,c,e,f,m,*j,*k,*l,*r,*h;char *d,*s;mpz_t
B,I,Q;i=atoi(z[1]);n=i;for(b=0;n%10<1;++b)n/=10;for(;n%2<1;++b)n/=2;for(;n%5<1;++b)n/=5;if(n<2)--b;d=calloc(n,1);j=calloc(n,sizeof(int));r=calloc(99,sizeof(int));c=2;d[1]=1;*j=r[1]=e=1;l=j+1;for(s=0;!s;++c){r[c]=e=e*10%n;k=l;for(h=j;h<k;h++){f=*h;m=(e+f)%n;if(d[m]<1){*l++=m;if(m<1){s=malloc(99);memset(s,48,99);for(f=c;f;f=d[m=(m+n-r[f])%n])s[c-f]++;s[c]=0;h=k;}d[m]=c;}}}f=strlen(s);s[f]=48;s[f+b]=0;mpz_init_set_str(B,s,10);mpz_init_set_si(I,i);mpz_init(Q);mpz_divexact(Q,B,I);d=mpz_get_str(0,10,Q);printf("%s\n",d);return 0;}

タイミング用のループバージョン(751バイト)

#include <gmp.h>
char **v;int main(){int i,n,b,c,e,f,m,*j,*k,*l,*r,*h;char *d,*s;mpz_t
B,I,Q;v=calloc(10001,sizeof(char*));v[1]=s=malloc(99);memset(s,48,99);*s=49;s[1]=0;for(i=0;++i<10001;){n=i;for(b=0;n%10<1;++b)n/=10;for(;n%2<1;++b)n/=2;for(;n%5<1;++b)n/=5;d=calloc(n,1);j=calloc(n,sizeof(int));r=calloc(99,sizeof(int));c=2;d[1]=1;*j=r[1]=e=1;l=j+1;for(;!v[n];++c){r[c]=e=e*10%n;k=l;for(h=j;h<k;h++){f=*h;m=(e+f)%n;if(d[m]<1){*l++=m;if(m<1){v[n]=s=malloc(99);memset(s,48,99);for(f=c;f;f=d[m=(m+n-r[f])%n])s[c-f]++;s[c]=0;h=k;}d[m]=c;}}}free(d);free(j);free(r);s=v[n];f=strlen(s);s[f]=48;s[f+b]=0;mpz_init_set_str(B,s,10);mpz_init_set_si(I,i);mpz_init(Q);mpz_divexact(Q,B,I);d=mpz_get_str(0,10,Q);printf("%s\n",d);free(d);s[f+b]=48;s[f]=0;}return 0;}

アンゴルフドループバージョン

#include <gmp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char **cache;

int main() {
    int i,n,shift,_kb,km,key,m,*ks,*ksi,*nksi,*res,*ii;
    char *d,*s;
    mpz_t B,I,Q;

    cache = calloc(10001,sizeof(char*));
    if (!cache) { printf("Failed to malloc cache\n"); return 1; }
    cache[1]=s = malloc(99);
    memset(s,48,99);
    *s=49;
    s[1]=0;
    for (i=0;++i<10001;) {
        n=i;
        for(shift=0;n%10<1;++shift)n/=10;
        for(;n%2<1;++shift)n/=2;
        for(;n%5<1;++shift)n/=5;

        d = calloc(n,1);
        if (!d) { printf("Failed to malloc d\n"); return 1; }

        ks = calloc(n,sizeof(int));
        if (!ks) { printf("Failed to malloc ks\n"); return 1; }

        res = calloc(99,sizeof(int));
        if (!res) { printf("Failed to malloc res\n"); return 1; }

        _kb = 2;
        d[1] = 1;
        *ks = res[1] = km = 1;
        nksi = ks + 1;

        for(;!cache[n];++_kb) {
            res[_kb] = km = km*10%n;
            ksi = nksi;
            for (ii = ks; ii < ksi; ii++) {
                key = *ii;
                m = (km + key) % n;
                if (d[m] < 1) {
                    *nksi++ = m;
                    if (m < 1) {
                        cache[n] = s = malloc(99);
                        if (!s) { printf("Failed to malloc s\n"); return 1; }
                        memset(s,48,99);
                        for(key=_kb;key;key = d[m = (m + n - res[key]) % n])s[_kb-key]++;
                        s[_kb]=0;
                        ii = ksi; // break
                    }
                    d[m] = _kb;
                }
            }
        }

        free(d);
        free(ks);
        free(res);

        // Add shift * '0'
        s=cache[n];
        key=strlen(s);
        s[key]=48;
        s[key+shift]=0;

        // convert to big integer, divide, print
        mpz_init_set_str(B,s,10);
        mpz_init_set_si(I,i);
        mpz_init(Q);
        mpz_divexact(Q,B,I);
        d = mpz_get_str(0,10,Q);
        if (!s) { printf("Failed to malloc quotient\n"); return 1; }
        printf("%s\n", d);
        free(d);

        // Remove shift * '0'
        s[key+shift]=48;
        s[key]=0;
    }
    return 0;
}

2

C + GMP、669

数字が小さい場合、これは非常に高速です。結果が64桁を超えると、チョークを開始します。

#include<gmp.h>
#define B(x)(int)((x*(long)k)%n);
int*M,*H,P[99],n,x,p,q=2,e=1,k=10,y,f,z;char*E,C[99];int b(int k,int t){int
j=E[k],a=1<<(j-2);if(j<2){C[t]=49;return 1;}x=(int)((k+n-P[j]*(long)H[k]%n)%n);if(x)b(x,t);return a+b(H[k],t-a);}int
main(){scanf("%d",&n);E=calloc(n+1,1);M=calloc(n+1,4);H=malloc(n*4);M[1]=E[1%n]=P[1]=1;while(!E[0]){P[++e]=k;p=q;for(x=0;++x<p;){y=B(M[x])if(E[n-y]){E[0]=e;H[0]=M[x];break;}}if(!E[x=0])while(++x<p){y=B(M[x])for(z=0;z<p;++z){f=y+M[z];if(f>=n)f-=n;if(!E[f]){E[f]=e;H[f]=M[x];M[q++]=f;}}}k=B(k)}memset(C,48,98);C[99]=0;x=b(0,97);mpz_t
m,r;mpz_init(r);mpz_init_set_str(m,C+98-x,10);mpz_fdiv_q_ui(r,m,n);puts(mpz_get_str(C,10,r));}

10000(671バイト)にループするバージョン:

#include<gmp.h>
#define B(x)(int)((x*(long)k)%n);
#define N 10001
int M[N],H[N],P[99],n=0,x,p,q,e,k,y,f,z;char E[N],C[99];int b(int k,int t){int
j=E[k],a=1<<(j-2);if(j<2){C[t]=49;return 1;}x=(int)((k+n-P[j]*(long)H[k]%n)%n);if(x)b(x,t);return a+b(H[k],t-a);}int
main(){while(++n<N){memset(E,M[0]=0,n);M[1]=E[1%n]=P[1]=e=1;q=2;k=10;while(!E[0]){P[++e]=k;p=q;for(x=0;++x<p;){y=B(M[x])if(E[n-y]){E[0]=e;H[0]=M[x];break;}}if(!E[x=0])while(++x<p){y=B(M[x])for(z=0;z<p;++z){f=y+M[z];if(f>=n)f-=n;if(!E[f]){E[f]=e;H[f]=M[x];M[q++]=f;}}}k=B(k)}memset(C,48,98);C[99]=0;x=b(0,97);mpz_t
m,r;mpz_init(r);mpz_init_set_str(m,C+98-x,10);mpz_fdiv_q_ui(r,m,n);puts(mpz_get_str(C,10,r));}}

コードと競合他社をテストするためのコマンドと、ラップトップでの結果を次に示します。

ls -l *.c*       
-rw-r--r-- 1 aditsu aditsu  669 Oct 27 15:01 mult-aditsu-single.c
-rw-r--r-- 1 aditsu aditsu  671 Oct 27 15:01 mult-aditsu.c
-rw-r--r-- 1 aditsu aditsu 3546 Oct 27 15:01 mult-anatoly.c
-rw-r--r-- 1 aditsu aditsu 6175 Oct 27 15:01 mult-anders.cpp
-rw-r--r-- 1 aditsu aditsu  621 Oct 27 15:01 mult-peter-single.c
-rw-r--r-- 1 aditsu aditsu  751 Oct 27 15:01 mult-peter.c

gcc -w -march=native -O3 mult-aditsu-single.c -lgmp -o mult-aditsu-single
gcc -w -march=native -O3 mult-aditsu.c -lgmp -o mult-aditsu
gcc -w -march=native -O3 mult-peter-single.c -lgmp -o mult-peter-single
gcc -w -march=native -O3 mult-peter.c -lgmp -o mult-peter
gcc -w -march=native -O3 --std=c99 mult-anatoly.c -o mult-anatoly
g++ --std=c++11 -march=native -O3 mult-anders.cpp -o mult-anders

for i in {1..5}; do time ./mult-anders mult-anders.txt; done
./mult-anders mult-anders.txt  0.34s user 0.00s system 99% cpu 0.344 total
./mult-anders mult-anders.txt  0.36s user 0.00s system 99% cpu 0.358 total
./mult-anders mult-anders.txt  0.34s user 0.00s system 99% cpu 0.346 total
./mult-anders mult-anders.txt  0.35s user 0.00s system 99% cpu 0.347 total
./mult-anders mult-anders.txt  0.34s user 0.00s system 99% cpu 0.344 total

for i in {1..5}; do ./mult-anatoly mult-anatoly.txt; done
Time: 0.254416
Time: 0.253555
Time: 0.245734
Time: 0.243129
Time: 0.243345

for i in {1..5}; do time ./mult-peter > mult-peter.txt; done
./mult-peter > mult-peter.txt  0.14s user 0.00s system 99% cpu 0.137 total
./mult-peter > mult-peter.txt  0.15s user 0.00s system 97% cpu 0.153 total
./mult-peter > mult-peter.txt  0.15s user 0.00s system 99% cpu 0.149 total
./mult-peter > mult-peter.txt  0.15s user 0.00s system 99% cpu 0.150 total
./mult-peter > mult-peter.txt  0.14s user 0.00s system 99% cpu 0.138 total

for i in {1..5}; do time ./mult-aditsu > mult-aditsu.txt; done
./mult-aditsu > mult-aditsu.txt  0.06s user 0.00s system 95% cpu 0.058 total
./mult-aditsu > mult-aditsu.txt  0.05s user 0.00s system 97% cpu 0.055 total
./mult-aditsu > mult-aditsu.txt  0.06s user 0.00s system 99% cpu 0.056 total
./mult-aditsu > mult-aditsu.txt  0.05s user 0.00s system 99% cpu 0.054 total
./mult-aditsu > mult-aditsu.txt  0.05s user 0.00s system 98% cpu 0.055 total

md5sum *.txt
6eef8511d3bc5769b5d9218be2e00028  mult-aditsu.txt
6eef8511d3bc5769b5d9218be2e00028  mult-anatoly.txt
6eef8511d3bc5769b5d9218be2e00028  mult-anders.txt
6eef8511d3bc5769b5d9218be2e00028  mult-peter.txt

賞金に値する答え。それは特殊なケースですので、私は、この問題(とあなたの最初の溶液)に特に関心を取るサブセット和問題 NP完全であることが知られている、(の残基のリスト与えられた10ⁱのmod nは、最も初期のサブセットを見つけます先の合計N)。
プリモ

@primoありがとう:)ここでの私のアプローチは異なります-インクリメントするのではなく、各ステップで桁数を2倍にしますそれら。そして、ゴルフの余地はまだあると確信しています。
-aditsu

面白い。各ステップで桁数を2倍にしようとすると、遅くなりました。ソリューションの事前チェックは大きな違いを生むかもしれません。
ピーターテイラー

@PeterTaylor可能です..また、ループでcallocを呼び出しているようです。とにかく、時間があるときにコードの未使用バージョンを追加したいと思います。また、より大きな/より厄介な数に対してより速くする方法も考えています。
-aditsu

2

T-SQL、164の 156 155 154 159バイト

(-1バイト。ジョナサンに感謝!)

(行末にスペースがあるのはなぜですか?SMH)

(+5でゴルフが壊れたことがわかりました)

create function b(@ int)
returns int
as begin
declare @b varchar(max)='',@i int=@
while @>0SELECT @b=cast(@%2 as varchar)+@b,@/=2
return cast(@b as int)/@i
end

私がバイナリに変換することになっているこれらの質問になぜ戻ってくるのかわかりません... T-SQLはそれを正しく行う方法を知りません。

いずれにせよ、これはSQLFiddleです。

ゴルフをしていない:

create function binarySquare(@id int)
returns int 
as BEGIN

私が知っている限り、これらのほとんどはT-SQLで関数を記述するために必要です。

    declare @bin nvarchar(max) = ''

2進数として保存する空の文字列を作成します。

    declare @id2 int = @id

最後に使用するために入力値を保存します。値を変更しても元の入力を使用する方法があるはずのようですが、見つけられません。

    while @id>0
      BEGIN
        SET @bin = cast(@id%2 as varchar(1)) + @bin

したがって、元の入力を取得し、2でMODして残りを見つけます。これが次に小さい桁になります。たとえば、5%2 = 1

        SET @id = @id/2

次に、番号を取得し、それを半分に分けます。これはint型なので、最も近い整数に切り捨てられ、5/2 = 2になります。END次に、値が0になるまでループします。したがって、5%2 = 1 5/2 = 2 2になります。 %2 = 0 2/2 = 1 1%2 = 1 1/2 = 0これにより、バイナリ文字列値101が得られます。

    declare @binNum int = (SELECT cast(@bin as int))

バイナリ文字列を取得し、int再度変換します。

    return @binNum/@id2

int質問の発信元ごとに、元の値で割ったバイナリ文字列を返します。

END

スペース@>0 SELECTは省略できませんか?
ジョナサンフレッチ

ナイスキャッチ!私は...スペースを省略可能な何であるかを覚えていることはできません
phroureo

ほとんどの場合、リテラルと変数/キーワードの間のスペースは、数字で始めることができないため、省略できます。
ジョナサンフレッチ

1

ルビー、46バイト

代替ループを使用して、whileループを実際に削除する必要があります。

n,k=gets,0;$_="#{n.to_i*k+=1}"while/[^01]/;p k

編集:1バイトを削ってくれてありがとう@manatwork!

Edit2:非常識な9バイトをありがとう@histocraft!

編集:7バイトを削ってくれてありがとう@manatwork!


z!=z[/[01]+/]短いです。z[/[^01]/]さらに短くなります。
マナトワーク

@manatworkありがとう!1バイト少ない!
ピーターレンケフィ

2
単一行のwhileループは最短になる傾向がありますz="#{n.to_i*k+=1}"while z[/[^01]/]
。– histocrat

@histocrat 9バイトです!そして、ルビーがこれに対応していることすら知りませんでした。ありがとう!
ピーターレンケフィ

興味深いことに、テストを否定文字セットに変更しなかったのも2回目が提案された後です。何らかの理由?
マナトワーク

1

Scala、114バイト

val i=scala.io.StdIn.readInt;Stream.from(1).foreach{x=>if((i*x+"").map{_.asDigit}.max<2){print(x);System.exit(0)}}

読みやすいバージョン

val i=scala.io.StdIn.readInt
Stream.from(1).foreach{x => 
    if((i*x+"").map{_.asDigit}.max<2) {
        print(x)
        System.exit(0)
    }
}

1

gawk4ブルートフォース、28 + 2 = 30バイト

{while(++n*$0~/[2-9]/);}$0=n

-M大きな数字を使用するオプションを指定して呼び出す必要があります。もちろん、これはとてつもなく遅く、大きな数値を使用するとさらに遅くなりますが、理論的には入力は制限されず、RAMの使用は無視できます。

使用例(無駄にする時間があった場合;)

echo 27 | awk -M '{while(++n*$0~/[2-9]/);}$0=n'

gawk4最適化、69 + 2 = 71バイト

{for(;!a[0];NR*=10)for(i in a)a[j=(s=a[i]+NR)%$0]?0:a[j]=s}$0=a[0]/$0

まあ、これは最終的にaditsuの答えのクローンになりました。この質問を見た後、ここで他の答えを見ることを拒むことができなかったとき、私はまだサブセット合計部分をコーディングする方法を考えていました。

awkの配列要素には、(存在しない要素を何かと比較すると、比較される前に何らかの方法で空として初期化される(奇妙な?)動作があります(そこで何が起こっているのかよくわかりません)。その!a[0]ため、for(i in a)ループをチェックした後、aditsuのように初期化せずにループが開始a[$0]0れます。

もちろん、-Mこれもオプションを使用する必要があります。

かなり高速ですが、それでもPythonよりも著しく遅いです。以下のために79992、この私の2GHzのCore2Duoの上に約14秒かかります。最悪の場合、入力数のサイズを持つ大きな数の配列(gawk4はこのためにGMPを使用)を構築する必要があるため、最大2 ^ 31までの入力に対して機能するとは言いません。「ボーナス」として大きな配列はawkで非常に非常に遅いです...


1

Dyalog APL、25

これにより、適切なプログラム「P」(名前のない関数だけでなく)が定義されます。

P←2∘{0::⍵∇⍨1+⍺⋄⍺⊣~⍎¨⍕⍺×⍵}

2∘左の引数として2で始まる
0::いずれかのエラーが発生した場合...
⍵∇⍨1+⍺インクリメント左引数で自身を呼び出して
⍺×⍵乗算左と右の引数
の文字列に作る
⍎¨数に各文字を作る
~、それが失敗した場合、エラー処理上記に行く(論理否定しようelse ...)
⍺⊣現在の左引数を返します。

      P 2
50
      P 21
481
      P¨⍳8    ⍝ 1 through 8
10 5 37 25 2 185 143 125
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.