소수가 이진수처럼 보이는 주어진 수의 배수를 찾습니다


34

Code Review 사이트에서 흥미로운 것 같은 질문 을 받았습니다. OP가 잘못하고 있다고 생각하지만 확신 할 수는 없습니다. 따라서 그를 위해 해결합시다! (기능 / 프로 시저가 아닌 프로그램 작성)

입력 (stdin 또는 이와 유사한) :

x십진 표기법 의 정수 . 1보다 크고 2 ^ 31보다 작습니다.

출력 (stdout 또는 이와 유사한) :

y십진 표기법 의 정수 . x * y10 진수로 표시된 제품 은 숫자 0과 1 만 포함해야합니다. 이는 0보다 큰 최소 숫자 여야합니다.

참고 : 출력은 제한되지 않습니다-최소값 y이 약 10 ^ 100 인 경우 프로그램은 100 자릿수를 모두 출력해야합니다 (2 ^ 64와 같은 합리적인 제한이 있는지 여부는 알 수 없음 y-해결하지 못했습니다) ).

당신의 프로그램은 모든 x범위에서 적당한 시간 (1 초? 1 시간? – 비슷한 것)으로 끝나야 합니다.

보너스:

프로그램에 입력 크기 (RAM 제외)의 제한이없고 다항식 복잡성이있는 경우 프로그램의 바이트 수에 곱하고 0.8내림하십시오.


예 : 입력 2; 52 * 5 = 10이므로 출력

예 : 입력 21; 48121 * 481 = 10101이므로 출력


면책 조항 : 나는 Code Review 사이트의 질문에 대해 책임을지지 않습니다. 불일치하는 경우 위의 설명 만 적절한 사양으로 간주해야합니다.

OEIS A079339


6
항상 해결할 수 있어야합니다. 10 ^ n mod x = q와 같은 무한 수의 n이 있도록 적어도 하나의 q가 분명히 존재해야합니다. x의 이러한 n 값을 취하고 각각의 거듭 제곱 10 ^ n을 더합니다.
feersum

1
9의 배수는 비정상적으로 높은 결과를 생성하는 것으로 보입니다.
SuperJedi224

1
관련 프로젝트 오일러 문제는 이 질문을 생각 다른 사람에 대해 잘 알고 보았다
SP3000

1
다항식 복잡도에 따라 입력 자릿수의 다항식 또는 입력 값의 다항식을 의미합니까?
Reto Koradi

3
@anatolyg 광산은 무차별 강제하지 않습니다
aditsu

답변:


8

Pyth, 9 바이트

f!-`*TQ10

데모

각 배수에 대해 문자열로 변환하고 10(이 경우 Pyth의 편리한 int를 사용하여 캐스팅)에서 숫자를 빼고 결과를 논리적으로 무시하여 올바른 배수를 찾은 경우에만 seach를 종료하십시오.

보너스 솔루션, 10 바이트 :

f.xi`*TQ2Z

