Bu oluşturulan ikili matriste belirli bir değer yazdırın


14

Sonsuz bir matris tanımlamak varsayalım Mile, N^2 -> {0, 1}(burada Nitibaren başlar 1yerine 0) bu şekilde:

  • M(1, 1)= 0.

  • Her için x > 1, M(x, 1)= 1eğer xasal ve bir 0başka türlü.

  • Her için y > 1, M(1, y)= yiçinde inci terim Thue-Morse sequence.

  • Her biri için x, y > 1, M(x, y)= M(x, y-1) + M(x-1, y) mod 2.

16x16Bu matrisin sol üst kısmı şuna benzer ( xsatır ve ysütun olmak üzere):

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

Göreviniz, bu matristeki rastgele bir girişin değerini olabildiğince doğru bir şekilde değerlendirecek bir program oluşturmaktır.

Programınız iki tamsayı alır xve ygirdi olarak, seçtiğiniz herhangi bir biçimde ve döner M(x, y), ya 0da olur 1.

Kodunuz herhangi bir dilde yazılabilir, ancak 64 kilobaytı (65.536 bayt) kaynak kodu boyutundan veya 2 MB (2.097.152 bayt) toplam bellek kullanımından fazla olmamalıdır. Programınız boş bellekle başlamalıdır (yani başka bir yerden veri yükleyemez) ve her giriş için bağımsız olarak çalışmalıdır (yani, birden çok işlem için ortak verileri depolamayabilir). Programınız, sol üst köşedeki tüm girişleri 8192x8192makul bir süre içinde değerlendirebilmelidir.

Sol üstteki 8192 x 8192karede en fazla girişi doğru değerlendiren program kazanır ve kısa kod bir bağlayıcı olarak işlev görür.


Muhtemelen test vakasını birazdan daha zarif bir şeye güncelleyeceğim, bu yüzden soruyu tekrar düzenleyene kadar teste devam edin.
Joe Z.

@mbuettner Evet, var.
Joe Z.

1
"Doğruluk" için nasıl yeni bir etikete ihtiyacımız olduğunu göremiyorum. Bu sadece bir [kod meydan okuması]. Lütfen önce meta aracılığıyla yeni meydan okuma türü fikirleri çalıştırın ([kod trolling] 'ten öğrendiğimiz bir şey var).
Kapı tokmağı

^ Kaydetti. Bu etiketi kaldıracağım.
Joe Z.

1
@TheDoctor Çok nadir değil. Kabul edilen cevap zamanla değişir.
Joe Z.

Yanıtlar:


9

J - 42 38 karakter

Oldukça hızlı,% 100 doğru ve bellek kısıtlamaları içinde.

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

Strateji aşağıdaki gibidir: bu matrisin art arda antidiagonallerini hesaplayacağız, hareket etmek için çift XOR gerçekleştirerek mevcut Thue-Morse ve prime bitlerini uçlara ekleyeceğiz. Daha sonra oraya vardığımızda gerekli rakamı antidiagonalden çıkarırız.

Patlama ile açıklama:

(                                 )&<:  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)

Bu fiilin kullanımı x m y, soruda belirtildiği gibi M (x, y) içindir m, fiil nerede .

   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

Tuş vuruşlarını kaydetmek için hala daha fazla asal mı yoksa Thue-Morse bitine mi ihtiyacımız olduğunu söylemeye çalışmıyoruz, bu yüzden istediğimiz biti elde etmek için tüm antidiagonali hesaplıyoruz. Ancak, 8192 m 8192mütevazı dizüstü bilgisayarımda hala 0.07 saniyeden daha az ve yaklaşık 100 KiB'de çalışıyor.


6

Mathematica'da -% 100 doğru 223 193 189 bayt

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])&

İşte okunaklı bir versiyon:

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]
   );

Temelde sabitin köşegenleri boyunca önceden hesaplama yaparım x+y.

