Llhuii, dünyadaki 42 byte Python'da Evil Numbers'ı nasıl üretti?


71

Bu ilgilendiren Python golf için bir ipucu sorudur Evil Numaraları üzerinde soru Anarchy Golf .

İkili genişlemesi 1 sayısı çift ise, bir sayı kötüdür . Buradaki zorluk ilk 400 kötülüğü 0,3,5,...,795,797,798, her satıra bir tane basmaktır.

Python 2 başvuruları , 42 baytlık bir çözümle llhuii tarafından yönetiliyor. Bir sonraki en iyiler, 47 byte gönderim ardından da 47 byte. Llhuii, 2 yıldan fazla bir süredir birçok güçlü Python golfçüsünden kaçan gerçekten büyülü bir şey buldu. Bu kadar kısa bir golf için 4 veya 5 byte tasarruf etmek çok büyük.

Python 2 puan tablosu

Hala 47 bayttayım. Umarım bu bulmacayı bir topluluk olarak kırabiliriz. Ortaklaşa bir cevap alırsak, katkıda bulunan herkesin isimleriyle bildiririm. Bu sorunun cevabı bir kod parçası veya yeni bir fikir veya bir analiz parçası olabilir. Eğer llhuii iseniz, lütfen bizim için şımartmayın.

Her ne kadar başvurular açıklanmasa da, bu sorun Sonsuz olduğu için bazı ipuçlarını veriyoruz. Kazanan sunumun çalışması, diğerlerinden çok daha uzun süren 0.1699 saniye sürdü ve verimsiz bir yöntem ortaya çıktı. Bayt istatistiklerinden, 42 karakterden 23'ü alfanümerik [0-9A-Za-z], 19'u ASCII sembolüdür. Bu, llhuii'nin çözümünde boşluk olmadığı anlamına gelir.

Kodunuzu sorun sayfasından test edebilirsiniz , dil açılır menüsünden Python'u seçerek veya bir .pydosya yükleyerek . Bunu not et:

  • Python 2.7 kullanılır
  • Kodunuz yazdırılan tam bir program olmalıdır
  • Bu sorun için girdi yok, gibi
  • Programınız, daha büyük değerleri bozsa bile 400 değeri verilen şekilde yazdırmak zorundadır
  • Programların çalışması için 2 saniye var
  • Programlar hatalı sonlandırılabilir
  • Kullanabilirsiniz exec; "exec reddedildi", kabuk exec anlamına gelir

2
Ayrıca, bu dizilerin "Thue-Morse dizisindeki A010060 sırasındaki sıfır endeksleri" olduğuna dikkat etmek de faydalı olabilir. (kaynak: oeis )
Conor O'Brien

Yanıtlar:


51

Bu llhuii'ninkiyle aynı çözüm değil, aynı zamanda 42 byte uzunluğunda.

n=0;exec'print n;n^=(n^n+2)%3/2;n+=2;'*400

Çevrimiçi deneyin!

@JonathanFrech sayesinde, şu an 40 bayttayız.

n=0;exec'print n;n=n+2^(n^n+2)/2%3;'*400

Çevrimiçi deneyin!

Kaydedilecek başka bir bayt var, toplamda 39.

n=0;exec'print n;n=n+2^-(n^n+2)%3;'*400

Çevrimiçi deneyin!


1
Merak etmeden, 42-byte sürümü llhuii ile aynı olmadığını nasıl biliyorsunuz? (Ben hiç Anarchy Golf’e katılmadım)
Luis Mendo

6
@LuisMendo İstatistikler sekmesi 23 alfanümerik bayt ve 19 ASCII sembolünü listeler, bu nedenle boşluk yoktur. Llhuii'nin yazdığı sürece print+n, onların çözümü benimkinden farklı olmalı.
Dennis,

Ah, kodları bilmiyor olsanız bile bilgi alabilirsiniz. Bu iyi. Teşekkürler!
Luis Mendo

