Ters XOR değerini hesaplayın


13

Izin fbir bit maskesini (eşler fonksiyonu {0 1}boyutta) n+1büyüklüğünün saklayıcısında için nbaşvurarak XORiçin ith ve i+1inci bit ve yeni saklayıcısında sonucu yazma.

Misal: f("0101") = "111"

Gayri resmi hesaplama:

0 XOR 1 = 1

1 XOR 0 = 1

0 XOR 1 = 1

Izin vermek f_inverseters fonksiyonu olmak f. Tersi benzersiz olmadığından f_inversegeçerli bir çözüm döndürür.

Girdi: dizge (bit) olarak bit alanı "0101111101011"ve belirli bir doğal sayık

Output: dize olarak bitfield; böylece girdi bit alanına süreler f_inverseuygulanırsa dize sonucu içerir k. (yani f_inverse(f_inverse(f_inverse(input))))

Kazanan kriterler: en az Karakter

Bonus:

-25Eğer Karakterler f_inverseyinelemeli uygulanmaz / iteratif yerine çıkış dizesi doğrudan hesaplanır

Testscript:

a = "011001"
k = 3

def f(a):
    k = len(a)
    r = ""
    for i in xrange(k-1):
        r += str(int(a[i]) ^ int(a[i+1]))
    return r

def iterate_f(a, k):
    print "Input ", a
    for i in xrange(k):
        a = f(a)
        print "Step " + str(i+1), a

iterate_f(a, k)

Örneğin buraya yapıştırabilir ve daha sonra deneyebilirsiniz.


3
Doğrulamak için bazı test durumları verebilir misiniz?
Doktor

3
Onlara {0-1}-Bitfields demeyi keser misiniz? Ayrıca anlamını da anlamıyorum f, nereden igeliyor? XOR'un ikinci argümanı nedir? nasıl alabilirim 111dan 0101?
mniip

Daha iyi bir isim nedir? ben endeksi gösterir
nvidia

Sadece bir "bitfield" yapardı. / Değeri / değeri nedir i? "0 XOR 1" = 1 "1 XOR 0" = 1 "0 XOR 1" = 1hiçbir şeyi açıklamıyor: XOR'un nasıl çalıştığını biliyorum, ama tam olarak XORing'i yapıyoruz ve sonucu nerede saklıyoruz?
mniip

9
Ne demek düşünüyorum: f([a,b,c,d]) = [a^b, b^c, c^d]. Ve o yani o işlevinin tersini, istediği f'([x,y,z]) = [a,b,c,d]şekilde a^b=x, b^c=y, c^d=z.
marinus

Yanıtlar:


14

Pyth, 33 30-25 = 5 bayt

Jiz8K+lzQ%"%0*o",KuxG/G8rQ^2KJ

Stdin gibi girdilerle çalıştırın (çevrimiçi yorumlayıcı: https://pyth.herokuapp.com/ ):

111
3

ve sonuç stdout'a yazılacaktır.

Bu doğrudan bir çeviri:

Python 2, 127 118 79-25 = 54 bayt

def i(s,k):
 l=int(s,8);t=len(s)+k
 while k<1<<t:l^=l/8;k+=1
 print'%0*o'%(t,l)

Buna şöyle deyin i("111", 3)ve sonuç stdout'a yazılacaktır.

K'nin çok büyük olmamasını beklediğimizi unutmayın, çünkü kod golf amaçlı iç döngü O (2 k ) kez çalışacaktır .


Bence bu işleme genellikle "xorshift" falan diyoruz. Girişi big-endian tamsayıları olarak ifade edersek, f işlevi basitçe:

  • f (x) = x ⊕ (x ≫ 1)

Eğer iki kez f uygularsak :

  • f 2 (x) = x ⊕ (x ≫ 2)

Ancak 3 kez uygulamak farklı bir desene sahip olacaktır:

  • f 3 (x) = x ⊕ (x ≫ 1) ⊕ (x ≫ 2) ⊕ (x ≫ 3)

4 kez uygulandığında temel forma dönün:

  • f 4 (x) = x ⊕ (x ≫ 4)

Ve bunun gibi:

  • f 2 k (x) = x ⊕ (x ≫ 2 k )

Yeterince büyük bir 2 k seçersek , o zaman (x ≫ 2 k ) = 0, yani f 2 k (x) = x demektir ve tersi önemsiz bir şekilde kimlik işlevidir!

F bulmak için strateji Yani -k f uğramadan (x) -1 (x) hiç geçerli:

  1. K'yi şu şekilde bulun:

    • K ≥ k
    • K> log 2 x
    • K, 2'nin gücüdür
  2. Hızlı f -k (x) = f -K + (Kk) (x) = f -K (f K-k (x)) = f K-k (x)

  3. Böylece, sonuç fKk kez denir

  4. 25 karakter kar: p


Güncelleme 1 : %Çok sayıda bayt kaydetmek için biçimlendirmeyi kullanabilmemiz için ikili yerine sekizli gösterim kullanıldı .

Güncelleme 2 : 'nin periyodik yapısını kullanın f. Yinelemesiz sürüm -25 bayt bonusu olmasa bile daha kısa olduğu için yinelemeli sürümü kullanımdan kaldırdı.

Güncelleme 3 : Pyth'ten 3 bayt düşürüldü, teşekkürler isaacg!


İpuçlarında açıklandığı gibi: codegolf.stackexchange.com/a/45280/20080 for döngüsünü ve atamalarını aşağıdaki gibi bir azaltma ile değiştirebilirsiniz:Jiz8K+lzQ%"%0*o",KuxG/G8rQ^2KJ
isaacg

11

CJam, 15 14 bayt

l~{0\{1$^}/]}*

