r과 n이 주어지면 x의 첫 번째 숫자를 마지막으로 이동하면 x / r = y가되는 x의 처음 n 개 숫자를 찾습니다.


11

객관적인

입력을 감안 r하고 n처음 발견 n자연수는 x우리가 마지막 장소에 첫 번째 자리를 회전 할 경우 우리가 얻을 수 있도록 x/r.

당신은 그 가정 할 수 2 <= r <= 91 <= n <= 65535.

stdin 또는 명령 행 인수에서 입력을받는 프로그램을 작성할 수 있습니다. 또는 당신이받는 함수 쓸 수 있습니다 rn매개 변수로합니다. 그러나 출력은 표준 출력이어야합니다. 출력 값 당 하나 개의 라인이어야 x로 포맷, x/r=y증가하는 순서를 x.

솔루션은 합리적인 데스크톱 컴퓨터에서 1 분 이내에 모든 유효한 사례를 처리 할 수 ​​있어야합니다.

테스트 사례

입력 : 4 5
출력 :

102564/4=25641  
205128/4=51282  
307692/4=76923  
410256/4=102564  
512820/4=128205

입력 : 5 1
출력 :714285/5=142857

이것은 코드 골프이므로 최소 바이트가 이깁니다. 당첨 답변은 지금부터 4 주 후에 접수됩니다 (2014-09-19).

이 질문에 대한 크레딧은 내 동료에게 가서 질문을 게시 할 수있게했습니다 :)


필요한 출력량으로 인해 시간 제한이 까다 롭습니다. 에 따르면 gprof내 프로그램의 한 입력 사례가 코드에서 0.5 초 미만을 소비하지만 총 80 초가 걸리므로 출력에서 ​​대부분 차단해야한다고 가정합니다.
aschepler

아, 나는 그것을 피함으로써 그 문제를 해결했다 printf.
aschepler

답변:


7

하스켈, 182 (179)

두 번째 버전은 아마도 더 골프화가 가능하지만 이번에는 "적절한"알고리즘을 사용합니다. 특히, 함께 몇 분 이내에 완료 r=4하고 n=65535, 그러나 기회는 다른 컴퓨터에 분 내에서이 체류가 그래서 다시 내 컴퓨터는 합리적인이나 바탕 화면도이다.

