ミラーレベルを出力するプログラムを作成する


31

95個の印刷可能なASCII文字があります。

 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~

Consolasフォント(スタック交換コードブロックのデフォルト)、文字の一部は、対称の垂直軸の周りに鏡を持っています。

  • これらの文字のペアは、相互のミラーです。 () [] {} <> /\
  • これらのキャラクターは自分自身のミラーです:(! "'*+-.8:=AHIMOTUVWXY^_ovwx|スペースは1つです。)
  • これらにはミラーがありません。 #$%&,012345679;?@BCDEFGJKLNPQRSZ`abcdefghijklmnpqrstuyz~

il0#、およびおそらく他の文字は、一部のフォントでは、独自のミラーであるが、我々はConsolas形状に固執するでしょう。)

文字列が39個のミラー文字のみで作られている場合、文字列は中央の垂直対称線を持つように配置されているため、それ自体の鏡であると言われます。それ](A--A)[はそれ自体の鏡ですが、そうでは](A--A(]ありません。

それ自体のミラーである1行の偶数長のプログラムを作成します。左半分のN個のコピーが追加され、右半分のN個のコピーが追加された場合、N + 1が出力されます。Nは負でない整数です。

たとえば、プログラムが](A--A)[(左半分:](A-、右半分:)の場合、次のよう-A)[になります。

  • 実行](A--A)[すると出力されます1。(N = 0)
  • 実行](A-](A--A)[-A)[すると出力されます2。(N = 1)
  • 実行](A-](A-](A--A)[-A)[-A)[すると出力されます3。(N = 2)
  • 実行](A-](A-](A-](A--A)[-A)[-A)[-A)[すると出力されます4。(N = 3)
  • 。。。
  • 実行](A-](A-](A-](A-](A-](A-](A-](A-](A-](A--A)[-A)[-A)[-A)[-A)[-A)[-A)[-A)[-A)[-A)[すると出力されます10。(N = 9)

ルール

  • stdoutまたは言語の最も近い代替への出力。オプションの末尾の改行がある場合があります。何も入力しないでください。
  • このプロセスは、十分なメモリと計算能力があれば、理論的には2 15 -1以上のNで機能するはずです。
  • REPLコマンドだけでなく、完全なプログラムが必要です。

バイト単位の最短の初期プログラム(N = 0の場合)が優先されます。


一部のフォントで#は、独自の修正もありますが、コンソラではなく、あなたは正しいです。
SuperJedi224

1
replsの使用は許可されていますか?言い換えれば、完全な有効なプログラムを作成する必要がありますか、それとも式で十分ですか?Haskellエントリについて考えています。これはghciで実行するときに機能しますが、有効な完全なプログラムではありません。
バクリウ

@Bakuriu完全なプログラムが必要です。Haskellの答えは無効です。
カルバンの趣味

4
なぜ「b」と「d」がお互いのミラーではないのですか?それは私の計画を不可能にします:P
タイステルハール

1
@ThijsterHaar私は実際にはそれを考慮しませんでしたが、コンソラスの形がわずかに異なっているように見えます、申し訳ありません:P
カルビンの趣味

回答:


20

ピップ、12 8 4バイト

バイトが66%減りました!

x++x
  • xは事前に初期化された変数です""。数値コンテキストでは、これはになり0ます。
  • 前半は、決勝戦+ではなく、形式の表現を作りx+x+...+xます。これは何もしない有効なステートメントです。
  • 前半の最終を含む+後半は、の形式の式を作成し++x+x+...+xます。++xに増分x1、残りはそれをN回追加します。式はPipで左から右に評価されるため、増分が最初に発生することが保証され、結果はミラーレベルの数に等しくなります。
  • 最後に、この式の値は自動印刷されます。

残念ながら、Pipは巨大な式をうまく処理できません。このソリューションでは、maximum recursion depth exceeded500以上のNに対してエラーが発生します。8バイトの場合、以前の解決策はありません:

x++oo++x

ピップの詳細


誰かが2バイトの回答を投稿しない限り、これをバッグに入れたように見えます。ところで、N = 32767で実行したかどうかはわかりませんが、実際の出力はFatal error: maximum recursion depth exceeded while calling a Python objectです。
デニス

@Dennis Yeah、私は実際にそれに遭遇しました-それはかなり前に開始します。その理由は、最初にすべての部分式を再帰的に評価することで式が評価されるため、x+x+...+xO(N)の再帰の深さが生成されるためです。多分それはこの答えを無効にします。メモを追加します。
DLosc

再帰制限はPythonで簡単に調整できますよね?
デニス

@Dennisはい、システムの設定が高すぎるとシステムに何が起こるかについての厳しい警告がありますが、私は試したことはありません。;)それに、Pip内から設定することはできないので、私にはごまかしているようです。ただし、試してみたい場合は、結果を聞いてみたいと思います。
DLosc

