Faisons un peu "enciph5r47g"


35

C'est l'inverse de Faisons un peu "deciph4r4ng"


Dans ce défi, votre tâche consiste à chiffrer une chaîne. Heureusement, l'algorithme est assez simple: en lisant de gauche à droite, chaque caractère d'écriture typique (plage ASCII 32-126) doit être remplacé par un nombre N (0-9) pour indiquer qu'il est identique au caractère N + 1. positions devant elle. L'exception est lorsque le caractère n'apparaît pas dans les 10 positions précédentes de la chaîne d'origine. Dans ce cas, vous devez simplement réimprimer le personnage. En réalité, vous devriez pouvoir inverser l'opération par rapport au défi initial.

Exemple

La chaîne d'entrée "Programming"serait encodée de cette façon:

Exemple 1

Par conséquent, le résultat attendu est "Prog2am0in6".

Clarifications et règles

  • La chaîne en entrée contiendra exclusivement des caractères ASCII compris entre 32 et 126. Vous pouvez supposer qu'il ne sera jamais vide.
  • La chaîne d'origine est garantie de ne contenir aucun chiffre.
  • Une fois qu'un caractère a été encodé, il peut être référencé par un chiffre ultérieur. Par exemple, "alpaca"devrait être codé comme "alp2c1".
  • Les références ne seront jamais entourées d'une chaîne: seuls les caractères précédents peuvent être référencés.
  • Vous pouvez écrire un programme complet ou une fonction qui imprime ou produit le résultat.
  • C'est le code de golf, donc la réponse la plus courte en octets gagne.
  • Les échappatoires standard sont interdites.

Cas de test

Input : abcd
Output: abcd

Input : aaaa
Output: a000

Input : banana
Output: ban111

Input : Hello World!
Output: Hel0o W2r5d!

Input : this is a test
Output: this 222a19e52

Input : golfing is good for you
Output: golfin5 3s24o0d4f3r3y3u

Input : Programming Puzzles & Code Golf
Output: Prog2am0in6 Puz0les7&1Cod74G4lf

Input : Replicants are like any other machine. They're either a benefit or a hazard.
Output: Replicants 4re3lik448ny3oth8r5mac6in8.8T64y'r371it9376a1b5n1fit7or2a1h2z17d.

6
Je vois que vos cas de test utilisent toujours le chiffre le plus bas possible pour toute substitution. S'agit-il d'un comportement requis ou pouvons-nous utiliser des chiffres plus élevés également lorsqu'il existe plus d'une possibilité?
Leo le

@Leo Vous pouvez utiliser n'importe quel chiffre que vous voulez entre 0 et 9 tant qu'il est valide.
Ingénieur Toast

C'est comme un encodeur à mouvement frontal , sauf sans le déplacement :)
pipe du

Réponses:


6

05AB1E , 20 19 18 octets

-2 Merci à Emigna

õ¹vDyåiDykëy}?yìT£

Essayez-le en ligne!

õ                  # Push an empty string
 ¹v y              # For each character in input
   D               # Duplicate the string on the stack (call this S)
     åi            # If this character is in S
       Dyk         #   Push the index of that that character 
          ë }      # Else
           y       #   Push the character 
             ?     # Print without newline
              yì   # Prepend this character to S
                T£ # Remove all but the first 10 elements from S

Je pense que ça )¹vDyåiDykëy}?y¸ìT£marche aussi.
Emigna

En fait, combiner votre réponse avec la mienne donne õIvDyåiDykëy}?yìT£pour 18 :)
Emigna

@Emigna N'hésitez pas à mettre à jour le vôtre avec ça :)
Riley

Je n'y aurais pas pensé sans votre réponse, alors vous devriez l'avoir. Bon travail!
Emigna

@ Emigna Je suppose que c'est juste. Merci!
Riley

12

Retina , 24 23 octets

(.)(?<=\1(.{0,9}).)
$.2

Essayez-le en ligne!

