Kaynağı Çıkarın, Her Seferinde Bir Bit


18

Boş bir program veya işlev çağrıldığında tek bir değer, 1 veya 0 çıktı verir ve birden çok kez çağrıldığında, çıktı sayıları programınızın kaynak kodunun (kodunuzun derlendiği kod sayfasında) ikili temsilini üretir /) olarak yorumlanır.

Örneğin, kaynak kodunuz abc(ASCII'de) olsaydı, çıktılar şöyle olur:

1st call:  0           // ASCII letter 'a'
2nd call:  1
3rd call:  1
4th call:  0
5th call:  0
6th call:  0
7th call:  0
8th call:  1

9th call:  0           // ASCII letter 'b'
10th call: 1
11th call: 1
12th call: 0
13th call: 0
14th call: 0
15th call: 1
16th call: 0

17th call: 0           // ASCII letter 'c'
18th call: 1
19th call: 1
20th call: 0
21st call: 0
22nd call: 0
23rd call: 1
24th call: 1

After the 24th call, the behaviour is undefined.

Kaynağın ikili gösterimi en az bir 0 bit ve bir 1 bit içermelidir.

1 ve 0 yerine, iki farklı, tutarlı değer ( trueve gibi false) çıktısı alabilirsiniz .

Daha sonra ne yazdıracağını bulmak için kaynak kodunu okumaması koşuluyla, orijinal kaynağın ikili sunumunu yapan kendi kendini değiştiren programlara izin verilir.

Bu , bu yüzden bayttaki en kısa cevap kazanır.

Yanıtlar:


8

Korkak , 47 41 37 bayt

Bir biti temsil eden bir sayı döndürür.

f=_=>1&("%b"%("f="+f)[i//8])>>7-i++%8

Bu, quine biçimini kullanır f=_=>"f="+f. ⌊İ / 8⌋ konumundaki karakteri alır , sonra, mevcut karakterin ascii değerinin n >> 7-i%8nerede nolduğu çiftliğini alarak biti alır .

Bu, iher çağrıda artan yinelemeli bir işlevdir , kaynak kodundan çıktıktan sonra nsonsuza kadar kodu yazar .

Çevrimiçi deneyin!


Bu JavaScript'li bir çok dilli mi?
Stan Strum

9

Bash , 105 bayt

trap -- 'trap|xxd -b -c1|cut -d\  -f2|tr -d \\n|cut -c`x=\`cat f||echo 1\`;echo $((x+1))>f;echo $x`' EXIT

NOT : Bunu ftest ettiğiniz dizinde adlandırılan önemli bir dosyanız olmadığından emin olun .


Bunu test etmek isterseniz, aşağıdaki komutu kullanabilirsiniz:

for i in $(seq 848); do bash path/to/script.sh 2> /dev/null; done | tr -d \\n

Hangi aynı çıktıyı vermelidir xxd -c1 -b path/to/script.sh|cut -d\ -f2|tr -d \\n.

açıklama

Bu traphileyi kullanıyor - eylemin trapiçinde çağırmak trapo satırı yazdırıyor. Daha sonra bu çıkış, ikiliye xxddönüştürülecek şekilde borulaştırılır (maalesef xxd -bpişe yaramaz - bu nedenle cut& ile geçici çözüm tr):

xxd -c1 -b $0|cut -d\  -f2|tr -d \\n

Bundan sadece Nseçebileceğimiz bir bit (diyelim ) ile ilgileniyoruz cut -cN.

Ne Nkullandığımızı öğrenmek için (her çağrıdan sonra artırılması gereken bölüm olduğunu unutmayın), xdosyanın içeriğini ayarlamayı deneyin fve yoksa, 1 olarak ayarlayın:

x=`cat f||echo 1`

Yapılacak son şey dosyayı güncellemektir f- dosyaya yazmak x+1:

echo $((x+1))>f

7

TI-Basic (TI-83 serisi), 592 357 309 bayt

"123456789ABCDEF02A3132333435363738394142434445463004AA003FB958833404593FB9588338045A3F3230363FDA582B383F303FCE5A405A6B3232333F5A70BB0FAA002BBB0CAA002B5A2B313FB932BA32F01058713459713511BB0FAA002BBB0CAA002B597031377132722B31→Str1
iPart(X/4→Y
iPart(X/8→Z
206
IS>(X,8
0
If Z and Z<223
Z+inString(Str1,sub(Str1,Z,1
iPart(2fPart(2^(X-4Y-5)inString(Str1,sub(Str1,Y+17-2Ans,1

Bu tablo , hesap makinesinin kaynak kodunun ikili gösterimi için olası bir referanstır, ancak sonuçta sadece Sanal TI'nın hata ayıklayıcısını kullandım.

Karşılaştırma ve / veya tarihsel ilgi için: TI-Basic ile yazılmış ilk alıntılar .

Nasıl çalışır

Str1kaynak kodunu saklar (şimdi görkemli onaltılık düzende, önceki ikili versiyona göre çok fazla alan tasarrufu sağlar) ve içeriğinin Str1temsil edileceği bitleri dışarıda bırakır .

Böylece, programın kimin bellek sadece temizlendi Hesap makinesinde başlar olduğunu varsayıyoruz Xolduğunu 0. Program boyunca her seferinde artarız X.

Genellikle, biraz ayıklamaya, okuyup Str1, onaltılıktan ikiliye dönüştürmeye ve yazdırmaya çalıştığımız yarım baytı anlıyoruz. Kaynak kodun sakladığı Str1(programın toplam uzunluğunun üçte ikisidir) kısmındaysanız, önce dize depolamasının ilgili kısmına geçeriz 31, 32vb.


4

Java 8, 249 241 237 234 148 bayt

int i;v->{String s="int i;v->{String s=%c%s%1$c;return s.format(s,34,s).charAt(-i/8)>>(--i&7)&1;}";return s.format(s,34,s).charAt(-i/8)>>(--i&7)&1;}

Uzun açıklamalar için şimdiden özür dilerim. :)

  • @Nevay sayesinde 89 bayt kurtardı .

Burada deneyin.

Açıklama:

int i;                     // Index-integer on class-level
v->{                       // Method with empty unused parameter and integer return-type
  String s="int i;v->{String s=%c%s%1$c;return s.format(s,34,s).charAt(-i/8)>>(--i&7)&1;}";
                           //  String containing the unformatted source code
  return s.format(s,34,s)  //    Quine to get the source code,
      .charAt(-i/8)        //     and get the character at index `-i/8`
     >>                    //    And bitwise right-shift it with:
       (--i&7)             //     `i-1` bitwise-AND 7
                           //     by first decreasing `i` by 1 with `--i`
      &1;                  //   Then bitwise-AND everything above with 1
}                          // End of method

Ek açıklama:

-part:

  • String s biçimlendirilmemiş kaynak kodunu içerir
  • %s bu String'i kendi içine koymak için kullanılır s.format(...)
  • %c, %1$cve 34çift ​​tırnak işaretlerini ( ") biçimlendirmek için kullanılır
  • s.format(s,34,s) hepsini bir araya getirir

Quine çıktılarının kendi kaynak kodunu doğrulamak için bazı parçaları kaldırılmış / değiştirilmiş olarak burada deneyin.

bölüm:


Eski 233 bayt cevap:

int i;v->{String s="int i;v->{String s=%c%s%1$c;return Long.toString((s.format(s,34,s).charAt(i/8)&255)+256,2).substring(1).charAt(i++%%8);}";return Long.toString((s.format(s,34,s).charAt(i/8)&255)+256,2).substring(1).charAt(i++%8);}

Burada deneyin.

Açıklama:

int i;                           // Index-integer on class-level
v->{                             // Method with empty unused parameter and char return-type
  String s="int i;v->{String s=%c%s%1$c;return Long.toString((s.format(s,34,s).charAt(i/8)&255)+256,2).substring(1).charAt(i++%%8);}";
                                 //  String containing the unformatted source code
  return Long.toString(
          (s.format(s,32,s)      //  Quine-formatting
          .charAt(i/8)           //  Take the current character
           &255)+256,2).substring(1)
                                 //  Convert it to an 8-bit binary-String 
         .charAt(i++%8);         //  And return the bit at index `i` modulo-8
                                 //  and increase index `i` by 1 afterwards with `i++`
}                                // End of method

Ek açıklama:

-part:

Yukarıdaki açıklama ile aynı açıklama:

  • %%modulo-işaretinin ( %)

Quine çıktılarının kendi kaynak kodunu doğrulamak için bazı parçaları kaldırılmış / değiştirilmiş olarak burada deneyin.

bölüm:

  • i/8tamsayı bölmesinde otomatik olarak kesilir, bu nedenle i0-7 olduğunda 0; i8-15 ise , olacak 1; vb.
  • Böylece s.charAt(i/8)kaynak kodun geçerli karakterini birbirinden sekiz kez alır. Değiştirilmiş bir sürümle burada deneyin.
  • 255olduğu 0xFFya da 11111111(işaretsiz bayt için maksimum değer)
  • 256olduğu 0x100veya 100000000.
  • &Bir tamsayıya ASCII karakter upcasts. Bu noktada, 0ve 255( 00000000- 11111111) arasında bir yerdedir .
  • Long.toString(...,2) 9-bit ikili Dize gösterimine dönüştürür
  • +256ve .substring(1)önde gelen sıfırlar olmasını sağlar ve 9 bit'i 8 bit'e dönüştürür.

Baytların tamamını doğrulamak için bazı bölümleri kaldırılmış / değiştirilmiş olarak burada deneyin.


1
149 bayt:int i;v->{String s="int i;v->{String s=%c%s%1$c;return 1&s.format(s,34,s).charAt(-i/8)>>(--i&7);}";return 1&s.format(s,34,s).charAt(-i/8)>>(--i&7);}
Nevay

@Nevay Whopping 88 bayt kaydedildi. Teşekkürler! Ve aslında başlangıçta sahip olduğumdan biraz farklı bir yaklaşım olduğundan, eski cevabı sakladım ve yenisini ekledim. (İsterseniz tekrar kaldıracağım ve kendiniz gönderebilirsiniz, ancak geçmişte bana kendi cevabınızı göndermek yerine diğer insanların - çoğunlukla benim XD kodunu - golf oynamayı tercih ettiğinizi söylediniz?)
Kevin Cruijssen

2

Javascript ES6, 73 58 52 bayt

o=_=>`o=${o}`.charCodeAt((o.n=1+o.n|0)/8)>>(7-o.n%8)&1

açıklama

Kod dökümü:

  • o=_=>: bir işlevi tanımlar.
  • `o=${o}`: bir dize oluşturun; o, bu durumda işlevin kaynak kodu olan bir dizeye dönüştürülür.
  • .charCodeAt(: dizede ASCII karakter kodu olarak bir karakter olsun.
  • (o.n=1+o.n|0)/8: bir karakter seçmenizi sağlar. Bu aynı zamanda sayacın artırıldığı yerdir.
  • )>>(7-o.n%8): sonuçta ortaya çıkan karakter kodunu, istenen bit doğru konumda olacak şekilde kaydırın.
  • &1: diğer tüm bitleri 0 olarak ayarlamanızı sağlar.

Bunu bir lambda ile kısaltabilirsinizo=_=>(o+'').charCodeAt(('n'in top?++n:n=0)/8|0)>>(7-n%8)&1
ATaco

Bu, bir işlevi tanımlamak olarak sayılır.
ATaco

1
Deneyin o=_=>('o='+o).charCodeAt(('n'in top?++n:n=0)/8|0)>>(7-n%8)&1
ATaco

Yerine 'n'in top?++n:n=0kullanabilirsiniz ++n||(n=0)ya ++n?n:n=0ya n=++n||0ya n=1+n||0da tamamen yok falsiness yararlanmakNaN o arttırarak üretilirundefined
Bergi

1
o=_=>('o='+o).charCodeAt((o.n=1+o.n|0)/8)>>(~o.n&7)&1
tsh

2

q / kdb + , 45 bayt

Çözüm:

a:-1;f:{((,/)0b vs'4h$"a:-1;f:",($).z.s)a+:1}

Misal:

q)f[] / call function f with no parameters
0b   
q)f[]
1b   
q)f[]
1b   
q)f[]
0b   
q)f[]
0b   
q)f[]
0b   
q)f[]
0b   
q)f[]
1b   
q)f[]  
q)"c"$0b sv 01100001b / join back to a byte and cast to a character
"a"

Açıklama:

Ben düşünüyorum ben kısa anladım.

Önce abaşlangıç ​​değeri olan global bir değişken oluşturun -1. İşlev , işlevin dize temsilinin fikili gösterimini oluşturur ({} , a:-1;f:önemsiz ile birlikte eklenmiş ) a dizininde (her çağrı artırılır) bu ikili listeye dizinler.

a:-1;f:{(raze 0b vs'4h$"a:-1;f:",string .z.s)a+:1} / ungolfed solution
a:-1;                                              / stick -1 in variable a
     f:{                                         } / define function f
                                             a+:1  / increment a by 1 (:: is required as a is a global variable), indexes into the left
        (                                   )      / do all this together
                                 string .z.s       / z.s is the function, string converts it to a string
                       "a:-1;f:",                  / prepend "a:-1;f:" to the start
                    4h$                            / cast to bytes
              0b vs'                               / convert each byte to binary
         raze                                      / flatten binary into long list

2

Python 2 , 164 bayt

lambda s='lambda s=%r,i=[]:i.append(1)or"{:08b}".format(ord((s%%s)[~-len(i)/8]))[~-len(i)%%8]',i=[]:i.append(1)or"{:08b}".format(ord((s%s)[~-len(i)/8]))[~-len(i)%8]

Çevrimiçi deneyin!

açıklama

Standart bir Python 2 ile başlayalım.

s = '...'; print s % s

Tamam, işte böyle çıktı. İkiliye ihtiyacımız var!

s = '...'; print "\n".join("\n".join("{:08b}".format(ord(i))) for i in s % s)

Doğru, bu sadece her şeyi ikiliye dönüştürür. Ancak başlıkta "her seferinde bir bit" yazıyor. Birden fazla koşuda devam etmek için bir şeye ihtiyacımız var. Biliyorum, hadi bir işlev yapalım!

lambda s = '...': "\n".join("\n".join("{:08b}".format(ord(i))) for i in s % s)

Bekle, bu yardımcı olmuyor ... Hmm, çıktı için gereken bit indeksini nasıl takip edebiliriz? Ooh, ooh, takip etmek için bir tamsayı alalım.

lambda s = '...', i = 0: "{:08b}".format(ord((s % s)[i / 8]))[i % 8]

Um ... her zaman ilk biti verir. Oh, izleyiciyi artırmamız gerekiyor! Lanet olsun, Python varsayılan bağımsız değişken olarak tamsayıların değiştirilmesine izin vermez. Ve ödevler Python'daki ifadeler değildir, bu yüzden bunu bir lambdada yapamazsınız. Vay canına, Python'da bu mümkün değil, dava kapandı.

...Pek iyi değil. Python yapar varsayılan argümanlar değiştirilecek olarak listelerini tanır. (Ve her zaman Python programcılarını ısırır.) Uzunluğunu kullanalım!

lambda s = '...', i = []: "{:08b}".format(ord((s % s)[len(i) / 8]))[len(i) % 8]

Bu yine de izleyiciyi değiştirmiyor ... Uzunluğunu artırmak için bir şeyler ekleyebiliriz ... Ama nasıl? Ah, iyi list.append. lst.append(1)eşittir lst += [1]. Harika!

lambda s = '...', i = []: i.append(1) and "{:08b}".format(ord((s % s)[len(i) / 8]))[len(i) % 8]

Hata! Bu, ilk biti atlar çünkü bit çıkmadan önce izleyicinin uzunluğu 1'dir . Kullandığı uzunluğu azaltmamız gerekir.

lambda s = '...', i = []: i.append(1) and "{:08b}".format(ord((s % s)[(len(i) - 1) / 8]))[(len(i) - 1) % 8]

İşte, millet! Golf ve benim çözüm var!


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.