brainfuck- 617 616 604バイト
+>>>>,[>++++[<-------->-]<[>>>>],]<<<<[>+<<+<+>>-]<[>+<-]+<+<<[>+>-<<-]>[<+>-]>[,+++++[>+++++<-]>>[<->-]<[>>>>>[>>>>]+[<<<<]<-]>>[<+>-]<<<]>[>>[,<]<<+++++++++<]<<<[-[+>>-<]>[>>[<+<+>>-]<<<<[>+>-<<-]>[<+>-]>[<<[<<<<]>>>>[[<<<<+>>>>-]>>>>]<<<<+>>-]>[>+<-]]<<<[-[+>]+<<<<]>>>>-<<<<<]>>>>>+++++[>----<-]>->[<+>>+<-]<[<<<[<<<<]+[>>>>]<-]>>[<+>-]<[<<<<]>>>++++[<-------->-]>[-[,+++>]+>>>[<<<->>]>]<<<<<[>-]>[>>]>>+[<++++[<++++++++>-]<]>>[+++++++++++++>>>>]<<<<----<+++[<<+<<[<<+<<]+[>>>>]<<<<-]<<<<[-<<<<]>[.,>>]<<<<<[<<<<]<++++++++++<<.<+<<+<<+<<+<<+<[.,>>]<<<<<[<<]>++++++++++<+<<+<<+<..<+<[.,>>]<[<<]<...<<.
これは私に2日間の大半を費やした。価値があったと思う。おそらく、どのセルに何を格納するかなどを変更することで、もっとゴルフをすることができる部分がありますが、今のところ、私はそれを機能させて満足しています。
質問で入力がソートされることを指定していない場合、このプログラムは完全に異なっている必要があります。これが機能する方法は、入力されるピンの周りに10個のピンのリストを作成することです。それはちょっと紛らわしいですが、おそらくこれはそれをより良く説明するでしょう:
If you input these pins: [2, 3, 6, 8, 9]
First, the program does this: [2, 3, 6, 8, 9] + [10]
Then this: [2, 3, 6] + [7] + [8, 9, 10]
Then this: [2, 3] + [4, 5] + [6, 7, 8, 9, 10]
Finally, this: [1] + [2, 3, 4, 5, 6, 7, 8, 9, 10]
To build this: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
それを行っている間、ユーザーがそこに置いたピンとそこに置いたピンを覚えています。入力がソートされていない場合、この戦略を使用するのは非常に困難です。
ソートが簡単になるもう1つのことは、数値10の検出です。brainfuckは「数値」そのものではなく、個々のバイトを処理するため、お尻が痛いかもしれませんが、ソートされた入力により処理がはるかに容易になりましたと。その理由は、プログラムにデータを保存する方法に関係しています。入力を一度に1文字ずつ取り、結果から32を引きます。その後、セルがゼロ以外であれば、4セル進みます。繰り返す前に。これは、4セルごとに非スペースバイトの入力を取得し、ピンを事実上その数+ 16として格納することを意味します。ただし、10は入力に2バイトかかるため、特別な場合がありました。入力がソートされていない場合、ピンを調べる必要がありますが、ソートされているため、表示される場合は常に最後のピンになります。(入力の最後のバイト+ 1)==(入力の最後から2番目のバイト)であるかどうかをチェックし、そうであれば、10でなければなりません。最後のバイトを取り除き、最後から2番目のバイトをシステムが理解するものに設定します「10」。キャラクター'1'
そして'0'
、1バイトに収まらないが、26番は確かに収まります!
何かをうまく機能させるためだけにトリックを考え出すことは、この言語を使用する私のお気に入りの部分です。:)
このプログラムがどのように機能するかについて詳しく知りたい場合は、作成中に使用したコメントとともにプログラムを確認し、すべてが何をしたかを確認してください。コメント構文はないので、brainfuckでコメントを書くことさえ困難です。代わりに、以外のすべての文字<[+.,-]>
はノーオペレーションです。誤ってコメントを追加したり、コメントに追加し.
たり,
すると、バグを簡単に導入できます。それが文法がとても不安定で、セミコロンが至る所にある理由です。
編集:これがいかに簡単かを示す例として、コメントの1つで「スペースなし」を使用しました。ソースからすべての非bf文字を削除したとき、それを行うために使用したプログラムはに保持されました-
。幸いなことに、何も壊れませんでしたが、バイトを節約するために削除しました。:)
編集II:これに触れてからしばらく経ちました(笑)。このサイトの別のブレインファックの回答で、コメント版で誤ってコンマを使用したことに気付きました。入力はすでに使い果たされているため、現在のセルを0に設定します(これは実装に依存しますが、私の経験では最も一般的な動作です)。バグを修正しましたが、考えさせられました。セルを0に設定する慣用的な方法は[-]
(大まかにwhile (*p) { *p--; }
)2バイト長いです。すべての入力が読み取られるたびに、,
代わりに使用できます。これにより、その回答で2バイト、この回答で12バイト節約できました。
one flag at the very left; will be important later
+>>>>
all nonspace bytes of input separated by 3 empty cells; pin number `n` stored with value `n` plus 16
,[>++++[<-------->-]<[>>>>],]<<<<
test if last pin is 10
[>+<<+<+>>-]<[>+<-]+<+<<[>+>-<<-]>[<+>-]>
[
if not: find 10 minus the number it is; put that many placeholder pins (cells with value 1) at the end
,+++++[>+++++<-]>>[<->-]<[>>>>>[>>>>]+[<<<<]<-]>>[<+>-]<<<
]>
[
if so: get rid of '0' byte; convert '1' byte to 26 (10 plus 16)
>>[,<]<<+++++++++<
]<<<
pointer now sitting on the cell with the second greatest pin that was inputted (ie not a placeholder)
;;;;;;;
[
check for flag placed at the very beginning of the program; if present: break
-[+>>-<]>
[
find ((pin to our right) minus 1) minus pin to our left
move all pins left of us 4*(that value) cells and insert placeholder pins
>>[<+<+>>-]<<<<[>+>-<<-]>[<+>-]>[<<[<<<<]>>>>[[<<<<+>>>>-]>>>>]<<<<+>>-]>[>+<-]
]
find first non placeholder pin to our left
there has to be one because we haven't hit the flag yet
<<<[-[+>]+<<<<]>>>>-<<<<<
]>>>>>+
we have now added placeholder pins at the end and in the middle; all that's left is the beginning
subtract 17 from lowest pin and put that many placeholders to the left
++++[>----<-]>->[<+>>+<-]<[<<<[<<<<]+[>>>>]<-]>>[<+>-]
subtract 32 from an empty cell 2 to the left of the lowest pin; will be useful later
<[<<<<]>>>++++[<-------->-]>
placeholder pins have the value 1; real pins have a value somewhere between 17 and 26
normalize it by stepping through and setting every pin with value != 1 to 3 (0's ascii code is 2 higher than period so this will make it easier to print later)
[-[,+++>]+>>>[<<<->>]>]<<<<<[>-]>[>>]>>
start writing 32s across the board; hitting every second cell
that's every pin and the cell 2 to the right of each pin
this is done in such a way that it will only halt if adding 32 to a cell sets it to 0; which is why we subtracted 0 from an empty cell earlier
it will catch us and prevent an infinite loop
+[<++++[<++++++++>-]<]
now write 13 to each pin; this adds up to 46 or 48; which are exactly the ascii values we want
>>[+++++++++++++>>>>]
we happen to have made a 14; turn it into a 10 for a newline
<<<<----
we're so close now; i can taste it
we have a list of 10 pins; each one with the ascii value that needs to be written
we have 32 everywhere because we'll need spaces
we even have a newline
the only problem now is that our list looks like this:
;;;;;;;;;;;;;;;;;;;;;;;;
;;1 2 3 4 5 6 7 8 9 10;;
;;;;;;;;;;;;;;;;;;;;;;;;
and we need to print in this order:
;;;;;;;;;;;;;;;;;;;;;;;;
;;7 8 9 10 4 5 6 2 3 1;;
;;;;;;;;;;;;;;;;;;;;;;;;
it's a pretty simple fix
once we print a pin we obviously don't need to remember it any more
so we simply print the last 4 pins on the list; destroying them on the way
then we print the last 3; which have become the ones we want
then two; then one
<+++[<<+<<[<<+<<]+[>>>>]<<<<-]<<<<[-<<<<]
print pins 7 8 9 10
>[.,>>]
print pins 4 5 6
<<<<<[<<<<]<++++++++++<<.<+<<+<<+<<+<<+<[.,>>]
print pins 3 2
<<<<<[<<]>++++++++++<+<<+<<+<..<+<[.,>>]
print the final pin!! :)
<[<<]<...<<.