Keluarkan Sumber, Satu Bit Sekaligus

18

Tulis program atau fungsi yang tidak kosong yang ketika dipanggil menampilkan nilai tunggal, 1 atau 0, dan ketika dipanggil berulang kali, nomor output menghasilkan representasi biner dari kode sumber program Anda (di halaman kode yang sama dari mana kode Anda dikompilasi / ditafsirkan).

Misalnya, jika kode sumber Anda abc(dalam ASCII), hasilnya adalah:

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.

Representasi biner dari sumber harus mengandung setidaknya satu 0 bit dan satu 1 bit.

Alih-alih 1 dan 0, Anda dapat menampilkan dua nilai yang berbeda dan konsisten (seperti truedan false).

Program modifikasi diri yang menghasilkan representasi biner dari sumber asli diizinkan, asalkan mereka tidak membaca kode sumber untuk mengetahui apa yang akan dicetak berikutnya.

Ini adalah , jadi jawaban tersingkat dalam byte menang.

Steadybox
sumber

Jawaban:

8

Funky , 47 41 37 byte

Mengembalikan angka yang mewakili sedikit.

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

Ini menggunakan format quine dari f=_=>"f="+f. Dibutuhkan karakter pada posisi ⌊i / 8⌋ , lalu, dapatkan bitnya dengan mengambil pairity di n >> 7-i%8mana nnilai ascii dari karakter saat ini.

Ini adalah fungsi berulang yang bertambah idengan setiap panggilan, setelah keluar dari kode sumber, itu akan menulis kode untuk nselamanya.

Cobalah online!

ATaco
sumber
Apakah ini polyglot dengan JavaScript?
Stan Strum
9

Bash , 105 byte

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

CATATAN : Pastikan Anda tidak memiliki file penting yang disebut fdi direktori yang Anda uji ini.


Jika Anda ingin menguji ini, Anda dapat menggunakan perintah berikut:

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

Yang mana harus memberikan output yang sama xxd -c1 -b path/to/script.sh|cut -d\ -f2|tr -d \\n.

Penjelasan

Ini menggunakan traptrik - memanggil trapdi dalam trapaksi hanya mencetak garis itu. Selanjutnya output disalurkan ke xxdyang mengonversinya menjadi biner (sayangnya xxd -bptidak berfungsi - dengan demikian solusinya dengan cut& tr):

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

Dari situ kami hanya tertarik pada satu bit (katakanlah N) yang dapat kami pilih cut -cN.

Untuk mengetahui apa yang Nkami gunakan (ingat itu bagian yang perlu ditambahkan setelah setiap panggilan), cukup coba setel xke konten file fdan jika tidak ada setel ke 1:

x=`cat f||echo 1`

Hal terakhir yang harus dilakukan, adalah memperbarui file f- menulis x+1padanya:

echo $((x+1))>f
ბიმო
sumber
7

TI-Basic (seri TI-83), 592 357 309 byte

"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

Tabel ini adalah referensi yang mungkin untuk representasi biner kalkulator dari kode sumber, meskipun pada akhirnya saya hanya menggunakan debugger Virtual TI.

Untuk perbandingan dan / atau kepentingan historis: quine pertama ditulis dalam TI-Basic .

Bagaimana itu bekerja

Str1menyimpan kode sumber (sekarang dalam heksadesimal yang mulia, menghemat banyak ruang di atas versi biner sebelumnya), meninggalkan bit-bit di mana konten Str1itu sendiri akan diwakili.

Kami mengasumsikan bahwa program dimulai pada kalkulator yang ingatannya baru saja dihapus, demikian Xjuga halnya 0. Setiap kali melalui program, kami bertambah X.

Biasanya, kita hanya mencari setengah byte yang kita coba untuk mengekstrak sedikit dari, membacanya Str1, mengkonversi dari heksadesimal ke biner, dan mencetaknya. Jika kita pada bagian dari kode sumber yang menyimpan Str1(yang dua-pertiga dari total panjang dari program), maka kita langkah pertama untuk bagian yang sesuai dari string menyimpan 31, 32dan sebagainya.

Misha Lavrov
sumber
4

Java 8, 249 241 237 234 148 byte

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;}

Maaf sebelumnya untuk penjelasan panjang. :)

  • Kekalahan 89 byte disimpan berkat @Nevay .

Coba di sini.

Penjelasan:

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

Penjelasan tambahan:

:

  • String s berisi kode sumber yang tidak diformat
  • %s digunakan untuk menempatkan String ini ke dalam dirinya dengan s.format(...)
  • %c, %1$cdan 34digunakan untuk memformat tanda kutip ganda ( ")
  • s.format(s,34,s) menempatkan semuanya bersama-sama

Coba di sini dengan beberapa bagian dihapus / dimodifikasi untuk memverifikasi output quine itu kode sumber sendiri.

-part:


Old 233 byte menjawab:

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

Coba di sini.

Penjelasan:

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

Penjelasan tambahan:

:

Penjelasan yang sama seperti di atas, dengan tambahan:

  • %%adalah bentuk lolos dari tanda-modulo ( %)

Coba di sini dengan beberapa bagian dihapus / dimodifikasi untuk memverifikasi output quine itu kode sumber sendiri.

-part:

  • i/8akan secara otomatis terpotong pada pembagian integer, jadi ketika i0-7, itu akan menjadi 0; jika i8-15, itu akan menjadi 1; dll.
  • Jadi s.charAt(i/8)mengambil karakter kode sumber saat ini, delapan kali setelah satu sama lain. Cobalah di sini dengan versi yang dimodifikasi.
  • 255adalah 0xFFatau 11111111(nilai maksimum untuk byte yang tidak ditandatangani)
  • 256adalah 0x100atau 100000000.
  • The &upcasts ASCII karakter ke integer. Pada titik itu, ia berada di antara 0dan 255( 00000000ke 11111111).
  • Long.toString(...,2) mengubahnya menjadi representasi String biner 9-bit
  • +256dan .substring(1)akan memastikan ada nol di depannya, dan akan mengubah 9-bit menjadi 8-bit.

Coba di sini dengan beberapa bagian dihapus / dimodifikasi untuk memverifikasi seluruh byte.

Kevin Cruijssen
sumber
1
149 byte: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 byte disimpan. Terima kasih! Dan karena itu sebenarnya sedikit pendekatan yang berbeda dari yang saya miliki, saya menyimpan jawaban yang lama, dan menambahkan yang baru. (Jika Anda mau, saya akan menghapusnya lagi dan Anda dapat mempostingnya sendiri, tetapi Anda mengatakan kepada saya sebelumnya bahwa Anda lebih suka golf orang lain - terutama milik saya XD - kode daripada memposting jawaban Anda sendiri, bukan?)
Kevin Cruijssen
2

Javascript ES6, 73 58 52 byte

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

Penjelasan

Rincian kode:

  • o=_=>: mendefinisikan suatu fungsi.
  • `o=${o}`: membangun string; odikonversi menjadi string, yang dalam hal ini adalah kode sumber fungsi.
  • .charCodeAt(: dapatkan karakter dalam string sebagai kode karakter ASCII-nya.
  • (o.n=1+o.n|0)/8: pilih karakter. Ini juga tempat penghitung bertambah.
  • )>>(7-o.n%8): menggeser kode karakter yang dihasilkan sehingga bit yang diinginkan berada di posisi yang tepat.
  • &1: setel semua bit lainnya ke 0.
RamenChef
sumber
Anda dapat mempersingkat ini dengan lambda menjadio=_=>(o+'').charCodeAt(('n'in top?++n:n=0)/8|0)>>(7-n%8)&1
ATaco
Ini dianggap sebagai mendefinisikan fungsi.
ATaco
1
Cobao=_=>('o='+o).charCodeAt(('n'in top?++n:n=0)/8|0)>>(7-n%8)&1
ATaco
Alih-alih 'n'in top?++n:n=0Anda dapat menggunakan ++n||(n=0)atau ++n?n:n=0atau n=++n||0atau n=1+n||0yang semua memanfaatkan falsiness dari NaNyang dihasilkan oleh incrementingundefined
Bergi
1
o=_=>('o='+o).charCodeAt((o.n=1+o.n|0)/8)>>(~o.n&7)&1
tsh
2

q / kdb + , 45 byte

Larutan:

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

Contoh:

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"

Penjelasan:

Saya pikir saya mengerti briefnya.

Pertama, atur variabel global adengan nilai awal -1. Fungsi fmembangun representasi biner dari representasi string dari fungsi (semuanya termasuk {}) yang diuraikan dengan a:-1;f:sampah, dan mengindeks ke dalam daftar biner ini di indeks a (yang akan bertambah setiap panggilan).

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
streetster
sumber
2

Python 2 , 164 byte

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]

Cobalah online!

Penjelasan

Mari kita mulai dengan quine standar Python 2.

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

Oke, well, ini hasilnya begitu saja. Kami membutuhkan biner!

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

Benar, itu hanya mengubah segalanya menjadi biner. Namun judulnya mengatakan "sedikit demi sedikit". Kami membutuhkan sesuatu untuk bertahan melalui beberapa putaran. Saya tahu, mari kita jadikan fungsi!

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

Tunggu, itu tidak membantu ... Hmm, bagaimana kita bisa melacak indeks bit yang diperlukan untuk menjadi output? Ooh, ooh, mari kita memiliki bilangan bulat untuk melacak.

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

Um ... itu selalu menampilkan bit pertama. Oh, kita perlu menambah pelacak! Oh sial, Python tidak mengizinkan bilangan bulat sebagai argumen default untuk dimodifikasi. Dan tugas bukan ekspresi dalam Python, jadi Anda tidak bisa melakukannya dalam lambda. Yah, ini tidak mungkin dengan Python, case closed.

... Yah, tidak cukup. Python tidak memungkinkan daftar sebagai argumen default untuk dimodifikasi. (Dan itu menggigit programmer Python sepanjang waktu.) Mari kita gunakan panjangnya!

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

Itu masih belum memodifikasi pelacak ... Kita bisa menambahkan sesuatu padanya untuk menambah panjangnya ... Tapi bagaimana? Ah, ya sudah list.append. lst.append(1)setara dengan lst += [1]. Bagus!

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

Ups, ini melompati bit pertama karena panjang pelacak adalah 1 sebelum bit dikeluarkan. Kita perlu mengurangi panjang di mana itu digunakan.

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

Itu dia, teman-teman! Golf itu dan Anda punya solusi saya!

benar-benar manusiawi
sumber
2

Perl 5 , 59 byte

sub{$_=q{unpack(B.++$-,"sub{\$_=q{$_};eval}")=~/.$/g};eval}

Cobalah online!

Dom Hastings
sumber