Un dérivé de Brainfuck
Définissons un langage de programmation simple de type Brainfuck . Il a une bande de cellules bidirectionnelle et chaque cellule contient un bit. Tous les bits sont initialement 0. Il y a une tête mobile sur la bande, initialement à la position 0. Un programme est une chaîne sur les caractères <>01!
, exécutée de gauche à droite, avec la sémantique suivante:
<
déplace la tête d'un pas vers la gauche.>
déplace la tête d'un pas vers la droite.0
met 0 dans la cellule courante.1
met 1 dans la cellule courante.!
retourne la cellule actuelle.
Il n'y a pas de boucles, donc un programme de n caractères se termine après exactement n étapes. Un programme est ennuyeux si toutes les cellules contiennent 0 à la fin de l'exécution et excitant s'il y en a au moins un. circulaire.
Un exemple de programme
Considérez le programme 1>>>!<<<<0>!>>>!
. Sur une bande infinie, l'exécution se déroule comme suit:
v
00000000000000 Put 1
v
00000100000000 Move by >>>
v
00000100000000 Flip
v
00000100100000 Move by <<<<
v
00000100100000 Put 0
v
00000100100000 Move by >
v
00000100100000 Flip
v
00000000100000 Move by >>>
v
00000000100000 Flip
v
00000000000000
À la fin, toutes les cellules sont à 0, donc ce programme est ennuyeux. Maintenant, exécutons le même programme sur une bande circulaire de longueur 4.
v
0000 Put 1
v
1000 Move by >>>
v
1000 Flip
v
1001 Move by <<<< (wrapping around at the edge)
v
1001 Put 0
v
1000 Move by > (wrapping back)
v
1000 Flip
v
0000 Move by >>>
v
0000 Flip
v
0001
Cette fois, il y a une cellule de valeur 1, donc le programme est passionnant! Nous voyons que si un programme est ennuyeux ou excitant dépend de la taille de la bande.
La tâche
Votre entrée est une chaîne non vide <>01!
qui représente un programme dans le langage de programmation ci-dessus. Un tableau de caractères est également un format d'entrée acceptable. Le programme est garanti d'être ennuyeux lorsqu'il est exécuté sur une bande infinie. Votre sortie sera la liste des longueurs de bande sur lesquelles le programme est passionnant. Notez que vous devez uniquement tester le programme sur des bandes plus courtes que la longueur du programme.
La solution avec le nombre d'octets le plus bas dans chaque langue est la gagnante. Les règles de code-golf standard s'appliquent.
Cas de test
> : []
110 : []
1>0<! : [1]
0>>1>0<<>! : [1]
1>>>!<<<<0>!>>>! : [2, 4]
!<!<><<0>!>!<><1!>>0 : [2]
>>!>><>001>0<1!<<!>< : [1, 2, 3]
1!><<!<<<!!100><>>>! : [1, 3]
!!1>!>11!1>>0<1!0<!<1><!0<!<0> : [3, 4]
<><<>>!<!!<<<!0!!!><<>0>>>>!>> : [1, 2, 4]
0>>><!<1><<<0>!>>!<<!!00>!<>!0 : [3]
0000!!!!><1<><>>0<1><<><<>>!<< : []
!>!>!>!>!>1>!>0<!<!<!<0<!<0<!<!<!<1>!>0<<! : [1, 2, 5, 7]
<!!>!!><<1<>>>!0>>>0!<!>1!<1!!><<>><0<<!>><<!<<!>< : [1, 2, 4, 5]
!>1<<11<1>!>!1!>>>0!!>!><!!00<><<<0<<>0<<!<<<>>!!> : [1, 2, 3, 5, 6]
<>01!
?Réponses:
Haskell, 119 octets
Essayez-le en ligne!
La fonction
#
est l'interpréteur d'une seule commandec
. L'ensemble du programmep
est exécuté enfold
ing#
avec la bande de départ dansp
.f
s'exécutep
pour chaque bande et conserve celles où la somme des cellules est d'au moins 1.la source
n<-[1..length p] ... 0<$[1..n]
semble assez long, il doit y avoir un chemin plus court.n
comme résultat, donc si vous avez construit0<$[1..n]
une manière différente (par exemple avecscanr(:)
), vous devez en prendrelength
. (J'ai également essayé d'utiliser1
(à remplacerlength
parsum
) ouFalse
(à utiliseror
pour le test) au lieu de0
, mais cela n'a pas été plus court.)n<-init$scanr(:)[]$0<$p ... n
ce qui est plus court de 2 octets, mais il retourne une liste de bandes de départ au lieu de leur longueur, par exemple[[0],[0,0,0]]
. Avec un peu de flexion des règles, les bandes peuvent être considérées comme des nombres unaires, alors peut-être que ça va.init$
peut être remplacé en mettant une[0]
liste initiale, mais elle n'est toujours pas assez courte. Je pense que l'unaire n'est autorisé que pour les langues sans représentation plus naturelle des nombres .Stax ,
5654433835 octets CP43742 octets une fois déballés,
Exécutez et déboguez en ligne!
-2 octets par commentaire de @recursive
Explication
J'utiliserai la version avec un préfixe
i
(iei%fz(y{{|(}{|)}{B!s+}{0_]e&}4ls"><! "I@!F|a
) pour expliquer et j'expliquerai pourquoi lei
peut être suppriméCode pour exécuter le programme:
la source
i
chèque.0]*
peut être remplacé parz(
. De plus, si vous changez la chaîne en "<>!", Alors0
et1
donnera l'index -1, de sorte que votre liste de blocs n'a besoin que de 4 blocs, au lieu de 5. Cela fonctionnera puisque les gestionnaires0
et1
sont de toute façon identiques.CJam ,
57564946 octets-7 grâce à @MartinEnder
Essayez-le en ligne!
la source
Perl 5 ,
83827977 octetsComprend
+3
pour-F
Donner des instructions en une seule ligne sur STDIN
Essayez-le en ligne!
la source
Perl 5 (
-F
), 101 octetsEssayez-le en ligne!
la source
Rouge , 243 octets
Essayez-le en ligne!
Mise en œuvre simple et verbeuse. L'indexation 1 de Red ne me permet pas de réduire le nombre d'octets en utilisant l'arithmétique modulaire pour parcourir les bandes circulaires.
Ungolfed
la source
Python 2 ,
139135133132131 131 octets-3 octets grâce à M. Xcoder
Essayez-le en ligne!
la source
Rétine , 121 octets
Essayez-le en ligne! Explication:
Créez un tableau de bandes de chaque longueur jusqu'à la longueur du programme d'entrée.
Boucle jusqu'à ce que le programme soit consommé.
Si le caractère suivant du programme est 0 ou 1, remplacez le premier caractère de chaque ligne par ce caractère.
Si c'est un,
!
basculez le premier caractère sur chaque ligne.S'il s'agit d'un
>
ou<
alors faites pivoter la ligne. (Plus facile que de bouger la tête.)Supprimez l'instruction et terminez la boucle.
Ne gardez que les lignes excitantes.
Comptez la longueur de chaque ligne.
la source
JavaScript (ES6),
126118 octetsSauvegardé 3 octets grâce à @ user71546
Prend l'entrée comme un tableau de chaînes de 1 caractère.
Essayez-le en ligne!
la source
t.some(x=>x)?
par à la+t.join``?
place, vérifiez le tableau sous forme de chiffres (et 0 indique une bande entièrement nulle), mais 3 octets de moins.APL (Dyalog Unicode) ,
796454 octets ( SBCS d'Adám )Essayez-le en ligne!
-15 merci à Adám (oublié monadique
⍸
).-10 grâce à ngn .
la source
↓
). Je vais l'examiner et mettre à jour. :)↓
vous aurez besoin d'un;
, non?MATL ,
4639 octetsEssayez-le en ligne! Ou vérifiez tous les cas de test .
Comment ça marche
la source
APL (Dyalog Unicode) ,
19278 octetsEssayez-le en ligne! (résultat non aplati)
Essayez-le en ligne! (aplati)
Après un certain temps passé à me cogner la tête contre le mur, j'ai décidé de faire un Tradfn au lieu d'un Dfn. Voilà le résultat. Des gens plus intelligents que moi pourront peut-être jouer au diable.Surprise, surprise, quelqu'un de plus intelligent que moi a joué au golf. Merci Adám pour 114 octets.
Il a dit:
La fonction suppose
⎕IO←0
.Comment?
(Cette explication utilise une version "non golfée" pour faciliter la lecture)
la source
t←l⍴0
bet←l⍴i←0
et en supprimant la ligne au-dessus. Vous pouvez également en enregistrer un autre en remplaçantt[i|⍨≢t]←1-t[i|⍨≢t]
part[i|⍨≢t]←~t[i|⍨≢t]
.∇
s?∇
? C'est une fonction tacite.Gelée , 41 octets
Essayez-le en ligne!
la source
C (clang) , 171 octets
Essayez-le en ligne!
J'ai dû utiliser clang, car l'utilisation
char*p,t[l=strlen(S)]
comme expression d'initialisation pour une raison quelconque fait penser à GCC que je veux déclarerstrlen
au lieu de l'appeler.Assez simple: exécute le programme sur des bandes circulaires de longueur décroissante, produisant n'importe quelle longueur qui a entraîné un 1 quelque part sur la bande.
Essayé de raccourcir l'enchevêtrement des opérateurs ternaires, mais a fini par avoir besoin de plus de parenthèses que ce qui était sain.
la source
i=0,bzero(t,l)
au lieu dememset(t,i=0,l)
et*p-62?t[i]=*p^33?*p-48:t[i]^1:(i=~i+l?i+1:0)
au lieu de*p==62?i=i^l-1?i+1:0:*p^33?t[i]=*p-48:(t[i]^=1)