brainfuck - 617 616 604 byte
+>>>>,[>++++[<-------->-]<[>>>>],]<<<<[>+<<+<+>>-]<[>+<-]+<+<<[>+>-<<-]>[<+>-]>[,+++++[>+++++<-]>>[<->-]<[>>>>>[>>>>]+[<<<<]<-]>>[<+>-]<<<]>[>>[,<]<<+++++++++<]<<<[-[+>>-<]>[>>[<+<+>>-]<<<<[>+>-<<-]>[<+>-]>[<<[<<<<]>>>>[[<<<<+>>>>-]>>>>]<<<<+>>-]>[>+<-]]<<<[-[+>]+<<<<]>>>>-<<<<<]>>>>>+++++[>----<-]>->[<+>>+<-]<[<<<[<<<<]+[>>>>]<-]>>[<+>-]<[<<<<]>>>++++[<-------->-]>[-[,+++>]+>>>[<<<->>]>]<<<<<[>-]>[>>]>>+[<++++[<++++++++>-]<]>>[+++++++++++++>>>>]<<<<----<+++[<<+<<[<<+<<]+[>>>>]<<<<-]<<<<[-<<<<]>[.,>>]<<<<<[<<<<]<++++++++++<<.<+<<+<<+<<+<<+<[.,>>]<<<<<[<<]>++++++++++<+<<+<<+<..<+<[.,>>]<[<<]<...<<.
Questo mi ha portato la parte migliore di due giorni. Penso che ne sia valsa la pena. Probabilmente ci sono parti che possono essere giocate di più cambiando in quale cella è memorizzato qualcosa o qualunque cosa, ma in questo momento sono solo felice di averlo fatto funzionare.
Questo programma dovrebbe essere completamente diverso se la domanda non specifica che l'input verrà ordinato. Il modo in cui funziona è costruendo un elenco di 10 pin attorno a quelli che vengono inseriti. È un po 'confuso, ma forse questo lo spiegherà meglio:
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]
Mentre lo fa, ricorda quale dei pin l'utente ha messo lì e quali ha messo lì. Questa strategia sarebbe molto difficile da usare se l'input non fosse ordinato.
Un'altra cosa che semplifica l'ordinamento è il rilevamento del numero 10. Dato che brainfuck si occupa di singoli byte, non di "numeri" di per sé, avrebbe potuto essere un dolore nel culo, ma l'input ordinato ha reso molto più facile per me gestire con. La ragione di ciò ha a che fare con il modo in cui ho archiviato i dati nel programma. Prendo l'input di un carattere alla volta e sottraggo 32 dal risultato. Se la cella è diversa da zero dopo, mi sposto in avanti di 4 celle. prima di ripetere. Ciò significa che ricevo un byte di spazio non spaziale ogni 4 celle e in effetti memorizzo i pin come numero + 16. Tuttavia, 10 richiede due byte per digitare, quindi ho dovuto fare un caso speciale. Se l'input non è stato ordinato, dovrei guardare attraverso i pin, ma dato che è ordinato sarà sempre l'ultimo pin se appare. Controllo se (l'ultimo byte di input + 1) == (il secondo ultimo byte di input) e, in tal caso, deve essere 10. Mi libero dell'ultimo byte e imposto il secondo ultimo su ciò che il mio sistema comprende "10". I personaggi'1'
e '0'
non rientrano in un singolo byte, ma sicuramente il numero 26 lo fa!
Venire con i trucchi solo per far funzionare qualcosa è la mia parte preferita dell'uso di questo linguaggio. :)
Se sei interessato a come funziona questo programma in modo più dettagliato, puoi vedere il programma con i commenti che ho usato durante la scrittura per assicurarmi di ricordare cosa ha fatto tutto. Anche scrivere commenti in brainfuck è difficile, dal momento che non c'è sintassi dei commenti. Invece, tutti i personaggi tranne quelli in <[+.,-]>
non sono operazioni. È facile introdurre bug includendo accidentalmente .
o ,
nei tuoi commenti! Ecco perché la grammatica è così traballante e i punti e virgola sono ovunque.
EDIT: Come esempio di quanto sia facile rovinare tutto: ho usato "non-spazio" in uno dei commenti! Quando ho rimosso tutti i caratteri non bf dalla fonte, il programma che ho usato per farlo è rimasto nel -
. Fortunatamente non ha rotto nulla, ma ora l'ho rimosso per salvare un byte. :)
EDIT II: È passato un po 'di tempo da quando ho toccato questo, haha. In un'altra risposta brainfuck su questo sito, ho notato che ho usato accidentalmente una virgola nella versione commentata. Poiché l'input era già stato esaurito, imposta la cella corrente su 0 (dipende dall'implementazione, ma nella mia esperienza è il comportamento più comune). Ho corretto l'errore, ma mi ha fatto pensare. Il modo idiomatico di impostare una cella su 0 è [-]
(approssimativamente while (*p) { *p--; }
), che è più lungo di due byte. Ogni volta che tutti gli input sono stati letti, posso usare ,
invece. Questo mi ha salvato 2 byte in quella risposta e 12 in questo!
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!! :)
<[<<]<...<<.