brainfuck - 617 616 604 octets
+>>>>,[>++++[<-------->-]<[>>>>],]<<<<[>+<<+<+>>-]<[>+<-]+<+<<[>+>-<<-]>[<+>-]>[,+++++[>+++++<-]>>[<->-]<[>>>>>[>>>>]+[<<<<]<-]>>[<+>-]<<<]>[>>[,<]<<+++++++++<]<<<[-[+>>-<]>[>>[<+<+>>-]<<<<[>+>-<<-]>[<+>-]>[<<[<<<<]>>>>[[<<<<+>>>>-]>>>>]<<<<+>>-]>[>+<-]]<<<[-[+>]+<<<<]>>>>-<<<<<]>>>>>+++++[>----<-]>->[<+>>+<-]<[<<<[<<<<]+[>>>>]<-]>>[<+>-]<[<<<<]>>>++++[<-------->-]>[-[,+++>]+>>>[<<<->>]>]<<<<<[>-]>[>>]>>+[<++++[<++++++++>-]<]>>[+++++++++++++>>>>]<<<<----<+++[<<+<<[<<+<<]+[>>>>]<<<<-]<<<<[-<<<<]>[.,>>]<<<<<[<<<<]<++++++++++<<.<+<<+<<+<<+<<+<[.,>>]<<<<<[<<]>++++++++++<+<<+<<+<..<+<[.,>>]<[<<]<...<<.
Cela m'a pris la plus grande partie de deux jours. Je pense que ça valait le coup. Il est probablement possible de jouer au golf davantage en modifiant la cellule dans laquelle un objet est stocké, mais pour le moment, je suis simplement heureux de l'avoir fait fonctionner.
Ce programme devrait être complètement différent si la question ne spécifiait pas que l'entrée serait triée. Cela fonctionne en construisant une liste de 10 broches autour de celles qui sont entrées. C'est un peu déroutant mais peut-être que cela l'expliquera mieux:
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]
Pendant ce temps, il se souvient quelles broches l’utilisateur a placées et celles qu’il a placées là. Cette stratégie serait très difficile à utiliser si l'entrée n'était pas triée.
Une autre chose que le tri facilite est la détection du nombre 10. Étant donné que le brainfuck concerne des octets individuels, et non pas des "nombres" en tant que tels, cela aurait pu être un casse-tête, mais l'entrée triée m'a beaucoup facilité la gestion avec. La raison en est liée à la manière dont j'ai stocké les données dans le programme. Je prends l’entrée un caractère à la fois et soustrais 32 du résultat. Si la cellule est non nulle par la suite, j'avance 4 cellules. avant de répéter. Cela signifie que je reçois un octet d’entrée non-espace toutes les 4 cellules et que je stocke effectivement les épingles sous leur numéro + 16. Cependant, il faut deux octets à la saisie de 10, j’ai donc dû le mettre dans un cas spécial. Si l'entrée n'était pas triée, il faudrait que je regarde à travers les punaises, mais comme elle est triée, ce sera toujours la dernière punaise si elle apparaît. Je vérifie si le (dernier octet de l'entrée + 1) == (l'avant-dernier octet de l'entrée) et, dans l'affirmative, il doit être 10. Je me débarrasse du dernier octet et mets l'avant-dernier en fonction de ce que mon système comprend "dix". Les personnages'1'
et '0'
ne rentre pas dans un seul octet, mais le nombre 26 le fait!
Utiliser des astuces pour faire fonctionner quelque chose est ce que je préfère dans l'utilisation de ce langage. :)
Si le fonctionnement de ce programme vous intéresse plus en détail, vous pouvez consulter le programme avec les commentaires que j'ai utilisés lors de sa rédaction pour vous assurer que je me souvenais de tout. Même écrire des commentaires dans brainfuck est difficile, car il n'y a pas de syntaxe de commentaire. Au lieu de cela, tous les personnages sauf ceux qui <[+.,-]>
sont dedans sont no-ops. Il est facile d'introduire des bugs en incluant .
ou ,
dans vos commentaires accidentellement ! C'est pourquoi la grammaire est si méchante et les points-virgules sont partout.
EDIT: Comme exemple de combien il est facile de tout gâcher: j'ai utilisé "non-espace" dans l'un des commentaires! Quand j'ai enlevé tous les caractères non-bf de la source, le programme que j’avais l'habitude de faire était conservé dans le -
. Heureusement, rien n'a été cassé, mais maintenant je l'ai supprimé pour sauvegarder un octet. :)
EDIT II: Cela fait longtemps que je n’ai pas touché celui-ci, haha. Dans une autre réponse de brainfuck sur ce site, j'ai remarqué que j'avais accidentellement utilisé une virgule dans la version commentée. Comme l'entrée avait déjà été épuisée, la cellule actuelle était définie sur 0 (cela dépend de la mise en œuvre, mais d'après mon expérience, c'est le comportement le plus courant). J'ai corrigé le bug, mais ça m'a fait réfléchir. La manière idiomatique de définir une cellule sur 0 est [-]
(approximativement while (*p) { *p--; }
), ce qui correspond à deux octets de plus. Chaque fois que toutes les entrées ont été lues, je peux les utiliser à la ,
place. Cela m'a sauvé 2 octets dans cette réponse et 12 dans celle-ci!
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!! :)
<[<<]<...<<.