Développez une chaîne codée

18

Il y a l'encodage et le décodage classiques.

input   output
a3b2c5  aaabbccccc

Et c'est assez simple et fait avant.

Le défi consiste également à prendre en compte un comportement non standard lorsque plusieurs caractères précèdent la longueur d'exécution (un seul chiffre de 0 à 9). Chaque caractère avant le chiffre de la longueur d'exécution (le dernier chiffre avant un non-chiffre ou la fin de la chaîne) a cette valeur qui lui est appliquée individuellement et imprimé dans l'ordre.

Quelques entrées et sorties de test, y compris certains cas de bord:

input   output
ab3c5   aaabbbccccc
a0b3    bbb  
13b1    111b
a13b1   aaa111b
a123b1  aaa111222b
aa2a1b1 aaaaab
  • Une séquence de caractères ( [a-zA-Z0-9]+) doit être suivie de sa longueur de longueur ( [0-9])
  • Seule une entrée valide doit être prise en compte ( ([a-zA-Z0-9]+[0-9])*)
    • oui, une chaîne vide est une entrée valide.
  • L'entrée se fait via une entrée standard, la sortie via une sortie standard

Il s'agit du code golf, le nombre d'octets détermine le gagnant.


la source
@AlexA. Correct. Il y a des esolangs que j'aime voir de temps en temps qui sont autrement pénalisés par le nombre d'octets. (Je suis certainement ouvert aux suggestions sur les raisons pour lesquelles cela peut être une erreur de compter de cette façon)
4
@MichaelT La notation par caractères encourage fortement la compression du code source en UTF32, qui permet le codage de jusqu'à 4 octets par caractère, mais est complètement illisible.
isaacg
@isaacg fair 'nuff. Je vais modifier pour passer en octets. Je vais réfléchir à un moyen d'exprimer le style de sclipting pour être acceptable pour les défis futurs.
Notre soumission est-elle censée se terminer sans erreur si l'entrée est la chaîne vide? Le consensus sur la méta est que la sortie vers STDERR peut être ignorée, mais comme vous l'avez explicitement mentionné, je dois demander.
Dennis
@Dennis une chaîne vide comme entrée devrait, devrait s'arrêter. Il ne doit pas entrer dans une boucle infinie ou imprimer un autre texte sur la sortie standard.

Réponses:

3

Pip, 22 + 1 = 23 octets

Utilise le -rdrapeau. Notez que cela vous oblige à 1) entrer un EOF après l'entrée (Ctrl-D sous Linux, Ctrl-Z sous Windows) ou 2) diriger l'entrée depuis un autre endroit.

(^_@<v)X_@vMa@`\D*\d+`

Explication:

                        a is first line of stdin (from -r flag) and v is -1 (implicit)
              `\D*\d+`  Pattern (regex) object that matches zero or more non-digits
                        followed by at least one digit
            a@          Find all non-overlapping matches in a, returning a list of strings
           M            To that list, map a lambda function:
  _@<v                    Argument sans last character (equivalent to Python a[:-1])
(^    )                   Split into a list of characters
        _@v               Last character of argument
       X                  Repeat each character of the list that many times
                          (String multiplication X, like most operators, works item-wise
                          on lists)
                        Auto-print (implicit)

Le résultat de l'opération de mappage est en fait une liste de listes, mais par défaut, les listes sont simplement concaténées ensemble lors de l'impression, donc aucune conversion manuelle en chaîne n'est nécessaire.

Exemple, avec entrée a13b1:

Var a gets        "a13b1"
After regex match  ["a13" "b1"]
After map          [["aaa" "111"] ["b"]]
Final output       aaa111b

Pip a un support regex de base en date de ... il y a 2 jours . Bon timing!

