brainfuck - 617 616 604 bajtów
+>>>>,[>++++[<-------->-]<[>>>>],]<<<<[>+<<+<+>>-]<[>+<-]+<+<<[>+>-<<-]>[<+>-]>[,+++++[>+++++<-]>>[<->-]<[>>>>>[>>>>]+[<<<<]<-]>>[<+>-]<<<]>[>>[,<]<<+++++++++<]<<<[-[+>>-<]>[>>[<+<+>>-]<<<<[>+>-<<-]>[<+>-]>[<<[<<<<]>>>>[[<<<<+>>>>-]>>>>]<<<<+>>-]>[>+<-]]<<<[-[+>]+<<<<]>>>>-<<<<<]>>>>>+++++[>----<-]>->[<+>>+<-]<[<<<[<<<<]+[>>>>]<-]>>[<+>-]<[<<<<]>>>++++[<-------->-]>[-[,+++>]+>>>[<<<->>]>]<<<<<[>-]>[>>]>>+[<++++[<++++++++>-]<]>>[+++++++++++++>>>>]<<<<----<+++[<<+<<[<<+<<]+[>>>>]<<<<-]<<<<[-<<<<]>[.,>>]<<<<<[<<<<]<++++++++++<<.<+<<+<<+<<+<<+<[.,>>]<<<<<[<<]>++++++++++<+<<+<<+<..<+<[.,>>]<[<<]<...<<.
Zajęło mi to większą część dwóch dni. Myślę, że było warto. Prawdopodobnie są części, które można golfować bardziej, zmieniając komórkę, w której coś jest przechowywane, czy cokolwiek innego, ale teraz jestem szczęśliwy, że to działa.
Ten program musiałby być zupełnie inny, gdyby pytanie nie określało, że dane wejściowe zostaną posortowane. Działa to poprzez zbudowanie listy 10 pinów wokół tych, które są wprowadzane. To trochę mylące, ale może to lepiej to wyjaśni:
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]
Robiąc to, pamięta, które z pinów umieścił tam użytkownik, a które tam. Ta strategia byłaby bardzo trudna w użyciu, gdyby dane wejściowe nie były posortowane.
Kolejną rzeczą, która ułatwia sortowanie, jest wykrycie liczby 10. Ponieważ pieprzenie mózgu zajmuje się pojedynczymi bajtami, a nie „liczbami” jako takimi, mógł to być problem w dupie, ale posortowane dane wejściowe znacznie ułatwiły mi radzenie sobie z. Powodem tego jest sposób przechowywania danych w programie. Pobieram jeden znak naraz i odejmuję 32 od wyniku. Jeśli po tym komórka nie jest zerowa, przesuwam do przodu 4 komórki. przed powtórzeniem. Oznacza to, że co 4 komórki otrzymuję bajt niebędący spacją i skutecznie przechowuję piny jako ich liczbę + 16. Jednak 10 zajmuje dwa bajty na pisanie, więc musiałem to zrobić w specjalnym przypadku. Jeśli dane wejściowe nie zostały posortowane, musiałbym przejrzeć piny, ale ponieważ są posortowane, zawsze będzie to ostatni pin, jeśli się pojawi. Sprawdzam, czy (ostatni bajt wejścia + 1) == (drugi ostatni bajt danych wejściowych), a jeśli tak, to musi być 10. Pozbywam się ostatniego bajtu i ustawiam drugi ostatni na to, co mój system rozumie jako „10”. Postacie'1'
i '0'
nie mieszczą się w jednym bajcie, ale liczba 26 na pewno tak!
Wymyślanie sztuczek tylko po to, żeby coś w ogóle działało, jest moją ulubioną częścią używania tego języka. :)
Jeśli jesteś zainteresowany bardziej szczegółowym działaniem tego programu, możesz zobaczyć program z komentarzami, których użyłem podczas pisania, aby upewnić się, że pamiętam, co wszystko zrobiłem. Nawet pisanie komentarzy w przeróbce mózgu jest trudne, ponieważ nie ma składni komentarzy. Zamiast tego, każda postać oprócz tych w <[+.,-]>
nie ma operacji. Łatwo jest wprowadzić błędy, przypadkowo włączając .
lub ,
w komentarzach! Właśnie dlatego gramatyka jest tak dziwna, a średniki są wszędzie.
EDYCJA: Jako przykład tego, jak łatwo to zepsuć: użyłem „spacji” w jednym z komentarzy! Kiedy usunąłem wszystkie znaki inne niż bf ze źródła, program, który kiedyś to robiłem, zachował się w -
. Na szczęście nic nie zepsuło, ale teraz usunąłem go, aby zaoszczędzić bajt. :)
EDYCJA II: Minęło trochę czasu, odkąd go dotknąłem, haha. W innej odpowiedzi na temat pieprzenia mózgu na tej stronie zauważyłem, że przypadkowo użyłem przecinka w skomentowanej wersji. Ponieważ dane wejściowe zostały już wyczerpane, ustawiono bieżącą komórkę na 0 (jest to zależne od implementacji, ale z mojego doświadczenia wynika, że jest to najczęstsze zachowanie). Naprawiłem błąd, ale przyszło mi to do głowy. Idiomatyczny sposób ustawienia komórki na 0 to [-]
(z grubsza while (*p) { *p--; }
), który jest o dwa bajty dłuższy. Za każdym razem, gdy wszystkie dane wejściowe zostały odczytane, mogę ,
zamiast tego użyć . To zaoszczędziło mi 2 bajty w tej odpowiedzi i 12 w tym!
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!! :)
<[<<]<...<<.