Interpréter /// (prononcé «barres obliques»)

30

Parce que nous ne pouvons pas en avoir assez des golfs en langue ésotérique, n'est-ce pas?

/// - prononcé des barres obliques -est un langage peu amusant basé sur la s///fonction regex-remplacement de la renommée Perl. Il ne contient que deux caractères spéciaux, barre oblique /et barre oblique inverse \. Vous pouvez trouver un article complet à ce sujet sur le wiki esolangs , mais je vais reproduire une description du langage ci-dessous, ainsi que quelques exemples.

En bref, cela fonctionne en s'identifiant /pattern/repl/restdans le programme et en effectuant la substitution autant de fois que possible. Aucun caractère n'est spécial sauf /et \: /délimite les modèles et les remplacements dans le programme, tandis que \vous permet d'insérer des littéraux /ou des \caractères dans votre code. Notamment, ce ne sont pas des expressions régulières, juste des substitutions de chaînes simples.

Votre défi est de produire un interpréteur pour le langage ///, soit un programme lisant STDIN soit une fonction prenant un argument chaîne, en le moins de caractères possible.

Vous pouvez utiliser n'importe quelle langue à l'exception de /// lui-même. Vous ne pouvez utiliser aucune bibliothèque interprétant ///; vous pouvez cependant utiliser des expressions régulières, des bibliothèques d'expressions régulières ou des bibliothèques de correspondance de chaînes.


Exécution