Une substitution de regex assez simple. Nous associons chaque caractère et essayons de trouver une copie de 0 à 9 caractères devant. Si nous le trouvons, nous remplaçons le caractère par le nombre de caractères que nous devions apparier pour obtenir la copie.

Les résultats ne correspondent pas tout à fait aux cas de test, car celui-ci utilise le plus grand chiffre possible au lieu du plus petit possible.


4
Une longueur variable en regardant en arrière est une tricherie: p
Dada

8
@Dada La longueur variable est la voie de l'illumination.
Martin Ender

Malheureusement, c'est le cas ... Si vous vous ennuyez, n'hésitez pas à les implémenter dans Perl!
Dada

Selon le commentaire de l' OP sur la tâche d' origine, « Vous pouvez utiliser un seul chiffre que vous voulez 0-9 tant qu'il est valide. » ... donc plus possible devrait être valable
Doktor J

@DoktorJ oui, je l'ai changé après que le PO ait ajouté cette clarification.
Martin Ender

8

JavaScript (ES6), 74 57 54 octets

Économisé 3 octets grâce à ETHproductions avec le brillant p=/./gau lieu de p={}(inspiré par Neil)

s=>s.replace(p=/./g,(c,i)=>(i=p[c]-(p[c]=i))>-11?~i:c)

Cas de test


Comme il est garanti que la chaîne ne contient pas de chiffre, pouvez-vous utiliser à la splace de p?
Neil

(J'ai pu utiliser votre findversion originale par- dessus lastIndexOf, ce qui est un peu surprenant étant donné qu'il compte 11 lettres ....)
Neil

@ Neil Je ne suis pas devant un ordinateur pour le moment, mais je ne pense pas que cela fonctionnerait, car les chaînes JS sont immuables.
Arnauld

2
Je peux confirmer que définir des propriétés sur des littéraux de chaîne ne fonctionne pas. Mais ... il semble que cela fonctionne avec regex, donc je pense que vous pourriez éventuellement faire s=>s.replace(p=/./g,(c,i)=>(i=p[c]-(p[c]=i))>-10?~i:c)pour économiser 3 octets.
ETHproductions

1
@YOU Je ne sais pas vraiment ce qui s'est passé ici, mais il s'est avéré que j'avais introduit un bogue pour tous les navigateurs lors de ma dernière édition. Ceci est maintenant corrigé. Merci d'avoir remarqué!
Arnauld

7

Haskell , 72 66 octets

Merci à Laikoni pour avoir joué au golf 6 octets!

(a:r)%s=last(a:[n|(n,b)<-zip['0'..'9']s,b==a]):r%(a:s)
e%s=e
(%"")

Essayez-le en ligne!

La fonction %conserve la chaîne partiellement traitée en sens inverse dans son deuxième argument afin de pouvoir rechercher dans les 10 premiers éléments de cette chaîne les occurrences du caractère examiné. La soumission consiste en la fonction non nommée (%"")qui appelle la fonction précédente avec la chaîne vide comme second argument.


f(a:s)=f s++(last$[a]:[show n|(n,b)<-zip[0..9]s,b==a])enregistre deux octets.
Laikoni

Attendez, f(a:s)=f s++[last$a:[n|(n,b)<-zip['0'..'9']s,b==a]]économise encore plus.
Laikoni

Inverser sur la route au lieu d'utiliser reverseenregistre un octet supplémentaire: essayez-le en ligne!
Laikoni

@ Laikoni Merci, c'est merveilleux!
Leo


3

Perl 5 , 36 octets

35 octets de code + -pdrapeau.

s/(\D)(.{0,9})\K\1/length$2/e&&redo

Essayez-le en ligne!

Quelques explications:
Le but est de remplacer un caractère non-numérique ( \Dmais il correspond à la référence arrière \1dans mon regex) précédé de moins de 10 caractères ( .{0,9}) et du même caractère ( (\D)... \1) par la longueur du .{0,9}groupe ( length$2). Et redopendant que les personnages sont remplacés.


apparemment le .*n'est pas obligatoire, tout caractère valide dans la plage avant le chiffre remplacé est correct.
Colsw