38 için bir şansın olduğunu düşünüyor musun? Teoride , çalışacak bir şey almadığım halde , -işaretini kullanarak veya kullanarak ve ya print~nda print-nkullanarak işaretini kaldırma potansiyeli vardır . Ayrıca, güzel ama 40 bayt. &~n=0;exec"print n;d=n^n+2;n^=d^-d%3;"*400
xnor

print-nnve bit kümeleri arasında kolay bir ilişki olmadığı için olası görünmüyor -n. print~nTeoride daha umut verici gelebilir, ancak bu yaklaşımla 40 baytın altına giremiyorum.
Dennis,

28

39 bayt almak

Bu, Dennis ve Jonathan Frech'in de ayrı olarak buldukları 39 baytlık bir çözüme nasıl ulaştığımın bir açıklaması . Ya da daha doğrusu, bir kişinin cevaba nasıl ulaşabileceğini, çamurlu muhakeme ve çıkmazlarla dolu olan asıl yolumdan çok daha güzel bir şekilde nasıl açıklanabileceğini açıklar.

n=0
exec"print n;n=n+2^-(n+2^n)%3;"*400

Bunu biraz daha az golf oynayarak ve daha çok parenle yazarken, şöyle görünür:

n=0
for _ in range(400):
  print n
  n=(n+2)^(-((n+2)^n))%3

Bit pariteleri

Benim bir fikirle başlar 47 bayt çözümü çıkışı formun tüm sayılar için yukarı sayar ve 1'ler bile toplam sayısını kılan bir eşlik biti olduğunu.n=2*k+bk0,1,...,399b

En yazalım par(x)için biraz parite ait xxor (olduğunu ^) biti tümünün x. Bu, eğer 1 bitlik bir çift varsa (sayı kötüdür) ve tek sayıda 1 bit varsa 1'dir. Çünkü n=2*k+b, ihtiyacımız olan par(n) = par(k)^bkötülüğü elde etmek için , yani son bit , önceki bitlerin bit paritesi olacaktı.par(n)==0b=par(k)n

Golf Benim ilk çabalar ifade edildi par(k), ilk doğrudan en ile bin(k).count('1')%2birlikte daha sonra, ve biraz manipülasyon .

Eşlik güncellemeleri

Yine de kısa bir ifade yoktu. Bunun yerine, çalışmak için daha fazla bilgi olduğunu fark etmemize yardımcı oldu. Mevcut sayının bit paritesini hesaplamak yerine,

k  ---->  par(k)

Biz artırmak olarak biz biraz paritesine güncelleyebilir kiçin k+1.

k   ---->  par(k)
      |
      v
k+1 ---->  par(k+1)

Yani, saydığımız için k=0,1,2,..., her seferinde sıfırdan hesaplamak yerine sadece mevcut bit paritesini korumamız gerekir. Parite biti güncelleme par(k+1)^par(k)giden çevrilmiş bit sayısının paritesi ise khiç k+1, yani par((k+1)^k).

par(k+1) ^ par(k) = par((k+1)^k)
par(k+1) = par(k) ^ par((k+1)^k)

Formu (k+1)^k

Şimdi hesaplamamız gerekiyor par((k+1)^k). Hiçbir yere ulaşmamışız gibi görünebilir, çünkü hesaplama bit paritesi tam olarak çözmeye çalıştığımız problemdir. Ancak, (k+1)^kforma sahip olarak ifade edilen sayılar 1,3,7,15,.., yani 2 bit gücünün altında olan, genellikle bit bilgisayar korsanlarında kullanılan bir gerçek . Bunun neden olduğunu görelim.

Arttığımızda k, ikili taşıyıcıların etkisi sonuncuyu 0ve hepsini 1sağa çevirmek, 0eğer yoksa yeni bir lider oluşturmaktır . Örneğin, almakk=43=0b101011

      **
  101011  (43)
 +     1
  ------
= 101100  (44)

  101011  (43)
 ^101100  (44)
  ------
= 000111  (77)   