DLosc
la source
Celui-là fonctionne (et il en est de même maître) avec le -rdrapeau. (La question spécifie que l'entrée doit provenir de STDIN.)
Dennis
@ Dennis Oups, ça a manqué. Drapeau ajouté au nombre d'octets. J'aurais dû être en mesure d'utiliser la variable spéciale qau lieu de asans drapeaux supplémentaires, mais il semble y avoir un bug et il demande l'entrée deux fois.
DLosc
Enfin une langue de golf avec support regex!
Dennis
@Dennis Je te vois passer au pip maintenant!
Optimizer
8

Perl / Bash 54 40 + 1 = 41 octets

perl -pe's:(\D*\d*)(\d):"\$1=~s/./\$&x$2/egr":ege'

C'est fondamentalement une expression régulière dans une expression régulière. Et un peu de magie.

Explication

L'expression régulière externe /(\D*\d*)(\d)/gextrait chaque groupe codé de longueur d'exécution. Nous capturons les éléments à répéter $1et le nombre de répétitions $2. Maintenant, nous substituons chacun de ces groupes à l'expansion de ce groupe. Pour cela, nous évaluons le code "\$1=~s/./\$&x$2/egr" deux fois (comme par le /eedrapeau sur la substitution externe).

La première évaluation n'interpole que le nombre de répétitions dans la chaîne - les autres variables sont protégées par une barre oblique inverse. En supposant donc l'entrée a14, nous aurions maintenant le code $1=~s/./$&x4/egr, qui sera à nouveau évalué.

Cela appliquera la substitution au contenu de $1(le truc à répéter a1). La substitution correspond à chaque caractère .. La $&variable contient la correspondance entière, que nous répétons x4fois. Nous faisons cela de manière /globaire pour chaque correspondance et /rretournons la chaîne substituée plutôt que de modifier la $1variable (qui est en lecture seule). Le résultat de la substitution intérieure est donc aaaa1111.

L' -pindicateur applique la substitution à chaque ligne d'entrée et imprime le résultat.

amon
la source
3
Il est habituel de noter cela comme une solution Perl, où vous ajoutez simplement 1 octet pour le -pmodificateur. Je compte 45 octets. De plus, vous devriez pouvoir utiliser à la \Dplace de [a-z], ce qui a également éliminé le besoin de i.
Dennis
7

CJam, 33 31 27 octets

Ughh, le manque d'expressions régulières rend cela assez long ...

qN+{:XA,s&L\:L>{])~e*[}&X}%

Comment ça fonctionne

Nous parcourons tous les caractères de la chaîne d'entrée et à chaque itération, gardons une trace du dernier caractère rencontré (en commençant par un caractère vide pour la première fois). Ensuite, nous vérifions si le caractère actuel n'est pas numérique et le dernier caractère est numérique. Si c'est le cas, nous répétons chaque caractère précédent (qui n'a pas déjà été répété), le nombre de fois.

(Expansion de code un peu dépassée)

q{                       }%        e# Read the input (q) and loop through each character
  L                                e# Put variable L (initially empty character) on stack
   A,                              e# Put variable A (equals 10) and create an array 0..9
     s                             e# Convert the array to string "0123456789"
      &                            e# Do a set intersect b/w previous char and 0-9 string
                                   e# If numeric, it gives 1 char string, otherwise 0
       \:LA,s&                     e# Swap to bring current character on top. Store it in L
                                   e# and do the same set intersect with it
              >                    e# Means we are checking that current char is non-numeric
                                   e# and previous numeric
               {      }&           e# Run this block if above is true
                ])~                e# Wrap everything not already repeated in an array and
                                   e# take out the last character and convert it to integer.
                                   e# This is the run length of the preceding string
                   e*              e# Repeat each character in the string, run length times
                     [             e# Start a new array to help when next run length is found
                        L          e# Restore the current character back on stack to be used
                                   e# in next iteration
                           )~e*    e# The last string-run-length pair is not decoded..
                                   e# So we do that now

Essayez-le en ligne ici

Optimiseur
la source
J'apprécie la démonstration du problème causé par le qualificatif d'octets. Je vous remercie. Je réfléchis un peu à la façon de formuler la qualification de sorte que les langues où une seule instruction est un caractère multi-octets ne soient pas pénalisées pour ce style de langage sans autoriser l'encodage UTF que vous avez montré pour entrer via une échappatoire. PS J'aime vraiment voir la ventilation algorithmique que vous fournissez.
6

rs , 43 71 caractères

Eh bien, cela a tourné longtemps rapidement. Des nombres stupides ...

(\d)(\D)/\1 \2
+(\w)(\w+?)(\d)(?= |$)/\1\3 \2\3
(\w)(\d)/(\1)^^(\2)
 /

Essayez-le ici!

Version originale (ne fonctionnait pas avec une entrée comme 123):

+(\D)(\D+)(\d)/\1\3\2\3
(\D)(\d)/(\1)^^(\2)

Explication

Les premiers espaces de lieux de ligne entre séries contenant des nombres, par exemple transformer a313ena3 13 .

La deuxième ligne développe en continu les encodages compressés comme aa5poura5a5 .

La troisième ligne convertit chaque instance de a5en aaaaautilisant l' opérateur de répétition .

La dernière ligne supprime les espaces.

kirbyfan64sos
la source
Comment ça marche a123b1?
Optimizer
@Optimizer Pas bien. Je dois le modifier un peu ...
kirbyfan64sos
@Optimizer Fixed.
kirbyfan64sos
5

Javascript ( ES6 ), 86 83 octets

alert(prompt().replace(/(.+?)(\d)(?!\d)/g,(a,b,c)=>b.replace(/./g,y=>y.repeat(c))))

