Sous-programmes Brainf *** avec sorties uniques

19

Vous devez écrire un programme de brainfuck (BF) long de 100 octets.

Un caractère en sera supprimé de toutes les manières possibles, les 100 nouveaux programmes résultants (de 99 octets de long). Par exemple , pour le programme ++.>.les 5 sous - programmes sont +.>., +.>., ++>., ++..et ++.>.

Votre score sera le nombre de sorties uniques générées par les 100 programmes. Un score plus élevé est meilleur.

Détails

  • Vos programmes seront interrompus après la sortie du premier caractère.
  • Les programmes invalides ou non terminés et les programmes générant des sorties vides ne sont pas pris en compte dans le score.
  • Les cellules BF sont des cellules enveloppantes 8 bits. (255 + 1 = 0, 0-1 = 255)
  • Votre programme ne reçoit aucune entrée. Si vous utilisez ,dans le code, il définit la cellule actuelle sur 0.
  • Il n'y a pas de cellules sur le côté gauche de la position de départ. Par exemple, il <.n'est pas valide mais .<est valide car l'exécution se termine à .. La bande est illimitée dans l'autre sens.
  • Les programmes avec des crochets non équilibrés ( [et ]) ne sont pas valides.
  • Votre programme d'origine peut être plus court que 100 octets car il est facile de l'étendre à 100 octets sans changer le score.
  • Votre programme d'origine ne doit pas nécessairement être un code BF valide.

Vous pouvez utiliser ce programme python3 (lien ideone) pour déterminer le score de votre réponse. (Pour les programmes de longue durée, vous devrez peut-être modifier la maxstepvariable.)

Exemple

(Pour plus de simplicité, ce programme est plus court que 100 octets.)

Solution: ++,+[-]+><.-,-.

Score: 3

Explanation:

Subprogram     => Output