Taşımaya neden olan sütunlar ile işaretlenmiştir *. Bunlar var 1bir değişikliği 0ve bir taşıma bit geçmek 1bir vurur kadar kalan ilerleyen tutar, 0in kdeğişir, 1. Soldan ilerideki herhangi bir bit etkilenmez. Yani, k^(k+1)bit pozisyonu çekleri değiştirmek kiçin k+1, bu en sağdaki konumlarını bulur 0ve 1onun sağa 's. Yani, değişen bitler bir sonek oluşturur, bu nedenle sonuç 0'ın ardından bir veya daha fazla 1'dir. Baştaki sıfırlar olmadan, 1, 11, 111, 1111, ...2 gücünün altında bir olan ikili sayılar vardır.

Bilgi işlem par((k+1)^k)

Şimdi bunun (k+1)^ksınırlı olduğunu anladığımızda 1,3,7,15,..., bu sayıların bit paritesini hesaplamanın bir yolunu bulalım. Burada, faydalı bir gerçek, ve arasında beri 1,2,4,8,16,...alternatif modülo olmasıdır . Yani, modulo alarak , tam olarak onların bit paritesi olan verir . Mükemmel!3122==-1 mod 31,3,7,15,31,63...31,0,1,0,1,0...

Yani, güncellemeyi yapabilirsiniz par(k+1) = par(k) ^ par((k+1)^k)olarak

par(k+1) = par(k) ^ ((k+1)^k)%3

Eşliği bsakladığımız değişken olarak kullanmak , bu gibi görünüyor

b^=((k+1)^k)%3

Kod yazma

Kodunda birlikte bu koyarak, biz başlatmak kve parite bit bhem 0sonra defalarca baskı, n=2*k+bve güncelleme b=b^((k+1)^k)%3ve k=k+1.

46 bayt

k=b=0
exec"print 2*k+b;b^=(k+1^k)%3;k+=1;"*400

Çevrimiçi deneyin!

Biz etrafında parens kaldırıldı k+1içinde ((k+1)^k)%3çünkü Python öncelik ilk Neyse, görünüşe garip olarak eklenme yapar.

Kod geliştirmeleri

Doğrudan tek bir değişkenle çalışarak n=2*k+bve güncellemeleri doğrudan üzerinde gerçekleştirerek daha iyisini yapabiliriz . Yapmak k+=1karşılık gelir n+=2. Ve, güncelleme b^=(k+1^k)%3karşılık gelir n^=(k+1^k)%3. İşte, k=n/2güncellemeden önce n.

44 bayt

n=0
exec"print n;n^=(n/2+1^n/2)%3;n+=2;"*400

Çevrimiçi deneyin!

Yeniden yazarak kısaltabiliriz n/2+1^n/2(bunu hatırlayın (n/2+1)^n/2).

n/2+1 ^ n/2
(n+2)/2 ^ n/2
(n+2 ^ n)/2    

Yana /2geçen biraz kaldırır önce veya xor-ing sonra yaparsanız, hiç önemli değil. Yani biz var n^=(n+2^n)/2%3. Biz modülo işaret ederek başka byte kaydedebilirsiniz 3, /2eşdeğerdir *2eşdeğerdir -belirterek, n+2^nbölünme döşeme olmadan gerçek halving bile böyledir. Bu verirn^=-(n+2^n)%3

41 bayt

n=0
exec"print n;n^=-(n+2^n)%3;n+=2;"*400

Çevrimiçi deneyin!

Son olarak, biz işlemleri birleştirebilirsiniz n^=c;n+=2içine n=(n+2)^cnerede, cbiraz. Bu işe yarıyor, çünkü ^csadece son bit üzerinde hareket ediyor ve son bit ile +2ilgilenmiyor, bu yüzden işlemler yolunda gidiyor. Yine, öncelik, parens atlamamıza ve yazmamıza izin verir n=n+2^c.

39 bayt

n=0
exec"print n;n=n+2^-(n+2^n)%3;"*400

Çevrimiçi deneyin!


13