n#r=take n$[s(10^k*a+d)++'/':s r++'=':s d++s a|k<-[0..],a<-[1..9],let(d,m)=divMod(a*(10^k-r))(10*r-1),m<1]
s=show
main=interact$unlines.(\(r:n:_)->n#fromIntegral r).map read.words

그것은 x=10^k*a + m첫 번째 숫자 0≤a≤9가 끝까지 이동하도록하는 아이디어에 근거 하고 있습니다 y=10*m+a. 약간의 수학은 그 계시 m로 얻을 수 있습니다 a*(10^k-r)/(10*r-1)우리는 단순히 스캔, 그래서 a이상 [1..9]모든을 위해 k무한대로 0에서, 그리고 유지하고 첫 번째 인쇄 n에 대한 위의 표현되는 결과 m필수입니다.

fromIntegral필요하기 때문에 read와 목록을 보내고 n있는 요소 중 하나로서 main,의 사용과 조합 ntake, 강제 rInt문제의 큰 숫자 불쾌한 오버 플로우에서 어떤 결과를 걸쳐. 나는 사용할 수 genericTake있었지만 import.

이 코드는 또한 10이 아닌 다른 기지로 확장하는 데 거의 사소한 이점이 있습니다.

에서 입력을 읽고 stdin두 값을 공백으로 구분할 수 있습니다.


당신이 backsticks을 제거하는 경우 코드는 짧게해야한다
자랑 haskeller

@proudhaskeller : 공백없이 연산자와 피연산자를 구분하기 위해 괄호가 없기 때문에 확실하지 않습니다.
TheSpanishInquisition

나는 Haskell을 읽을 수 없으므로, 당신이 무엇을하고 있는지 잘 모르겠습니다. r = 5; n = 655351 분 안에 해결 됩니까?
Martin Ender

@ MartinBüttner : 그 의견을 기다리고있었습니다. 예, 아마도 내 컴퓨터 (또는 실제로 다른 사람의 컴퓨터)에서는 그렇지 않을 것입니다. 문제는 더 고급 알고리즘이 필요하다고 생각합니다. :(
TheSpanishInquisition

@TheSpanishInquisition하지만 당신은 대체 할 수 ahould y`mod`10mod y10짧은 문자 인
자랑 haskeller가

1

Pure Bash (외부 유틸리티 없음), 80 바이트

for((;++x,c<$2;));{
y=$[10#${x:1}${x:0:1}]
((y*$1==x))&&echo $x/$1=$y&&((c++))
}

참고 bash는 정수 산술 만 수행하고 부동 소수점은 수행하지 않으므로 x == y * r대신 대신 검사합니다 x / r == y. 또한 곱셈은 일반적으로 더 빠릅니다. 여전히 성능 요구 사항을 충족 할 수있는 곳은 없습니다.

산출:

$ ./rotdiv.sh 4 5
102564/4=25641
205128/4=51282
307692/4=76923
410256/4=102564
512820/4=128205
$ ./rotdiv.sh 5 1
714285/5=142857
$ 

1

C 468

#include <stdlib.h>
#include <stdio.h>
#define a(s)fputs(s,stdout);
#define b(c)putchar(c);
int r;int z(char*s,int m){for(int i=0;i++<=m;)a(s)b(47)b(r+48)b(61)char*t=s;
while(*++t==48);a(t)while(m--)a(s)b(*s)b(10)}char x[10][60];
int main(int c,char**v){r=atoi(v[1]);int n=atoi(v[2]),q=10*r-1,d=0,p;
while(d++<9){p=r*d;char*y=x[d];do{p*=10;*y++=p/q+48;p%=q;}while(p!=r*d);}
d=1;p=q=0;while(n--){r==5&p<6?z(x[7],7*q+p++):(z(x[d],(r==5&d==7)?7*q+6:q),
++d>9?q+=d=1,p=0:0);}}

(바이트 수로 계산되지 않은 일부 줄 바꿈이 스크롤 막대를 제거하기 위해 위에 추가되었습니다. 예, 마지막 줄 바꿈이 계산됩니다.)

명령 행에서 인수를 예상하고 표준 출력이 ASCII를 승인한다고 가정합니다. 런타임은 O (바이트 수 출력) = O (n * n)입니다.

아니요, 사용할 수 없습니다 printf. 시간이 너무 많이 걸리고 바탕 화면의 분 단위로 프로그램을 푸시합니다. 그대로, 일부 테스트 케이스는 약 30 초가 걸립니다.

알고리즘은 출력이 빠르게 커지고 출력에 강한 패턴이 있기 때문에 출력을 숫자가 아닌 문자열로 처리합니다.

언 골프 :

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

/* r is as in the problem description */
int r;

void show_line(const char* num, int repeats) {
    for (int i=0; i <= repeats; ++i)
        fputs(num, stdout);
    printf("/%c=", '0'+r);

    /* Assume the repeated num is a solution. Just move the first
       digit and skip any resulting leading zeros. */
    const char* num_tail = num;
    ++num_tail;
    while (*num_tail=='0')
        ++num_tail;
    fputs(num_tail, stdout);
    while (repeats--)
        fputs(num, stdout);
    printf("%c\n", *num);
}

/* sol[0] is unused. Otherwise, sol[d] is the repeating digits in the
   decimal representation of (r*d)/(10*r-1). */
char sol[10][60];

int main(int argc, char** argv) {
    r = atoi(argv[1]);
    int n = atoi(argv[2]);
    int q = 10*r-1;
    int d = 0;

    /* Populate the strings in sol[]. */
    while (d++<9) {
        int p = r*d;
        char* sol_str = sol[d];

        /* Do the long division p/q in decimal, stopping when the remainder
           is the original dividend. The integer part is always zero. */
        do {
            p *= 10;
            *sol_str++ = p/q + '0';
            p %= q;
        } while (p != r*d);
    }

    /* Output the answers. */
    d = 1;
    int repeats = 0;
    int r5x7_repeats = 0;
    while (n--) {
        if (r==5 && r5x7_repeats<6) {
            show_line(x[7], 7*repeats + r5x7_repeats);
        } else {
            if (r==5 && d==7)
                show_line(x[d], 7*repeats + 6);
            else
                show_line(x[d], repeats);
            if (++d > 9) {
                d = 1;
                ++repeats;
                r5x7_repeats = 0;
            }
        }
    }
}

증명

프로그램이 문제를 해결한다는 것을

(증거에서 모든 연산자와 함수를 근사한 컴퓨터 연산이 아니라 실제 수학 함수로 만듭니다. ^비트 xor가 아닌 지수를 나타냅니다.)

명확하게하기 위해 함수 ToDec를 사용 하여 숫자를 일련의 10 진수로 쓰는 일반적인 프로세스를 설명합니다. 범위는 정렬 된 튜플 세트입니다 {0...9}. 예를 들어

ToDec(2014) = (2, 0, 1, 4).

양의 정수의 경우 소수점 이하 자릿수로 표시되는 자릿수로 n정의 L(n)하십시오 n. 또는,

L(n) = 1+floor(log10(n)).

양의 정수 k와 음이 아닌 정수 nL(n)<k정의 Rep_k(n)의 십진수 앞에 0을 더한 실수로 n얻기 위해 필요한 경우, k숫자는 총 후 무한 그 반복 k소수점 후 숫자. 예 :

Rep_4(2014) = .201420142014...
Rep_5(2014) = .020140201402...

Rep_k(n) * 10^k하면 n소수점 앞의 자릿수와 n소수점 다음 에 무한 반복되는 (0이 채워진) 자릿수가 표시 됩니다. 그래서

Rep_k(n) * 10^k = n + Rep_k(n)
Rep_k(n) = n / (10^k - 1)

양의 정수가 주어지면 문제에 대한 해결책 r이라고 가정 x하고

ToDec(x) = ( x_1, x_2, ..., x_k )

어디 x_1 != 0에서 k = L(x).

해가 되려면의 x배수 r이며

ToDec(x/r) : ( x_2, x_3, ..., x_k, x_1 ).

Rep_k함수를 적용하면 멋진 방정식이 나타납니다.

10*Rep_k(x) = x_1 + Rep_k(x/r)

위에서 닫힌 양식을 사용하여

10x / (10^k - 1) = x_1 + x / r / (10^k - 1)
x = x_1 * r * (10^k-1) / (10r - 1)

x_1세트에 있어야합니다 {1 ... 9}. r세트에 있도록 지정되었습니다 {2 ... 9}. 이제 유일한 질문은 k위의 공식 중 어떤 값이 x양의 정수 를 제공합니까? 우리는 각각의 가능한 모든 가치를 고려할 것 r입니다.

경우 r= 2, 3, 6, 8, 9, 10r-1각각 19, 29, 59, 79, 또는 89이다. 모든 경우에 분모 p = 10r-1가 가장 중요합니다. 분자에서, 단지 10^k-1의 배수가 될 수 p발생,

10^k = 1 (mod p)

덧셈과 뺄셈에서 음수를 나타내지 않는 솔루션 세트는 닫힙니다. 따라서이 집합은 공통 요소의 모든 배수로 구성되며에 대한 최소 양성 솔루션입니다 k.

언제 r = 4그리고 10r-1 = 39; 또는 때 r = 710r-1 = 69분모는 3 번 다른 주요이다 p=(10r-1)/3. 10^k-1는 항상 3의 배수이며 분자의 다른 요소는의 배수가 될 수 p없으므로 다시 문제는

10^k = 1 (mod p)

다시 솔루션은에 대한 최소 양성 솔루션의 배수입니다 k.

[완료되지 않았습니다 ...]


0

파이썬 -91 90

첫 번째 장면은 다음과 같습니다.

r,n=input();i=1
while n:
 if int(`i`[1:]+`i`[0])*r==i:print'%d/%d=%d'%(i,r,i/r);n-=1
 i+=1

편집 : 좋아, 아마 65K 숫자에 필요한 1 분 시간 제한을 충족시키는 속도가 느려질 것입니다.


1
성능 요구 사항에 대해 이것을 테스트 했습니까?
피터 테일러

2
나는 이것이 태양이 폭발하기 전에 65k와 같은 숫자를 찾을 것이라는 의심을 가지고 있습니다.
Martin Ender

0

자바 스크립트-145

function f(a,b){for(d=0;d<b;d++)for(i=1;;i++){c=i/a;if(c==parseInt(i.toString().substring(1)+i.toString().charAt(0)))console.log(i+'/'+a+'='+c)}}

골프를 치지 않음 :

function f(a,b){
    for(d=0;d<b;d++) //loop for the right amount
        for(i=1;;i++){ //iterating loop
            c=i/a; //actual result of the division
            if(c==parseInt(i.toString().substring(1)+i.toString().charAt(0)))
                console.log(i+'/'+a+'='+c)
        }
}

이 기능을 전혀 사용할 수는 없지만 성능이 요구되는 경우에도 성능 요구 사항을 충족하지는 않을 것입니다.
Martin Ender

@ MartinBüttner 그것은 나를 위해 완벽하게 잘 작동합니다. 성능 요구 사항을 충족시키지 못할 수도 있지만 현재 컴퓨터가 매우 약합니다.이 코드를 작동시키기 위해 무엇을 했습니까?
Armin

1
콘솔에 복사하여 추가했습니다 (5,4). 작동하지 않는 이유는 숫자가 매우 커지기 때문입니다. a) JS의 숫자보다 큰 숫자는 정확하게 나타낼 수 있으며 b) 모든 숫자를 반복하여 도달 할 수있을 정도로 너무 큽니다.
Martin Ender

0

파이썬 3-223 179 바이트

TheSpanishInquisition 솔루션의 Python 구현 :

r,n=map(int,input().split());k=0
while 1:
 for a in range(1,10):
  D,M=divmod(a*(10**k-r),10*r-1)
  if M==0:
   print("%d/%d=%d"%(a*10**k+D,r,10*D+a));n-=1
   if n==0:exit()
 k+=1

운영:

  • python3 <whatever you named it>.py
  • stdin에 입력을받습니다
  • 입력 공간 분리

산출:

$python3 <whatever you named it>.py
4 8
102564/4=25641
205128/4=51282
307692/4=76923
410256/4=102564
512820/4=128205
615384/4=153846
717948/4=179487
820512/4=205128

결과:

각 r의 첫 번째 값은 https://oeis.org/A092697 입니다.

k의 특정 값만 응답을 생성하고 간격이 규칙적인 것으로 보입니다. 예를 들어 r = 4 :

Form: k [a, a, ...]
0 []
1 []
2 []
3 []
4 []
5 [1, 2, 3, 4, 5, 6, 7, 8, 9]
6 []
7 []
8 []
9 []
10 []
11 [1, 2, 3, 4, 5, 6, 7, 8, 9]
12 []
13 []
14 []
15 []
16 []
17 [1, 2, 3, 4, 5, 6, 7, 8, 9]
18 []
19 []
20 []
21 []
22 []
23 [1, 2, 3, 4, 5, 6, 7, 8, 9]

간격은 다음과 같습니다.

  • 2 = 18
  • 3 = 28
  • 4 = 6
  • 5 = 6 (5는 비정상적인 것으로 보입니다 .r의 대부분의 값은 9의 덩어리가 있습니다 .5의 형태는 9와 1의 덩어리입니다 (a = 7 만 작동), 아래 참조)
  • 6 = 58
  • 7 = 22
  • 8 = 13
  • 9 = 44

https://oeis.org/A094224 양식 입니다.

이 값을 사용하면보다 효율적인 버전을 구축 할 수 있습니다.

import math

def A094224(n):
    return [18,28,6,6,58,22,13,44][n-2]


r,n=map(int,input().split());k=A094224(r)-1
H={}
while 1:
    for a in range(1,10):
        D,M=divmod(a*10**k-a*r,10*r-1)
        if M==0:
            print("%d/%d=%d"%(a*10**k+D,r,10*D+a));n-=1
            if n==0:exit()
    k+=A094224(r)

그러나 나는 이것이 수학적으로 계속되고 있음을 증명할 수는 없다.

r = 5에 대한 결과 :

0 []
1 []
2 []
3 []
4 []
5 [7]
6 []
7 []
8 []
9 []
10 []
11 [7]
12 []
13 []
14 []
15 []
16 []
17 [7]
18 []
19 []
20 []
21 []
22 []
23 [7]
24 []
25 []
26 []
27 []
28 []
29 [7]
30 []
31 []
32 []
33 []
34 []
35 [7]
36 []
37 []
38 []
39 []
40 []
41 [1, 2, 3, 4, 5, 6, 7, 8, 9]

2
입력으로 테스트 했습니까 9 65535?
피터 테일러

아마 그걸 사용해야 unsigned long long하고 1 분 안에 멀티 코어로 만들 수 있습니다.
matsjoyce

1
경우 unsigned long long64 비트, 그것은 큰 충분하지 않습니다.
피터 테일러

사실, @TheSpanishInquisition의 솔루션으로 전환하고 대신 파이썬을 사용했습니다.
matsjoyce
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.