Brainf *** NOP'ların Üretilmesi


26

Bazen beyin şifresi kodu yazarken, hata ayıklamayı teşvik etmek için gerekenden daha uzun hale getirme ihtiyacı hissedersiniz . Sadece onu içeri sokarak yapabilirsin ><, ama bu ne eğlenceli? Kodunuzu okuyan birinin kafasını karıştırmak için daha uzun ve daha az NOPey'e ihtiyacınız olacak.

Brainfuck'a hızlı giriş

Brainfuck , 1993 yılında Urban Müller tarafından oluşturulan ve aşırı minimalizmi ile dikkat çeken ezoterik bir programlama dilidir. (Vikipedi)

Brainfuck sekiz komutları dayalı bir dildir: +-><,.[]. Kod, bir Turing makinesi gibi bir şey üzerinde çalıştırılır: üzerinde değerlerin değiştirilebileceği sonsuz bir bant. Bu mücadelede ilk dörde odaklanacağız:

+    increment the value at the pointer
-    decrement the value at the pointer
>    move the pointer right
<    move the pointer left

Brainfuck NOP'ları

Beyin fırtınası NOP, herhangi bir devletten yürütüldüğünde, devlette hiçbir değişikliğe yol açmayan bir beyin fırtınası karakter dizisidir. Yukarıda belirtilen dört karakterden oluşur.

Meydan okuma

Buradaki zorluk, yürütüldüğü zaman verilen uzunlukta rastgele bir beyin hastası NOP üreten bir program veya işlev yazmaktır.

Giriş

Girdi olarak negatif olmayan bir tamsayı alın n. (NOP’lar garip değildir n.)

Çıktı

Boyunda NOP rastgele bir beyin fırtınası çıktısı alacaksınız n.

kurallar

  • NOP'un tanımı: Programın çıktısı bir beyin fırtınası programında herhangi bir noktaya yerleştirildiğinde, söz konusu programın davranışı hiçbir şekilde değişmemelidir. Başka bir deyişle, tercümanın durumunu değiştirmemelidir.
    • Örneğin +>-<, iki hücrenin değerlerini geri değiştirmeden değiştirdiği için yanlış olduğunu unutmayın . Lütfen yayınlamadan önce çözümünüzü test edin.
    • Ayrıca +>-<->+<, yalnızca kaldırarak hiçbir şeye indirgenemeyecek bir NOP olduğunu unutmayın >< <> +- -+. Böylece, bunları sadece içlerine ekleyen bir algoritma kullanamazsınız.
  • Uzunluktaki her geçerli NOP n, çıktıda sıfır görünme şansına sahip olmamalıdır. Dağılım olsa da tekdüze olmak zorunda değildir.
  • Söz konusu beyin hilesi tercümanı, iki kat sınırsız keyfi hücre hücresine sahiptir. Yani, her iki yöne de sonsuz gidebilir ve her bir hücreyi süresiz olarak artırabilir / azaltabilirsiniz.
  • Program , makinemde = 100 için 1 dakika içinden bitmelidir, bu nedenle olası tüm NOP'ları oluşturmaz ve birini seçmez.
  • Geçersiz bir giriş (tamsayı olmayan, negatif, tek, vb.) Verilirse, kilitlenme dahil istediğiniz her şeyi yapabilirsiniz.

puanlama

Bu , yani bayt cinsinden en kısa cevap kazanır.

Örnekler

n= 4 için geçerli tüm çıktılar :

++--    +-+-    +--+    --++    -+-+    -++-
>><<    ><><    ><<>    <<>>    <><>    <>><
><+-    ><-+    <>+-    <>-+
>+-<    >-+<    <+->    <-+>
+><-    -><+    +<>-    -<>+
+-><    -+><    +-<>    -+<>

n= 20 için olası birkaç çıktı :

+>>->+<->-<<<->>++<<
>+>-<+<->+-<>->+<-<+
+--+-++--++-+--+-++-
>>>>>>>>>+-<<<<<<<<<

18
işte +-<>istediğiniz gibi kullanmayan bir beyin fırtınası NOP :a
undergroundmonorail

1
Basit olmayan NOP'ların var olduğunu sanmıyorum, bu yüzden muhtemelen bu niteliği kaldırabilirsiniz. .yan etkisi vardır, ,kullanılmadan alınamayan bir değerin üzerine yazar []. Fakat []bir değeri sıfır olarak ayarlayacaktır. Bu, aynı zamanda [], etkilenen hücrenin başlangıçta sıfır olduğundan emin olmadıkça, bir değerin üzerine yazar (böylece onu kurtarmak için başka birine ihtiyacımız olur). Bununla birlikte, böyle bir hücreyi böyle bir şeyi aramak [>]zorunda kalırdık ve geldiğimiz konuma güvenilir bir şekilde geri dönmek imkansızdır.
Martin Ender