Bu benim (xnor'ın) 47 baytlık çözümünü ve beni buna yönlendiren düşüncemi verir. Bunu kendin çözmek istersen bunu okuma.

Doğal bir ilk fikir, 0'dan 799'a kadar olan sayıları yinelemektir, sadece ikili sayıları 1 olanları basar.

52 bayt

for n in range(800):
 if~bin(n).count('1')%2:print n

Çevrimiçi deneyin!

Burada, sayımı değiştirmek ve sadece eşit sayılarda bir truthy değeri vermek ~için bit tamamlayıcısını alır even<->odd.

Bu yöntemi filtreleme yerine tüm değerleri üreterek geliştirebiliriz. Çıktı değerlerinin, her biri 1 bit sayısını eşitlemek için bir bit eklenmiş 0 ila 399 sayıları olduğunu gözlemleyin.

0 = 2*0 + 0
3 = 2*1 + 1
5 = 2*2 + 1
6 = 2*3 + 0
...

Yani, nth sayısı ya 2*n+bile ya b=0da b=1. Biraz bsayarak bulunabilir 1ait bit 's nve sayım modulo 2.inci.

49 bayt

for n in range(400):print 2*n+bin(n).count('1')%2

Çevrimiçi deneyin!

2 2*byte'ı yineleyerek kesebiliriz, 0,2,4,...bu sayı sayılmaz 1. Bunu exec400 kez çalışan ve nher döngüyü 2 artıran bir döngü kullanarak yapabiliriz .

47 bayt

n=0;exec"print n+bin(n).count('1')%2;n+=2;"*400

Çevrimiçi deneyin!

Ve bu benim 47 baytlık çözümüm. Diğer tüm 47 baytlık çözümlerin aynı olmadığından şüpheleniyorum.


1
47 bayt uzunluğunuz için execizin var mı?
Jonathan Frech

1
@JonathanFrech Evet, sayfa "exec reddedildi" dediğinde, Python'a execdeğil komut satırına atıfta bulunur exec.
xnor

9

llhuii'nin Python 3 gönderimi

İşte Python 3 Yazma Sırasında Evil Numbers için başvuruları:

görüntü tanımını buraya girin

llhuii muhtemelen numaralarını Python 3'e taşıdı ve bu konuda bir çözüm buldu.

  • Python 2 çözümünden daha uzun 3 bayt ve
  • 45 - (25 + 18) = 2 bayt beyaz boşluk var.

Xnor’ın 47B’sini Python 3’e taşımak, tam anlamıyla 50B’yi alıyoruz:

n=0;exec("print(n+bin(n).count('1')%2);n+=2;"*400)

Olarak gönderdim ppcg(xnor). ( Şimdi işlevli olanlara parantez ekler execve bunlara eklenir print.) Hepsinde bir miktar boşluk olan, diğer Python 3 cevaplarından farklı kod istatistiklerine sahiptir. İlginç!

Yine de yeniden yazmak için daha kısa bir yol var ( execPython 3'teki rekabet gücünü kaybetme eğiliminde):

n=0
while n<800:print(n+bin(n).count('1')%2);n+=2

49 bayttır. Olarak gönderdim ppcg(xnor,alternative). Bunun iki baytlık boşluğu var, tıpkı llhui'nin cevabı gibi! Bu, llhuii'nin Python 3 yanıtının bu şekilde göründüğüne inanmamı sağlıyor (newline, sonra bir whiledöngü.) Bu yüzden llhuii muhtemelen execPython 2'de ve whilePython 3'te, tıpkı bizim gibi; bu, boşlukların tutarsızlığını açıklar.


47B'imiz Python 3'te 49B oldu. Şimdi ilginç olan, llhuii'nin 42B'sinin 44B olmadığı, 45B olduğu! Llhuii'nin çözümü ile ilgili bir şey Python 3'te fazladan bir bayt alıyor. Bu, çok çeşitli anlamlara gelebilir.

  • Akla gelen ilk şey bölünme : belki llhuii kullanır /hale Python 2'de //Python 3'te (onlar bizim gibi ikişer ikişer sayıyorsanız, o zaman n/2kaydırmaya kullanılabilecek nbir bit sağa dön?)

  • Akla gelen diğer bir şey, baskıdan sonra unary operatörleri . Bizim print blaholdu print(blah)llhuii gibi bir şey yazdıysam (1 bayt ekstra), ancak print~-blahPython 2'de bu hale ediyorum print(~-blah)Python 3'te.

  • Belki başka fikirler vardır. Lütfen bana haber ver.

Şimdi benimki de dahil olmak üzere tüm Py3 çözümleri için kod istatistikleri:

görüntü tanımını buraya girin


1
İlginç bulduğum şey, onların Python 3 çözümünün Python 2 çözümünden çok daha hızlı olmasıdır. Ya Python 3'te daha verimli olan bazı Python özelliğini kullanıyorlar ya da sonuçta basit bir port değiller (belki de doğrudan bir porttan daha kısa bir Python 3 çözümü bulmuşlardır).
Jonathan Frech

2
Anagol'deki çalışma sürelerinin çok büyük farklılıkları vardır, OP'ye göre llhuii'nin çalışma zamanlarının Py2 çalışma zamanlarının sadece kırmızı bir ringa balığı / dışlayıcı olduğunu düşündürdüğünü söyledim
Lynn

Ayrıca, ben XNOR çok benzer bir hile bulundu ve (olamaz üzerine geliştirilmiş farz olduğunu ?! kötüyüm, sayıları yazdırmak için birçok yol) ve bunların çözüm bol hızlı!
Lynn

7

Diğer yaklaşımlar

1) A001969 için formül kullanma

İkiliye dönüştürmek yerine, aşağıdaki formülden ( OEIS'den ) faydalanmak mümkün olabilir :

a(1) = 0
for n > 1: a(n) = 3*n-3-a(n/2) if n is even
           a(n) = a((n+1)/2)+n-1 if n is odd

Python'da golf oynamakta çok kötüyüm, o yüzden denemeyeceğim bile. Ancak burada JS hızlı bir girişimdir.

Not: Geçerli bir JS gönderimi olacağını sanmıyorum çünkü göstermeden sadece bir diziyi dolduruyor. Ve yine de, şu anki en iyi JS çözümünden (45 byte) 5 byte daha uzundur. Ama zaten buradaki nokta bu değil.

for(a=[n=0,3];n<199;)a.push(2*++n+a[n],6*n+3-a[n])

Umarım biraz ilham verebilir.

Bir dizinin kullanılması muhtemelen iyi bir fikir değildir, çünkü başlatılması ve güncellenmesi gerekir. Bunun yerine özyinelemeli bir işlev kullanmak daha etkili (kod boyutu) olabilir; bu, kazanan çözümün neden diğerlerinden daha fazla zaman aldığını açıklar .

2) Thue-Morse dizisinin yer değiştirmeleri ile oluşturulması

Teoride, bu kod çalışması gerekir:

n=0;a="1";b="0";exec"t=a;a+=b;b+=t;print(int(b[n]))+n;n+=2;"*400

Çevrimiçi deneyin! (çalıştırılabilir sürüm 20 terimle sınırlıdır)

Thue-Morse dizisini ardışık sübstitüsyonlarla hesaplar ve aynı döngüdeki 1'lerin (Evil Numbers) konumunu arar.

Fakat:

  • Şu anki haliyle çok uzun
  • Hızlı bir şekilde bellek taşmasına yol açar

3) Thue-Morse dizisinin bit işlemi ile oluşturulması