Gibi girdi alır

"111" 3

Burada test edin.

açıklama

l~{0\{1$^}/]}*
l~             "Read and evaluate input.";
  {         }* "Repeat k times.";
   0\          "Push a 0 and swap it with the string/array.";
     {   }/    "For each element in the string/array.";
      1$       "Copy the previous element.";
        ^      "XOR.";
           ]   "Wrap everything in a string/array again.";

Sonuç, programın sonunda otomatik olarak yazdırılır.

Ben bir dize (ki sadece bir karakter dizisi) ile başlar, çünkü "dize / dizi" diyorum, ama aralarında ve sayılar arasında da XORs almaya devam. Character Character ^bir tamsayı verir (kod noktalarının XOR'u temel alınarak) Character Integer ^ve Integer Character ^bir karakter verir (kod noktası olarak kod numarasının yorumlandığı - kod noktası olarak yorumlanmış sayının XOR'u temel alınarak). Ve Integer Integer ^elbette sadece bir tam sayı verir.

Tipleri neyse biryere uçan, fakat Yani bir tamsayı buldukça, ya var 0ya 1ben bir karaktere sahip olduğunda o da var '0ve '1sonuç her zaman (her iki tip) tane arzu. Dizeler sadece karakter dizisi olduğundan, karakterleri sayılarla karıştırmak hiç sorun değil. Ve sonunda, her şey basıldığında, karakterlerin özel sınırlayıcıları yoktur, bu nedenle çıktı hangi bitin bir sayı veya karakter olarak temsil edildiğinden etkilenmez.


CJam karakter / sayı tipi davranış Kişisel mükemmel açıklama üzerimden bir bayt tıraş izin benim çözüm 25 = 0 bayt - 25 ulaşan. Teşekkürler ve +1!
Ilmari Karonen

2
Bu tür davranışlar dehşet verici (+1).
ballesta25

8

J, 17 karakter

