Jumble de caractères ASCII

24

Écrivez un programme qui prend en entrée une chaîne composée de caractères imprimables (ASCII 20-7E) et un entier nen [2,16] et effectue la modification suivante de la chaîne.

  • Chaque caractère de la chaîne est converti en son code ASCII (les exemples donnés sont en hexadécimal, bien que la base 10 soit également acceptable).
  • Les codes ASCII sont convertis en base net concaténés ensemble.
  • La nouvelle chaîne est divisée tous les autres caractères. S'il y a un nombre impair de caractères, le dernier caractère est entièrement supprimé.
  • Les codes ASCII d'impression (en base 16) sont reconvertis en leurs caractères, tandis que les codes ASCII non imprimables sont supprimés.
  • La chaîne résultante est imprimée.

Cas de test

Contribution

Hello, World!
6

Pas

Hello, World!
48 65 6C 6C 6F 2C 20 57 6F 72 6C 64 21
2002453003003031125222330331030024453
20 02 45 30 03 00 30 31 12 52 22 33 03 31 03 00 24 45

La sortie de ce programme est E001R"31$E.


C'est du golf de code, donc les règles standard s'appliquent. Le code le plus court en octets gagne.

Arcturus
la source
Cet algorithme de codage peut être utile pour envoyer des messages secrets!
Kritixi Lithos
Je dois le faire un jour!
anOKsquirrel
@ ΚριτικσιΛίθος alors que le programme fonctionne pour chaque chaîne d'entrée possible, chaque chaîne de sortie n'est pas unique. Par exemple, dans la base 7, la chaîne Jpassera par les étapes J-> 50-> 101-> 10-> (no output), tout comme la chaîne Kou L.
Arcturus
Comme l'a dit @Eridan, il s'agit d'un chiffrement avec perte, car les séquences impaires obtiennent le dernier caractère. Bien que je sois sûr pour l'observateur ignorant, cela pourrait être une façon sournoise de communiquer :)
DoctorHeckle
1
L'étape 1 prête à confusion - pas besoin de convertir les caractères en hexadécimal - dans l'exemple: Hest ASCII 72 (décimal) ou 48 (hex), mais ce dont j'ai besoin est 200 (base 6). Toute la ligne 2 de l'exemple est inutile et déroutante à mon avis
edc65

Réponses:

5

Pyth - 22 octets

J'espère jouer au golf beaucoup plus, assez simple.

sfq3l`TmCid16csjRQCMz2

Essayez-le en ligne ici .

Maltysen
la source
q3l`Test merveilleux.
isaacg
Ça ne devrait pas fgTdsuffire?
Jakube
4

CJam, 33 octets

q~:i\fb:~0+2/W<Gfb:c' ,-'ÿ),127>-

Prend la saisie dans le formulaire 6 "Hello, World!". Testez-le ici.

Voir la réponse de Dennis pour une solution similaire mais meilleure avec une belle explication.

Martin Ender
la source
3

Bash + Common Linux Utils, 118

printf %s "$1"|xxd -p|sed -r "s/../\U& /g;y/ /n/;s/^/dc -e$2o16i/e;s/../& /g;s/ .$//;"|xxd -rp|sed 's/[^[:print:]]//g'
Traumatisme numérique
la source
Je pense que vous pourriez raccourcir printf %s "$1"en echo -n "$1"pour économiser 2 octets
Aaron
@Aaron Cela fonctionne jusqu'à ce que la chaîne d'entrée soit -e. Essayezecho -n "-e"
Digital Trauma
Merde, joliment repéré!
Aaron
2

CJam, 24 octets