私はもう試した。私のマシンでは、再帰制限を20000に増やすと、すでにセグメンテーション違反が発生しています。しかし、答えは十分なメモリと計算能力を与えられた場合にのみ機能する必要があるため、それは問題ではないはずです。
デニス

34

GolfScript、10バイト

!:{)::(}:!

Web Golfscriptでオンラインで試してください:N = 0N = 1N = 2N = 3N = 41

Web GolfScriptには1024文字の制限がありますが、RubyインタープリターはN = 32767を完全に処理します。

$ curl -Ss http://www.golfscript.com/golfscript/golfscript.rb > golfscript.rb
$ echo '"!:{):"32768*":(}:!"32768*' | ruby golfscript.rb > mirror-level-32767.gs
$ ruby golfscript.rb mirror-level-32767.gs
32768

使い方

入力がない場合、GolfScriptは最初にスタックに空の文字列を持ちます。

左前半では、次のことが起こります。

  • !空の文字列に論理否定を適用します。これはプッシュし1ます。

  • :{スタック上の変数を変数に保存します{

    はい、それは有効な識別子ですが、保存された値を取得する方法はありません。

  • ) スタック上の整数をインクリメントします。

  • : 不完全な命令です。

その後の左半分では、次のことが起こります。

  • :!:以前の残りの部分は)変数のスタックに整数を保存します!

    はい、これも有効な識別子です。これは!コマンドを壊しますが、もう使用しません。

  • :{、前):同じように動作します。

前半では、次のことが行われます。

  • :::以前の残りの部分は)変数のスタックに整数を保存します:

    はい、それでも有効な識別子です。と同様{、保存された値を取得する方法はありません。

  • ( スタック上の整数をデクリメントし、左半分の数を生成します。

  • }、不一致であり、すぐに実行を終了するため。

    これは文書化されていない機能です。私はそれらをスーパーコメントと呼びます。

残りのコードは単に無視されます。


}ミラーコンペティションのコードの後半で比類のないものを見つけるのは本当に奇妙に思えます。
ballesta25

これは、回文変異体の一般的なトリックです。では"\""/"、2番目の二重引用符がエスケープされているため、4番目の二重引用符も一致しません。
デニス

27

Z80マシンコード、8 6バイト*

<8ww8> * Amstrad BASICから入力して特定の条件を想定

<   INC A         // A=A+1
8w  JR C, #77     ## C is unset unless A has overflowed, does nothing

w   LD (HL), A    // Saves A to memory location in HL (randomly initialised)
8>  JR C, #3E     ## C is still unset, does nothing

ABASICから入力した場合、最初は0です。それ刻みA のn倍、それに書き込むのn(BASICによって多少ランダムな位置に設定されている)同じメモリ位置に時間を!JR以来、ジャンプ相対的な操作は何もしませんでしCフラグが常に設定されていないので、次のバイト「コメントアウト」に使用されています!このバージョンは、特定の入力条件、つまりA常に0であるBASIC保証からの入力を想定することにより、少しごまかしてい(HL)ます。の位置は安全であるとは限りません。以下のコードははるかに堅牢であるため、非常に長くなります。

Z80マシンコード、30バイト

ASCIIとして: o!.ww.!>A=o>{))((}<o=A<!.ww.!o

基本的に、前半はゼロ値の作成を保証し、後半はそれをインクリメントしてメモリに書き込みます。以下の拡張バージョンで##は、ミラーの半分で目的を果たさないコードを示しています。

o   LD L, A       ## 
!.w LD HL, #772E  // Load specific address to not corrupt random memory!
w   LD (HL), A    ## Save random contents of A to memory
.!  LD L, #21     ## 
>A  LD A, #41     // A=#41
=   DEC A         // A=#40
o   LD L, A       // L=#40
>{  LD A, #7B     ## 
)   ADD HL, HL    // HL=#EE80
)   ADD HL, HL    // HL=#DD00. L=#00 at this point