이 솔루션은 실제로 숫자의 문자열 표현이 이진수 ( 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

골프 팁에 대한 Sp3000 감사합니다.

이 입력에 대한 결과를 얻을하는 데 걸리는 시간 (자신의 답변에) 게시물에 대한 다른 I 도전 모두 7299: 사람들은 정말 빠른 경우, 같은 시도 79992다음 (여전히 <1 초 여기를).

설명:

코드가 읽기 쉽기 때문에 이것이 필요하지 않다고 생각했지만 요청이 있었으므로 여기에갑니다.

첫 번째 아이디어는 이진수로 보이는 숫자가 10의 1 이상의 다른 거듭 제곱의 합이라는 것입니다. 따라서 나머지 0이 될 때까지 다양한 방식으로 10의 거듭 제곱을 추가 할 수 있습니다.

우리가 순진하게 그렇게하면 모든 이진수 모양의 숫자를 생성하고 테스트하는 것과 같습니다. 그러나 많은 나머지가 동일합니다. 더 좋은 방법은 특정 나머지를 제공 한 가장 작은 숫자 만 기록하고 기록한 숫자에 10의 거듭 제곱을 연속적으로 추가하는 것입니다. 그것이 프로그램이하는 일입니다.

d키가 나머지이고 값이 나머지와 함께 이진으로 보이는 숫자 인 사전 /지도입니다. 이니셜 n:0은 특별한 경우입니다 : 0:0우리는 그것에 힘을 더하기 시작할 수 있지만 키 0을 찾을 때 알고리즘이 멈추므로 n대신 사용했습니다. 대신 동일한 효과를 가지며 다른 값을 방해하지 않습니다.

그런 다음 k기존의 모든 숫자 에 10의 거듭 제곱을 저장 하고 나머지를 기록하기 시작합니다. 우리 k는 나머지 (x+k)%n와 숫자에 더하고 : d[x]+k새로운 나머지 인 경우에만 기록 d.setdefault(…)하고 다음 힘으로 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의 선택을 저주하십시오!" - 모든 자바 프로그래머 에버
애디슨 크럼프

@VTCAKAVSMoACE 왜 Long을 사용하지 않습니까?
aditsu

흠. 여분의 바이트이지만 가치가 있습니다. 감사!
애디슨 크럼프

아님 실제로 심각하게 줄어 듭니다. 감사!
애디슨 크럼프

1
99를 해결하기위한 타이밍 : 아디 츠 : 0.001 초; xnor : 5 시간 이상이며 여전히 완료되지 않았습니다.
user193661

13

파이썬 2, 47 바이트

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

입력 번호 n와 현재 배수를 추적합니다 a. 때 a보이는 이진, 출력에게 비를 좋아한다 a/n. 숫자가 구성되어 있는지 확인하기 위해 0의 및 1의, 우리는 그것의 문자열 표현에 최대 문자 비교 '1'.

으로 끝나는 long을 피하기 위해 str(a)대신에 사용 합니다 . 불행히도 보다 큽니다 .`a`L'L''1'


12

펄, 27 바이트

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

shebang을 하나로 계산하여 입력을 stdin에서 가져옵니다.

샘플 사용법

$ echo 2 | perl dec-bin.pl
5

$ echo 21 | perl dec-bin.pl
481

$ echo 98 | perl dec-bin.pl
112245

펄, 25 바이트

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

@skmrx에 의한 2 바이트 개선 .

정규 표현식을 검사하는 대신 제품을 이진 리터럴로 평가하려고합니다. 실패하면 다음으로 넘어갑니다. 일반적으로 oct함수는이 목적으로 사용되지만 유효하지 않은 숫자를 자동으로 자르므로이 문제에서는 유용하지 않습니다.


펄, 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 bigintOP가 지원하도록 요구 한 많은 수를 지원 하기 위해 포함해야 할 것 같습니다. (
svsd

1
@skmrn 훌륭합니다. 시도 oct'0b'.++$\*$_했지만 유효하지 않은 숫자를 자동으로 자릅니다. eval대신 에 사용하려고 생각하지 않았습니다 .
primo

11

자바 스크립트, 43 바이트

이것은 내가 생각했던 것보다 훨씬 짧았습니다. 기본적으로 y까지 1 씩 증가 합니다 y * (input number) = (binary-looking number). 분명히 비효율적입니다.

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


자바 스크립트 (보다 효율적인 솔루션), 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)


자바 스크립트 (보다 효율적인 솔루션), 76 바이트

이것은 위에서 설명한 두 가지 방법을 모두 결합합니다. 이 단위를 검사 y할 때까지 y * (input number) = (binary-looking number)(출력임을 의미 y) OR 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 고정-바이트 수 변경 없음!
Mama Fun Roll

Safari 9.0과 충돌합니다. Jussayin '. :)
애디슨 크럼프

1
그러나 출력의 작은 숫자로 제한됩니다. Javascript 숫자는 17 자리의 정밀도를 가지며 OP는 더 큰 것을 요구합니다 (모듈 식 산술을 사용하여 수행 가능)
edc65

팁 : 입력 72를 시도하지 마십시오. Firefox 41이 15 분 동안 정지 된 다음 작동이 중단됩니다. 나는 이것이 어려운 길을 발견했다.
ETHproductions

9

하스켈, 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
John Dvorak

f를 인라인하여 바이트를 저장할 수 있습니다.main=readLn>>= \x->print$[y|y<-[1..],all(<'2')$show$x*y]!!0
BlackCap

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

@BlackCap : 니스! 고마워요!
nimi

7

파이썬 2, 67 65 63 60 바이트

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

덕분에 상태 2 바이트를위한 오두막 5 바이트!


1
나는 당신이 초기화해야한다고 생각합니다b=1
anatolyg

2
다음을 수행하여 2 바이트를 면도 할 수 있습니다.any(c in`a*b`for c in'23456789')
Status

1
확실하지 않지만 not c in`a*b`for c in'10'작동합니까?
cole

2
while 조건을로 변경하여 6 바이트를 절약 할 수 있습니다 set('a*b')&set('23456789').
Kade

2
`Llong을 생산합니다 'L'>'1'.
user193661

6

자바 스크립트 (ES6) (222) (250)

임의 정밀도 수학 사용 (10 진수 문자열에서 작동)

이것은 조금 더 골프를 칠 수는 있지만 JS 표준 숫자 (정밀도 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]
}

나는 파이어 폭스의 작업에있어,하지만 더 큰 숫자를 처리하지 않는 것, 예를 들어 999
aditsu

36 초 안에 999를 처리 할 수있는 새로운 버전이 있지만, 자바 스크립트 타임 아웃으로 9999에 도달 할 수있는 희망은 없습니다 (추가 된 각 '9'는 완료하는 데 2 ​​^ 9 (~ 500) 배 더 필요)
edc65

@aditsu 그것이 JavaScript에서 할 수있는 최선입니다 (그러나 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

온라인으로 사용해보십시오

무차별 대입 솔루션 (Brute Force Solution). 조건을 충족 할 때까지 값을 순차적으로 시도합니다.

최신 버전을 사용하는 2 바이트의 감사를 저장 As하는 대신 "01"포함 된 문자열을 구축 0하고 1@aditsu에 의해 제안. 의견에서 제안 된 전체 솔루션은 다른 바이트를 절약하지만 내 것과 상당히 다르게 보이므로 내 이름으로 게시하고 싶지 않았습니다.

그리고 @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끈을 만드는 데는 매우 현지적인 변화가 있었기 때문에 끈으로 만들었습니다. (이것은 항상 훨씬 쉽습니다 ...) 생각했습니다.
Reto Koradi

1
@RetoKoradi 16 바이트, 적은 수정 : li:V!{)_V*sAs-}g또한 0{)_easi*sAs-}g(15 바이트)는 Java 인터프리터 및 명령 행 인수와 함께 작동합니다.
Dennis

4

파이썬 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 hmmm, 며칠이 걸릴 것 같습니다. -_-
Rnet

1
bin(m)[2:]형식 문자열보다 짧아야합니다. 이중 할당 b=m=1은 몇 가지를 저장해야합니다.
primo

4

자바, 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);}}

를 사용 BigInteger하고 그와 같이 (모든 합리적인 의도와 목적을 위해) 무제한 입력 크기를 갖습니다. 복잡성에 대해서는 잘 모르지만, 여기서 함수의 성장 속도에 달려 있습니다.

소량의 바이트를 절약 해 준 지오 비트와 ypnypn 덕분입니다.


안녕하세요, 주요 방법으로 이것을 어떻게 부를 것입니까? 시도했지만 성공하지 못함
Yassin Hajaj

static메소드에 수정자를 추가해야합니다 .
SuperJedi224

1
문제는 솔루션이 단순한 기능이 아니라 완전한 프로그램이어야한다는 것입니다.
raznagul

b.ONE!(b.multiply(c)+"")대신에 와를 사용 하여 15를자를 수 있습니다 toString().
Geobits

@ raznagul : 고정.
SuperJedi224

4

C, 3675 바이트

코드 골프를 위해 너무 오래 ...

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

어떤 명령 줄 매개 변수와 함께 실행 -이 도착 n에서 stdin하고 그 결과를 출력합니다 stdout. 파일 이름으로 실행-결과를 n = 1...10000해당 파일에 기록하고 시간을 측정합니다.

1 ~ 10000의 성능 : 140ms

이 코드는 속도를 위해 C로 구현 된 aditsu가 제안한 알고리즘을 사용합니다 . 나는 골프를 치기 위해 노력하지 않았으므로 코드를 쉽게 읽을 수 있습니다.

std::map검색 결과를 기록하기 위해 C ++에서 처음으로 구현했지만 다소 느 렸습니다. 그러나의 키 map는 연속 정수입니다 ( mod숫자는 modulo을 나타 내기 때문에 이라고 부릅니다 n). 배열을 사용하는 것이 자연 스럽기 때문에 C로 다시 작성했습니다.

추가 최적화는 매핑 값과 관련이 있습니다. 각각에 대해 큰 정수를 저장하지 않기 위해 mod최대 10의 거듭 제곱 만 저장합니다 mod. 이전으로 이동하기에 충분한 정보 입니다. 따라서 배열은 실제로 검색 트리 / 그래프입니다. 검색이에 도달 mod = 0하면 트리의 노드를 다시 루트로 추적하면 내림차순으로 10의 거듭 제곱이됩니다.

일반적으로 적은 수의 노드 만 방문하면 검색이 다소 빨리 중단되므로 활성 노드 목록이 필요합니다. mod_listlength 배열 로 구현됩니다 mod_list_length.

일부 런타임 통계 (16GB RAM이있는 시스템 n에서 프로그램은 5n바이트 단위의 메모리를 할당하기 때문에 큰 것으로 중요합니다 ) :

  • 입력 99999999-2 초
  • 입력 999999999-27 초 (결과는 111111111222222222333333333444444444555555555666666666777777777888888889아마도 32 비트 정수에서 가능한 가장 큰 결과 일 것입니다)
  • 입력 2147483647-26 초 (결과는 4661316525084584315813)
  • 입력 1999999998-52 초 (아마 32 비트 정수에서 가능한 가장 긴 런타임)

2
나는 당신이 현상금을 겪고 있음을 이해하지만, 이것이 코드 골프 문제이며 사이트 규칙에 따라 코드를 골프화 하기 위해 약간의 노력을 기울여야합니다.
피터 테일러

프로그램에 3546 바이트가 있습니다.
aditsu

@aditsu 나는 CR / LF 스타일 사용하는 Windows의 바이트 수를 측정
anatolyg

4

C ++ 11, 많은 바이트, 매우 빠름, 와우 (1999999998에서 1.5 초, 1… 10000에서 0.2 초)

(아래의 골프 파이썬 버전)

우리는 n 단계로 도달 가능한 모듈 식 나머지 모음을 유도 적으로 구축하는 aditsu의 솔루션과 다소 유사한 개념으로 시작합니다. 그러나 우리가 나머지 0을 찾을 때까지 기다리지 않고, a · 10 ^ n + b = 0이되도록 두 개의 발견 된 나머지 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, 파이썬에서 골프 버전을 추가했습니다.
Anders Kaseorg

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

자바 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+""사용, 2 차 프로그램의 트릭을 isEmpty사용하는 대신 길이를 확인하는 ;대신{}
aditsu

어쨌든, 코드 골프에 오신 것을 환영합니다 :)
aditsu

감동해야하지만, y long를 만드는 것은 코드를 더 짧게 만들지 않습니다
Joba

그렇습니다 :long x=…,y;
aditsu

y1 일부터 시작해야합니다, 당신은 선언을 초기화 할 수 있습니다, 당신의 클래스를 공개 할 필요가 없습니다, 당신은 이동할 수 있습니다 y++받는 x*y부분 ( x*y++)
aditsu

2

Pyth- 12 11 바이트

숫자 arg와 함께 filter를 사용하여 술어를 충족하는 첫 번째 자연수를 얻습니다. 기본값은 1입니다. diff를 설정하여 0과 1 만 검사하십시오.

f!-j*QT10U2

테스트 스위트 .


문자열로 변환하고 제거하십시오 "01. 하나의 문자를 저장합니다.
Jakube

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

자바, 198 (193) 181 바이트

5 바이트를 줄이고 테스트 가능한 숫자의 범위를 늘리는 @aditsu에게 감사드립니다!

Java가 정수를 구문 분석하는 방식으로 인해 일부 값이 음수로 반복됩니다. 이것은 BigInteger에 의해 우회 될 수 있지만 보너스는 그다지 가치가 떨어졌습니다.

나는 이길 수 없다는 것을 알고 있지만 이것이 더 짧은 다른 답변에 영감을주기를 바랍니다.

클래스 A {공공 정적 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);} 캐치 (예외 e) {}}}}

풀리지 않은 :

클래스 A {
   공개 정적 무효 main (String [] a) {
      for (long i = 1 ;; i ++) {// 1에서 시작하는 무한 루프
         try {// 이진으로 구문 분석하여 오류가 발생하면 1을 i에 추가하는 동안 다시 시작하십시오.
            긴 b = Long.parseLong (a [0]); // 나중에-두 번 사용하는 것보다 선언하는 것이 더 짧았습니다.
            if (b * i <0) 파손; // 우리가 반복하면 프로그램에서 빠져 나옵니다.
            Long.parseLong (b * i + "", 2); // 이진수로 곱할 수 있는지 곱하고 그렇지 않으면 오류를 던지고 루프의 맨 위로 돌아갑니다.
            System.out.println (b); // 출력
         } catch (예외 e) {} // catch 할 작업이 없습니다.
      }
   }
}

2
다음 Long보다 짧은 것이 재미있다 Integer:)
anatolyg

3
가장 문자 그대로의 아이러니가 있습니다.
애디슨 크럼

2

C, 107 101 바이트 ( 105 32- 비트 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없이 수행 할 수 있지만 모든 함수 정의는 내재적입니다. 주요 단점은 모든 함수가 정수를 반환한다는 가정을 유발한다는 것입니다. 실제로 포인터를 반환하는 함수의 경우 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 프레임 워크 4, 64 비트로 컴파일 및 테스트하여 출력을 널로 리디렉션합니다. 시간 : 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);
   }
}

타임즈 4.1. 현상금이 잘못되었습니다. 최신 버전의 PyPy에서 aditsu의 빠른 버전은 약 8 초이므로 두 배 빠릅니다.
primo

나는 당신이 현상금을 겪고 있음을 이해하지만, 이것이 코드 골프 문제이며 사이트 규칙에 따라 코드를 골프화 하기 위해 약간의 노력을 기울여야합니다.
피터 테일러

나는 현상금을 따르지 않고 구현의 예일뿐입니다. 하지만 네 말이 맞아 골프 버전을 추가하겠습니다.
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

@primo Thank you :) 여기 내 접근 방식이 다릅니다. 증가하는 것이 아니라 각 단계에서 자릿수를 두 배로 늘리고 실제로 계산하기 전에 새 숫자 중 하나가 해결책인지 먼저 (매우 빨리) 확인합니다. 그들. 그리고 여전히 골프를 할 여지가 있다고 확신합니다.
aditsu

흥미 롭군 각 단계에서 자릿수를 두 배로 늘리려 고하면 속도가 느려졌습니다. 솔루션에 대한 사전 검사가 큰 차이를 만들 수 있습니다.
피터 테일러

@PeterTaylor 가능합니다. 루프에서 calloc을 호출하여 속도가 느려질 수 있습니다. 어쨌든, 나는 시간을 찾을 때 코드의 ungolfed 버전을 추가하고 싶습니다. 그리고 더 큰 / 더 작은 숫자를 위해 더 빨리 만드는 방법에 대한 아이디어가 있습니다.
aditsu

2

T-SQL, 164 156 155 154 159 바이트

(-1 바이트. 감사합니다 조나단!)

(왜 줄에 후행 공백이 있기 때문에 더 많은가?

(+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) = ''

이진 숫자로 저장할 빈 문자열을 만듭니다.

    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생략 할 수 없습니까?
Jonathan Frech

좋은 캐치! 나는 어떤 공간을 생략 할 수 있는지 기억할 수 없다 ...
phroureo

대부분의 경우 문자로 시작할 수 없으므로 리터럴과 변수 / 키워드 사이에 공백을 생략 할 수 있습니다.
Jonathan Frech

1

루비, 46 바이트

대체 루프로 while 루프를 제거해야합니다.

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

편집 : 1 바이트를 면도 해 주셔서 감사합니다 @manatwork!

편집 2 : 미친 9 바이트에 대한 @histocraft 감사합니다!

편집 : 7 바이트를 면도 해주신 @manatwork에게 다시 한번 감사드립니다!


z!=z[/[01]+/]더 짧습니다. z[/[^01]/]훨씬 더 짧습니다.
manatwork

@manatwork 감사합니다! 1 바이트 이하!
Peter Lenkefi

2
단일 행 while 루프는 가장 짧은 경향이 있습니다.z="#{n.to_i*k+=1}"while z[/[^01]/]
histocrat

@histocrat 9 바이트입니다! 그리고 나는 루비가 이것을 할 수 있다는 것을 몰랐습니다. 감사!
Peter Lenkefi

테스트를 무효 문자 세트로 변경하지 않은 것에 대한 흥미는 두 번째로 제안되었습니다. 어떤 이유?
manatwork

1

스칼라, 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 배열 요소에는 존재하지 않는 요소를 무언가와 비교하면 비교하기 전에 어떻게 든 비어있는 것으로 초기화되는 (이상한?) 동작이 있습니다 (어떤 일이 일어나고 있는지 잘 모르겠습니다). 그래서 확인 후 도 초기화하지 않고 루프 시작 에 aditsu가 그랬던 것처럼.!a[0]for(i in a)a[$0]0

물론이 -M옵션도 사용해야합니다.

속도는 빠르지 만 여전히 파이썬보다 훨씬 느립니다. 들어 79992이 내 2GHz의 Core2Duo에 14 개의 초 정도 걸립니다. 그리고 최악의 경우 입력 번호의 크기를 갖는 큰 숫자 배열 (gawk4가 GMP를 사용함)을 만들어야하기 때문에 최대 2 ^ 31까지의 입력에 작동한다고 말하지는 않습니다. '보너스'로 큰 배열은 매우 느립니다 ...


1

Dyalog APL , 25

이것은 적절한 프로그램 "P"를 정의합니다 (이름이없는 함수 만이 아님) :

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

2∘
0::오류가있는 경우 왼쪽 인수로 2로 시작하십시오 ...
⍵∇⍨1+⍺증가 된 왼쪽 인수로 자신을 호출하십시오.
⍺×⍵왼쪽 및 오른쪽 인수
는 문자열로
⍎¨만들어 각 문자를
~논리적 NOT으로 시도합니다 (실패하면 위의 오류 처리로 이동하십시오. 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.