4
@Eumel "Söz konusu beynin tercümanı, iki kat sınırsız keyfi hücre hücresine sahip."
Martin Ender

2
Lütfen, "Brainfuck" ın artık sistem düzeyinde soru başlıklarına girmesine izin verilmediğini unutmayın . ASCII olmayan karakterleri kullanarak kısıtlamayı aşmayı başarabildiğiniz anlaşılıyor. Gelecekte, lütfen bu kısıtlamaya uyun.
Alex A.

2
@ undergroundmonorail Tamam, tamamlandı ... bu yüzden teknik olarak biri diğer dillerdeki gibi bir PRNG yazabilir. (Her ne kadar tohumlama zor olsa da.)
PurkkaKoodari

Yanıtlar:


13

CJam, 62 59 bayt

3 byte tasarruf için nhahtdh teşekkürler.

Her no-op sınırlı sonlu olasılıkta göründüğü sürece herhangi bir belirli dağıtım için bir gereklilik olmadığı için, yalnızca dengeli bir sayı içeren bir dize oluşturarak -+ve <>sırasıyla bir NOP olup olmadığını test ederek ve bunu sıralayarak sıralayarak basitleştirebiliriz . değil.

Tabii ki, daha uzun girdiler için, bu hemen hemen her zaman sıralı çıktıya neden olur, ancak kodu 8prensipte verilen uzunlukta herhangi bir NOP üretebildiğini görmek gibi bazı girdilerle test edebilirsiniz.

ri_0a*\2/{;"-+<>":L2/mR}%smr:SL["Xa.Xm"3/2e*L]z:sers~0-S$S?

Çevrimiçi deneyin.


1
Evet ... keyfi limit 10 saniye altında n = 1000 olmalıdır. Bilgisayarlar bugün oruç tutmanın yoludur ^ ^ Çünkü algoritmik cevap, n = 1000 için bile bir saniyenin altında çözüyor
Falco

Daha da büyük n için, dengeli dize NOP değilse, sadece çıktının sıralanmasının mümkün olduğunu düşünüyorum. Dağılım çok şaşkın, ancak soruya izin verildi.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ güzel bir fikir.
Martin Ender

@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ Teşekkürler, bu aslında üç byte'ı burada da kurtarıyor.
Martin Ender

16

CJam, 118 116 bayt

Bu durum biraz elden çıktı ... özellikle de ikinci yarısı golf oynamalı gibi görünüyor.

ri2/_)mr:R-"<>"R*mr_'=fm0\{1$+}%+__&e`]:\{mr1aa..+}*\@](\z:~\{~\("+-"*mr1$3$e=[{_,)mr_2$<@@>}*+]@@f{`1$`={(}@?\}W<}/

Burada test et.

Bu kolları N = 100 hemen hemen . Şimdi kodun tamamını yazacak vaktim yok, işte algoritma:

  • Rastgele dengeli dize oluşturun <ve >aralarında rasgele (çift) uzunluğunda 0veN dahil .
  • Şerit kafa pozisyonlarını bu diziye karıştırın. Eg "<>><"olur[0 '< -1 '> 0 '> 1 '< 0] .
  • Süreçte ulaşılan tüm pozisyonların bir listesini alın.
  • Her pozisyon için boş bir dize başlat. Ayrıca bir uzunluk uzunluğuna ulaşmak için kaç karakter çiftinin kaldığını da belirleyin.N .
  • Kalan her çift için +- için rastgele bir pozisyonun dize .
  • Bu dizelerin hepsini karıştır.
  • Her konum için, bu konumun oluklu dizide ne sıklıkta olacağını belirleyin ve karşılık gelen dizgiyi bu çok sayıda (rastgele uzunluk) topluluğa bölün.
  • Kıvrımlı dizide, pozisyonun oluşumlarını rastgele parçalarıyla değiştirin.

Bitti. Bu, şu gözlemlere dayanmaktadır:

  • Herhangi bir NOP eşit miktarda <ve> orijinal konumuna bant kafasını döndürmek için.
  • Kod, her bir bant hücresi azaltıldığı kadar sık ​​artırıldığı sürece bir NOP olacaktır.

Teyp başının belirli bir hücrede bulunduğu yerler arasında rastgele ancak dengeli miktarda +s ve -s dağıtarak , olası her NOP'yi bulmamızı sağlıyoruz.