Il existe quatre états: impression , motif , remplacement et substitution . Dans tous les états sauf substitution :

  • Si le programme est vide, l'exécution s'arrête.
  • Sinon, si le premier caractère est \, faites quelque chose avec le caractère suivant (s'il est présent) et supprimez les deux du programme.
  • Sinon, si le premier caractère est /, supprimez-le et passez à l'état suivant.
  • Sinon, faites quelque chose avec le premier caractère et supprimez-le du programme.
  • Répéter.

Les états font défiler l' impression , le motif , le remplacement et la substitution dans l'ordre.

  • En mode d' impression , «faire quelque chose» signifie sortir le caractère.
  • En mode modèle , «faire quelque chose» signifie ajouter le caractère au modèle actuel.
  • En mode de remplacement , «faire quelque chose» signifie ajouter le personnage au remplacement actuel.

En mode substitution , vous suivez un ensemble de règles différent. Remplacez à plusieurs reprises la première occurrence du modèle actuel par le remplacement actuel dans le programme, jusqu'à ce qu'aucune substitution ne soit possible. À ce stade, effacez le motif et le remplacement et revenez en mode d' impression .

Dans le programme /foo/foobar/foo foo foo, les événements suivants se produisent:

/foo/foobar/foo foo foo
foo foo foo
foobar foo foo
foobarbar foo foo
foobarbarbar foo foo
...

Cela boucle pour toujours et ne quitte jamais le mode de substitution . De même, si le Pattern est vide, la première occurrence de la chaîne vide - au début du programme - correspond toujours, donc le mode de substitution boucle pour toujours, sans jamais s'arrêter.


Exemples

no

Sortie: no.

/ world! world!/Hello,/ world! world! world!

Sortie: Hello, world!.

/foo/Hello, world!//B\/\\R/foo/B/\R

Sortie: Hello, world!.

a/ab/bbaa/abb

Sortie: a. Le programme ne s'arrête pas.

//

Sortie: aucune.

///

Sortie: aucune. Le programme ne s'arrête pas.

/\\/good/\/

Sortie: good.

Il y a aussi une quine sur le wiki que vous pouvez essayer.

algorithmshark
la source
/-/World//--/Hello//--W/--, w/---!Qu'est-ce qu'il n'y a pas à aimer? (Essayez de supprimer les tirets de la fin)
seequ
@Loovjo Le \ personnage échappe à tout personnage qui le suit, y compris /, qui peut ensuite être utilisé normalement. Bien que cela ne ressemble pas beaucoup, cela rend /// Turing-complet .
algorithmshark
Je pense que c'est une meilleure explication de la langue que l'article wiki d'esolangs. Va utiliser ces informations dans mon ///IDE que je fais!
clabe45

Réponses:

7

APL (133)

{T←''∘{(0=≢⍵)∨'/'=⊃⍵:(⊂⍺),⊂⍵⋄(⍺,N⌷⍵)∇⍵↓⍨N←1+'\'=⊃⍵}⋄⍞N←T⍵⋄p N←T 1↓N⋄r N←T 1↓N⋄''≡N:→⋄∇{⍵≡p:∇r⋄∨/Z←p⍷⍵:∇(r,⍵↓⍨N+≢p),⍨⍵↑⍨N←1-⍨Z⍳1⋄⍵}1↓N}

Il s'agit d'une fonction qui prend le ///code comme argument de droite.

Non golfé, avec explication:

slashes←{
   ⍝ a function to split the input string into 'current' and 'next' parts,
   ⍝ and unescape the 'current' bit
   split←''∘{
       ⍝ if the string is empty, or '/' is reached,
       ⍝ return both strings (⍺=accumulator ⍵=unprocessed)
       (0=≢⍵)∨'/'=⊃⍵:(⊂⍺),⊂⍵
       ⍝ otherwise, add current character to accumulator,
       ⍝ skipping over '\'s. (so if '\/' is reached, it skips '\',
       ⍝ adds '/' and then processes the character *after* that.)
       idx←1+'\'=⊃⍵
       (⍺,idx⌷⍵)∇idx↓⍵
   }

   ⍞   next ← split ⍵      ⍝ output stage
   pat next ← split 1↓next ⍝ pattern stage, and eat the '/'
   rpl next ← split 1↓next ⍝ replacement stage, and eat the '/'

   ⍝ if there are no characters left, halt.
   ''≡next:⍬

   ⍝ otherwise, replace and continue.
   ∇{  ⍝ if the input string equals the pattern, return the replacement and loop
       ⍵≡pat:∇rpl

       ⍝ otherwise, find occurences, if there are, replace the first and loop
       ∨/occ←pat⍷⍵:∇(rpl, (idx+≢pat)↓⍵),⍨ (idx←(occ⍳1)-1)↑⍵

       ⍝ if no occurences, return string
       ⍵

   }1↓next
}
marinus
la source
"s'il n'y a plus de personnages, arrête." Est-ce que cela fonctionne correctement sur ///et //foo/(c'est-à-dire en boucle pour toujours)?
algorithmshark
@algorithmshark: oui, dans cette situation, le /serait toujours laissé à ce point.
marinus
11

J - 181 190 170 char

Ce fut un cauchemar. Je l'ai réécrit à partir de zéro, deux fois, car il n'arrêtait pas de me déranger. Il s'agit d'une fonction prenant un seul argument de chaîne, sortie vers STDOUT.

(0&$`((2{.{:@>&.>)((j{.]),-i@=`p@.~:~/@[,]}.~#@p+j=.0{p I.@E.])i 5;@}.&,'/';"0;&.>)@.(2<#)@}.[4:1!:2~{:@>@p=.>@{.@[)@((0;(0,:~1 0,.2);'\';&<1 0)<;._1@;:'/'&,)i=. ::](^:_)

Pour l'expliquer, je vais le décomposer en sous-expressions.

i =. ::](^:_))
parse =: ((0;(0,:~1 0,.2);'\';&<1 0)<;._1@;:'/'&,)
print =: 4:1!:2~{:@>@p=.>@{.@[
eval  =: 0&$`((2{.{:@>&.>)sub 5;@}.&,'/';"0;&.>)@.(2<#)@}.
sub   =: ((j{.]),-i@=`p@.~:~/@[,]}.~#@p+j=.0{p I.@E.])i

interp =: (eval [ print) @ parse i
  • i(court pour itérer ) est un adverbe. Il prend un argument de verbe sur la gauche et renvoie un verbe (f)iqui, lorsqu'il est appliqué à un argument, s'applique à fplusieurs reprises à l'argument jusqu'à ce qu'une des deux choses se produise: il trouve un point fixe ( y = f y), ou il renvoie une erreur. Le comportement en virgule fixe est inhérent à ^:_, et ::]effectue la gestion des erreurs.

  • parsetokenise l'entrée dans ce que j'appelle une forme semi-analysée , puis la coupe au «/» non échappé. Il lie les contre-obliques qui s'échappent à leurs personnages, mais ne supprime pas les contre-obliques — nous pouvons donc soit le rétablir soit le terminer selon ce que nous voulons.

    La majeure partie du travail intéressant se produit en ;:. Il s'agit d'une primitive d'interpréteur de machine séquentielle, prenant une description de la machine ( (0;(0,:~1 0,.2);'\';&<1 0)) à gauche et quelque chose à analyser à droite. Cela fait la tokenisation. Je noterai que cette machine spécifique traite en fait le premier caractère non spécial, même si c'est un \et devrait se lier. Je le fais pour plusieurs raisons: (1) la table d'état est plus simple, donc elle peut être jouée plus loin; (2) nous pouvons facilement ajouter simplement un caractère factice à l'avant pour esquiver le problème; et (3) ce personnage factice est à moitié analysé sans frais supplémentaires, donc je peux l'utiliser pour configurer la phase de découpe, ensuite.

    Nous utilisons également <;._1pour couper le résultat symbolisé sur non échappé /(qui est ce que je choisis d'être le premier caractère). Ceci est pratique pour retirer la sortie, le modèle et le remplacement de out/patt/repl/resttout en une seule étape, mais malheureusement, coupe également le reste du programme, où nous avons besoin de ceux-ci /pour rester intacts. Je les épissure de nouveau pendant eval, car les <;._1laisser seuls finit par coûter beaucoup plus cher.

  • Le fork (eval [ print)s'exécute printsur le résultat de parsepour ses effets secondaires, puis s'exécute eval. printest un simple verbe qui ouvre la première boîte (celle dont nous savons à coup sûr qu'elle est sortie), termine l'analyse et l'envoie à STDOUT. Cependant, nous profitons également de l'occasion pour définir un verbe utilitaire p.

    pest défini comme >@{.@[, donc il prend son arg gauche (agit comme l'identité si on lui donne seulement un arg), prend le premier élément de cela (identité quand on lui donne un scalaire), et le déballe (identité s'il est déjà non boxé). Cela vous sera très utile sub.

  • evalévalue le reste du programme traité. Si nous n'avons pas de modèle complet ou de remplacement complet, le evaljette et renvoie simplement une liste vide, qui termine l'évaluation en faisant une erreur ;:(de parse) à la prochaine itération. Sinon, evalanalyse entièrement le motif et le remplacement, corrige le reste de la source, puis passe les deux à sub. Par explosion:

                                                  @}.  NB. throw out printed part
                                           @.(2<#)     NB. if we have a pattern and repl:
          2{.                                          NB.  take the first two cuts:
                 &.>                                   NB.   in each cut:
             {:@>                                      NB.    drop escaping \ from chars
         (          )                                  NB.  (these are pattern and repl)
                                       &.>             NB.  in each cut:
                                      ;                NB.   revert to source form
                                '/';"0                 NB.  attach a / to each cut
                              &,                       NB.  linearize (/ before each cut)
                         5  }.                         NB.  drop '/pattern/repl/'
                          ;@                           NB.  splice together
        (            sub                  )            NB.  feed these into sub
       `                                               NB. else:
    0&$                                                NB.  truncate to an empty list
    
  • subest l'endroit où un cycle (éventuellement infini) de substitutions se produit. En raison de notre configuration eval, la source est l'argument de droite et le modèle et le remplacement sont regroupés à gauche. Étant donné que les arguments sont ordonnés comme ceci et que nous savons que le modèle et le remplacement ne changent pas au sein d'un cycle de substitutions, nous pouvons utiliser une autre caractéristique de i-le fait qu'il modifie uniquement l'argument de droite et continue de passer dans la même gauche - pour déléguer à J la nécessité de s'inquiéter de garder une trace de l'état.

    Il y a cependant deux problèmes. Le premier est que les verbes J peuvent avoir au maximum deux arguments, nous n'avons donc pas de moyen facile d'accéder à ceux qui sont regroupés, comme le modèle et le remplacement, ici. Grâce à une utilisation intelligente de l' putilitaire que nous avons défini, ce n'est pas un gros problème. En fait, nous pouvons accéder au motif en un seul caractère, simplement en utilisant p, en raison de sa >@{.@[définition: la Unbox du premier élément de l'argument Left. Obtenir le remplacement est plus délicat, mais le moyen le plus court serait de p&|.2 caractères plus court que de le retirer manuellement.

    Le deuxième problème est que les isorties sur des points fixes au lieu de boucler pour toujours, et si le modèle et le remplacement sont égaux et que vous effectuez une substitution, cela ressemble à un point fixe pour J. Nous gérons cela en entrant une boucle infinie de négation de 1 sur et plus si nous détectons qu'ils sont égaux: c'est la -i@=`p@.~:~/partie, remplaçant p&|..

                                        p    E.]    NB. string search, patt in src
                                          I.@       NB. indices of matches
                                      0{            NB. take the first (error if none)
                                   j=.              NB. assign to j for later use
                               #@p+                 NB. add length of pattern
                           ]}.~                     NB. drop that many chars from src
                       /@[                          NB. between patt and repl:
                      ~                             NB.  patt as right arg, repl as left
                  @.~:                              NB.  if equal:
            -i@=                                    NB.   loop forever
                `p                                  NB.  else: return repl
     (j{.])                                         NB. first j chars of src
           ,              ,                         NB. append all together
    (                                           )i  NB. iterate
    
  • Ce cycle se répète en raison de l'utilisation de i, jusqu'à ce que quelque chose en dehors des suberreurs sorte. Pour autant que je sache, cela ne peut se produire que lorsque nous sommes à court de personnages, lorsque nous jetons un ensemble incomplet de modèle et de remplacement.

Faits amusants sur ce golf:

  • Pour une fois, l'utilisation ;:est plus courte que l'itération manuelle de la chaîne.
  • 0{devrait avoir une chance de sortir avant d' subentrer dans une boucle infinie, donc cela devrait fonctionner correctement si le motif correspond au remplacement mais n'apparaît jamais dans le reste de la source. Cependant, cela peut ou non être un comportement non spécifié, car je ne peux pas trouver de citation dans les documents. Whoopsie.
  • Les interruptions clavier sont traitées comme des erreurs spontanées dans les fonctions en cours d'exécution. Cependant, en raison de la nature de i, ces erreurs sont également bloquées. Selon le moment où vous appuyez sur Ctrl + C, vous pouvez:
    • Quittez la boucle negate-forever, erreur hors de la subboucle en essayant de concaténer un nombre dans une chaîne, puis continuez à interpréter /// comme si vous aviez fini de remplacer une chaîne par elle-même un nombre infini de fois.
    • Laisser à submi-chemin et continuer d'interpréter une expression /// semi-subbed.
    • Sortez de l'interpréteur et renvoyez un programme /// non évalué au REPL (pas STDOUT, cependant).

Exemple d'utilisation:

   f=:(0&$`((2{.{:@>&.>)((j{.]),-i@=`p@.~:~/@[,]}.~#@p+j=.0{p I.@E.])i 5;@}.&,'/';"0;&.>)@.(2<#)@}.[4:1!:2~{:@>@p=.>@{.@[)@((0;(0,:~1 0,.2);'\';&<1 0)<;._1@;:'/'&,)i=. ::](^:_)
   f 'no'
no
   f '/ world! world!/Hello,/ world! world! world!'
Hello, world!
   f '/foo/Hello, world!//B\/\\R/foo/B/\R'
Hello, world!
   f '//'  NB. empty string

   f '/\\/good/\/'
good
algorithmshark
la source
Sensationnel. J'appellerais cela masochiste. +1
seequ
Lorsque je lance ceci, j'obtiens la chaîne vide de chaque scénario de test. J'utilise jqt64, qu'utilisez-vous pour exécuter cela?
bcsb1001
@ bcsb1001 J'utilise directement le binaire jconsole (64 bits). En vérifiant jqt maintenant, j'obtiens réellement les résultats escomptés, sauf pour le /\\/good/\/cas de test; le débogage me dit que le problème est mon utilisation 1!:2&4, car jqt n'a pas stdin / out. Va enquêter. Quels sont vos 9!:12''et 9!:14''?
algorithmshark
@algorithmshark My a 9!:12''6 ans et 9!:14''est j701 / 2011-01-10 / 11: 25.
bcsb1001
4

Perl - 190

$|=1;$/=undef;$_=<>;while($_){($d,$_)=/(.)(.*)/;eval(!$e&&({'/','$a++','\\','$e=1'}->{$d})||('print$d','$b.=$d','$c.=$d')[$a].';$e=0');if($a==3){while($b?s/\Q$b/$c/:s/^/$c/){}$a=0;$b=$c=''}}

Lit le ///programme de stdin jusqu'à EOF.

faubi
la source
Est-ce qu'une approche dans le sens de la m/^(.*?)(?<!\\)\/(.*?)(?<!\\)\/(.*?)(?<!\\)\/(.*)$/ssortie, du modèle et du remplacement des matchs à la fois ferait un golf plus court? Je ne connais aucun Perl, moi-même.
algorithmshark
Je crois que cela échoue avec/a/\0/a
Asone Tuhid
3

Pip , 100 102 octets

Je n'avais jamais prouvé que Pip était complet de Turing (bien que ce soit évidemment le cas), et au lieu de suivre la voie habituelle de BF, je pensais que /// serait intéressant. Une fois que j'ai eu la solution, j'ai pensé que je jouerais au golf et la posterais ici.

101 octets de code, +1 pour l' -rindicateur:

i:gJnf:{a:xW#i&'/NE YPOia.:yQ'\?POiya}W#iI'\Q YPOiOPOiEIyQ'/{p:VfY0s:VfIyQ'/WpNi&YviR:Xp{++y?ps}}E Oy

Voici ma version non golfée avec de nombreux commentaires:

; Use the -r flag to read the /// program from stdin
; Stdin is read into g as a list of lines; join them on newline and assign to c for code
c : gJn

; Loop while c is nonempty
W #c {
 ; Pop the first character of c and yank into y
 Y POc
 ; If y equals "\"
 I yQ'\
  ; Pop c again and output
  O POc
 ; Else if y equals "/"
 EI yQ'/ {
  ; Build up pattern p from empty string
  p : ""
  ; Pop c, yank into y, loop while that is not equal to "/" and c is nonempty
  W #c & '/ NE Y POc {
   ; If y equals "\"
   I yQ'\
    ; Pop c again and add that character to p
    p .: POc
   ; Else, add y to p
   E p .: y
  }

  ; Yank 0 so we can reliably tell whether the /// construct was completed or not
  Y0
  ; Build up substitution s from empty string
  s : ""
  ; Pop c, yank into y, loop while that is not equal to "/" and c is nonempty
  W #c & '/ NE Y POc {
   ; If y equals "\"
   I yQ'\
    ; Pop c again and add that character to s
    s .: POc
   ; Else, add y to s
   E s .: y
  }

  ; If the last value yanked was "/", then we have a complete substitution
  ; If not, the code must have run out; skip this branch, and then the outer loop
  ; will terminate
  I yQ'/ {
   ; While pattern is found in code:
   W pNc {
    ; Set flag so only one replacement gets done
    i : 0
    ; Convert p to a regex; replace it using a callback function: if ++i is 1,
    ; replace with s; otherwise, leave unchanged
    c R: Xp {++i=1 ? s p}
   }
  }
 }
 ; Else, output y
 E Oy
}

Essayez-le en ligne! (Notez que TIO ne donne aucune sortie lorsque le programme ne se termine pas, et il a également une limite de temps. Pour des exemples plus grands et des boucles infinies, il est recommandé d'exécuter Pip à partir de la ligne de commande.)

DLosc
la source
Je pense que cela devrait être pip + -r, 101 octets
Asone Tuhid
3

C ++: Visual C ++ 2013 = 423, g ++ 4.9.0 = 442

Cela ne gagnera jamais mais comme j'ai décidé que tous mes futurs projets logiciels seront écrits dans ce langage génial, j'avais besoin d'un interprète pour cela et je me suis dit que je pourrais aussi bien partager celui que j'ai fait ...

La différence de score est que Visual C ++ n'a pas besoin du premier include mais g ++ en a besoin. Le score suppose que les fins de ligne comptent pour 1.

#include<string.h>
#include<string>
#define M(x)memset(x,0,99);
#define P o[i])
#define N(x)P;else if(n<x)(P==92?
#define O (o[++i]):(P==47?n++:
#define S std::string
int main(int n,char**m){S o=m[1];char p[99],*q=p,r[99],*s=r;M(p)M(r)for(int i=0,t;i<=o.size();++i){if(!N(3)putchar O putchar(N(4)*q++=O(*q++=N(5)*s++=O(*s++=P;if(n>4){for(;;){if((t=o.find(p,i+1))==S::npos)break;o=o.substr(0,t)+r+o.substr(t+strlen(p));}M(p)M(r)n=2;q=p;s=r;}}}
Jerry Jeremiah
la source
1
Pouvez - vous réécrire if(!o[i]);comme if(Ppour sauver les caractères, ou je comprends mal comment fonctionne #define?
algorithmshark
@algorithmshark comment ai-je raté ça?! si (! P est parfait. Je vais le changer.
Jerry Jeremiah
Chaque instance de Pin maina un espace après, vous pouvez donc enregistrer un caractère en remplaçant ces espaces par des points-virgules et en les supprimant #define. Ensuite, si vous pouvez utiliser des #defines à l'intérieur d'autres, vous pouvez en économiser davantage en réécrivant N(x)as (92==Pau lieu de o[i]==92et de Omême.
algorithmshark
@algorithmshark, vous êtes évidemment beaucoup mieux que moi. Merci pour l'aide.
Jerry Jeremiah
Je sais que cela remonte à environ quatre ans, mais la réécriture au N(x)fur P;else if(n<x)(P==92?et à mesure que les appels changent en Nconséquence pourrait économiser quelques octets.
Zacharý
2

Python 2 (236), Python 3 (198?)

from __future__ import print_function
def d(i):
 t=0;p=['']*3+[1]
 while i:
  if'/'==i[0]:t+=1
  else:
   if'\\'==i[0]:i=i[1:]
   p[t]+=i[0]
  i=i[1:]
  print(end=p[0]);p[0]=''
  if t>2:
   while p[1]in i:i=i.replace(*p[1:])
   d(i);i=0

Appelé comme d(r"""/foo/Hello, world!//B\/\\R/foo/B/\R"""). Les guillemets triples ne sont nécessaires que si le ///programme contient des retours à la ligne: sinon les guillemets simples sont corrects.

EDIT: Cet interpréteur imprime maintenant les choses comme prévu (auparavant, il ne s'imprimait qu'à la toute fin, cf. commentaires). Pour Python 3, supprimez la première ligne (mais je n'ai pas Python 3 sur mon ancienne installation, donc je ne peux pas être sûr qu'il n'y a pas d'autre changement).

Bruno Le Floch
la source
l'interprète n'imprime rien tant que la résiliation est problématique. l'écriture d'une boucle infinie dans /// est possible, donc votre interprète échoue sur les programmes qui ne se terminent pas mais qui impriment toujours quelque chose.
fier haskeller
@proudhaskeller Fixed.
Bruno Le Floch
En fait, ce n'est pas fixe, il n'imprime rien pour /a/ab/bbaa/abb.
Beta Decay
@BetaDecay /a/ab/bbaa/abbrestera coincé dans une boucle sans fin sans rien imprimer, car la première substitution est a=> ab. Le bon a/ab/bbaa/abbfonctionne comme annoncé.
algorithmshark
@BetaDecay: outre la modification suggérée par algorithmshark, vous devrez peut-être inclure l'option de ligne de commande -upour forcer le tampon de sortie à ne pas être tamponné.
Bruno Le Floch
2

Cobra - 226

sig Z as String
def f(l='')
    m=Z(do=[l[:1],l=l[1:]][0])
    n as Z=do
        if'/'<>(a=m())>'',return if(a=='\\',m(),a)+n()
        else,return''
    print n()stop
    p,s=n(),n()
    if''<l
        while p in l,l=l[:l.indexOf(p)+1]+s+l[p.length:]
        .f(l)
Οurous
la source
2

Rubis , 119110 octets

Se termine avec exception

r=->s,o=$>{s[k=s[0]]='';k==?/?o==$>?s.gsub!([r[s,''],e=r[s,'']][0]){e}:t=o:o<<(k==?\\?s[0]+s[0]='':k);t||redo}

Essayez-le en ligne!

Se termine proprement (116 octets)

r=->s,o=$>{s[k=s[0]||exit]='';k==?/?o==$>?s.gsub!([r[s,''],e=r[s,'']][0]){e}:t=o:o<<(k==?\\?s[0]+s[0]='':k);t||redo}

Essayez-le en ligne!

Asone Tuhid
la source
1

Python 2/3 (211 octets)

Le code suivant, basé sur la réponse de Bruno Le Floch , est compatible Python 2 et Python 3.

De plus, étant itératif plutôt que récursif, il ne risque pas d'atteindre la profondeur de récursivité maximale de Python.

def S(c):
 while c:
  B=["","",1]
  for m in 0,1,2:
   while c:
    if"/"==c[0]:c=c[1:];break
    if"\\"==c[0]:c=c[1:]
    if m:B[m-1]+=c[0]
    else:yield c[0]
    c=c[1:]
  while c and B[0]in c:c=c.replace(*B)
Carlos Luna
la source
Bonjour et bienvenue chez PPCG. Vous pouvez jouer in(0,1,2)au golf vers in 0,1,2et [""]*2+[1]vers ["","",1], ce qui donne 211 octets .
Jonathan Frech
J'ai lié à la réponse référencée et ajouté le mot "octets". Si vous n'êtes pas d'accord avec ma modification, n'hésitez pas à revenir en arrière.
Jonathan Frech
Merci Jonathan, vos suggestions sont les bienvenues!
Carlos Luna
0

BaCon , 391 387 395 octets

À partir des contributions sur cette page, je n'ai obtenu que le programme Python. Les autres fonctionnent pour certains /// échantillons, ou ne fonctionnent pas du tout. J'ai donc décidé d'ajouter ma version, qui est une implémentation en BASIC.

Participer à un concours CodeGolf avec BASIC n'est pas facile, car BASIC utilise des mots longs comme déclarations. La seule abréviation couramment trouvée dans BASIC est le «?» signe, ce qui signifie IMPRIMER.

Ainsi, le programme ci-dessous peut ne jamais gagner, mais au moins il fonctionne avec tout le code de démonstration sur cette page Codegolf et sur le Wiki Esolangs . Y compris toutes les versions des "99 bouteilles de bière".

p$=""
r$=""
INPUT i$
WHILE LEN(i$)
t$=LEFT$(i$,1)
i$=MID$(i$,2)
IF NOT(e) THEN
IF t$="\\" THEN
e=1
CONTINUE
ELIF t$="/" THEN
o=IIF(o<2,o+1,0)
IF o>0 THEN CONTINUE
FI
FI
IF o=1 THEN
p$=p$&t$
ELIF o=2 THEN
r$=r$&t$
ELIF o=0 THEN
IF LEN(p$) THEN i$=REPLACE$(i$,p$,r$)
IF NOT(INSTR(t$&i$,"/")) THEN
?t$;
BREAK
ELSE
?LEFT$(i$,INSTR(i$,"/")-1);
i$=MID$(i$,INSTR(i$,"/"))
FI
p$=""
r$=""
FI
e=0
WEND
?i$
Peter
la source
Ajout d'une instruction INPUT pour obtenir les entrées de l'utilisateur.
Peter