Her zaman baştaki basamak olarak 0 kullanılır.

   (~:/\@]^:[,~[$0:)

   3 (~:/\@]^:[,~[$0:) 1 1 1 
0 0 0 1 0 0

Üst satırın 128 1'in durumundan (sol) ve rastgele bir durumdan (sağ) başlayarak, ilk 129 yinelemede son 128 basamağı gösterir.

   viewmat (~:/\)^:(<129) 128$1               viewmat (~:/\)^:(<129) ?128$2

arsa arsa


6

APL 11

((0,≠\)⍣⎕)⎕

Açıklama:

≠\  compare increasing number of elements (1 1 1 ->1 0 1)
0,    add a starting zero
()⍣⎕  repeat the function in parenthesis ⎕ times, ⎕ is the second argument
()⎕   apply all to ⎕, that is first argument

Tryapl.org üzerinde deneyin


Tryapl'de (girdiler nasıl verilir?) Çalıştırılamadı ancak ≠\ bunun yerine çalışmaz 2|+\ mıydı?
randomra

⎕'ler girişlerdir, yazdığım ifadeyi kullanırsanız, program sizden istediğiniz sayıları, önce ikili vektörü, daha sonra yineleme sayısı için ikinci kez sormalıdır. Tryapl bağlantısında a ve b kullandım, bu yüzden sorulmadan yürütüldü. Ayrıca ≠ \ için teşekkürler !!
Moris Zucca

Ben kopyalarsanız ((0,≠\)⍣⎕)⎕geçersiz jetonu almak. Tryapl girdileri işleyemiyor mu?
randomra

1
Hmmmm ... haklısın, benim için de aynı şey oluyor. Dyalog APL kullanıyorum ve sonra sadece buraya göndermek için tryapl kullanıyorum, bu yüzden hiç fark etmedim, bunun için üzgünüm.
Moris Zucca

5

CJam, 25-25 = 0 bayt

q~1,*_@{[\{1$^}/_](;)\}/;

Bu, aşağıdaki GolfScript cevabının düz bir CJam portudur, çünkü Martin Büttner'in cevabını okuduktan sonra CJam'ın tamsayı ve karakter tiplerini işlemesi nedeniyle bir bayt kaydedebileceğimi fark ettim. (Temel olarak, CJam, 1&ASCII karakterlerini GolfScript kodundaki bitlere zorlamak için kullanılmasına gerek yoktur , ancak qgirişi okumak için bir öneri gerektirir .) Genellikle böyle önemsiz bir bağlantı noktasını ucuz bir numara olarak görüyorum, ancak sıfır puan elde ediyorum IMO değerli.

Her durumda, bu program aşağıdaki orijinal GolfScript programı gibi çalışır, bu yüzden lütfen açıklamasına ve kullanım talimatlarına bakın. Her zamanki gibi, bu çevrimiçi yorumlayıcıyı kullanarak CJam sürümünü test edebilirsiniz .


GolfScript, 26-25 = 1 bayt

~1,*.@{[1&\{1$^}/.](;)\}/;

Bu çözüm yalnızca bir kez giriş dizesi üzerinde yinelenir, bu yüzden by25 bayt bonusu için uygun olduğuna inanıyorum. Dahili olarak her bir k yinelemesinin geçerli bitini saklayan bir k- element dizisini koruyarak çalışır .

Giriş stdin aracılığıyla "1111111" 3, yani tırnak içine alınmış bir karakter 0ve 1karakter dizisi ve ardından k sayısı şeklinde verilmelidir . Çıktı tırnak işaretleri olmadan bir bit dizisi olarak stdout olacaktır.

Bu kodu çevrimiçi test edin. (Program zaman aşımına uğrarsa, yeniden çalıştırmayı deneyin; Web GolfScript sunucusu rastgele zaman aşımları için kötü şöhretlidir.)


İşte bu programın yorumlarla birlikte genişletilmiş bir sürümü:

~             # eval the input, leaving a string and the number k on the stack

1,*           # turn the number k into an array of k zeros ("the state array")
.             # make a copy of the array; it will be left on the stack, making up the
              # first k bits of the output (which are always zeros)

@             # move the input string to the top of the stack, to be iterated over
{
  [           # place a start-of-array marker on the stack, for later use
  1&          # zero out all but the lowest bit of this input byte
  \           # move the state array to the top of the stack, to be iterated over

  { 1$^ } /   # iterate over each element of the state array, XORing each
              # element with the previous value on the stack, and leave
              # the results on the stack

  .           # duplicate the last value on the stack (which is the output bit we want)
  ]           # collect all values put on the stack since the last [ into an array
  (;          # remove the first element of the array (the input bit)
  )           # pop the last element (the duplicated output bit) off the array
  \           # move the popped bit below the new state array on the stack
}
/             # iterate the preceding code block over the bytes in the input string

;             # discard the state array, leaving just the output bits on the stack

Temel olarak, yinelemeli çözümlerin çoğu gibi, bu kod yinelemenin uygulanması olarak anlaşılabilir

        b i , j : = b i , ( j −1)b ( i −1), ( j −1) ,

burada b , 0, j olan j (için inci giriş biti j ≥ 1), b , k , j olan j -inci çıkış biti ve B i , 0 varsayımı = 0. Fark (yani önce bu, iteratif çözeltiler ise, aslında, "satır satır" nüksetme hesaplamak olan b 1, J tüm j Daha sonra, b , 2, j , vs.), bu çözelti yerine "kolon o hesaplar sütun "(veya daha doğrusu" köşegen ile çapraz "), ilk önce b i , i için 1 ≤ ik , sonra b i , i +1 , sonra b i , i +2 vb.

Bu yaklaşımın (teorik) bir avantajı, prensip olarak, bu yöntemin keyfi olarak uzun bir giriş dizesini sadece O ( k ) depolaması kullanarak işleyebilmesidir . Elbette, GolfScript yorumlayıcısı, programı yine de çalıştırmadan önce belleğe tüm girdileri otomatik olarak okur ve çoğunlukla bu avantajı reddeder.


2

Python, 94 78

En az bir kez idam edilecek ve böylece n=0ven=1

def f(x,n):
 c='0'
 for i in x:c+='10'[i==c[-1]]
 return f(c,n-1)if n>1 else c

Dizeyi sayısal bir diziye dönüştüren ve modulo 2'yi "bütünleştiren" eski sürüm

from numpy import*
g=lambda x,n:g(''.join(map(str,cumsum(map(int,'0'+x))%2)),n-1)if n>0 else x

2

Python 2, 68

g=lambda l,n,s=0:n and g(`s`+(l and g(l[1:],1,s^(l>='1'))),n-1)or l

Tamamen tekrarlayan bir çözüm. İki fonksiyona bölündüğünü anlamak daha kolay

f=lambda l,s=0:`s`+(l and f(l[1:],s^(l>='1')))
g=lambda l,n:n and g(f(l),n-1)or l

Burada fbirbirini izleyen farkları hesaplar ve kendisiyle n kere gkompozisyon oluşturur f.

İşlev , ardışık XOR farklılıklarına ters fişlem olan kümülatif XOR toplamlarını hesaplar l. Girdi bir dize olarak verildiğinden int(l[0]), dize karşılaştırmasıyla çıkarmamız gerekir , ancak daha kısa yapmamız gerekir l>='1'.


Python 2, 69

Bir execdöngü kullanan yinelemeli bir çözüm 1 karakter daha uzun çıktı.

l,n=input()
exec"r=l;l='0'\nfor x in r:l+='10'[l[-1]==x]\n"*n
print l

Belki dizeyle başa çıkmanın daha kısa bir yolu vardır. Girdi / çıktılar sayı listesi olsaydı, 5 karakter kaydederdi

l,n=input()
exec"r=l;l=[0]\nfor x in r:l+=[l[-1]^x]\n"*n
print l

1

Perl 5, 34

#!perl -p
s/ .*//;eval's/^|./$%^=$&/eg;'x$&

Standart girişte boşlukla ayrılmış parametreler.

$ perl a.pl  <<<"1101 20"
101111011011011011010110

1

Javascript ES6, 47 karakter

f=(s,k)=>k?f(0+s.replace(s=/./g,x=>s^=x),--k):s

Bu arada, hiçbir yan etkisi yoktur :)


Yineleme sayısı için ak parametresini kabul etmeniz gerekir. (-25 bonusu, gerçekten yinelemeleri gerçekleştirmeden yinelemelerin sonucunu hesaplamak içindir.)
Brilliand

Şartnameyi dikkatlice
okumalıydım

1

C # - 178 161 115 karakter

static string I(string a, int k){var s = "0";foreach(var c in a)s+=c==s[s.Length-1]?'0':'1';return k<2?s:I(s,--k);}

Emniyet kemeri ile hareketsiz

using System;
using System.Text;

namespace InverseXOR
{
    class Program
    {
        static string I(string a, int k)
        {
            var s = "0";
            foreach (var c in a)
                s += c == s[s.Length - 1] ? '0' : '1';
            return k < 2 ? s : I(s, --k);
        }

        static void Main(string[] args)
        {
            Console.WriteLine(I(args[0], Convert.ToInt32(args[1])));
        }
    }
}

0

CJam, 20 bayt

q~{:~0\{1$!_!?}/]s}*

Girdi şöyle "111" 3

Buradan çevrimiçi deneyin


"011001" girişiniz için kodunuzdan kaynaklanır, ancak kontrol ederseniz doğru değildir
nvidia

@ user3613886 Üzgünüz, eski sürüm kopyalandı. Şimdi düzeltildi
Doktor
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.