((  JR Z, #28     ## 
}   LD A, L       // A=L
<   INC A         // A=L+1
o   LD L, A       // L=L+1
=   DEC A         // A=L
A   LD B, C       ## 
<   INC A         // A=L+1
!.w LD HL, #772E  // Load address back into HL
w   LD (HL), A    // Save contents of A to memory
.!  LD L, #21     ## 
o   LD L, A       // L=A

許可された指示の内訳:

n   op    description
--  ----  -----------
28  LD    LoaD 8-bit or 16-bit register
3   DEC   DECrement 8-bit or 16-bit register
1   INC   INCrement 8-bit or 16-bit register
1   ADD   ADD 8-bit or 16-bit register

Available but useless instructions:
3   JR    Jump Relative to signed 8-bit offset
1   DAA   Decimal Adjust Accumulator (treats the A register as two decimal digits
          instead of two hexadecimal digits and adjusts it if necessary)
1   CPL   1s ComPLement A
1   HALT  HALT the CPU until an interrupt is received

許可されている39個の命令のうち、28個はロード操作(0x40から0x7FまでのブロックはすべてシングルバイトLD命令です)で、そのほとんどはここでは役に立ちません!まだ許可されているメモリ命令への唯一のロードはLD (HL), A、値をに保存する必要があることを意味しAます。A許可されたINC命令を残した唯一のレジスタなので、これは実際には非常に便利です!

ロードできません AASCII 0x00は許可された文字ではないため、最初から0x00を!使用可能なすべての値は0からはほど遠いものであり、すべての数学および論理命令は許可されていません!を除いて...私はまだできるADD HL, HLHLそれ自体に16ビットを追加します!値を直接ロードする(ここでは使用しない!)、INCrementing AおよびDECrementing以外ALHLこれがレジスタの値を変更する唯一の方法です!実際には、前半には役立つかもしれないが後半には対処するのに苦労する特殊な命令と、ここではほとんど役に立たず、スペースを占有する1補数の命令があります。

だから、私は0に最も近い値を見つけました:0x41。それはどのように0に近いですか?バイナリでは0x01000001です。だから私はそれをデクリメントし、ロードして2回L実行ADD HL, HLします!LゼロになりましたA。残念ながら、のASCIIコードADD HL, HLは2回)使用する必要があります(。幸いなことに、(あるJR Z, e場合には、e次のバイトがあります。したがって、2番目のバイトを飲み込んでしまいます。Zフラグ!Zフラグに影響を与える最後の命令はDEC A(反直感的に、ADD HL, HL変更しない)であり、Aその時点で0x40であったことがわかってZいるため、設定されていないことが保証されます。

JR Z, #28Aが255から0にオーバーフローした場合にのみZフラグを設定できるため、後半の最初の命令は最初の255回は何もしません。ただし、その後は出力が間違っています関係ありません。コードは255回以上展開しないでください。

コードをスニペットとして実行する必要があるのは、きれいに戻るための利用可能なすべての方法が禁止されているためです。すべてのRETurn命令は0x80を超えており、8ビットの負の値もすべて許可されていないため、許可されるいくつかのジャンプ操作は正のオフセットにしかジャンプできません。


6
何。これは何ですか。
cloudfeet

4
GolfScript / J / etcを使用して、この答えを見ました。不正行為のようです。:p
cloudfeet

16ビットAレジスタを持つZ80互換のプロセッサはありますか?質問はコードがN = 32767で動作する必要があることを要求しているので、私は尋ねています。
デニス

1
@DennisプログラムがN = 32767で機能するには、少なくとも2 x 32767または65534バイトの長さが必要です。Z80は65536バイトのメモリしかアドレス指定できず、プログラムを6バイトより小さくできるとは思わないので、これは不可能なタスクです。Aレジスタは、そうでない場合、プロセッサがZ80と互換性がない、常に8ビットです。十分なメモリと計算能力があれば、ここでカバーされている思います!
CJデニス

1
@Dennis Z80互換プロセッサにA8ビット以外のレジスタがないのはなぜですか?16ビットに変更すると、たとえば255 + 1 = 0に依存するコードが破損します。CPUを発明する必要があります。デフォルトの16ビットレジスタを使用しますが、Z80からの同じ8ビット命令セットを使用するZ160と呼びます。変だ!
CJデニス

19

J、16 14バイト

(_=_)]++[(_=_)

使用法:

   (_=_)]++[(_=_)
1
   (_=_)]+(_=_)]++[(_=_)+[(_=_)
2
   (_=_)]+(_=_)]+(_=_)]++[(_=_)+[(_=_)+[(_=_)
3

説明:

  • Jは右から左に評価します。

  • (_=_)inf equals inftrueで、値は1であるため、式はになり1+]...[+1ます。((8=8)これも機能しますが、これはもっとクールに見えます。:))

  • []引数が2つある場合は、それぞれ左と右の引数を返します。彼らは1つだけを取得する場合、彼らはそれを返します。

  • +2つの引数を追加します。1しか取得しない場合、それを返します。

次に、レベル3の式を評価します(右から左へ)。

(_=_)]+(_=_)]++[(_=_)+[(_=_)  NB. (_=_) is 1

1]+1]+1]++[1+[1+[1  NB. unary [, binary +

1]+1]+1]++[1+[2  NB. unary [, binary +

1]+1]+1]++[3  NB. unary [, unary +

1]+1]+1]+3  NB. unary +, binary ]

