RLE Brainfuck dialect


14

RLE Brainfuck

(lié à BF-RLE )

L'hypothétique dialecte RLE ( Run-Length Encoding ) de Brainfuck accepte les symboles pour les 8 commandes et accepte également les chiffres. Les chiffres sont utilisés pour représenter le nombre de répétitions successives d'une commande, permettant ainsi le codage sur toute la durée du code source.

8>est égal à >>>>>>>>.

La longueur est toujours sur le côté gauche de la commande.

Votre tâche consiste à écrire le programme / la fonction la plus courte qui traduit la chaîne d'entrée (fragment RLE Brainfuck) en un programme Brainfuck normal.

Par exemple:

Contribution:

10+[>+>3+>7+>10+4<-]3>2+.>+.7+2.3+.2<2+.>15+.>.3+.6-.8-.2<+.<.

Ouptut:

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

Le code le plus court en nombre d'octets dans chaque langue gagnera.


10
Bonjour, j'ai rétrogradé cette question parce que je pense qu'elle va être dominée par un ou deux algorithmes de regex basés sur RLE qui sont ensuite simplement copiés dans le formatage de regex individuel de chaque langue. Il y a très peu de place pour jouer au golf ici.
AdmBorkBork

13
Cela ressemble beaucoup à un défi générique de décodage de longueur d'exécution . La différence ici est que les numéros à plusieurs chiffres sont pris en charge. Je pense que c'est toujours dupe, mais je ne vais pas le marteler.
2017

4
@xnor L'autre différence est que les chiffres ne sont pas toujours présents - cette forme de RLE garantit beaucoup moins de structure, et IMO peut conduire à des techniques intéressantes (comparer ma réponse Python ici avec celle du défi lié!)
Lynn

1
@Lynn Je ne l'ai pas explicitement décrit, mais comme on le voit dans l'exemple, 1 est omis; l'ajout de 0 ne raccourcit pas la chaîne, donc la réponse est non, aucun zéro ne peut ajouter une commande.
Galen Ivanov

6
L'autre direction serait plus intéressante, je pense (c'est-à-dire transformer un programme de brainfuck en programme de brainfuck RLE équivalent le plus court).
Paŭlo Ebermann

Réponses:


24

Python 2 , 62 61 octets

lambda s:eval(re.sub('(\d*)(.)',r'+1*\1*1*"\2"',s))
import re

Essayez-le en ligne!

La substitution d'expression régulière se développe 3<2+-dans la chaîne:

+1*3*1*"<"+1*2*1*"+"+1**1*"-"

qui est ensuite evaléd. (Notez comment quand \1est vide, nous obtenons 1**1 = 1.) Le premier +est un opérateur unaire qui se lie au premier nombre, et les autres +s sont la concaténation de chaînes. Cela bat le plus évident

lambda s:re.sub('(\d+)(.)',lambda m:int(m.group(1))*m.group(2),s)
import re

de 14 octets. Normalement, "\2"cela ne fonctionnerait pas toujours, mais heureusement \, ce "ne sont pas des commandes de cerveau.


xnor a enregistré un octet, fournissant l' 1*\1*1astuce. Auparavant, je l'avais \1Ldans l'expression régulière, et défini L=1comme un argument lambda, qui est également assez cool: 3Lest un littéral long int et Lest une variable.


1
C'est une utilisation astucieuse de Lpour gérer la chaîne vide. Il y a un chemin plus court cependant r'+1*\1*1*"\2"'.
xnor

3
... Pourquoi est en import redessous de la lambda?
Fund Monica's Lawsuit

