Revoltijo de caracteres ASCII

24

Escriba un programa que tome como entrada una cadena que consiste en caracteres imprimibles (ASCII 20-7E) y un número entero nen [2,16] y realiza la siguiente modificación a la cadena.

  • Cada carácter en la cadena se convierte a su código ASCII (los ejemplos dados están en hexadecimal, aunque la base 10 también es aceptable).
  • Los códigos ASCII se convierten en base ny se concatenan juntos.
  • La nueva cadena se divide en todos los demás caracteres. Si hay un número impar de caracteres, el último carácter se elimina por completo.
  • Los códigos ASCII de impresión (en la base 16) se convierten nuevamente en sus caracteres, mientras que los códigos ASCII que no se imprimen se eliminan.
  • La cadena resultante se imprime.

Caso de prueba

Entrada

Hello, World!
6

Pasos

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 salida de este programa es E001R"31$E.


Este es el código de golf, por lo que se aplican reglas estándar. El código más corto en bytes gana.

Arcturus
fuente
¡Este algoritmo de codificación puede ser útil para enviar mensajes secretos!
Kritixi Lithos
Tengo que hacer esto alguna vez!
anOKsquirrel
@ ΚριτικσιΛίθος mientras el programa funciona para cada posible cadena de entrada, no todas las cadenas de salida son únicas. Por ejemplo, en base 7, la cadena Jpasaría por los pasos J-> 50-> 101-> 10-> (no output), como lo haría la cadena Ko L.
Arcturus
Como dijo @Eridan, este es un cifrado con pérdida ya que las secuencias extrañas eliminan el último carácter. Aunque estoy seguro para el observador ignorante, podría ser una forma sarcástica de comunicarse :)
DoctorHeckle
1
El paso 1 es confuso, no es necesario convertir los caracteres en hexadecimal, en el ejemplo: Hes ASCII 72 (decimal) o 48 (hexadecimal), pero lo que necesito es 200 (base 6). Toda la fila 2 en el ejemplo es inútil y confusa en mi opinión
edc65

Respuestas:

5

Pyth - 22 bytes

Espero jugar mucho más al golf, bastante sencillo.

sfq3l`TmCid16csjRQCMz2

Pruébelo en línea aquí .

Maltysen
fuente
q3l`Tes maravilloso.
isaacg
¿No debería fgTdser suficiente?
Jakube
3

Bash + utilidades comunes de Linux, 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'
Trauma digital
fuente
Creo que se podría acortar printf %s "$1"a echo -n "$1"salvar 2 bytes
Aaron
@Aaron Eso funciona hasta que la cadena de entrada es -e. Pruebaecho -n "-e"
Trauma digital el
Maldita sea, muy bien visto!
Aaron
2

CJam, 24 bytes

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

Tenga en cuenta que hay un carácter DEL (0x7F) entre 'y ,. Pruébelo en línea en el intérprete de CJam .

Cómo funciona

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
fuente
¿Qué pasa con el personaje DEL ...? Parece que has trabajado en eso, ¡pero no puedo verlo en tu explicación!
wizzwizz4
StackExchange filtra los caracteres no imprimibles. El carácter DEL solo está presente en el enlace permanente e invisible incluso allí.
Dennis
Quiero decir ... Eliminar es un carácter de control, pero no es uno de los primeros 32 caracteres. Es el número de personaje 127, 0x7F, para personas que no están familiarizadas con ASCII.
wizzwizz4
No estoy seguro de haber entendido tu pregunta. ¿Te preguntas cómo lo filtro desde la salida?
Dennis
Sí. La explicación de su código no parece decir cómo filtra el DELcarácter de la salida.
wizzwizz4
2

JavaScript (ES6), 137147

Usando las funciones más detalladas 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
fuente
+1 parax=>x>=
Ypnypn
Creo que puede guardar algunos bytes utilizando en [for(z of ...)if(...)...]lugar demap(...).filter(...)
Ypnypn
@Ypnypn No encontré una manera de usar tu sugerencia (aparte de usar la comprensión de matriz que es ES7) pero me presionaste para repensarlo todo. Gracias. Espero que mantengas tu +1 incluso si se x=>x>=ha ido
edc65
1
¿Qué hay de malo en usar ES7?
Ypnypn
1
@Ypnypn Prefiero una respuesta que pueda funcionar incluso con motores javascript deficientes <troll on> como Chrome </ troll off>
edc65
1

Julia, 118 bytes

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...])))))

Sin 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.
fuente
1

Mathematica, 134 bytes

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

Si se permite una función:

Mathematica, 112 bytes

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

TeaScript, 23 bytes

TeaScript es JavaScript para jugar al golf

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

Relativamente sencillo pero deliciosamente corto. Probablemente pueda jugar golf a algunos personajes más con algunos operadores más. Algunas otras características nuevas también podrían usarse para reducir algunos bytes.

Ungolfed && Explicación

x.l(#
    l.c().T(y)
).K(2)
.m(#
    C(
      P(l,16)
    )
).j``
Downgoat
fuente
1
Creo que esto tiene 23 caracteres (29 bytes ) de largo.
Cristian Lupascu
@ w0lf Eso sería con la codificación UTF-8, pero debido a que todos los caracteres son menores de 256, podemos contarlos de forma segura como un byte
Downgoat
1

Rubí 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}

Prueba en línea aquí .

Cristian Lupascu
fuente
1

Python 2, 174 bytes

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

Pruébalo aquí

Realmente no es la mejor herramienta para el trabajo. Como Python no tiene una función de conversión a base arbitraria, tuve que implementar la mía. Eso fue divertido, al menos, particularmente encontrar una expresión [marginalmente] más corta para los dígitos que "0123456789ABCDEF"[n%b]. Para iterar sobre dos caracteres a la vez, descubrí que un whilebucle era ligeramente más corto que un enfoque funcional.

181 bytes como programa completo:

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
fuente
0

MATLAB, 103 bytes

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

He escrito una función k que toma una cadena sy un número entero n como entrada. p.ej:

k('Hello, World!',6)

da

 E001R"31$E

La cosa más molesta con la que tuve que trabajar son los ceros iniciales que se muestran al convertir a base n . Sacarlos de la matriz que se dividiría después de cada 2º carácter costaba muchos bytes. No estoy seguro de si es posible guardar más bytes con este enfoque.

slvrbld
fuente
0

PHP - 286 bytes

Ponga la cadena $sy el número entero $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)))));?>

Pase el valor a GET["s"].

indefinido
fuente