Vikipedi'nin Thue-Morse dizisinin Doğrudan Tanımı'ndan başlayarak, bu algoritmaya geldim (JS'ye geri döndüm ... üzgünüm):

for(e=n=0;n<799;)(e^=!(((x=n++^n)^x/2)&170))||console.log(n)

nerede şimdiki takip Kötülük içinde dizisinin e ve kullanımı 170 bir bayt garip bit bit maskesi olarak.


Özyinelemeli bir işlev fikrini seviyorum, ancak Python kazan plakası için çok kötü: f=lambda n:_ for n in range(400):print f(n)zaten 43 bayt alıyor. Belki de kendisine referans veren bir dizi ya da sonuna gelecek unsurları ekleyen bir dizi oluşturarak, özyinelemeyi simüle etmenin bir yolu vardır.
xnor

2
Ayrıca, llhuii çözümü o kullanmıyordu çok, içinde boşluk vardır def, for, while, lambda(bir parametre ile en azından) vb
Stephen

@Stephen Gibi bir şey while~0:print~1herhangi bir boşluk gerektirmez.
Jonathan Frech

3 numaralı yöntemde, ((x=n++^n)^x/2)sadece en düşük ayarlı biti bulmak için biraz ayrıntılı gözüküyor. Bütün bu karışıklık yerini alabilir ++n&-n. Çevrimiçi deneyin!
primo

@primo Burada ne düşündüğümü ve bu hantal formüle nasıl geldiğimi bilmiyorum. ¯ \ _ (ツ) _ / ¯
Arnauld

5

İç içe sayıcılar yaklaşımı

Farklı bir yaklaşım için bir fikrim var, ancak python golf alanında yeterince tecrübeli değilim, bu nedenle sizi golf için olası bir başlangıç ​​noktası olarak düşünmeniz için burada bırakacağım.

Asılsız fikir:

n=0
i=1
for _ in"01":
 i^=1
 for _ in"01":
  i^=1
  for _ in"01":
   i^=1
   for _ in"01":
    i^=1
    for _ in"01":
     i^=1
     for _ in"01":
      i^=1
      for _ in"01":
       i^=1
       for _ in"01":
        i^=1
        for _ in"01":
          i^=1
          if n<800:print i+n
          n+=2

Çevrimiçi deneyin!

Dokuz seviye yuvalama derinliği, tüm döngüler aynıdır, bu yüzden aklımda inşa edilmeleri gerekir exec"something"*9+"deepest stuff". Uygulamada, böyle bir şeyi for döngüsü ile yapmanın mümkün olup olmadığını bilmiyorum.

Golf için dikkat edilmesi gerekenler:

  • belki bir for döngüsünden iki kez başka bir döngü gerçekleştirme olasılığı daha var (iki kere biçimlendirme argümanı olarak kendi kendine iletilen dizeyle sine benzer bir yaklaşım denedim, fakat başım patladı).

  • bunun için daha iyi bir alternatif de olabilir if n<800:, çünkü burada gerekli olan, aksi takdirde 2 ^ 10'a kadar olan kötü numaraları basmaya devam edeceğiz



Belki döngüler için iç içe geçmiş yerine iç içe liste kavramalarını deneyebilirsiniz?
Sparr

@Sparr Sorun o zaman sayıları gerçekten yazdırmaktır. Python 2'de, printbir işlev değil, bir ifadedir ve bu nedenle bir anlama giremez.
Jonathan Frech

belkiprint '\n'.join([[[[[[[[[foo]foo]foo]foo]foo]foo]foo]foo]foo])
Sparr

@Sparr O zaman sorun listeyi düzleştirmekle yatıyor; str.joinyalnızca dizeleri içeren listelerde çalışır ve fazladan liste karakterleri yazdırılmamalıdır. Tek başına biçimlendirme, önemli miktarda bayt alır.
Jonathan Frech

5

Fikir: Daha kısa bit paritesi

bin(n).count('1')%2Bit sayısının paritesini hesaplamak için yapılması gereken birçok karakter var . Belki aritmetik bir şekilde daha kısa, özellikle sınırlı bir bit uzunluğu verilen.

Şirin bir aynı uzunluktaki yol, int(bin(n)[2:],3)%2ikili değeri taban 3(veya herhangi bir tek taban) olarak yorumlamaktır . Maalesef, baytların 4'ü 0bön eki kaldırarak harcıyor . Aynı zamanda yapmak için çalışıyor int(bin(n)[2:])%9%2.

Başka bir fikir, xor kullanarak bitleri birleştirmekten geliyor. nİkili gösterim varsa abcdefghi, o zaman

n/16 = abcde
n%16 =  fghi

r = n/16 ^ n%16 has binary representation (a)(b^f)(c^g)(d^h)(e^i)

Yani, r=n/16^n%16eğer kötülük ise ve sadece kötülük ise n. Daha sonra sıra tekrar edebilir s=r/4^r%4, bir değeri sde 0,1,2,3, bunların 1ve 2ile kontrol edilebilir, kötü değildir 0<s<3.

52 bayt

n=0;exec"r=n/16^n%16;print(0<r/4^r%4<3)+n;n+=2;"*400

Çevrimiçi deneyin!

Bu daha iyi bir anlaşma oldu. Sayının nasıl bölüneceği, son sayının nasıl kontrol edileceği (belki de bit tabanlı bir arama tablosu) nasıl çevrileceği hakkında çevrilecek birçok düğme vardır. Bunların ancak bu kadar ileri gidebileceğinden şüpheleniyorum.


to_bytesTamsayılı fonksiyonunu kullanma olasılığı olur mu? Bundan şüpheliyim ama dikkate alınması gereken bir şey :)
HyperNeutrino

