Quineは自身をバイナリで出力します


10

それを受け入れる場合のタスクは、独自のソースコードをバイナリのUTF-8表現で出力するプログラムを記述することです。

ルール

  • ソースは少なくとも1バイトの長さが必要です。

  • プログラムは入力をとってはなりませ(または、未使用の空の入力が必要です)。

  • 出力は任意の便利な形式にすることができます。

  • オプションの末尾の改行を使用できます。

  • 1バイトは8ビットであり、バイナリUTF-8表現の長さは必然的に8の倍数であることに注意してください。

  • これはので、すべての通常のゴルフ規則が適用され、最短のコード(バイト単位)が優先されます。

  • 標準の抜け穴は禁止されています。

あなたのソースコードがでありAä$$€h、それに対応するUTF-8バイナリ表現がであるとしましょう010000011100001110100100001001000010010011100010100000101010110001101000

私が実行Aä$$€hする場合、出力はでなければなりません010000011100001110100100001001000010010011100010100000101010110001101000

A      --> 01000001
ä      --> 1100001110100100
$      --> 00100100
$      --> 00100100
€      --> 111000101000001010101100
h      --> 01101000
Aä$$€h --> 010000011100001110100100001001000010010011100010100000101010110001101000

文字列からバイナリUTF-8へのコンバーター


1
「バイナリ」とは、バイナリ値の文字列表現、つまり1と0のみで構成される文字列を意味しますか?

1
@mdahmouneもういいですね 問題は、何かをUTF-8として表現する方法です。Unicode表現は主に文字の外観に基づいていることに注意してください(たまに意味的にのみ)。割り当てられたUnicodeグリフがソースコードの文字のように見えない場合はどうなりますか?Unicodeには、多くの類似(ホモグリフ)もあります。どれを使用するかをどのように決定しますか?例えばDyalog APLはとしてエンコードすることができ、機能を有している01011110か、0010011100100010(彼らはかなり似ている:UTF-8での^
アダム

1
より良い例:01111100および0010001100100010エンコード|
アダム

4
@アダム言語の特定の実装でコンパイル/実行されるシンボルに対応するバイナリシーケンスを出力するのは公平だと思います。
qwr

1
マシンコードはどうですか?(コモドールC64は、マシンコード自体が「ソース」であると想定して28バイトを必要とします)
Martin Rosenau

回答:


7

V、28(または16?)ラテン1バイト(35 UTF-8バイト)

ñéÑ~"qpx!!xxd -b
ÎdW54|D
Íßó

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

Hexdump(ラテン語1):

00000000: f1e9 d17e 2271 7078 2121 7878 6420 2d62  ...~"qpx!!xxd -b
00000010: 0ace 6457 3534 7c44 0acd dff3            ..dW54|D....

出力(ラテン語1ではなく、UTF-8での同じコードのバイナリ表現):

110000111011000111000011101010011100001110010001011111100010001001110001011100000111100000100001001000010111100001111000011001000010000000101101011000100000110111000011100011100110010001010111001101010011010001111100010001000000110111000011100011011100001110011111110000111011001100001010

説明:

ñéÑ~"qpx            " Standard quine. Anything after this doesn't affect the
                    " program's 'quine-ness' unless it modifies text in the buffer
        !!xxd -b    " Run xxd in binary mode on the text
Î                   " On every line...
 dW                 "   delete a WORD
   54|              "   Go to the 54'th character on this line
      D             "   And delete everything after the cursor
Í                   " Remove on every line...
  ó                 "   Any whitespace
 ß                  "   Including newlines

または...

V、16バイト

ñéÑ~"qpx!!xxd -b

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

出力:

00000000: 11000011 10110001 11000011 10101001 11000011 10010001  ......
00000006: 01111110 00100010 01110001 01110000 01111000 00100001  ~"qpx!
0000000c: 00100001 01111000 01111000 01100100 00100000 00101101  !xxd -
00000012: 01100010 00001010                                      b.

OPは言った:

出力は、任意の便利な形式にすることができます。

これはV:Pのはるかに便利な形式で出力します(ただし、それがルールを拡張しているかどうかはわかりません)



4

05AB1E、105 バイト

0"D34çýÇbεDg•Xó•18в@ƶà©i7j0ìëR6ôRíć7®-jšTìJ1®<×ì]ð0:J"D34çýÇbεDg•Xó•18в@ƶà©i7j0ìëR6ôRíć7®-jšTìJ1®<×ì]ð0:J

05AB1EにはUTF-8変換が組み込まれていないため、すべてを手動で行う必要があります。