l:irifbe_2/{Gbc',32>&}/

Notez qu'il y a un caractère DEL (0x7F) entre 'et ,. Essayez-le en ligne dans l' interpréteur CJam .

Comment ça marche

l:i                     Read a line from STDIN and cast each char to integer. 
   ri                   Read another integer (base) from STDIN.
     fb                 Convert each integer from line 1 to that base.
       e_2/             Flatten and split into chunks of length 2.
                        If the last chunk has only one element, it will get
                        converted into a control character, which will be
                        removed later.
          {         }/  For each digit pair:
           Gb             Convert the pair from base 16 to integer.
             c            Cast to character.
              ',          Push the string of ASCII characters up to '~'.
                32>       Remove the first 32 (control characters).
                   &      Intersect.
Dennis
la source
Et le personnage DEL ...? Il semble que vous ayez travaillé dessus, mais je ne le vois pas dans votre explication!
wizzwizz4
StackExchange filtre les caractères non imprimables. Le caractère DEL n'est présent que dans le permalien, et invisible même là.
Dennis
Je veux dire ... Supprimer est un caractère de contrôle, mais n'est pas l'un des 32 premiers caractères. Il s'agit du numéro de caractère 127, 0x7F, pour les personnes qui ne connaissent pas ASCII.
wizzwizz4
Je ne suis pas sûr d'avoir compris votre question. Vous vous demandez comment je le filtre à partir de la sortie?
Dennis
Oui. Votre explication de code ne semble pas indiquer comment vous filtrez le DELcaractère de la sortie.
wizzwizz4
2

JavaScript (ES6), 137 147

Utilisation des fonctions les plus verbeuses disponibles en JavaScript

f=(s,b)=>alert(s.replace(/./g,x=>x.charCodeAt().toString(b)).match(/../g).map(x=>(x=String.fromCharCode('0x'+x))<='~'&x>' '?x:'').join``)

// Just for test purpose, redefine alert()
alert=x=>document.write('<pre>'+x+'</pre>')

f('Hello, World!',6)
f('PORK',3)

edc65
la source
+1 pourx=>x>=
Ypnypn
Je pense que vous pouvez enregistrer quelques octets en utilisant [for(z of ...)if(...)...]au lieu demap(...).filter(...)
Ypnypn
@Ypnypn Je n'ai pas trouvé de moyen d'utiliser votre indice (à part utiliser la compréhension de tableau qu'est ES7) mais vous m'avez pressé de tout repenser. THX. J'espère que vous garderez votre +1 même s'il x=>x>=est parti
edc65
1
Quel est le problème avec l'utilisation d'ES7?
Ypnypn
1
@Ypnypn Je préfère une réponse qui peut fonctionner même avec des moteurs javascript inférieurs à <troll on> comme Chrome </ troll off>
edc65
1

Julia, 118 octets

f(s,n)=join(map(i->(c=string(Char(parse(Int,i,16))))^isprint(c),matchall(r"..",join(map(i->base(n,Int(i)),[s...])))))

Non golfé:

function f(s::AbstractString, n::Integer)
    # Construct an array of ASCII codes in base n
    v = map(i -> base(n, Int(i)), [s...])

    # Join into a string and get all pairs, truncating
    # to an even length
    m = matchall(r"..", join(v))

    # Parse each pair as an integer in base 16, get the
    # character associated with that code point, convert
    # to a string, and include if it's printable
    x = map(i -> (c = string(Char(parse(Int, i, 16)))^isprint(c), m)

    # Join as a string and return
    return join(x)
end
Alex A.
la source
1

Mathematica, 134 octets

Print@FromCharacterCode@Select[#~FromDigits~16&/@StringPartition[""<>ToCharacterCode@InputString[]~IntegerString~Input[],2],31<#<127&]

Si une fonction est autorisée:

Mathematica, 112 octets

FromCharacterCode@Select[#~FromDigits~16&/@StringPartition[""<>ToCharacterCode@#~IntegerString~#2,2],31<#<127&]&
LegionMammal978
la source
1

TeaScript, 23 octets

TeaScript est JavaScript pour le golf

£lc¡T(y©K(2)ßC(P(l,16±µ

Relativement simple mais délicieusement court. Je peux probablement jouer au golf avec quelques autres opérateurs avec plus d'opérateurs. Quelques autres nouvelles fonctionnalités pourraient également être utilisées pour réduire certains octets.

Ungolfed && Explication

x.l(#
    l.c().T(y)
).K(2)
.m(#
    C(
      P(l,16)
    )
).j``
Downgoat
la source
1
Je crois que cela fait 23 caractères (29 octets ).
Cristian Lupascu
@ w0lf Ce serait avec le codage UTF-8 mais parce que tous les caractères sont inférieurs à 256, nous pouvons les compter en toute sécurité comme un octet
Downgoat
1

Rubis 92

->s,n{o=''
s.chars.map{|x|x.ord.to_s n}.join.scan(/../).map{|x|x>?2&&x<?8&&o<<x.to_i(16)}
o}

Test en ligne ici .

Cristian Lupascu
la source
1

Python 2, 174 octets

def J(a,b,i=0):
 h=r=''
 B=lambda n,b:n*'x'and B(n/b,b)+chr(48+n%b+7*(n%b>9))
 for c in a:h+=B(ord(c),b)
 while i<len(h):v=int(h[i:i+2],16);r+=chr(v)*(31<v<127);i+=2
 print r

Essayez-le ici

Pas vraiment le meilleur outil pour le travail. Puisque Python n'a pas de fonction de conversion en base arbitraire, j'ai dû implémenter la mienne. C'était amusant, au moins - en particulier trouver une expression [légèrement] plus courte pour les chiffres que "0123456789ABCDEF"[n%b]. Pour itérer sur deux caractères à la fois, j'ai trouvé qu'une whileboucle était légèrement plus courte qu'une approche fonctionnelle.

181 octets en tant que programme complet:

B=lambda n,b:n*'x'and B(n/b,b)+chr(48+n%b+7*(n%b>9))
a=raw_input()
b=input()
h=r=''
for c in a:h+=B(ord(c),b)
i=0
while i<len(h):v=int(h[i:i+2],16);r+=chr(v)*(31<v<127);i+=2
print r
DLosc
la source
0

MATLAB, 103 octets

function k(s,n),b=dec2base(s,n)';b(~cumsum(b-'0',1))='';c=base2dec(textscan(b,'%2c'),16)';char(c(c>31))

J'ai écrit une fonction k qui prend une chaîne s et un entier n en entrée. par exemple:

k('Hello, World!',6)

donne

 E001R"31$E

La chose la plus ennuyeuse que j'ai dû contourner est que les zéros apparaissent lors de la conversion en base n . Les retirer du tableau qui devait être divisé après chaque 2ème caractère coûtait beaucoup d'octets. Je ne sais pas s'il est possible d'enregistrer d'autres octets en utilisant cette approche.

slvrbld
la source
0

PHP - 286 octets

Mettez la chaîne $set l'entier $b.

<?php $s=$_GET["s"];$b;$m="array_map";echo implode($m(function($v){return ctype_print($v)?$v:"";},$m("chr",$m("hexdec",str_split(strlen(implode($a=$m(function($v){global$b;return base_convert($v,16,$b);},$m("dechex",$m("ord",str_split($s))))))%2==1?substr(implode($a),0,-1):$a,2)))));?>

Passez la valeur à GET["s"].

indéfini
la source