이 생성 된 이진 행렬에 특정 값을 인쇄


14

우리는 무한 행렬을 정의한다고 가정 M에서, N^2 -> {0, 1}(단 N에서 시작 1하는 대신 0) 이와 같이 :

  • M(1, 1)= 0.

  • 모든를 들어 x > 1, M(x, 1)= 1경우는 x프라임이고 0, 그렇지 않으면.

  • 모든를 들어 y > 1, M(1, y)= y에서 일 용어 Thue-Morse sequence.

  • 모든 들어 x, y > 1, M(x, y)= M(x, y-1) + M(x-1, y) mod 2.

16x16이 행렬의 왼쪽 상단 부분은 다음과 같습니다 ( x행 및 y열).

0 1 1 0 1 0 0 1 1 0 0 1 0 1 1 0
1 0 1 1 0 0 0 1 0 0 0 1 1 0 1 1
1 1 0 1 1 1 1 0 0 0 0 1 0 0 1 0
0 1 1 0 1 0 1 1 1 1 1 0 0 0 1 1
1 0 1 1 0 0 1 0 1 0 1 1 1 1 0 1
0 0 1 0 0 0 1 1 0 0 1 0 1 0 0 1
1 1 0 0 0 0 1 0 0 0 1 1 0 0 0 1
0 1 1 1 1 1 0 0 0 0 1 0 0 0 0 1
0 1 0 1 0 1 1 1 1 1 0 0 0 0 0 1
0 1 1 0 0 1 0 1 0 1 1 1 1 1 1 0
1 0 1 1 1 0 0 1 1 0 1 0 1 0 1 1
0 0 1 0 1 1 1 0 1 1 0 0 1 1 0 1
1 1 0 0 1 0 1 1 0 1 1 1 0 1 1 0
0 1 1 1 0 0 1 0 0 1 0 1 1 0 1 1
0 1 0 1 1 1 0 0 0 1 1 0 1 1 0 1
0 1 1 0 1 0 0 0 0 1 0 0 1 0 0 1

당신의 임무는 가능한 정확하게이 행렬의 임의 항목의 값을 평가할 프로그램을 만드는 것입니다.

여러분의 프로그램은 두 개의 정수 걸릴 것입니다 xy모든 당신이 선택하는 형태로, 대가로, 같은 입력 M(x, y)이 될 것이다, 0또는 1.

코드는 모든 언어로 작성 될 수 있지만 소스 코드 크기의 64KB (65,536 바이트) 또는 총 메모리 사용량의 2MB (2,097,152 바이트)를 초과해서는 안됩니다. 프로그램은 빈 메모리로 시작해야하며 (즉, 다른 곳에서 데이터를로드 할 수 없음) 각 입력에 대해 독립적으로 실행해야합니다 (즉, 여러 실행에 대한 공통 데이터를 저장하지 못할 수 있음). 또한 프로그램은 왼쪽 상단의 모든 항목을 8192x8192적절한 시간 안에 평가할 수 있어야합니다 .

왼쪽 상단 8192 x 8192사각형 에서 가장 많은 항목을 정확하게 평가하는 프로그램이 승자가되고 짧은 코드는 타이 브레이커 역할을합니다.


아마도 테스트 케이스를 조금 더 우아하게 업데이트 할 것이므로 질문을 다시 편집 할 때까지 테스트를 계속 진행하십시오.
Joe Z.

@mbuettner 그렇습니다.
Joe Z.

1
"정확도"에 대한 새로운 태그가 어떻게 필요한지 알 수 없습니다. 이것은 단지 [코드 도전]입니다. 메타를 통해 새로운 도전 장르 아이디어를 먼저 실행하십시오 ([code-trolling]에서 배운 것이 하나 있습니다).
Doorknob

^ 주목했다. 그 태그를 제거하겠습니다.
Joe Z.

1
@TheDoctor 너무 드문 일이 아닙니다. 허용되는 답변은 시간이 지남에 따라 변경됩니다.
Joe Z.

답변:


9

J- 42 38 자

매우 빠르며 100 % 정확하며 메모리 제약 조건 내에 있습니다.

([{+2&(~:/@#:@#@],~:/\,(p:>:)&#)0:)&<:

전략은 다음과 같습니다.이 행렬의 연속 반 대각선을 계산하여 쌍으로 XOR을 수행하여 현재 Thue-Morse 및 소수 비트를 끝에 추가합니다. 그런 다음 우리가 도착하면 필요한 숫자를 대각선에서 빼냅니다.

폭발에 의한 설명 :

(                                 )&<:  NB. decrement each of x and y
     &(                        )        NB. apply the following function...
   +                                    NB. ... (x-1)+(y-1) times...
                                0:      NB. ... starting with a zero:
    2             ~:/\                  NB.   pairwise XOR on the argument
                      ,(p:>:)&#         NB.   append prime bit (is 1+length prime?)
       ~:/@#:@#@],                      NB.   prepend TM bit (XOR of binary)
 [{                                     NB. take the x-th bit (at index x-1)

이 동사의 사용법은 x m y질문에 지정된 M (x, y) m에 대한 것입니다. 동사는 어디에 있습니까 ?

   5 ([{+2&(~:/@#:@#@],~:/\,(p:>:)&#)0:)&<: 8
0
   m =: ([{+2&(~:/@#:@#@],~:/\,(p:>:)&#)0:)&<:
   1+i.16
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
   m/~ 1+i.16
0 1 1 0 1 0 0 1 1 0 0 1 0 1 1 0
1 0 1 1 0 0 0 1 0 0 0 1 1 0 1 1
1 1 0 1 1 1 1 0 0 0 0 1 0 0 1 0
0 1 1 0 1 0 1 1 1 1 1 0 0 0 1 1
1 0 1 1 0 0 1 0 1 0 1 1 1 1 0 1
0 0 1 0 0 0 1 1 0 0 1 0 1 0 0 1
1 1 0 0 0 0 1 0 0 0 1 1 0 0 0 1
0 1 1 1 1 1 0 0 0 0 1 0 0 0 0 1
0 1 0 1 0 1 1 1 1 1 0 0 0 0 0 1
0 1 1 0 0 1 0 1 0 1 1 1 1 1 1 0
1 0 1 1 1 0 0 1 1 0 1 0 1 0 1 1
0 0 1 0 1 1 1 0 1 1 0 0 1 1 0 1
1 1 0 0 1 0 1 1 0 1 1 1 0 1 1 0
0 1 1 1 0 0 1 0 0 1 0 1 1 0 1 1
0 1 0 1 1 1 0 0 0 1 1 0 1 1 0 1
0 1 1 0 1 0 0 0 0 1 0 0 1 0 0 1

키 입력을 저장하기 위해 여전히 더 많은 소수 또는 Thu-Morse 비트가 필요한지 확인하려고 시도하지 않으므로 원하는 비트를 얻기 위해 전체 대각 대각선을 계산합니다. 그러나 8192 m 8192겸손한 랩톱에서 여전히 0.07 초 미만 및 약 100 KiB에서 실행됩니다.


6

티카 - 100 % 정확도 223 193 189 바이트

f=(r=Array[0&,Max@##];For[s=2,s<=#+#2,++s,For[i=Max[1,s-#2],i<=Min[s-1,#],++i,j=s-i;r[[j]]=Which[i==1,PrimeQ@j,j==1,OddQ@Total@IntegerDigits[i-1,2],0<1,Xor@@r[[j-1;;j]]]]];If[r[[#2]],1,0])&

읽을 수있는 버전은 다음과 같습니다.

f[x_,y_] := (
   r = Array[0 &, Max[x,y]];
   For[s = 2, s <= x + y, ++s,
    For[
     i = Max[1, s - y],
     i <= Min[s - 1, x],
     ++i,

     j = s - i;
     r[[j]] = Which[
       i == 1,
       PrimeQ@j,
       j == 1,
       OddQ@Total@IntegerDigits[i - 1, 2],
       0 < 1,
       r[[j - 1]]~Xor~r[[j]]
       ]
     ]
    ];
   If[r[[y]], 1, 0]
   );

나는 기본적으로 상수의 대각선을 따라 사전 계산 x+y합니다.

풍모:

  • 정확합니다.
  • 에서 실행됩니다 O(x*y).
  • f[8192,8192]약 400 초가 걸립니다. 개선의 여지가 있다고 가정 RotateLeft합니다 (내부 루프를 교체 할 수 있음).
  • max(x,y)메모리에서 중간 결과 까지 하나의 배열 만 사용 합니다. 따라서 알고리즘 자체 (및 Mathematica가 사용하는 모든 것)에 약 32k 이상 (32 비트 정수로 가정)을 사용할 필요가 없습니다. 실제로 Mathematica는 자체 시스템에서 31M을 자체적으로 사용하지만 문제없이 작동합니다.

    MemoryConstrained[f[8192, 8192], 2^21]
    

알 겠어요. 그래도 앞으로 더 힘들게 만들 것입니다 : P
Joe Z.

흠, 변경 중 하나에서 런타임 성능을 망쳐 놓았어야합니다. 내부 루프는 여전히 O(x*y)시간 이라고 하지만 총 실행 시간은 그보다 빠릅니다. 무슨 일이 일어나고 있는지 잘 모르겠습니다. 일부 Mathematica Guru가 나를 밝힐 수 있다면, 루프에서 어떤 작업이 O(1)도움 이되지 않습니까! :) (물론, PrimeQTotal@IntegerDigits아니지만, 나는 처음부터 거기에 그들을 했어, 그들은에만 호출 O(y)O(x)각각 회)
마틴 청산

3

Matlab : 100 % 정확도, 120 자, 불합리한 실행 시간

function z=M(x,y)
if y==1 z=(x>1)*isprime(x);elseif x==1 z=mod(sum(dec2bin(y-1)-48),2);else z=xor(M(x,y-1),M(x-1,y));end

쓰다:

> M(4,4)
ans =
      0
> M(1, 9)
ans =
      1

1
이제 질문이 있습니다. 실제로이 프로그램을 실행하고 테스트 할 수 있습니까?
Joe Z.

당신이 실행할 수 없다면 M(8192, 8192), 나는 그것을 취할 수 없습니다.
Joe Z.

@JoeZ M 코드이므로 Matlab 또는 Octave에서 실행할 수 있습니다.
intx13

@JoeZ M (8192, 8192)을 정확하게 계산합니다. 도전은 완료 시간에 대해 아무 말도하지 않았다;)
intx13

1
@JoeZ는 M (20,20)이 기꺼이 기다릴 것보다 오래 걸리는 것처럼 보입니다. 그러나 "정확한"것입니다! : P
intx13

2

파이썬, 192 자

100 % 정확도, 내 컴퓨터에서 ~ 10 초 안에 M (8192,8192)을 계산합니다.

R=range
def M(X,Y):
 X+=1;c=[1]*X;r=[0]
 while len(r)<Y:r+=[i^1 for i in r]
 for i in R(2,X):
  if c[i]:
   for j in R(i+i,X,i):c[j]=0
  r[0]=c[i]
  for i in R(1,Y):r[i]^=r[i-1]
 return r[Y-1]

0

Haskell-261 바이트-100 %-1MB-곧 종료 될 것이라고 생각하지 않습니다.

m 16 16with 에 대해 약 10 초가 걸리지 -O2만 어쨌든 작성 했으므로이 문제에도 불구하고 표시 할 수 있습니다.

m x y=if n x y then 1 else 0 where n x 1=b x;n 1 y=(a!!13)!!(y-1);n x y=(n x (y-1))`f`(n(x-1)y)
f True False=True
f False True=True
f _ _=False
a=[False]:map step a where step a=a++map not a
b x=x`elem`takeWhile(<=x)e
e=c [2..]where c(p:s)=p:c[x|x<-s,x`mod`p>0]

어쩌면 좋은 Haskeller가 그것을 최적화 할 수 있습니까?

m' x y = if m x y then 1 else 0
    where
        m x 1 = isPrime x
        m 1 y = morse' y
        m x y = (m x (y-1)) `xor` (m (x-1) y)

xor True False = True
xor False True = True
xor _ _ = False

morse' x = (morse !! 13) !! (x-1)
morse = [False] : map step morse where step a = a ++ map not a

isPrime x = x `elem` takeWhile (<=x) primes
primes :: [Integer]
primes = sieve [2..] where sieve (p:xs) = p : sieve [x|x <- xs, x `mod` p > 0]

main = putStrLn $ show $ m' 16 16

알고리즘 자체에 결함이 있다고 생각합니다. 어쨌든, 이것을 골프하기 위해 할 수있는 일이 많이 있습니다. 대부분 여분의 괄호가 있지만 f p|p=not|0<1=id더 좋습니다. 또한 morse = False : concat $ iterate [True] (\a -> a ++ map not a)게으름을 높이기 위해 사용하십시오 . 성능에 어떤 영향을 미칠지 궁금합니다.
자부심을 가진 haskeller

또한, 당신은 골프 수 True0<1False에가 0>1.
자부심을 가진 haskeller

0

펄, 137

'승리'하지 말고 :-), 아직 Perl이 없으며 코드가 작성되었으므로 여기에 있습니다.

sub f{($n,$m)=@_;@a=0;@a=(@a,map{0+!$_}@a)while@a<$n;for$k(2..$m){$p=0;O:{$k%$_?1:last O for 2..sqrt$k;$p=1}$p=$a[$_]^=$p for 1..$n-1}$p}

호출하면 몇 초가 걸리고 print f(8192,8192)메모리에 단일 행의 행렬 (8192 정수 (스칼라)의 배열), 약 3.5Mb 전체 Perl 프로세스를 저장합니다. 배열 대신 문자열을 사용하여 (regexps 또는 substr로 액세스) 메모리를 적게 사용하고 더 골프를 칠 수 있지만 훨씬 느리게 실행하려고했습니다.

들여 쓰기 :

sub f{
    ($n,$m)=@_;
    @a=0;                                  # @a will be current line.
    @a=(@a,map{0+!$_}@a)while@a<$n;        # Fill it with Thue-Morse sequence.
    for$k(2..$m){                          # Repeat until required line number.
        $p=0;                              # Find out if current line number 
        O:{                                # is a prime.
            $k%$_?1:last O for 2..sqrt$k;
            $p=1                           # Store result (0 or 1) in $p.
        }
        $p=$a[$_]^=$p for 1..$n-1          # XOR previous value in current position
    }                                      # with $p and store in $p.
    $p                                     # Return $p.
}

0

하스켈, 223

g n=div(filter(>=n)(iterate(*2)1)!!0)2
1%1=0>1
1%n=not$1%(n-g n)
n%1=and[rem n x>0|x<-[2..n-1]]
a%b=g[0<1]where g s|foldr seq(0>1)s=0<1|n==a+b=s!!(b-1)|0<1=g$n%1:zipWith x s(tail s)++[1%n]where n=length s+1
x p|p=not|0<1=id

이것은 빠른 실행 시간을 갖습니다 (5.7 초 -O3). 메모리는 아직 검사되지 않았지만 선형이어야합니다.

이것은 전에 본 대각선 알고리즘을 사용합니다.

속도에 관한 한, 중요한 것은 대각선 알고리즘 -O3|foldr seq(0>1)s=0<1가드 뿐입니다 .이 목록은 엄격합니다. 다른 모든 것은 오히려 비효율적으로 구현됩니다-소수 검사는 분할을 위해 작은 숫자를 모두 검사하여 수행되며 모스 시퀀스의 요소는 지속적으로 재 계산됩니다. 그러나 그것은 여전히 ​​충분히 빠릅니다 :-).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.