4

Mathematica, 350 bayt

Quiet@(For[a="+",If[{##4}=={},#3!=0||Union@#!={0},Switch[#4,"+",#0[ReplacePart[#,#2->#[[#2]]+1],#2,#3,##5],"-",#0[ReplacePart[#,#2->#[[#2]]-1],#2,#3,##5],">",#0[#~Append~0,#2+1,#3+1,##5],"<",If[#2<2,#0[#~Prepend~0,1,#3-1,##5],#0[#,#2-1,#3-1,##5]]]]&@@{{0},1,0}~Join~Characters@a,a=""<>RandomSample@Flatten@RandomChoice[{{"+","-"},{">","<"}},#/2]];a)&

Çok mu uzun? Evet. Umrumda mı Başka biri geçerli bir cevap gönderinceye kadar.


4
Bir açıklama ekler misiniz, böylece insanlar kendilerini bu durumun geçerli olduğuna ikna edebilirler mi? :)
Martin Ender

Tam olarak nasıl yapar bu işi? Fonksiyonu bir numara ile çağırırsam sadece döner +.
Martin Ender

MartinBüttner Sabit @ ... Şu anda, sadece eşit sayıda rasgele programları üretir +- -ve <- >tek bir NOP olur dek çiftleri. Yarısı basit bir BF yorumlayıcısı tarafından alınır.
LegionMammal978

Bu aslında bir dakikadan az bir sürede 100 uzunluğu için geçerli bir işlem yapmaz mı?
Martin Ender

@ MartinBüttner Evet. Ortalama olarak, yaklaşık 5 saniye sürdüğünü söyleyebilirim. İlk başta tamamen rastgele programlar denedim, ancak hiçbir zaman uzunluk 100 için sonlandırılmadı.
LegionMammal978

2

Python 3 , 177 bayt

from random import*
n=int(input())
r=[0]*n*3
p=0
a=[43,45]
s=choices(a+[60,62],k=n)
for c in s:p+=~c%2*(c-61);r[p]+=c%2*(44-c)
if any(r+[p]):s=a*(n//2)
print(*map(chr,s),sep='')

Çevrimiçi deneyin!

Bubbler'ın cevabından BF simülasyonu için kod kullandım.


2

Python 3 , 163 bayt

from random import*
n=int(input())
p=0;d=[0]*n;a=choices(b'+-<>',k=n)
for c in a:d[p]+=c%2*(44-c);p+=~c%2*(c-61)
if p|any(d):a=n//2*b'+-'
print(*map(chr,a),sep='')

Çevrimiçi deneyin!

STDOUT'a sonuçları basan tam program. BF kodunu çalıştıran satır golf oynayabilir.

Tyilo'nun yaklaşımını benimsemiştir; Eğer oluşturulan BF kodu bir NOP değilse, tamamen atın ve '+-'tekrar edin.


N = 100
l4m2

@ l4m2 Bu gereksinimi farketmedi. Sabit.
Bubbler


1

Wolfram Dili (Mathematica) , 224 bayt

(s=RandomSample[##&@@@Table["<"">",(r=RandomInteger)[#/2]]];While[(g=Length@s)<#,s=Insert[s=Insert[s,"+",i=r@g+1],"-",RandomChoice@@Select[GatherBy[0~Range~++g,Count[#,"<"]-Count[#,">"]&@Take[s,#]&],!FreeQ[#,i]&]+1]];""<>s)&

Çevrimiçi deneyin!

İşte golfsüz (veya daha doğrusu önceden golf) versiyon:

Function[{n},
 k = RandomInteger[n/2];
 s = RandomSample[## & @@@ Table["<" ">", k]];
 While[Length[s] < n,
   s = Insert[s, "+", i = RandomInteger[Length[s]] + 1];
   p = GatherBy[Range[0, Length[s]], 
     Count[#, "<"] - Count[#, ">"]& @ Take[s, #]&];
   j = RandomChoice @@ Select[p, ! FreeQ[#, i] &]];
   s = Insert[s, "-", j + 1];
   ];
 ""<>s]

İlk önce rastgele bir <'s' ve >'s kullanacağız ve her birine eşit sayıda rastgele bir liste hazırlayacağız.

Karakterlerin geri kalanını doldurmak için, a'nın ekleneceği bir konum seçtik +, ardından işaretçinin aynı konuma işaret ettiği bir konum bulup orada bir konum ekledik -.

Liste uzunluğa kadar tekrarlayın nve sonucu sıralayın .

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.