+,+[-]+><.-,-. => 1
+,+[-]+><.-,-. => 1
+++[-]+><.-,-. => 1
++,[-]+><.-,-. => 1
++,+-]+><.-,-. => None
++,+[]+><.-,-. => None
++,+[-+><.-,-. => None
++,+[-]><.-,-. => 0
++,+[-]+<.-,-. => None
++,+[-]+>.-,-. => 0
++,+[-]+><-,-. => 255
++,+[-]+><.,-. => 1
++,+[-]+><.--. => 1
++,+[-]+><.-,. => 1
++,+[-]+><.-,- => 1

Unique outputs are [0, 1, 255]    
Score is 3 for ++,+[-]+><.-,-. (length = 15)

En cas d'égalité, le gagnant est celui qui a le code le plus court. (Votre programme peut être inférieur à 100 octets, comme indiqué dans la section Détails.) Si les codes sont de longueur égale, le gagnant est l'affiche précédente.

Puzzle bonus: sans la restriction en gras, pouvez-vous trouver un programme avec un score de 100?

randomra
la source
J'ai résolu le puzzle bonus; la réponse est (censurée).
AJMansfield
@AJMansfield Pourriez-vous modifier votre commentaire afin que d'autres puissent aussi penser au puzzle? Par exemple, changez votre solution en un lien pastebin.com qui contient la réponse.
randomra
3
Hmm. J'ai écrit un optimiseur génétique pour cette question pour essayer de trouver des micro-améliorations aux réponses existantes, mais ce n'est pas trop réussi jusqu'à présent. Ils se retrouvent bloqués à 79 et 43 respectivement. Ah bien, ça valait le coup!
wchargin

Réponses:

12

Résultat: 35 41 69 78 79 83

(Supprimez la nouvelle ligne.)

-->+>->+>->+>->+>->+>->+>->+>->+>->+>->+>->+>->+>-
>+>->+>->+>->+>->+>->+>->+>->+>++[>[-<+++>]<<++]>.

Essayez-le en ligne!

Je ne sais pas exactement pourquoi cela fonctionne ...

Résultat: 79

X->>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>
+>+>+>+>+>+>+>+>+>+>+>+[>[-<+>>+<]+>[-<+>]<<<+]>>.

Essayez-le en ligne!

Il était censé additionner 2 * mem [i] * i et ajouter le nombre de cellules (+ const) où les adresses sont comptées de la droite vers la gauche. Le multiplicateur 2 et le nombre de cellules peuvent rendre la suppression de + et> ayant une parité différente.

Cela a en effet fonctionné comme ça dans la version 69 points. Mais la dernière version a cassé cela et a obtenu quelque chose d'autre par coïncidence. Il calcule la somme (mem [i] * i + i + 1) et la suppression de + et> fait presque la même chose, à l'exception de la somme (i) qui a une différence du nombre de cellules, qui est aussi le nombre de sortie différente pour supprimer + et>.

Pour le bonus:

+. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +.

jimmy23013
la source
Remarque: si vous testez cela avec le programme de scoring fourni, assurez-vous d'augmenter la maxstepvaleur (in def evaluate(r,maxstep=20000):) car certains sous-programmes s'exécutent pendant une longue période.
randomra
1
Le score peut en fait être augmenté 79en remplaçant ->+>+> ...par->,>+> ...
BrainSteel
@BrainSteel Je viens de le changer en no-op.
jimmy23013
9

Résultat: 37 43

+>-,->,+-><->-[>---+-+<[--->>+><,+>>>++<><<<+<[>--]]><><+-+>+<<+<><+++<[[<[---->-<-]>++>],>,]<,]<+-.

EDIT: Mon programme autorise maintenant quelques crochets. Je ne gagnerai aucun prix avec, mais c'est ce que j'obtiens pour que certains RNG pondérés fassent le travail occupé pour moi.

Cela a été généré par un programme que j'ai écrit en C.

Pour chaque Ne caractère supprimé, voici les sorties:

N = 0 => 158
N = 1 => 158
N = 2 => 158
N = 3 => 187
N = 4 => 129
N = 5 => 100
N = 6 => 158
N = 7 => 13
N = 8 => 1
N = 9 => 211
N = 10 => 129
N = 11 => 1
N = 12 => 57
N = 13 => 255
N = 14 => Mismatched Braces
N = 15 => 59
N = 16 => 11
N = 17 => 11
N = 18 => 11
N = 19 => 117
N = 20 => 11
N = 21 => 117
N = 22 => 166
N = 23 => Mismatched Braces
N = 24 => 206
N = 25 => 206
N = 26 => 206
N = 27 => 147
N = 28 => 147
N = 29 => 158
N = 30 => 148
N = 31 => 188
N = 32 => 51
N = 33 => 17
N = 34 => 84
N = 35 => 84
N = 36 => 84
N = 37 => 158
N = 38 => 158
N = 39 => 94
N = 40 => 46
N = 41 => 94
N = 42 => 94
N = 43 => 94
N = 44 => 17
N = 45 => 196
N = 46 => Mismatched Braces
N = 47 => 149
N = 48 => No Termination
N = 49 => No Termination
N = 50 => Mismatched Braces
N = 51 => Mismatched Braces
N = 52 => 45
N = 53 => 77
N = 54 => 45
N = 55 => 77
N = 56 => 50
N = 57 => 209
N = 58 => 50
N = 59 => 251
N = 60 => 249
N = 61 => 99
N = 62 => 99
N = 63 => 117
N = 64 => 89
N = 65 => 207
N = 66 => 89
N = 67 => 115
N = 68 => 115
N = 69 => 115
N = 70 => 95
N = 71 => Mismatched Braces
N = 72 => Mismatched Braces
N = 73 => 104
N = 74 => Mismatched Braces
N = 75 => No Termination
N = 76 => No Termination
N = 77 => No Termination
N = 78 => No Termination
N = 79 => Left Overflow
N = 80 => 3
N = 81 => 2
N = 82 => No Termination
N = 83 => Mismatched Braces
N = 84 => No Termination
N = 85 => 133
N = 86 => 133
N = 87 => 0
N = 88 => Mismatched Braces
N = 89 => 158
N = 90 => 0
N = 91 => 4
N = 92 => Mismatched Braces
N = 93 => 0
N = 94 => 158
N = 95 => Mismatched Braces
N = 96 => 0
N = 97 => 157
N = 98 => 159
N = 99 => None

Il y a un total de 37 sorties uniques, qui sont (par ordre numérique):

0, 1, 2, 3, 4, 11, 13, 17, 45, 46, 50, 51, 57, 59, 77, 84, 89, 94, 95, 99,
100, 104, 115, 117, 129, 133, 147, 148, 149, 157, 158, 159, 166, 187, 188, 
196, 206, 207, 209, 211, 249, 251, 255

Je suis certain à 90% que cette solution n'est pas optimale , mais prouve que cela peut être extrêmement difficile . Il y a quelques choses qui sont claires. Ne pas avoir de .symboles avant le dernier caractère semble être la voie à suivre , et les crochets ( []) semblent plutôt inutiles . J'ai réfléchi un peu ici, que j'aimerais souligner:

Soit Lla longueur du code en octets (dans le défi, 100) et nle nombre de sorties uniques des sous-programmes.

Pour L=3, il existe plusieurs solutions optimales de la forme +-., où n=2(dans ce cas, les sorties sont 1 et 255 pour +.et -., respectivement.) Cela met le meilleur rapport pour L = 3à n/L = 66.67%. Notez que ce ratio ne peut pas être battu au moins L<10.

Pour L=10, les solutions sont assez simples pour le brutaliser. Voici toutes les meilleures solutions, sur n = 6:

++>-->+<+. => 6
++>-->+<+. => 6
+++>->+<+. => 6
--->->+<+. => 6
++>---><+. => 6
+++>--><+. => 6
-->++>-<-. => 6
+++>+>-<-. => 6
--->+>-<-. => 6
-->+++><-. => 6
--->++><-. => 6

Ce qui donne un rapport de score de n/L = 60%.

Comme L->infinity, il est clair que le rapport doit approcher 0, puisqu'il n'y a que 255 sorties possibles pour un potentiel infini L.

Cependant, le rapport ne diminue PAS uniformément. Il n'est pas possible de construire une solution pour n=6, L=9, donc le meilleur rapport possible pour L=9est 5/9 = 55.56% < 60%.

Cela soulève la question de savoir à quelle vitesse et dans quelle mesure le ratio diminue-t-il? Car L = 100, et à 10^9 checks/second, il faudrait plusieurs ordres de grandeur plus longs que la durée de vie de l'univers pour forcer brutalement une solution optimale. Y a-t-il une manière élégante de procéder? Je doute fort que ce soit 37%pour L = 100.

Le ratio augmente en fait, jusqu'à L=100. Consultez les autres réponses pour confirmer.

Je serais ravi d'entendre vos évaluations de ce qui précède. Je pouvais me tromper atrocement, après tout.

BrainSteel
la source