брейкфук - 617 616 604 байта
+>>>>,[>++++[<-------->-]<[>>>>],]<<<<[>+<<+<+>>-]<[>+<-]+<+<<[>+>-<<-]>[<+>-]>[,+++++[>+++++<-]>>[<->-]<[>>>>>[>>>>]+[<<<<]<-]>>[<+>-]<<<]>[>>[,<]<<+++++++++<]<<<[-[+>>-<]>[>>[<+<+>>-]<<<<[>+>-<<-]>[<+>-]>[<<[<<<<]>>>>[[<<<<+>>>>-]>>>>]<<<<+>>-]>[>+<-]]<<<[-[+>]+<<<<]>>>>-<<<<<]>>>>>+++++[>----<-]>->[<+>>+<-]<[<<<[<<<<]+[>>>>]<-]>>[<+>-]<[<<<<]>>>++++[<-------->-]>[-[,+++>]+>>>[<<<->>]>]<<<<<[>-]>[>>]>>+[<++++[<++++++++>-]<]>>[+++++++++++++>>>>]<<<<----<+++[<<+<<[<<+<<]+[>>>>]<<<<-]<<<<[-<<<<]>[.,>>]<<<<<[<<<<]<++++++++++<<.<+<<+<<+<<+<<+<[.,>>]<<<<<[<<]>++++++++++<+<<+<<+<..<+<[.,>>]<[<<]<...<<.
Это заняло у меня лучшую часть двух дней. Я думаю, это того стоило. Вероятно, есть детали, которые можно больше играть в гольф, изменяя, в какой ячейке что-то хранится или что-то в этом роде, но сейчас я просто счастлив, что все заработало.
Эта программа должна была бы быть совершенно другой, если бы в вопросе не было указано, что входные данные будут отсортированы. Это работает путем построения списка из 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]
При этом он запоминает, какие из выводов пользователь вставил туда, а какие - туда. Эту стратегию было бы очень сложно использовать, если входные данные не были отсортированы.
Еще одна вещь, которую упростит сортировка, - это обнаружение числа 10. Поскольку мозговой трах имеет дело с отдельными байтами, а не с «числами» как таковыми, это могло быть болезненным задом, но отсортированный ввод сделал мне намного легче иметь дело с. Причина этого связана с тем, как я хранил данные в программе. Я беру ввод по одному символу за раз и вычитаю 32 из результата. Если после этого ячейка станет ненулевой, я продвигаюсь на 4 ячейки. перед повторением. Это означает, что я получаю непустой байт ввода каждые 4 ячейки, и я эффективно сохраняю выводы как их число + 16. Однако для ввода 10 требуется два байта, поэтому мне пришлось использовать его в особом случае. Если вход не был отсортирован, мне пришлось бы просматривать контакты, но поскольку он отсортирован, он всегда будет последним, если он появится. Я проверяю, является ли (последний байт ввода + 1) == (вторым последним байтом ввода), и если да, то должно быть 10. Я избавляюсь от последнего байта и устанавливаю второй последний на то, что моя система понимает как "10". Персонажи'1'
и '0'
не помещается в один байт, но число 26 точно подходит!
Придумывать трюки, чтобы заставить что-то работать, - моя любимая часть использования этого языка. :)
Если вас интересует, как эта программа работает более подробно, вы можете увидеть программу с комментариями, которые я использовал при ее написании, чтобы убедиться, что я вспомнил, что все делал. Даже писать комментарии в Brainfuck сложно, так как нет синтаксиса комментариев. Вместо этого, все персонажи, кроме тех, которые в не <[+.,-]>
являются опа. Легко вносить ошибки, случайно включив .
или ,
в ваших комментариях! Вот почему грамматика такая шаткая, а точки с запятой везде.
РЕДАКТИРОВАТЬ: В качестве примера того, как это легко облажаться: я использовал "не пробел" в одном из комментариев! Когда я удалил все не-bf символы из источника, программа, которую я использовал для этого, сохранилась в -
. К счастью, это ничего не сломало, но теперь я удалил его, чтобы сохранить байт. :)
РЕДАКТИРОВАТЬ II: Прошло много времени с тех пор, как я коснулся этого, ха-ха. В другом ответе о бреде на этом сайте я заметил, что я случайно использовал запятую в закомментированной версии. Поскольку ввод уже исчерпан, он устанавливает текущую ячейку на 0 (это зависит от реализации, но, по моему опыту, это наиболее распространенное поведение). Я исправил ошибку, но это заставило меня задуматься. Идиоматический способ установить ячейку в 0 - это [-]
(примерно while (*p) { *p--; }
), что на два байта длиннее. Каждый раз, когда все входные данные были прочитаны, я могу использовать ,
вместо этого. Это спасло мне 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!! :)
<[<<]<...<<.