@ConnorLSW Oui, je viens de voir cette mise à jour du défi et j'ai modifié ma réponse, merci de l'avoir signalé.
Dada

3

Python 2, 89 84 octets

m=input()[::-1];j=1;t=''
for i in m:s=m[j:].find(i);t=[i,`s`][0<s<10]+t;j+=1
print t

Essayez-le en ligne!

Itère dans la chaîne en sens inverse et construit une nouvelle chaîne avec les bons numéros insérés.


3

Japt , 18 octets

£¯Y w bX s r"..+"X

Essayez-le en ligne!

Explication

£   ¯  Y w bX s r"..+"X
mXY{s0,Y w bX s r"..+"X}
                          // Implicit: U = input string
mXY{                   }  // Replace each char X and index Y in U by this function:
    s0,Y                  //   Take U.slice(0,Y), the part of U before this char.
         w bX             //   Reverse, and find the first index of X in the result.
                          //   This gives how far back this char last appeared, -1 if never.
              s           //   Convert the result to a string.
                r"..+"X   //   Replace all matches of /..+/ in the result with X.
                          //   If the index is -1 or greater than 9, this will revert to X.
                          // Implicit: output result of last expression


2

05AB1E , 20 octets

õIv¹N£RT£©yåi®ykëy}J

Essayez-le en ligne!

Explication

õ                     # push an empty string
 Iv                   # for each [index,char] [N,y] in input
   ¹N£                # push the first N characters of input
      R               # reverse
       T£             # take the first 10 characters of this string
         ©            # save a copy in register
          yåi         # if y is in this string
             ®yk      #   push the index of y in the string in register
                ë     # else 
                 y    #   push y
                  }   # end if
                   J  # join stack as one string


2

C (tcc) , 113 octets

Étant donné que la fonction crée une copie d'une chaîne d'entrée, la taille maximale de l'entrée est de 98 caractères (plus que suffisant pour s'adapter à la plus longue entrée de test). Bien sûr, cela peut être changé pour n’importe quelle autre valeur.

i,j;f(char*s){char n[99];strcpy(n,s);for(i=1;s[i];i++)for(j=i-1;j>-1&&i-j<11;j--)if(n[i]==n[j])s[i]=47+i-j;j=-1;}

Essayez-le en ligne!

modifier

-15 octets. Merci Johan du Toit .


Agh! Limitez la saisie à 98 caractères et économisez un octet!
pipe le

Belle solution mais vous pouvez économiser 15 octets supplémentaires: i,j;f(char*s){char n[99];strcpy(n,s);for(i=1;s[i];i++)for(j=i-1;j>-1&&i-j<11;j--)if(n[i]==n[j])s[i]=47+i-j,j=-1;}
Johan du Toit

@JohanduToit Merci! J'ai une question. Comment fonctionne exactement s [i] comme condition de la boucle for? Je l'ai souvent vu dans les réponses d'autres personnes sur ce site.
Maxim Mikhaylov

Max Lawnboy. À l'origine, vous aviez le texte suivant: 's [i] ^' \ 0 '', qui signifie "s [i]! =" \ 0 ". Le caractère littéral '\ 0' est égal à zéro, vous pouvez donc l'écrire ainsi: 's [i]! = 0'. L'instruction if en C ne teste que si la valeur est évaluée à zéro ou non à zéro, ainsi le '! = 0' n'est pas nécessaire.
Johan du Toit


2

Java 7, 102 101 octets

void a(char[]a){for(int b=a.length,c;--b>0;)for(c=b;c-->0&c+11>b;)if(a[c]==a[b])a[b]=(char)(b-c+47);}

Essayez-le en ligne!

-1 octet grâce à Kevin Cruijssen . J'apprécie toujours une excuse pour utiliser l'opérateur qui va à.


Pourquoi --c>=0? Vous pouvez le remplacer par c-->0pour sauvegarder un octet.
Kevin Cruijssen le

@KevinCruijssen J'avais en tête que je devais prédécrémenter sinon le calcul serait faux ... Belle prise!
Poke

1