Commenté:

alert( // output final result
    prompt(). // take input
    replace(/(.+?)(\d)(?!\d)/g, // replace ungreedy capture group of any characters 
                                // followed by a digit (captured)
                                // and not followed by a digit (negative lookahead)
        (a, b, c)=> // replace with a function
            b.replace(/./g, // replace all characters in b
                y=>y.repeat(c) // with that character repeated c times
            )
    )
)
nderscore
la source
Ne fera pas alert(prompt().replace(/(.+?)(\d)(?!\d)/g,(a,b,c)=>Array(c+1).join(b)))la même chose? Il ne fait que 71 octets de long.
Ismael Miguel
@IsmaelMiguel qui ne fonctionnerait que s'il y avait un seul caractère avant le chiffre. La compréhension du tableau gère la répétition de chaque caractère individuellement.
nderscore
Essayez Array(6).join('12')et il reviendra '1212121212'.
Ismael Miguel
Celui-ci fonctionne: alert(prompt().replace(/(.+?)(\d)(?!\d)/g,(a,b,c)=>Array(-~c).join(b)))(même 71 octets de long, testé sur es6fiddle.net/ia7gocwg )
Ismael Miguel
1
J'ai trouvé une manière différente (évidente) de dire 3 octets: D
nderscore
4

CJam, 27 25 octets

r_'A+1>.{64&1$>{])~f*o}&}

Essayez-le en ligne dans l' interpréteur CJam .

Comment ça fonctionne

r_                        e# Read a token from STDIN and push a copy.
  'A+                     e# Append the character A to the copy.
     1>                   e# Discard the first character of the copy.
       .{               } e# For each character C of the input string and the
                          e# corresponding character D of the copy:
         64&              e#   Take the bitwise and of D and 64. This pushes @
                          e#   if D is a letter and NUL if it is a digit.
            1$>           e#   Compare the result to a copy of C. This pushes 1
                          e#   if and only if D is a letter and C is a digit.
               {      }&  e#   If the result was 1, do the following:
                ]         e#     Wrap the stack in an array.
                 )~       e#     Pop and evaluate the last character.
                   f*     e#     Repeat each char in the array that many times.
                     o    e#     Print all characters.
Dennis
la source
3

Pyth, 33 32 28 octets

ssmm*vedkPdPcz-hMJf<@zT\=UzJ

Essayez-le en ligne: démonstration ou test de harnais

Explication

Je vais expliquer le code en utilisant l'exemple d'entrée aa1a23b2. J'espère que c'est un peu plus facile à suivre que sans.

                               implicit: z = input string = 'aa1a23b2'
                         Uz    the indices of z: [0, 1, 2, 4, 5, 6, 7]
                  f            filter for indices T, which satisfy:
                   <@zT\=        z[T] < "="
                               this gives us the list of indices [2, 4, 5, 7], 
                               which correspond to digits in z. 
                 J             assignment, J = [2, 4, 5, 7]
               hMJ             increment all element in J: [3, 5, 6, 8]
              -            J   and remove the elements of J:
                                 [3, 5, 6, 8] - [2, 4, 5, 7] = [3, 6, 8]
            cz                 split z at these indices: ['aa1', 'a23', 'b2', '']
           P                   remove last element: ['aa1', 'a23', 'b2']
  m                            map each string d to:
   m     Pd                      map each string k of d-without-last-char to:
     ved                           int(last element of d)
    *   k                          * k
                               this creates [['a', 'a'], ['aaa', '222'], ['bb']]
 s                             sum the lists: ['a', 'a', 'aaa', '222', 'bb']
s                              sum the strings: 'aaaaa222bb'
Jakube
la source
2

Rubis 73

gets.split(/(\d)(?!\d)/).each_slice(2){|s,i|s.chars.map{|c|$><<c*i.to_i}}

Tests: http://ideone.com/L1fssb

Cristian Lupascu
la source
2

JavaScript 112

alert(prompt().replace(/.*?\d+/g,function(m){for(i=n=m.length-1,o="";i--;){j=m[n];while(j--)o=m[i]+o}return o}))

marteau-de-loup
la source
2

Python 2.7, 98 octets

import re
print"".join(c*int(m[-1])for m in 
re.findall(r".+?\d(?!\d)",raw_input())for c in m[:-1])

Cela fait juste une recherche regex simple pour les chiffres qui ne sont pas suivis par un chiffre, puis fait l'arithmétique des chaînes sur chaque groupe et les regroupe tous.

récursif
la source
Vous pouvez économiser 2 octets en passant de Python 2 à 3. raw_inputdevient inputmais a printbesoin de parenthèses.
Alex A.
C'est vrai, mais je préfère jouer au golf en python 2.7.
récursif
1