オンラインそれを試してみたり、それはQUINEだことを確認してください

説明:

-part:

最短:05AB1Eため、この一つである0"D34çý"D34çý14バイトによって提供@OliverNi。私の答えは、...ここに追加することにより、そのクインの修正バージョンを使用します:0"D34çý..."D34çý...。この羽の簡単な説明:

0               # Push a 0 to the stack (can be any digit)
 "D34çý"        # Push the string "D34çý" to the stack
        D       # Duplicate this string
         34ç    # Push 34 converted to an ASCII character to the stack: '"'
            ý   # Join everything on the stack (the 0 and both strings) by '"'
                # (output the result implicitly)

チャレンジパート:

次に、コードのチャレンジ部分について説明します。冒頭で述べたように、05AB1EにはUTF-8変換が組み込まれていないため、これらを手動で行う必要があります。私はこのソースを、それを行う方法の参照として使用しました:手動でUnicodeコードポイントをUTF-8およびUTF-16に変換します。Unicode文字からUTF-8への変換に関する概要を次に示します。

  1. Unicode文字をUnicode値に変換します(つまり、に"dЖ丽"なります[100,1046,20029]
  2. これらのユニコード値をバイナリに変換します(つまり、に[100,1046,20029]なります["1100100","10000010110","100111000111101"]
  3. 文字が次の範囲のどれであるかを確認します。
    1. 0x00000000 - 0x0000007F (0-127): 0xxxxxxx
    2. 0x00000080 - 0x000007FF (128-2047): 110xxxxx 10xxxxxx
    3. 0x00000800 - 0x0000FFFF (2048-65535): 1110xxxx 10xxxxxx 10xxxxxx
    4. 0x00010000 - 0x001FFFFF (65536-2097151): 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

5バイトまたは6バイトの範囲もありますが、ここでは省略します。

文字dは最初の範囲になるため、UTF-8では1バイトです。文字Жは2番目の範囲にあるため、UTF-8では2バイトです。文字は3番目の範囲にあるため、UTF-8では3バイトです。

そのx後ろのパターンのは、これらの文字のバイナリで右から左に埋められます。したがって、d1100100)のパターンはに0xxxxxxxなり01100100ます。Ж10000010110)パターンと110xxxxx 10xxxxxxなります11010000 10010110。及び100111000111101パターン)が1110xxxx 10xxxxxx 10xxxxxxなる1110x100 10111000 10111101た後、残りは、xで置換されています011100100 10111000 10111101

だから、私も私のコードで使用したアプローチ。実際の範囲をチェックする代わりに、バイナリの長さを見て、それをxパターン内の量と比較するだけです。これにより、数バイトが節約されるためです。

Ç               # Convert each character in the string to its unicode value
 b              # Convert each value to binary
  ε             # Map over these binary strings:
   Dg           #  Duplicate the string, and get its length
     Xó•       #  Push compressed integer 8657
         18в    #  Converted to Base-18 as list: [1,8,12,17]
            @   #  Check for each if the length is >= to this value
                #  (1 if truthy; 0 if falsey)
   ƶ            #  Multiply each by their 1-based index
    à           #  Pop and get its maximum
     ©          #  Store it in the register (without popping)
   i            #  If it is exactly 1 (first range):
    7j          #   Add leading spaces to the binary to make it of length 7
      0ì        #   And prepend a "0"
   ë            #  Else (any of the other ranges):
    R           #   Reverse the binary
     6ô         #   Split it into parts of size 6
       Rí       #   Reverse it (and each individual part) back
    ć           #   Pop, and push the remainder and the head separated to the stack
     7®-        #   Calculate 7 minus the value from the register
        j       #   Add leading spaces to the head binary to make it of that length
         š      #   Add it at the start of the remainder-list again
    Tì          #   Prepend "10" before each part
      J         #   Join the list together
    1®<×        #   Repeat "1" the value from the register - 1 amount of times
        ì       #   Prepend that at the front
  ]             # Close both the if-else statement and map
   ð0:          # Replace all spaces with "0"
      J         # And join all modified binary strings together
                # (which is output implicitly - with trailing newline)

