ソースを一度に1ビットずつ出力する


18

空ではないプログラムまたは関数を作成し、呼び出されると単一の値1または0を出力し、複数回呼び出されると、出力番号はプログラムのソースコードのバイナリ表現を生成します(コードのコンパイル元と同じコードページで) / interpreted)。

たとえば、ソースコードがabc(ASCII)の場合、出力は次のようになります。

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.

ソースのバイナリ表現には、少なくとも1つの0ビットと1つの1ビットが含まれている必要があります。

1と0の代わりに、2つの異なる一貫した値(trueandなどfalse)を出力できます。

元のソースのバイナリ表現を出力する自己修正プログラムは、ソースコードを読み取って次に印刷するものを見つけなければ、許可されます。

これはであるため、バイト単位の最短回答が優先されます。

回答:


8

ファンキー47 41 37バイト

ビットを表す数値を返します。

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

これはの形式を使用しますf=_=>"f="+f。位置⌊i/8⌋にある文字を取得し、次に現在の文字のascii値がn >> 7-i%8どこにあるかというペアを取得してビットを取得しますn

これは、i呼び出しごとに増分する反復関数です。一度ソースコードがなくなると、n永久にコードが書き込まれます。

オンラインでお試しください!


これはJavaScriptを使用したポリグロットですか?
スタン・ストラム

9

Bash、105バイト

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

fこれをテストしているディレクトリに重要なファイルが呼び出されていないことを確認してください。


これをテストする場合は、次のコマンドを使用できます。

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

同じ出力が得られるはずxxd -c1 -b path/to/script.sh|cut -d\ -f2|tr -d \\nです。

説明

これはtrapトリックを使用しています- アクションtrap内で呼び出すと、trap単にその行が出力されます。次に、その出力がパイプさxxdれてバイナリに変換されます(残念ながらxxd -bp機能しません-したがって、cut&による回避策tr)。

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

それから、でN選択できる1ビット(たとえば)だけに興味がありますcut -cN

N使用しているものを見つけるには(各呼び出しの後に増分する必要がある部分であることを思い出してください)、単にxファイルのコンテンツを設定し、f存在しない場合は1に設定してください。

x=`cat f||echo 1`

最後に行うことは、ファイルを更新することですf- x+1それに書き込みます:

echo $((x+1))>f

7

TI-Basic(TI-83シリーズ)、592 357 309バイト

"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

このテーブルは、計算機のソースコードのバイナリ表現の可能なリファレンスですが、最終的には仮想TIのデバッガーを使用しました。

比較および/または歴史的関心:TI-Basicで書かれた最初のクイン

使い方

Str1ソースコードを格納し(以前のバイナリバージョンよりも多くのスペースを節約する、現在は栄光の16進数で)、Str1それ自体のコンテンツを表すビットを省きます。

私たちは、プログラムがそのメモリだけので、クリアされた電卓上で起動することを想定しているXです0。プログラムを実行するたびに、をインクリメントしますX

通常、ビットの抽出、読み取りStr1、16進数からバイナリへの変換、および印刷を試みているハーフバイトを特定します。我々は記憶のソースコードの一部にしている場合Str1、文字列記憶手段の対応する部分に(プログラムの全体の長さの三分の二である)、そして我々最初の動き3132など。


4

Java 8、249 241 237 234 148バイト

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

長い説明のために事前に申し訳ありません。:)

  • なんと89のバイトがに感謝を保存@Nevay

ここで試してみてください。

説明:

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

追加の説明:

-part:

  • String s 未フォーマットのソースコードが含まれています
  • %s この文字列をそれ自体に入れるために使用されます s.format(...)
  • %c%1$cおよび34二重引用符のフォーマットに使用されます("
  • s.format(s,34,s) すべてをまとめる

いくつかのパーツを削除/変更して試してみて、クインの出力が独自のソースコードであることを確認してください。

部分:


古い233バイトの答え:

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

ここで試してみてください。

説明:

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

追加の説明:

-part:

上記と同じ説明に加えて、以下を追加します。

  • %%モジュロ符号(%)のエスケープ形式です

いくつかのパーツを削除/変更して試してみて、クインの出力が独自のソースコードであることを確認してください。

部分:

  • i/8整数の除算で自動的に切り捨てられるため、i0〜7の場合は0; になります。i8-15の場合、次のようになり1ます。等
  • したがってs.charAt(i/8)、ソースコードの現在の文字を8回ずつ取得します。ここで修正版を試してください。
  • 255である0xFF11111111(符号なしバイトの最大値)
  • 256です0x100100000000
  • &整数にASCII文字をupcasts。その時点で、それはどこかの間だ02550000000011111111)。
  • Long.toString(...,2) 9ビットのバイナリ文字列表現に変換します
  • +256そして.substring(1)先行ゼロがあることを確認し、8ビット、9ビットを変換します。

