Veuillez noter: De par sa nature, les spécifications de ce défi sont difficiles à comprendre. Cela nécessite probablement au moins un cours de première année en théorie de la calculabilité, ou une lecture de fond équivalente. De plus, le défi lui-même est plutôt difficile. Pour y répondre, il faudra écrire un interprète entier pour un sous-ensemble de la langue de votre choix, et non seulement cela, mais l'interprète devra être sous la forme d'un quelque chose comme une quine. Si votre réponse ne fait pas tout cela, il est presque certain de ne pas répondre aux spécifications.
Vous n'avez pas besoin de résoudre le problème d'arrêt (même partiel) pour résoudre ce défi. Cependant, vous certainement faire besoin d'écrire un interprète (de la langue que vous utilisez, écrit dans la même langue , il interprète), mais il ne doit pas être fonction complète. C'est cela qui en fait un défi intéressant.
J'ai promis d'accorder une prime de 500 points à la première réponse qui répond aux spécifications, et cela sera attribué à la réponse BF de Jo King .
Le défi
Une version approximative et simplifiée de la preuve d'Alan Turing de l'insolvabilité du problème d'arrêt ressemble à ceci:
Supposons que j'ai écrit un programme F
destiné à résoudre le programme d'arrêt. Autrement dit, F
prend le code source d'un autre programme en entrée et F(G)
est censé retourner 1
si G
s'arrête, et 0
sinon.
Mais si je vous donne mon programme, F
vous pouvez construire un autre programme H
, qui exécute mon programme avec H
comme entrée. Si F(H)
retourne 0
alors H
retourne 0
, mais sinon il va délibérément dans une boucle infinie. Cela conduit à un paradoxe, et nous devons conclure que F
ne peut pas résoudre le problème de l'arrêt après tout.
Votre tâche consiste à écrire le programme H
, mais avec une torsion: je ne vais pas vous donner mon programme. Au lieu de cela, votre programme recevra le code source de mon programme en entrée. C'est:
Votre programme recevra mon programme en entrée, sous forme de code source. (Par exemple, sous forme de fichier ou d'entrée de ligne de commande, les détails vous appartiennent.)
Mon programme sera écrit dans la même langue que votre programme et prendra également la forme d'une chaîne de code source.
Si mon programme revient
0
quand on lui donne son programme en entrée, votre programme devrait s'arrêter (et retourner0
) quand on lui donne mon programme en entrée. (La signification exacte de "returing0
" dépend de vous.)si mon programme ne s'arrête pas, ou s'il renvoie autre chose que
0
lorsqu'il est donné à votre programme en entrée, votre programme devrait continuer à fonctionner indéfiniment.
La torsion est que, juste pour le rendre vraiment beaucoup plus difficile, vous devez obéir aux règles suivantes:
Vous ne pouvez utiliser aucun type de fonction intégrée
exec
ou deeval
type.Vous ne pouvez pas utiliser de méthodes de "triche" pour obtenir le code source de votre propre programme. (Par exemple, vous ne pouvez pas dire «enregistrez-le dans un fichier appelé« programme »», puis
open(program)
dans votre programme.)
Cela signifie que votre programme doit être une sorte de super-quine folle qui peut non seulement reproduire son propre code source sous la forme d'une chaîne, mais est également capable d'analyser et d'interpréter correctement la langue dans laquelle il est écrit.
Pour le rendre un peu moins incroyablement difficile, vous êtes autorisé à utiliser juste un sous-ensemble (Turing-complet) de votre langue choisie. Donc, si votre programme est écrit en Python et ne fonctionnera que si mon programme ne contient que des if
s et des while
boucles et des opérations de chaîne de base, alors c'est OK tant que votre programme n'utilise que ces choses aussi. (Cela signifie que vous n'avez pas à vous soucier de l'implémentation de la bibliothèque standard de votre langue choisie!) Cependant, votre programme doit réellement s'exécuter - vous ne pouvez pas simplement créer votre propre langue.
C'est un concours de popularité , donc la réponse avec le plus de votes l'emporte. Cependant, comme mentionné ci-dessus, c'est un défi sérieux de répondre à la spécification, donc j'accorderai une prime de 500 points à la première réponse qui le fait selon mon jugement.
s'il vous plaît noter: sans aucun doute, il existe de nombreuses façons de "tricher" à ce défi, compte tenu de la formulation exacte que j'ai utilisée. Cependant, j'espère vraiment des réponses qui entrent dans l'esprit de la question. Le défi comme prévu est très difficile mais possible, et j'espère vraiment y trouver de véritables solutions. Je n'accorderai pas la prime à une réponse qui semble trompeuse à mon avis.
Remarque: ce défi a été initialement publié comme concours de popularité , mais il a été fermé en 2016 en raison de l'absence de "critère de gain objectif", et je l'ai changé en code-golf afin de le rouvrir. Cependant, j'ai découvert qu'en janvier 2018, les concours de popularité ne sont en fait pas interdits sur PPCG ( ce qui est la plus récente méta-discussion), donc la fermer en premier lieu était contraire à la politique du site. Je comprends que les popcons ne sont pas populaires de nos jours, mais c'est un vieux défi, et sa nature le rend vraiment inapproprié pour le code-golfsystème de notation. Si quelqu'un croit toujours fermement que cela ne devrait pas être autorisé, nous allons avoir une méta-discussion avant de commencer à voter. Enfin, au cas où une personne aurait passé la dernière année à essayer sa solution, soyez assuré qu'elle sera tout aussi compétitive dans ce défi et tout aussi digne de la prime qu'elle l'aurait été dans le code-golf version.
la source
F
dans un fichier et de l'import
intégrer? ; 3Réponses:
brainfuck ,
601348774376 octetsModifier: -1136 octets. Passé à une meilleure façon de générer les données pour le quine
Edit2: -501 octets. Revisité mon auto-interprète et coupé quelques centaines d'octets
Essayez-le en ligne! L'entrée ici est un simple programme cat (
,[.,]
) qui imprimera le programme lui-même."Retour 0" est défini en terminant le programme sur une cellule avec la valeur 0.
Une combinaison impie de deux programmes que j'ai écrits dans le passé, un quine et un auto-interprète. La première section est la partie quine, qui prend les données et remplit la bande avec la génération de données suivie du code source. Vient ensuite l'auto-interprète, qui prend votre programme et l'exécute. Il s'agit à peu près d'une copie inchangée d'un auto-interprète normal, sauf qu'au lieu de prendre directement une entrée, il obtient une entrée depuis le début de la section de données, définissant la cellule sur 0 s'il n'y a plus d'entrée. Enfin, terminez sur la cellule actuelle de votre programme et exécutez
[]
. Si la valeur retournée était 0, mon programme se terminera sur zéro. Si c'est autre chose, il exécutera une boucle infinie. Si votre programme fonctionne pour toujours,mon programme fonctionnera pour toujours.Comment ça marche:
Partie 1: Génération de données
Cette partie constitue la section de données du quine, et est de loin la majorité du code à 3270 octets. Le début
-
est un marqueur pour le début des données. Chacun>+++
représente un caractère du code après cette section.Partie 2: générer la section de données à l'aide des données
Cela utilise les données de la première partie pour ajouter les caractères utilisés pour générer les données dans la section de code. Il ajoute un
>
à la fin de la section de code et la valeur de cette cellule de nombreux avantages.Partie 3: générer le reste du code en utilisant les données
Détruit la section de données et ajoute le reste du code source à la section de code
Partie 4: Obtenez le programme saisi
Obtient le programme entré. Supprime les caractères non-brainfuck et représente chaque personnage avec un nombre:
Représente la fin du programme avec
255
.Partie 5: Interpréter l'entrée
Interprète le programme. La seule différence par rapport à une normale est que l'entrée est prise depuis le début de la section de code au lieu de l'entrée.
Partie 6: Arrêtez si le retour n'est pas 0
Accédez à la dernière cellule de votre programme et exécutez une boucle infinie si le retour n'est pas 0. S'il est 0, quittez la boucle et terminez sur ce même 0.
Entrées de test:
Retourne toujours 0 (arrête et retourne 0)
Renvoie toujours 1 (fonctionne pour toujours)
Renvoie toutes les entrées ajoutées ensemble, mod 256 (renvoie 211, donc il fonctionne pour toujours)
Retourne 0 si les deux derniers caractères d'un code sont une boucle infinie (
[]
) ( votre programme retourne 0 quand on me donne mon programme , donc mon programme s'arrête)Fait amusant pour ceux qui lisent encore
Si l'entrée de ce programme est le code source de ce programme, alors il commencera à se reproduire, créant à plusieurs reprises des auto-interprètes qui exécutent ce programme et lui donneront ensuite le même programme. Cela me donne quelques idées intéressantes sur la création de programmes récursifs réels dans brainfuck. Au lieu de vérifier la valeur de retour et de démarrer une boucle infinie comme dans cette question, la valeur de retour peut être enregistrée et traitée. Un exemple simple serait un programme factoriel qui va
Bien sûr, c'est une façon complètement folle de coder le brainfuck, étant donné que l'exécution d'auto-interprètes récursifs augmentera le temps d'exécution de manière exponentielle.
la source
.
. Bien que ce ne soit plus une question de code-golf, la prise en charge de l'ensemble du langage peut être plus impressionnante.