мозковий ебать - 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. Оскільки brainfuck має справу з окремими байтами, а не з "числами", це могло бути болем у попці, але відсортований вклад значно полегшив мені справу з. Причина цього пов’язана з тим, як я зберігав дані в програмі. Я беру вхід один символ за один раз і віднімаю 32 від результату. Якщо комірка після цього не дорівнює нулю, я рухаюся вперед на 4 комірки. перед повторенням. Це означає, що я отримую непробільний байт введення кожні 4 комірки, і я ефективно зберігаю шпильки як їх кількість + 16. Однак 10 займає два байти, щоб набрати, тому мені довелося це робити окремо. Якщо введення не було відсортовано, я повинен був би переглядати шпильки, але оскільки він відсортований, він завжди буде останнім штифтом, якщо він з'явиться. Я перевіряю, чи (останній байт введення + 1) == (другий останній байт вводу), і якщо так, то він повинен бути 10. Я позбавляюсь останнього байта і встановлюю другий останній на те, що моя система розуміє як "10". Персонажі'1'
і '0'
не вміщуються в одному байті, але число 26 точно!
Створення хитрощів просто для того, щоб взагалі щось працювати - це моя улюблена частина використання цієї мови. :)
Якщо вас цікавить, як ця програма працює більш детально, ви можете побачити програму з коментарями, які я використовував під час її написання, щоб переконатися, що я запам'ятав, що все робив. Навіть писати коментарі в мозковому слові важко, оскільки немає синтаксису коментарів. Натомість кожен персонаж, за винятком тих, що <[+.,-]>
знаходяться, не є. Вносити помилки легко, випадково включивши .
або ,
у ваші коментарі! Ось чому граматика така вибаглива, а крапки з комою є скрізь.
EDIT: Як приклад того, як легко це викрутити: я використав "непробіл" в одному з коментарів! Коли я знімав усі символи, що не належать до BF, у програмі, яку я раніше робив, зберігалася в -
. На щастя, це нічого не зламало, але тепер я його видалив, щоб зберегти байт. :)
РЕДАКЦІЯ ІІ: Минув час, коли я торкнувся цього, ха-ха. В іншій відповіді на цей епізод на цьому сайті я помітив, що випадково використав кому у коментованій версії. Оскільки вхід вже вичерпано, він встановив поточну комірку 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!! :)
<[<<]<...<<.