1
Mettre le lambda en premier signifie que je peux utiliser la fonction Header / Footer de tio.run pour montrer comment le code est censé être appelé (j'ai mis f=\ le Header - maintenant le lambda a un nom!)
Lynn

18

Pyth , 2 octets

r9

Essayez-le ici!

Comment ça fonctionne

r9 - Programme complet recevant la chaîne de STDIN.

r - Ensemble d'opérations de chaîne étendue de Pyth.
 9 - La neuvième commande de cet ensemble (décodage de durée). Cela prend en charge les numéros à plusieurs chiffres.

31
Rappel nécessaire: arrêtez de voter des solutions triviales (comme celle-ci).
M. Xcoder

4
Ce n'est pas si trivial de connaître cette commande et de savoir qu'elle fonctionne lorsque des chiffres manquent
Luis Mendo

1
@ Mr.Xcoder Attendez, quoi? N'est-ce pas le point de golf entier qui a le plus petit nombre d'octets?
Deacon

4
@Deacon oui, mais une réponse Python jouée au golf est généralement beaucoup plus difficile à faire et plus intéressante qu'une réponse golflang à 2 octets.
Stephen

8
@Deacon Upvoting ne concerne pas uniquement les solutions courtes de vote ascendant. Les utilisateurs sont généralement encouragés à voter pour des solutions intéressantes et créatives, par opposition à des solutions courtes triviales dans les langues de golf.
LyricLy

17

Lua, 65 64 63 octets

Génial ! Pour une fois, Lua bat Python!

Edit: Sauvegardé un octet grâce à @Jarhmander, merci à lui pour l'astuce utile pour forcer un seul résultat

print(((...):gsub("(%d+)(.)",function(a,b)return b:rep(a)end)))

Essayez-le en ligne!

Explications

print)((...):gsub(             -- iterate over the argument and replace the strings
            "(%d+)(.)",       -- matching this pattern (at least one digit and a non-digit)
            function(a,b)     -- capture the digit and non-digit parts in separate variables
              return b:rep(a) -- repeat the non-digit a times, a being the digit part
            end)))                    


@Lynn Un octet de moins, 3 de plus à parcourir!
Katenkyo

Vous pouvez enregistrer un octet en supprimant ,""et en mettant entre parenthèses l'intégralité de l'argument d'impression. Les expressions entre parenthèses sont ajustées à une valeur en Lua (voir lua.org/manual/5.3/manual.html#3.4 ).
Jarhmander



8

vim, 29 25 23 22 16 octets

:s/\D/a&<C-v><ESC>/g
D@"

<C-V>est 0x16, <ESC>est 0x1b.

Il fonctionne en remplaçant chaque non-chiffre par une commande qui ajoute ce caractère au tampon. Les comptes sont laissés seuls et modifient ces commandes. À ce stade, le tampon est un programme vimscript qui produit le programme Brainfuck souhaité, nous le tirons donc dans un registre et l'exécutons.

Essayez-le en ligne!

Edit: Réductions de taille grâce aux suggestions: H.PWiz: 5, TheFamilyFroot: 5, DJMcMayhem: 1


TheFamilyFroot avait une bonne astuce de golf: vous n'avez pas besoin d'utiliser un groupe de capture, vous pouvez simplement utiliser le groupe 0 (&ou\0) à la place sans parenthèses. En outre, un bout de moi, pas TheFamilyFroot est que vous pouvez utiliserDlieu deddpour-1octet.
James

1
Merci pour toutes les suggestions, H.PWiz, TheFamilyFroot et DJMcMayhem. Cela l'a amené en dessous de la solution Perl de 18 octets et à la deuxième place. Maintenant, nous avons juste besoin de trouver 15 autres octets dont nous pouvons nous débarrasser et cela battra le Python intégré. :-)
Ray

8

RLE Brainfuck, 204 octets

-3>,[[->+>+<<]>>47-3<10+<->[-<+4>->+<[>-]>[3<+<[-]4>->]5<]3>57+[-]+<<[>>-<<[3>+3<-]]3>[3<+3>-]<[>>+7<+[->11-<+[-<+]->>+[-<[->10+<]>>+]<[-4>.4<]4>[-]-3<-<+7>-7<[8>+8<-]]8>[8<+8>-]<[3<.3<[-]-6>-]7<--5>-]<,]

Si je comprends bien, les spécifications de l'environnement brainfuck ne sont pas très bien définies. Ce programme suppose que les cellules de la bande autorisent des entiers positifs et négatifs arbitrairement grands, sans débordement. Ce code transcrira également les commentaires non liés aux commandes, mais il étendra l'encodage de la durée des commentaires (par exemple, "voir 3b" → "voir bbb"). Le programme résultant devrait fonctionner de la même manière, donc je ne suis pas trop inquiet.

Je suis sûr que je pourrais encore jouer au golf à quelques octets, mais je suis épuisé de travailler avec.

Voici l'interpréteur personnalisé + tests que j'ai utilisé pour le tester. Si vous passez cette entrée dans la zone Entrée standard, elle doit s'exécuter sur cette entrée au lieu d'exécuter les tests.