Julia, 105 99 95 87 octets

s->join([join([string(b)^(int(p[end])-48)for b=chop(p)])for p=matchall(r"\D*\d*\d",s)])

Cela crée une fonction sans nom qui prend une chaîne en entrée et renvoie une chaîne. Pour l'appeler, donnez-lui un nom, par exemple f=s->....

Deux compréhensions de tableau sont utilisées ici, l'une imbriquée dans l'autre. La compréhension externe agit sur chaque correspondance de la chaîne d'entrée contre l'expression régulière\D*\d*\d . La compréhension intérieure répète chaque caractère de la correspondance en fonction du chiffre de fin. Les éléments du tableau interne sont joints en une chaîne, donc le tableau externe est un tableau de chaînes. Ceux-ci sont joints et retournés.

Dans Julia, les chaînes peuvent être traitées comme des tableaux de caractères. Cependant, notez que les types Charet Stringdans Julia n'ont pas les mêmes méthodes définies; en particulier, il n'y a pas de méthode de répétition utilisant ^des caractères for. Cela utilise une solution de contournement:

  • Faites une boucle sur la chaîne en omettant le dernier caractère, qui est supprimé à l'aide de chop() .
  • Convertissez le caractère actuel en chaîne à l'aide de string() .
  • Convertissez le dernier chiffre, qui est également un caractère, en entier. Cependant, notez que, par exemple,int('4') ne renvoie pas 4. Il renvoie plutôt le point de code, qui dans ce cas est 52. Ainsi, nous pouvons soustraire 48 pour récupérer l'entier réel.
  • Répétez string(b)selon int(p[end]) - 48.

Exemples:

julia> f("ab3c5")
"aaabbbccccc"

julia> f("a0b3")
"bbb"

julia> f("13b1")
"111b"
Alex A.
la source
1

Python 3, 148 144 136 135 135 octets

w,o,r,d=''.join,'',[],[]
for c in input()+' ':
 if'/'<c<':':d+=[c]
 elif d:o+=w(x*int(w(d))for x in r);r=[c];d=[]
 else:r+=[c]
print(o)

Merci à Pietu1998 et mbomb007 pour les suggestions.

Python 2, 161 151 147 147 139 138 octets

Peut-être que la journée d'aujourd'hui a été longue au travail, mais je n'arrive pas à comprendre comment jouer au golf.

w,o,r,d=''.join,'',[],[]
for c in raw_input()+' ':
 if'/'<c<':':d+=[c]
 elif d:o+=w(x*int(w(d))for x in r);r=[c];d=[]
 else:r+=[c]
print o
Kade
la source
3
Le passage à Python 3 enregistre quelques octets ( raw_out, parenthèses to print). len(d)>0peut être remplacé par dcar une liste vide est fausse et une liste non vide véridique. list(...)peut aller directement au for. Les crochets ne w([...])sont pas nécessaires car c'est le seul argument. Vous pouvez supprimer l'espace dedans ) for. C'est toutes les petites choses que j'ai trouvées jusqu'à présent.
PurkkaKoodari
@ Pietu1998 Merci pour l'aide!
Kade
Sans trop changer votre approche, vous pouvez vous en débarrasser list()car les chaînes sont itérables. Vous pouvez utiliser w=r=''. Si vous êtes prêt à changer beaucoup de choses, voyez ma solution. :)
récursif
if c.isdigit()peut devenir if'/'<c<':', si je ne me trompe pas.
DLosc
@DLosc merci, cela semble fonctionner.
Kade
0

Java 7, 175 octets

String c(String s){String r="",a[];for(String x:s.split("(?<=(\\d)(?!\\d))")){a=x.split("");for(int i=0,j,l=a.length-1;i<l;i++)for(j=0;j++<new Short(a[l]);r+=a[i]);}return r;}

Le défi est plus difficile qu'il n'y paraît, imo ..

Code non testé et testé:

Essayez-le ici.

class M{
  static String c(String s){
    String r = "",
           a[];
    for(String x : s.split("(?<=(\\d)(?!\\d))")){
      a = x.split("");
      for(int i = 0, j, l = a.length-1; i < l; i++){
        for(j = 0; j++ < new Short(a[l]); r += a[i]);
      }
    }
    return r;
  }

  public static void main(String[] a){
    System.out.println(c("ab3c5"));
    System.out.println(c("a0b3"));
    System.out.println(c("13b1"));
    System.out.println(c("a13b1"));
    System.out.println(c("a123b1"));
    System.out.println(c("aa2a1b1"));
    System.out.println(c("123"));
  }
}

Production:

aaabbbccccc
bbb
111b
aaa111b
aaa111222b
aaaaab
111222
Kevin Cruijssen
la source