Combinazione di caratteri ASCII


24

Scrivi un programma che accetta come input una stringa composta da caratteri stampabili (ASCII 20-7E) e un numero intero nin [2,16] ed esegue la seguente modifica alla stringa.

  • Ogni carattere nella stringa viene convertito nel suo codice ASCII (gli esempi forniti sono in esadecimali, sebbene anche la base 10 sia accettabile).
  • I codici ASCII vengono convertiti in base ne vengono concatenati insieme.
  • La nuova stringa è divisa ogni altro carattere. Se è presente un numero dispari di caratteri, l'ultimo carattere viene rimosso completamente.
  • I codici ASCII di stampa (nella base 16) vengono riconvertiti nei loro caratteri, mentre i codici ASCII non stampabili vengono rimossi.
  • La stringa risultante viene stampata.

Caso di prova

Ingresso

Hello, World!
6

passi

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

L'output di questo programma è E001R"31$E.


Questo è il golf del codice, quindi si applicano le regole standard. Vince il codice più breve in byte.


Questo algoritmo di codifica può essere utile per inviare messaggi segreti!
Kritixi Lithos,

Devo farlo prima o poi!
anOKsquirrel

@ ΚριτικσιΛίθος mentre il programma funziona per ogni possibile stringa di input, non tutte le stringhe di output sono uniche. Ad esempio, in base 7, la stringa Jdovrebbe passare attraverso i passaggi J-> 50-> 101-> 10-> (no output), così come la stringa Ko L.
Arcturus,

Come ha detto @Eridan, questa è una crittografia con perdita poiché le sequenze dispari vengono cancellate dall'ultimo carattere. Anche se sono sicuro per l'osservatore ignorante, potrebbe essere un modo
snello

1
Il passaggio 1 è confuso - non è necessario convertire i caratteri in esadecimali - nell'esempio: Hè ASCII 72 (decimale) o 48 (esadecimale), ma ciò di cui ho bisogno è 200 (base 6). Tutta la riga 2 nell'esempio è inutile e confusa secondo me
edc65

Risposte:




3

Bash + utility Linux comuni, 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'

Penso che si potrebbe ridurre printf %s "$1"in echo -n "$1"per salvare 2 byte
Aaron

@Aaron Funziona fino a quando la stringa di input è -e. Provaecho -n "-e"
Digital Trauma,

Accidenti, ben individuato!
Aaron,

2

CJam, 24 byte

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

Si noti che esiste un carattere DEL (0x7F) tra 'e ,. Provalo online nell'interprete CJam .

Come funziona

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.

Che dire del personaggio DEL ...? Sembra che tu l'abbia aggirato, ma non riesco a vederlo nella tua spiegazione!
wizzwizz4,

StackExchange filtra i caratteri non stampabili. Il personaggio DEL è presente solo nel permalink e invisibile anche lì.
Dennis,

Voglio dire ... Elimina è un personaggio di controllo, ma non è uno dei primi 32 caratteri. È il numero di carattere 127, 0x7F, per le persone che non hanno familiarità con ASCII.
wizzwizz4,

Non sono sicuro di aver capito la tua domanda. Ti stai chiedendo come posso filtrarlo dall'output?
Dennis,

Sì. La spiegazione del codice non sembra dire come si filtra il DELcarattere dall'output.
wizzwizz4,

2

JavaScript (ES6), 137 147

Utilizzo delle funzioni più dettagliate disponibili in 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)


+1 perx=>x>=
Ypnypn

Penso che puoi salvare alcuni byte usando [for(z of ...)if(...)...]invece dimap(...).filter(...)
Ypnypn

@Ypnypn Non ho trovato un modo per usare il tuo suggerimento (a parte l'uso della comprensione dell'array che è ES7) ma mi hai spinto a ripensare tutto. Grazie. Spero che manterrai il tuo +1 anche se x=>x>=è andato
edc65

1
Cosa c'è di sbagliato nell'usare ES7?
Ypnypn,

1
@Ypnypn Preferisco una risposta che può funzionare anche con i motori javascript subpar <troll on> come Chrome </ troll off>
edc65,

1

Julia, 118 byte

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

Ungolfed:

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

1

Mathematica, 134 byte

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

Se una funzione è consentita:

Mathematica, 112 byte

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

1

TeaScript, 23 byte

TeaScript è JavaScript per il golf

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

Relativamente semplice ma deliziosamente breve. Posso probabilmente giocare a golf con qualche altro personaggio con altri operatori. Alcune altre nuove funzionalità potrebbero anche essere utilizzate per ridurre alcuni byte.

Ungolfed && Explanation

x.l(#
    l.c().T(y)
).K(2)
.m(#
    C(
      P(l,16)
    )
).j``

1
Credo che questo sia lungo 23 caratteri (29 byte ).
Cristian Lupascu,

@ w0lf Sarebbe con la codifica UTF-8 ma poiché tutti i caratteri sono inferiori a 256 possiamo tranquillamente contarli come un byte
Downgoat

1

Ruby 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 online qui .


1

Python 2, 174 byte

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

Provalo qui

Non è davvero lo strumento migliore per il lavoro. Dato che Python non ha alcuna funzione di conversione in base arbitraria, ho dovuto implementare la mia. È stato divertente, almeno - in particolare trovare un'espressione [marginalmente] più corta per le cifre rispetto a "0123456789ABCDEF"[n%b]. Per aver ripetuto più di due personaggi alla volta, ho scoperto che un whileciclo era leggermente più breve di un approccio funzionale.

181 byte come programma 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

0

MATLAB, 103 byte

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

Ho scritto una funzione k che prende una stringa s ed un numero intero n come input. per esempio:

k('Hello, World!',6)

 E001R"31$E

La cosa più fastidiosa su cui ho dovuto lavorare è la visualizzazione degli zeri durante la conversione in base n . Ottenere questi dall'array che doveva essere diviso dopo ogni 2 ° carattere costava parecchi byte. Non sono sicuro se è possibile salvare altri byte usando questo approccio.


0

PHP - 286 byte

Inserire la stringa $se l'intero $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)))));?>

Passa il valore a GET["s"].

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.