Mon workpad désordonné et désordonné:

->>>,
[
  [->+>+<<]>>  clone 2 into 3 and 4
  if read char is between zero and nine
  (num buffer | max | is_digit | original char | read | temp0 | temp1)
                                                   ^
  47-
  <<<10+  set max
  <->  handle gross 0 case
  [  while max
    -  max minus one
    <+  buffer plus one
    >>>>-  read minus one
    IF STATEMENT : if read is 0
    >+<
    [>-]>[<
      <<+  is_digit = 1
      <[-]>>>  max = 0
    >->]<<  back to read
    <<<     back to max
  ]

  >>>57+[-]  reset `read` (need to add first to avoid infinite negative)

  +<<  check is_digit flag
  ( end marker | 0 | is_digit | original char | temp0 | temp1 | temp2 | temp3)
  x[  IF READ WAS DIGIT
    CODE 1a
    >>temp0 -<<x
    [>>>temp1 +<<<x-]
  ]
  >>>temp1 [<<<x+>>>temp1 -]
  <temp0 [
    START CODE 2a
    >>temp2 +
    7<y+[  IF THERE IS A NUMBER PREFIX
      -
      START CODE 1b
      >11-  end marker is negativeone
      <   on smallest digit
      +[-<+]->  find largest digit
      >+[  sum digits until we hit the end marker negativeone
        -
        <[->10+<]>  h1 = ten * h0; h0 = 0
        >
        +
      ]  leave the negativeone at zero though
      num | 0 | 0 | 0 | original char
            ^
      <num
      [->>>>.<<<<]  print `original char` `num` times
      >>>>[-]-  set `char` to negativeone
      <<<- last ditch guess
      END CODE 1b
      <y+
      7>temp2 -
      7<y[8>temp3 +8<y-]
    ]
    8>temp3 [8<y+8>temp3 -]
    <temp2 [
      CODE 2b
      <<<.  print original char
      <<<[-]-  set num buffer to new left edge
      >>>>>>temp2 -
    ]
    7<y--

    END CODE 2a
    5>temp0 -
  ]
  <
  ,
]

Le cas 0 brut fait-il uniquement référence à un comptage nul réel, ou se produit-il également lors de l'analyse, par exemple 10+? L'OP a précisé dans un commentaire que le nombre sera toujours supérieur à 0, donc vous pourriez être en mesure de raser certains octets si c'est le premier.
Ray

Le cas 0 brut sert à analyser n'importe quel 0. Étant donné que la while maxboucle s'exécute toujours au moins une fois et que je monte inconditionnellement le tampon dans lequel je stocke la valeur du chiffre dans cette boucle, je dois démarrer ce tampon à -1. Je me demande si je pourrais économiser quelques octets en laissant ce tampon logiquement à value+1though
Orez

6

Empilé , 24 octets