(セクション鉱山のこの05AB1Eの答えを参照してください?大きな整数を圧縮する方法どのように圧縮整数リストへ?理由を理解すること•Xó•18вです[1,8,12,17]


3

JavaScript(Node.js)、60バイト

@Neilおよび@Shaggyから-15バイト

f=_=>[...Buffer(`f=`+f)].map(x=>x.toString(2).padStart(8,0))

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


padStart(8,0)2バイトを節約します。
ニール

仕様では、出力を任意の便利な形式にすることができるため、mapを維持してjoinビットの配列を出力できます
Shaggy

バイトの配列として出力される60バイト
シャギー

@ニールと@シャギーに感謝!!
Luis felipe De jesus Munoz




2

Java 10、339 308 265 227 225 186 184バイト

v->{var s="v->{var s=%c%s%1$c;return 0+new java.math.BigInteger(s.format(s,34,s).getBytes()).toString(2);}";return 0+new java.math.BigInteger(s.format(s,34,s).getBytes()).toString(2);}

不要な@NahuelFouilleulを削除したおかげで-8バイト&255(そして、チャレンジの完全なプログラム仕様が取り消され、関数も今は許可されていることを私の注意を喚起するための追加の-35)
-41バイト@OlivierGrégoireのおかげ。

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

説明:

-part:

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

チャレンジパート:

v->{                         //  Method with empty unused parameter and String return-type
  var s="...";               //   Unformatted source code String
  return 0+                  //   Return, with a leading "0":
   new java.math.BigInteger( //    A BigInteger of:
     s.format(s,34,s)        //     The actual source code String
      .getBytes())           //     Converted to a list of bytes (UTF-8 by default)
   .toString(2);}            //    And convert this BigInteger to a binary-String      

1
すべてのソースがASCIIであるため、ラムダを使用して265バイト。符号なしint c&255は必要ないようです
Nahuel Fouilleul

@NahuelFouilleul元の質問では、「完全なプログラムを構築する必要があります。」と「出力はSTDOUTに出力する必要があります。」と記述されていたため、ラムダ関数ではなく、文字列を返す詳細なボーダープレートコードがあります。&255ただし、ASCII以外の文字は使用しないので、必要ないのは良い点です。ありがとうございます。
Kevin Cruijssen、

わかりました。まだ使い方に慣れていませんが、JavaScriptのような他の言語では文字列を返すラムダを提供します。また、ラムダを使用するときにJavaで型と最後のセミコロンを数えない理由がわかりません。ルールを見つける?
Nahuel Fouilleul

1
まあ、それは私が迷っているところです。しかし私が試したところ、184バイトの新しい候補があります。私がどこか間違っているかどうか教えてください;)
OlivierGrégoire

1
@OlivierGrégoireああ、素敵なアプローチ!BigIntegerバイナリ文字列に変換するためのかなり短いことを完全に忘れていました。そして、変更して2バイト以上return'0'+return 0+。うーん、なぜそれが0必要なのですか?これは、すべての内部バイナリ文字列は、このリード持っている私を混乱させる0が、使用していない非常に最初の1 BigInteger.toString(2)...
ケビンCruijssen

2

Pythonの268の 67バイト

_="print''.join(bin(256|ord(i))[3:]for i in'_=%r;exec _'%_)";exec _

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

の修正 この回答の

'in'の後のスペースを削除して-1バイト(@mdahmouneに感謝)


-1バイト:スペースを後から落とすことができるin
mdahmoune

TIOリンクを更新していません。また、私はの'%08b'%ord(i)代わりにしようとしましたがbin(256|ord(i))[3:]、それは何らかの理由で機能しませんでした
Jo King

2

R138 114バイト

x=function(){rev(rawToBits(rev(charToRaw(sprintf("x=%s;x()",gsub("\\s","",paste(deparse(x),collapse="")))))))};x()

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

Rの機能を使用して、関数をそれらの文字表現に分解します。revsがあるため必要とされていますrawToBits最下位ビットを最初に配置する。as.integerそれ以外の場合、ビットは先行ゼロで表示されるため、必要です。

便利な出力が許可されていることに気づいたときに編集しました。また、元のバイトカウントが1つ減っていました。


1

C#(Visual C#Interactive Compiler)、221バイト

var s="var s={0}{1}{0};Write(string.Concat(string.Format(s,(char)34,s).Select(z=>Convert.ToString(z,2).PadLeft(8,'0'))));";Write(string.Concat(string.Format(s,(char)34,s).Select(z=>Convert.ToString(z,2).PadLeft(8,'0'))));

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

C#(Visual C#Interactive Compiler)、フラグ付き/u:System.String、193バイト

var s="var s={0}{1}{0};Write(Concat(Format(s,(char)34,s).Select(z=>Convert.ToString(z,2).PadLeft(8,'0'))));";Write(Concat(Format(s,(char)34,s).Select(z=>Convert.ToString(z,2).PadLeft(8,'0'))));

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


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