1]+1]+3  NB. unary +, binary ]

1]+3  NB. unary +, binary ]

3

の右半分1が追加され、の左側1が省略され、目的の整数N、ミラーレベルが得られることがわかります。

こちらからオンラインでお試しください。


12

Haskell、42バイト

(8-8)-(-(8-8)^(8-8))--((8-8)^(8-8)-)-(8-8)

幸いなことに、Haskellの行コメント(-> --)はミラーリング可能であり、その半分(-> -)は有効な関数です。残りは番号を取得するための、いくつかの数学である01。基本的に(0)-(-1)、コメントN=0と先頭に追加する(0)-(-1)-、各ステップにて追加します。

浮動小数点数を出力するために許可されている場合は、私たちが構築することができます1から、8/8と26バイトのことで取得します:

Haskell、26バイト

(8-8)-(-8/8)--(8\8-)-(8-8)

出力1.02.0など


2
これは完全なプログラムでなければならないため、技術的には無効です。
カルバンの趣味

@ Calvin'sHobbies:なるほど。完全なプログラムの最小要件についてコンセンサスはありますか?メタを検索しましたが、プログラムについてではなく、機能についてのみの議論を見つけました。完全なプログラムの定義によっては、ソリューションを修正できる場合があります。
nimi

ファイルに保存してコマンドラインからprogram.hs実行$ runhaskell program.hsし、出力を確認できる場合は、完全なプログラムと呼びます。Haskellがわからないので、何を変更する必要があるかを正確に言うことはできません。
カルビンの趣味

2
@ Calvin'sHobbies:runhaskellいくつかの環境をセットアップし、最後ghcにHaskellコンパイラーを呼び出すシェルスクリプトです。あなたは私のコードを直接実行できますghcghc -e "(8-8)-(-8/8)--(8\8-)-(8-8)"。これが起動ghcし、引数として提供されたコードを評価し、結果を出力して終了します。REPLなし、相互作用なし。もちろん、これはのバイトカウントに+1を追加し-eます。
nimi

@nimi:-eこの場合、スコアに寄与しません。perl -Eまたはそのバイト数はカウントしませんgcc -std=c99
デニス

11

CJam、14バイト

]X+:+OooO+:+X[

CJamインタープリターでオンラインで試してください:N = 0N = 1N = 2 N = 3 N = 41

このコードはエラーメッセージで終了することに注意してください。Javaインタープリターを使用して、STDERRを閉じるかリダイレクトすることにより、そのエラーメッセージを抑制することができます。1

使い方

左半分では、次のことが起こります。

  • ] スタック全体を配列にラップします。

  • X1その配列に追加します。

  • :+ すべての配列要素の合計を計算します。

  • Oo 空の配列の内容を出力します(つまり、何もしません)。

前半では、次のことが行われます。

  • o スタックに整数を出力します。これは望ましい出力です。

  • O+ 空の配列をスタックの一番上のアイテムに追加しようとします。

    ただし、プッシュする前にスタックは空Oでした。これは失敗し、プログラムの実行を終了します。

残りのコードは単に無視されます。

1 メタポーリングによると、提出はエラーで終了することを許可すべきですか?、これは許可されています。


エラーが原因でこれを受け入れることに懐疑的ですが、勝てないのであまり心配していません。
カルビンの趣味

このようなタスクは、CJamではゴルフ言語であることを考えると驚くほど困難です。未実行ブロックの構文エラー(未定義の演算子など)でさえ、プログラム全体の実行を妨げます。私はまだエラーを取り除こうとしています。
デニス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.