['(\d+)(.)'[\#~*]3/repl]

Essayez-le en ligne!

Explication

['(\d+)(.)'[\#~*]3/repl]
[                      ]   anonymous function, taking string as argument
 '(\d+)(.)'                for all matches of this regex:
           [    ]3/repl      replace (stack = (whole match, digit, repetend))
            \#~              convert digit to number
               *             repeat the character by that digit

5

TeX, 124 octets

\newcount\n\def\b{\afterassignment\r\n0}\def\r#1{\ifx;#1\else\p#1\expandafter\b\fi
}\def\p#1{#1\ifnum\n>1\advance\n-1\p#1\fi}

(écrit en deux lignes pour être visible, mais le code peut être écrit en une seule ligne)

Cela définit une macro \bqui prend l'entrée dans le formulaire \b<input>;et imprime la sortie souhaitée dans le document.


5

Rétine , 28 23 octets

merci à @Leo pour -5 octets

\d+
$*
+`1(1\D)
$1$1
1

Essayez-le en ligne!


Pouvez-vous utiliser \bdans le deuxième regex pour correspondre à un seul 1par série de 1s?
Neil

Ou vous pourriez faire quelque chose comme ça
Leo

4

Pyon , 66 octets

print(re.sub("\d+.",lambda k:(int(k.group()[:-1])*k.group()[-1]),a

Essayez-le en ligne!

Pyon est à peu près juste Python, mais c'est plus court car re est automatiquement importé lorsque vous l'utilisez et aest automatiquement défini sur un argument ou l'entrée

-4 octets grâce à M. Xcoder


Vous devez passer g[0]à g[:-1](échoue pour le scénario de test donné ou tout nombre supérieur à 9).
M. Xcoder

Quoi qu'il en soit, pourquoi auriez-vous même besoin d'un lambdaqui gaspille des octets? Golfé et corrigé pour 66 octets
M. Xcoder

@ Mr.Xcoder whoops, pas sûr de ce que je pensais ... merci
HyperNeutrino

@ Mr.Xcoder oh ouais j'essaie de faire beaucoup de choses qui finissent par être des non-golfs xD
HyperNeutrino



3

R , 121 106 90 octets

function(s,a=strsplit)cat(rep(el(a(gsub("\\d","",s),"")),pmax(el(a(s,"\\D")),"1")),sep="")

Essayez-le en ligne!

15 octets enregistrés en réalisant que rep()cela contraindra le numérique. 16 autres sauvés grâce à Giuseppe, principalement de l'utilisation de pmaxpour remplacer les chaînes vides par1

function(s) {
  x <- el(strsplit(s,"\\D")) # Split the string on anything that is not a digit...
  x <- pmax(x, "1")          # ... and replace any empty strings with 1. This gets us the numbers of repeats
  y <- gsub("\\d","",s)      # Remove all digits from the original string...
  y <- el(strsplit(y))       # ... and split into individual units. This gets us the symbols to repeat
  z <- rep(y, x)             # Implement the repeats. x is coerced to numeric
  cat(z, sep = "")           # Print without separators
}

très agréable! Je crois que ifelse(x>"",x,1)c'est un octet plus court, et \\Dest équivalent [^\\d] et surtout, vous n'avez pas besoin perl=T, c'est donc un doux 99 octets . Je ne pensais vraiment pas que cela pouvait être inférieur à 100 octets!
Giuseppe


@Giuseppe Utilisation très intelligente de pmaxdonner une belle amélioration importante - merci!
user2390246

remplacer "1"par 1comme pmaxle contraindra à characterla comparaison.
Giuseppe

85 octets en changeant les alias
Giuseppe

2

PowerShell , 66 62 octets

-join("$args"-split'\b'|%{(,$(,$_[0]*$n+$_))[!!($n=$($_-1))]})

Essayez-le en ligne!

Panne

Quel bordel!

A partir de $args , qui est un tableau d'éléments unique contenant la chaîne RLE, je force dans une chaîne réelle en l'encapsulant entre guillemets.

Ensuite, divisez-le par limite de mot ( \ben regex). Cela me donnera un tableau de chaînes, où chaque élément est soit un nombre, soit le ou les jetons BF qui viennent après le nombre. Ainsi , dans l'exemple, les 4 premiers éléments de ce tableau de répartition sont 10, +]>+>, 3,+> (tous sont string).

Ensuite, je redirige cela dans ForEach-Object( %) pour gérer chaque élément .

Le milieu est un golfisme PowerShell bien connu, avec une touche; il s'agit essentiellement d'un opérateur ternaire bricolage, dans lequel vous créez un tableau à 2 éléments, puis l'indexez à l'aide de l'expression booléenne que vous souhaitez tester, un faux résultat vous donnant l'élément 0 et un vrai résultat vous donnant l'élément 1.

Dans ce cas, je crée en fait un tableau à élément unique avec la virgule unaire , , car je ne veux pas de sortie dans le vrai cas.

Examinons d'abord l'indexeur, même s'il est exécuté plus tard.

L'idée est que $_(l'élément actuel) peut être soit un nombre valide, soit une autre chaîne. Si c'est un nombre, je veux $nêtre la valeur de ce nombre moins 1 (comme un nombre, pas une chaîne). Si ce n'est pas le cas, je veux $nêtre faux-y.

PowerShell essaie généralement de contraindre la valeur de droite au type du côté gauche, mais cela peut dépendre de l'opération. Par ailleurs, "10"+5vous donnera une nouvelle chaîne "105", tandis que 10+"5"vous donnera un entier ( 15).

Mais les chaînes ne peuvent pas être soustraites.Par conséquent, PowerShell peut déduire automatiquement la valeur numérique avec une chaîne sur le côté gauche de la soustraction, donc "10"-5donne5 .

Donc, je commence par $_-1, ce qui me donnera le nombre que je veux quand $_c'est en fait un nombre, mais quand ce n'est pas le cas, je ne reçois rien. En surface, "rien" n'est falsey, mais le problème est qu'il arrête l'exécution de cette affectation, il $nconservera donc sa valeur précédente; pas ce que je veux!

Si je l'enveloppe dans une sous-expression, puis quand il échoue, j'obtiens ma valeur de falsey: $($_-1) .

Que tout est attribué à $net puisque cette affectation est elle-même enveloppée entre parenthèses, la valeur qui a été affectée à$n également transmise au pipeline.

Étant donné que je l'utilise dans l'indexeur et que je souhaite 1que la conversion réussisse, j'utilise deux notexpressions booléennes !!pour convertir cette valeur en booléen. Une conversion de nombre réussie se termine comme vraie, tandis que le néant de falsey nous donne ce doux, doux 0qui permet de retourner le seul élément de ce faux tableau ternaire.

Pour en revenir à ce tableau, l'élément est le suivant: $("$($_[0])"*$n*$_) $(,$_[0]*$n+$_)

"$($_[0])"- c'est un moyen ennuyeusement long d'obtenir le premier caractère de l'élément courant (disons, en +provenance de +[>+), mais en tant que chaîne et non en tant [char]qu'objet. J'ai besoin que ce soit une chaîne car je peux multiplier une chaîne par un nombre pour la dupliquer, mais je ne peux pas le faire avec un caractère.

En fait, j'ai réussi à enregistrer 4 caractères en utilisant un [char]tableau au lieu d'une chaîne (en utilisant une autre virgule unaire ,), j'ai donc pu supprimer les guillemets et la sous-expression supplémentaire. Je peux multiplier un tableau pour dupliquer ses éléments. Et puisque le résultat entier de cette itération finit par être un tableau de toute façon et doit être-join modifié, l'utilisation d'un tableau ici n'entraîne aucun coût supplémentaire.

Ensuite, je multiplie ce tableau de chaînes par $n, pour le dupliquer $nfois. Rappelez-vous que cela $npourrait être $nullou ce pourrait être la valeur des chiffres précédents moins un.

+$_Ajoute ensuite l'élément en cours à la fin du premier caractère dupliqué de cet élément. C'est pourquoi$n est moins un.

De cette façon, 10+[>+finit par $négal à 9, puis nous faisons 9 +et ajoutons cela à la+[>+ chaîne pour obtenir les 10 requis, ainsi que les autres éléments individuels le long du trajet.

L'élément est encapsulé dans une sous $()- expression parce que quand $nest $null, l'expression entière échoue, donc la création du tableau échoue, donc l'indexeur ne s'exécute jamais, donc $nn'est jamais attribué.

La raison pour laquelle j'ai utilisé cette astuce ternaire est due à l'une de ses particularités: contrairement à un véritable opérateur ternaire, les expressions qui définissent les éléments ne s'évaluer si oui ou non ils sont « sélectionnés », et d' abord pour cette question.

Étant donné que je dois attribuer puis utiliser $nsur des itérations distinctes, cela est utile. La valeur de l'élément de tableau ternaire est évaluée avec la $nvaleur de l'itération précédente , puis l'indexeur est réaffecté $npour l'itération en cours.

Ainsi, les ForEach-Objectboucles finissent par produire tout ce qu'elles sont censées (un tas d'erreurs que nous ignorons), mais comme un tableau de nouvelles chaînes.

Donc, tout cela est entouré de parenthèses, puis précédé d'unaire -joinpour donner la chaîne de sortie.


1
Grande explication, qui à elle seule mérite déjà un vote positif.
Mât

1
Merci @Mast, et à cause de votre commentaire, j'ai relu ma réponse et réalisé comment je pouvais économiser 4 octets.
briantist

2

QuadR , 17 octets

\d+.
¯1((⍎↓)⍴↑)⍵M

Essayez-le en ligne!

Merci à Adám d' avoir fourni la bonne version du code.

Comment ça fonctionne:

\d+.           Regex to match any sequence of digits followed by a character.
¯1((⍎↓)⍴↑)⍵M   Transformation line
¯1(      )⍵M   Arguments: -1 and the matching expression
   ( ↓)        'Drop' the last item (-1) from the match (⍵M), yielding a string which is a sequence of digits.
              Execute. In this case, it transforms a string into a number.
              'Take' the last item (-1) from the match (⍵M), yielding a character.
              Reshape it. That will take the character resulting from the 'Take' operation and repeat it n times,
               where n is the result from the 'Drop' and 'Execute' operations.

Equivalent à la fonction APL'\d+.'⎕R{¯1((⍎↓)⍴↑)⍵.Match}
Adám


1

Java 8, 148 octets

s->{for(s=s.format(s.replaceAll("(\\d+)","%1\\$0$1d"),0);!s.matches("\\D+");s=s.replaceAll("0(\\D)","$1$1"));return s.replaceAll("((.)+)\\2","$1");}

Les fichus regex Java sont si inutiles parfois .. La dernière fois, c'était lemanque d'utiliser le groupe de capture"$1"pour rien, maintenant ça .. Je veux remplacer3cparcccou000cavecccc comme une seule ligne, mais malheureusement Java n'a aucun moyen de le faire sans un boucle. Et bien.

Explication:

Essayez-le ici.

s->{                          // Method with String as both parameter and return-type
  for(s=s.format(s.replaceAll("(\\d+)","%1\\$0$1d"),0);
                              //  Replace every numbers of that many zeroes
                              //  (i.e. "3>2+" -> "000>00+")
      !s.matches("\\D+");     //  Loop as long as the String contains zeroes
    s=s.replaceAll("0(\\D)",  //   Replace every 0 followed by a non-0 character,
                   "$1$1")    //   with two times this captured non-0 character
  );                          //  End of loop
  return s.replaceAll("((.)+)\\2","$1");
                              //  Reduce every repeated character amount by 1,
                              //  and return this as result
}                             // End of method

1
Salut Kevin, ravi de vous voir ici, traitant d'énigmes autres que sinueuses :)
Galen Ivanov

@GalenIvanov Oh, salut! Je ne savais pas non plus que vous étiez actif sur PPCG.
Kevin Cruijssen

Je ne l'étais que récemment :) J'apprends le J et j'ai décidé que c'était une bonne occasion de tester mes compétences.
Galen Ivanov

1

Haskell , 84 octets

f s@(x:r)|(n:m,x:r)<-span(`elem`['0'..'9'])s=(x<$[1..read$n:m])++f r|1<3=x:f r
f e=e

Essayez-le en ligne!

Explication:

span(`elem`['0'..'9'])sdivise la chaîne donnée sen un préfixe de chiffres et le reste. Faire correspondre le résultat sur le modèle (n:m,x:r)garantit que le préfixe numérique n'est pas vide et lie le caractère après les chiffres à xet le reste à r. x<$[1..read$n:m]lit la chaîne de chiffres n:msous forme de nombre et la répète xplusieurs fois. Le résultat est concaténé au traitement récursif de la chaîne restante r.


1

R , 151 octets

Dépassé par user2390246 ! C'est maintenant fondamentalement une approche ordonnée par rapport à celle-là, mais je vais continuer à l'améliorer.

function(s,G=substr)for(i in el(strsplit(gsub("(\\d+.)","!\\1!",s),"!")))cat("if"(is.na(g<-as.double(G(i,1,(n=nchar(i))-1))),i,rep(G(i,n,n),g)),sep='')

Essayez-le en ligne!

Émet également un tas d'avertissements.

function(s){
s <- gsub("(\\d+.)","!\\1!",s)               # surround groups with !
X <- el(strsplit(s,"!"))                   # split to groups
for( i in X ){                             # iterate over groups
 n <- nchar(i)                             # length of group
 r <- substr(i,1,n-1)                      # potential number (first n-1 chars)
 d <- substr(i,n,n)                        # last character
 if( is.na(as.double(r)) ){                # if it's not a number
   cat(i)                                  # print out the whole string
  } else {
   cat(rep(d,as.double(r)),sep="")         # repeat d r times, and print with no separator
  }
 }
}

Ensuite, voir si l'utilisation d'un grepest plus efficace quesubstr



1

JavaScript (ES6), 46 octets

a=>a.replace(/(\d+)(.)/g,(_,n,b)=>b.repeat(n))

Explication assez simple:

a=>a.replace(/(\d+)(.)/g,                      // Match globally the following: a number N followed by a character
                         (_,n,b)=>b.repeat(n)) // Replace each occurrence by the matched character repeated N times


1

Calcul lambda non typé , 452 octets

(λp.λq.(λb.λg.(λi.(λp.λq.λb.p q b)(q(λq.λj.λl.j((λq.λj.qλq.λl.(λu.g i j(λp.u)(g j(λq.λg.q(b(p(λp.λq.p q))(p(λp.λq.p(p q)))q g))(λp.u)(λu.u qλq.λu.g j i q(b l(p(λp.λq.p(p(p(p q)))))q u))))λp.p(λp.λb.q p((λp.λq.l(λp.l)(λp.λq.p q)(λq.p j q)q)p b))λp.λp.p)l q))(λp.p)(λp.p(λp.λp.p)λp.λp.p)(λp.λq.p)))(b(p(λp.λp.p))(p(λp.λq.p(p q)))))(λp.λq.λb.p(q b))λp.λq.q(λp.λq.λb.p(λp.λb.b(p q))(λp.b)λp.p)p)λp.λq.λb.q(q(q(q(q(q(p q b))))))

L'entrée et la sortie comprennent des listes à droite des codes de caractères codés par église , par exemple le code de caractère d'une nouvelle ligne est 10, de sorte que le codage par église le serait λf.λx.f(f(f(f(f(f(f(f(f(f x))))))))). La conversion de "ABCD" en liste ressemble àλf.λx.f 65 (f 66 (f 67 (f 68 x))) mais avec les nombres encodés par l'église.

Appliquer une chaîne codée au programme et la réduire complètement devrait vous donner une chaîne de sortie codée avec le RLE appliqué.


1
Bonjour et bienvenue sur le site! Cela ressemble à une solution intéressante, mais nous nous attendons à ce que les langues aient un interprète valide, avez-vous l'un des calculs lambda non typés?
Post Rock Garf Hunter

De plus, que signifie la qλqnotation? Je n'avais jamais vu ça auparavant.
Zacharý


1

C ++, 239 235 octets

-4 octets grâce à Zacharý

#include<regex>
using s=std::string;std::regex m("[0-9]*[<>+.,\\[\\]-]");s t(s r){s d,h;std::sregex_iterator i(r.begin(),r.end(),m),e;while(i!=e){h=(*i)[0];int g=std::strtol(h.data(),NULL,10);g+=!g;d+=s(g,h[h.size()-1]);++i;}return d;}

1
Pouvez-vous changer g=(g?g:1)pour g+=!g? Si cela ne fonctionne pas, ne pouvez-vous pas supprimer les parenthèses autourg?g:1
Zacharý

0

Dart, 78 octets (avec regex), 102 octets (sans regex)

Avec Regex:

(i)=>i.splitMapJoin(new RegExp(r"(\d+)(.)"),onMatch:(m)=>m[2]*int.parse(m[1]))

Sans regex:

(i,[n=0,d=0])=>i.codeUnits.map((c)=>i[d++]*((c-=48)>=0&&c<10?0*(n=n*10+c):n<1?1:(n=0*(c=n))+c)).join()

Les deux doivent être invoqués comme (<code here>)("input string") .

L'un regex est assez standard, mais celui sans regex est assez spécial.

Sans regex abuse des paramètres optionnels pour allouer des variables locales dans la fonction "single return", sinon vous auriez besoin de faire un bloc et d'avoir le mot-clé return. Pour chaque unité de code, si l'unité de code est comprise entre 0 et 9, elle est cumulée net une chaîne vide est renvoyée. Sinon, le caractère est multiplié par la valeur de n(casse spéciale si n == 0, dans ce cas, il émettra toujours 1 caractère) et nest défini sur 0. (n=0*(c=n))+cdéfinit l'argument du code char à la valeur de n, multiplie n/ cavec 0 , stocke 0 à n, puis ajoute c. Cela réinitialise notre nsans être dans un contexte de déclaration.


0

Python3, 96 octets

s,r=input(),""
while s:
 d=0
 while"/"<s[d]<":":d+=1
 r+=int(s[:d] or 1)*s[d];s=s[d+1:]
print(r)

J'ai essayé une autre implémentation en Python, mais je ne bat pas /codegolf//a/146923/56846 :(

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.