Özellikleri:

  • Doğru.
  • İçeri giriyor O(x*y).
  • f[8192,8192]yaklaşık 400 saniye sürer. Sanırım iyileştirme için yer var (belki RotateLeftiç döngüyü değiştirebilir).
  • max(x,y)Bellekte yalnızca bir ara ara sonuç dizisi kullanır . Bu nedenle algoritmanın kendisi (artı Mathematica ne kullanırsa kullansın) için yaklaşık 32k'den (32 bit tamsayı varsayarak) daha fazla kullanmaya gerek yoktur. Aslında, Mathematica kendi sistemimde kendi başına 31M kullanıyor, ancak bu sorunsuz çalışıyor:

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

Anlaşıldı gibi görünüyor. Gelecekte daha da zorlaşacağım: P
Joe Z.

Hm, değişikliklerden birinde çalışma zamanı performansını düşürmeliydim. İç döngü hala zaman olarak adlandırılır O(x*y), ancak toplam yürütme süresi bundan daha hızlı artar. Ne olduğundan tam olarak emin değilim. Bazı Mathematica Guru beni aydınlatabilirse, döngüdeki hangi işlem O(1)çok yararlı olmaz! :) (iyi, PrimeQve Total@IntegerDigitsdeğildir, ancak ben başından beri orada onları yaşadım ve sadece denilen O(y)ve O(x)sırasıyla kez)
Martin Ender

3

Matlab:% 100 doğruluk, 120 karakter, makul olmayan yürütme süresi

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

Kullanmak:

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

1
Şimdi soru şu, bu programı çalıştırabilir ve test edebilir misiniz?
Joe Z.

Eğer koşamazsan M(8192, 8192), ben alamam.
Joe Z.

@JoeZ M kodu, Matlab veya Octave'de çalıştırabilirsiniz.
19x14

@JoeZ M'yi (8192, 8192) doğru bir şekilde hesaplar.
Zorluk

1
@JoeZ, M (20,20) beklemek istediğimden daha uzun sürüyor gibi görünüyor. Ama hey, "doğru"! : P
intx13

2

Python, 192 karakter

% 100 doğruluk, M (8192,8192) makinemde ~ 10 saniye içinde hesaplar.

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 bayt -% 100 - 1MB - Yakında biteceğini düşünmüyorum

10 saniye sürer m 16 16ile -O2, ama yine de yazdığınız gibi bu soruna rağmen bunu gösterebilir:

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]

Belki bazı iyi Haskeller onu optimize edebilir?

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

Bence algoritmanın kendisi kusurlu. Neyse, bunu golf yapmak için yapabileceğiniz birçok şey var. çoğunlukla ekstra parantez, ama aynı zamanda f p|p=not|0<1=iddaha iyi olmalıdır. ayrıca, morse = False : concat $ iterate [True] (\a -> a ++ map not a)tembelliği artırmak için kullanmayı deneyin . Performansı nasıl etkileyeceğini merak ediyorum.
gururlu haskeller

ayrıca, golf Trueiçin 0<1ve Falseiçin 0>1.
gururlu haskeller

0

Perl, 137

'Kazanmak' için değil :-), ama burada henüz Perl olmadığından ve kod zaten yazıldığından, işte burada.

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}

Çağırılırsa birkaç saniye sürer print f(8192,8192), tek bir matris satırını (8192 tamsayı dizisi (skalar)), yaklaşık 3,5 Mb tüm Perl işlemi belleğinde saklar. Dizi yerine dizgi ile yapmaya çalıştım (regexps ile ya da substr ile erişim), daha az bellek alır ve daha fazla golf olabilir, ama çok daha yavaş çalışır.

Girintili'ye:

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

Haskell, 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

bu hızlı çalışma süresine sahiptir (5,7 saniye ile -O3). bellek henüz kontrol edilmedi, ancak doğrusal olmalıdır.

burada daha önce görülen çapraz algoritmayı kullanır.

hız söz konusu olduğunda, önemli olan tek şey diyagonal algoritma -O3ve |foldr seq(0>1)s=0<1listeyi katılaştıran muhafızdır. diğer her şey verimsiz bir şekilde uygulanır - bölümleme için daha az sayı kontrol edilerek ana kontrol yapılır, Morse dizisinin elemanları sürekli olarak yeniden hesaplanır. ama yine de yeterince hızlı :-).

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.