バイト全体を検証するために、いくつかのパーツを削除/変更して試してみてください。


1
149バイト: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なんと88バイトが保存されました。ありがとう!そして、実際には私が元々持っていたものとはかなり異なるアプローチなので、古い答えを保持し、新しいものを追加しました。(必要に応じてもう一度削除し、自分で投稿することもできますが、過去に自分の回答を投稿するのではなく、他の人(主に私のXD)のコードをゴルフすることを好むと言っていましたよね?)
Kevin Cruijssen

2

JavascriptをES6、73の 58 52バイト

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

説明

コードの内訳:

  • o=_=>:関数を定義します。
  • `o=${o}`:文字列を作成します。o文字列に変換されます。この場合、関数のソースコードです。
  • .charCodeAt(:文字列内の文字をASCII文字コードとして取得します。
  • (o.n=1+o.n|0)/8:文字を選択します。これは、カウンターがインクリメントされる場所でもあります。
  • )>>(7-o.n%8):目的のビットが正しい位置になるように、結果の文字コードをシフトします。
  • &1:他のすべてのビットを0に設定します。

ラムダでこれを短くすることができますo=_=>(o+'').charCodeAt(('n'in top?++n:n=0)/8|0)>>(7-n%8)&1
-ATaco

これは、関数の定義としてカウントされます。
アタコ

1
試してくださいo=_=>('o='+o).charCodeAt(('n'in top?++n:n=0)/8|0)>>(7-n%8)&1
-ATaco

代わりに'n'in top?++n:n=0、あなたは使うことができ++n||(n=0)たり++n?n:n=0またはn=++n||0またはn=1+n||0すべてのfalsiness利用するNaNインクリメントすることにより生成されるundefined
Bergi

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

2

q / kdb +、45バイト

解決:

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

例:

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、開始値でグローバル変数をセットアップします-1。関数fは、ジャンクが先頭に追加された関数の文字列表現(を含むすべて{})のバイナリ表現をa:-1;f:作成し、このバイナリリストにインデックスa(呼び出しごとにインクリメントされます)でインデックスを付けます。

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バイト

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]

オンラインでお試しください!

説明

標準のPython 2クインから始めましょう。

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

さて、まあ、これはそれをそのように出力します。バイナリが必要です!

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

そう、それはすべてをバイナリに変換するだけです。しかし、タイトルには「一度に1ビット」と書かれています。複数回実行しても持続するものが必要です。知って、機能にしましょう!

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

待って、それは助けになりません...うーん、出力に必要なビットのインデックスをどのように追跡できますか?おおおおおお、追跡する整数を持ちましょう。

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

ええと...それは常に最初のビットを出力します。ああ、トラッカーを増やす必要があります!うーん、Pythonは整数をデフォルト引数として変更することを許可していません。また、割り当てはPythonの式ではないため、ラムダでそれを行うことはできません。Welp、これはPythonでは不可能であり、ケースは閉じられています。

...そうではありません。Python では、デフォルトの引数としてリストを変更できます。(そして、それは常にPythonプログラマーを噛みます。)その長さを使用しましょう!

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

それでもトラッカーは変更されません...長さを増やすために何かを追加することができます...しかし、どのように?ああ、まあ、私たちは持っていlist.appendます。lst.append(1)はと同等lst += [1]です。すごい!

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

ビットが出力される前にトラッカーの長さが1であるため、これは最初のビットをスキップします。使用される長さを減らす必要があります。

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

そこに、人々!それをゴルフすると、あなたは私の解決策を手に入れました!


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.