MATL, 31 à 30 octets

&=R"X@@f-t10<)l_)t?qV}xGX@)]&h

Essayez-le sur MATL Online!

Explication

        % Implicitly grab input as a string
&=      % Perform element-wise comparison with automatic broadcasting.
R       % Take the upper-triangular part of the matrix and set everything else to zero
"       % For each column in this matrix
X@      % Push the index of the row to the stack
@f      % Find the indices of the 1's in the row. The indices are always sorted in
        % increasing order
-       % Subtract the index of the row. This result in an array that is [..., 0] where
        % there is always a 0 because each letter is equal to itself and then the ...
        % indicates the index distances to the same letters
t10<)   % Discard the index differences that are > 9
l_)     % Grab the next to last index which is going to be the smallest value. If the index
        % array only contains [0], then modular indexing will grab that zero
t?      % See if this is non-zero...
  qV    % Subtract 1 and convert to a string
}       % If there were no previous matching values
  x     % Delete the item from the stack
  GX@)  % Push the current character
]       % End of if statement
&h      % Horizontally concatenate the entire stack
        % Implicit end of for loop and implicit display

Vous pourriez être un peu hors mais je super ne peut pas dire où. L'entrée this is a testdonne this 222a1te52au lieu de this 222a19e52. La seconde tn'est pas convertie en 9.
Ingénieur Toast

@ IngénieurToast Haha merci. Je regarderai.
Suever

1

PHP, 104 octets

solution avancée

for($i=0;$i<strlen($a=&$argn);$f[$l]=$i++)$a[$i]=is_int($f[$l=$a[$i]])&($c=$i-$f[$l]-1)<10?$c:$l;echo$a;

Solutions inverses

Versions en ligne

PHP, 111 octets

for(;++$i<$l=strlen($a=&$argn);)!is_int($t=strrpos($argn,$a[-$i],-$i-1))?:($p=$l-$i-$t-1)>9?:$a[-$i]=$p;echo$a;

PHP, 112 octets

for(;++$i<$l=strlen($a=&$argn);)if(false!==$t=strrpos($argn,$a[-$i],-$i-1))($p=$l-$i-$t-1)>9?:$a[-$i]=$p;echo$a;

Version en ligne


1

REXX, 124 125 octets

a=arg(1)
b=a
do n=1 to length(a)
  m=n-1
  c=substr(a,n,1)
  s=lastpos(c,left(a,m))
  if s>0&m-s<=9 then b=overlay(m-s,b,n)
  end
say b

Vous êtes peut-être un peu en retrait. Je ne connais pas REXX mais je présume que l’erreur est à la ligne 7 où elle a été s<9remplacée par s<10ou s<=9. L'entrée this is a testdonne this 222a1te52au lieu de this 222a19e52. La seconde tn'est pas convertie en 9. Essayez-le en ligne
Engineer Toast le

Merci, c'était une tentative stupide de supprimer un octet. Le code a été corrigé.
idrougge

1

C (gcc) , 117 103 octets

i,j;f(char*s){for(i=strlen(s)-1;s[i];i--)for(j=i-1;s[j]&&i-j<11;j--)if(s[i]==s[j]){s[i]=47+i-j;break;}}

Essayez-le en ligne!

103 octets sans importation string.h, fonctionne avec warning. Si c'est contre les règles, je le tire

Pretty Code:

i,j;
f(char *s) {
    // Chomp backwards down the string
    for(i=strlen(s)-1; s[i]; i--)
        // for every char, try to match the previous 10
        for(j=i-1; s[j] && i-j < 11; j--)
            // If there's a match, encode it ('0' + (i-j))
            if (s[i] == s[j]) {
                s[i] = 47+i-j;
                break;
            }
}

Modifications:

  • Changement de LLVM en gcc pour autoriser les déclarations i, j implicites, l'importation de lib supprimée.
  • Ajout de wrapper de fonctions pour la conformité

Suggérez au (i=strlen(s);s[--i];)lieu de(i=strlen(s)-1;s[i];i--)
ceilingcat
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.