@HyperNeutrino Sadece bu Python 3 olduğunu düşünüyorum?
xnor

kötü benim yup: / rip
HyperNeutrino

9
Basitçe kullanmak 0b: int(bin(n),13)%2! : D
Noodle9

3
İlerleme! Noodle9's numarası 44 baytlık bir çözüm sunuyor:n=0;exec"print~int(bin(n),13)%2+n;n+=2;"*400
Lynn

4

Yapım n+n^ngereği her zaman kötüdür, fakat zayıf Python becerilerim ancak 61 baytlık bir çözüm bulabildi:

for n in sorted(map(lambda n:n+n^n,range(512)))[:400]:print n

5 byte tasarruf için @Peilonrayz ve 1 byte tasarruf için @ Mr.Xcoder'e teşekkürler:

for n in sorted(n^n*2for n in range(512))[:400]:print n

55 byte : for n in sorted(n^n*2for n in range(512))[:400]:print n. n+n^naynın^n*2
Bay Xcoder

3

Fikir: A006068 (“a (n) n'ye gri kodludur”)

Neil'in bütün 2n XOR nmeraklılarımı sıralama fikri bu yüzden arkasındaki endeksleri bulmaya çalıştım. Bu kodu yazdım ve şöyle bir şey yazabileceğimizi ortaya koyuyor:

for n in range(400):x=a(n);print 2*x^x

Burada a(n)A006068 (n). Çevrimiçi deneyin!

Ancak, bu A006068'i hesaplamak için kısa bir yolumuz olduğunu varsayar. Bu zaten 38 byte, sanırım 4 byte olarak hesaplayabiliriz ( a(n)kısım). Gerçek uygulama (TIO başlığında) bundan çok daha uzundur. Bunun için fazla umut yok sanırım.


3

Fikir: XOR üzerinde azaltmak

Eğer nbirlikte tüm parçaları XOR , 0kötülük için ve kötülük için olacak 1. Bunu özyinelemeli bir işlevle yapabilirsiniz (ki bu daha fazla zaman almış olabilir?), Şöyle:

f=lambda n:f(n/2^n&1)if n>1else-~-n

Bu kötülük için 1 döndürür.

Bu, 35 bayttır ve bir sayının kötü olup olmadığını kontrol eder. Ne yazık ki, filterzaten 6 bayt, bu yüzden sözlü olarak en iyi çözüm değildi ama bu fikir muhtemelen golf olabilir.


f=lambda n:n>1and f(n/2^n&1)or-~-n-1 bayt için yapabileceğini düşünüyorum .
Outgolfer Erik 29:17

@EriktheOutgolfer Denedim ama f(n/2^n&1)0 döndürdüğünde hatalara neden oldu ...
HyperNeutrino

2

İkame yöntemi: {1 -> {1, -1}, -1 -> {-1, 1}}

Bu değişikliği 10 defa {1 -> {1, -1}, -1 -> {-1, 1}} yapabilir, sonra düzleştirip 1'lerin pozisyonlarını kontrol edebilirsiniz.

matematiksel kod burada

(F = Flatten)@
Position[F@Nest[#/.{1->{1,-1},-1->{-1,1}}&,1,10],1][[;; 400]] - 1

Bunu python'da nasıl yaparsınız?
Aneesh Durg

2
@AneeshDurg bu çözümde ilginç bir şey buluyor musunuz? kutunun dışında düşünün ve yaşamın anlamına giden yolu bulabilirsiniz AKA 42
J42161217
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.