Zebrane znaki ASCII

24

Napisz program, który pobiera jako ciąg wejściowy ciąg znaków składający się z drukowalnych znaków (ASCII 20-7E) i liczbę całkowitą nw [2,16] i wykonuje następującą modyfikację ciągu.

  • Każdy znak w ciągu jest konwertowany na kod ASCII (podane przykłady są w systemie szesnastkowym, chociaż podstawa 10 jest również dopuszczalna).
  • Kody ASCII są konwertowane na bazę ni łączone razem.
  • Nowy ciąg znaków jest dzielony co drugi znak. Jeśli jest nieparzysta liczba znaków, ostatni znak jest całkowicie usuwany.
  • Drukowanie kodów ASCII (w bazie 16) jest konwertowane z powrotem na ich znaki, natomiast niedrukowalne kody ASCII są usuwane.
  • Powstały ciąg jest drukowany.

Przypadek testowy

Wkład

Hello, World!
6

Kroki

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

Dane wyjściowe tego programu to E001R"31$E.


To jest kod golfowy, więc obowiązują standardowe zasady. Najkrótszy kod w bajtach wygrywa.

Arktur
źródło
Ten algorytm kodowania może być przydatny do wysyłania tajnych wiadomości!
Kritixi Lithos
Muszę to kiedyś zrobić!
anOKsquirrel
@ ΚριτικσιΛίθος podczas gdy program działa dla każdego możliwego ciągu wejściowego, nie każdy ciąg wyjściowy jest unikalny. Na przykład w bazie 7ciąg Jbędzie przechodził kolejne kroki J-> 50-> 101-> 10-> (no output), podobnie jak ciąg Klub L.
Arcturus,
Jak powiedział @Eridan, jest to szyfrowanie stratne, ponieważ nieparzyste sekwencje usuwają ostatni znak. Chociaż jestem pewien, że nieświadomy obserwator może być wrednym sposobem komunikowania się :)
DoctorHeckle
1
Krok 1 jest mylący - nie trzeba konwertować znaków na szesnastkowy - w przykładzie: Hjest ASCII 72 (dziesiętny) lub 48 (szesnastkowy), ale potrzebuję 200 (podstawa 6). Cały wiersz 2 w tym przykładzie jest bezużyteczny i mylący moim zdaniem
edc65

Odpowiedzi:

5

Pyth - 22 bajty

Mam nadzieję na golfa o wiele więcej, całkiem proste.

sfq3l`TmCid16csjRQCMz2

Wypróbuj online tutaj .

Maltysen
źródło
q3l`Tjest wspaniałe.
isaacg
Nie fgTdpowinno wystarczyć
Jakube,
4

CJam, 33 bajty

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

Pobiera dane wejściowe w formularzu 6 "Hello, World!". Sprawdź to tutaj.

Zobacz odpowiedź Dennisa na podobne, ale lepsze rozwiązanie z dobrym wyjaśnieniem.

Martin Ender
źródło
3

Bash + wspólne narzędzia 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'
Cyfrowa trauma
źródło
Myślę, że można skrócić printf %s "$1"do echo -n "$1"zaoszczędzić 2 bajty
Aaron
@Aaron Działa, dopóki nie zostanie wprowadzony ciąg znaków -e. Spróbujecho -n "-e"
Digital Trauma
Cholera, ładnie zauważona!
Aaron,
2

CJam, 24 bajty

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

Zauważ, że pomiędzy 'i ,. Występuje znak DEL (0x7F) . Wypróbuj online w interpretatorze CJam .

Jak to działa

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
źródło
Co ze znakiem DEL ...? Wygląda na to, że nad tym pracowałeś, ale nie widzę tego w twoich wyjaśnieniach!
wizzwizz4,
StackExchange filtruje znaki niedrukowalne. Znak DEL jest obecny tylko w łączu bezpośrednim i jest niewidoczny nawet tam.
Dennis
Mam na myśli ... Usuń jest znakiem kontrolnym, ale nie jest jednym z pierwszych 32 znaków. Jest to znak o numerze 127 0x7F dla osób, które nie są zaznajomione z ASCII.
wizzwizz4,
Nie jestem pewien, czy zrozumiałem twoje pytanie. Zastanawiasz się, jak odfiltrować go z wyjścia?
Dennis,
Tak. Twoje objaśnienie kodu nie mówi, jak odfiltrować DELznak z wyniku.
wizzwizz4,
2

JavaScript (ES6), 137 147

Korzystanie z najbardziej szczegółowych funkcji dostępnych w 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
źródło
+1 zax=>x>=
Ypnypn
Myślę, że możesz zaoszczędzić trochę bajtów, używając [for(z of ...)if(...)...]zamiastmap(...).filter(...)
Ypnypn
@Ypnypn Nie znalazłem sposobu na użycie twojej podpowiedzi (oprócz używania rozumienia tablicowego, czyli ES7), ale nacisnąłeś mnie, abym wszystko przemyślał. Dzięki. Mam nadzieję, że zatrzymasz swoją +1, nawet jeśli jej x=>x>=nie ma
edc65
1
Co jest złego w korzystaniu z ES7?
Ypnypn
1
@Ypnypn Wolę odpowiedź, która może działać nawet z silnikami napisanymi poniżej javascript <troll on> jak Chrome </ troll off>
edc65
1

Julia, 118 bajtów

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

Nie golfowany:

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.
źródło
1

Mathematica, 134 bajty

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

Jeśli funkcja jest dozwolona:

Mathematica, 112 bajtów

FromCharacterCode@Select[#~FromDigits~16&/@StringPartition[""<>ToCharacterCode@#~IntegerString~#2,2],31<#<127&]&
LegionMammal978
źródło
1

TeaScript, 23 bajty

TeaScript to JavaScript do gry w golfa

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

Stosunkowo prosty, ale zachwycająco krótki. Prawdopodobnie mogę zagrać w golfa o kilka innych postaci z kilkoma innymi operatorami. Można także użyć kilku innych nowych funkcji do zmniejszenia niektórych bajtów.

Niegolfowane i objaśnienia

x.l(#
    l.c().T(y)
).K(2)
.m(#
    C(
      P(l,16)
    )
).j``
Downgoat
źródło
1
Uważam, że ma on 23 znaki (29 bajtów ).
Cristian Lupascu,
@ w0lf To byłoby z kodowaniem UTF-8, ale ponieważ wszystkie znaki są mniejsze niż 256, możemy bezpiecznie policzyć je jako jeden bajt
Downgoat
1

Rubin 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 tutaj .

Cristian Lupascu
źródło
1

Python 2, 174 bajty

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

Wypróbuj tutaj

Niezupełnie najlepsze narzędzie do pracy. Ponieważ Python nie ma funkcji konwersji do arbitralnej bazy, musiałem zaimplementować własną. To była co najmniej zabawna - szczególnie znalezienie [nieznacznie] krótszego wyrazu dla cyfr niż "0123456789ABCDEF"[n%b]. W przypadku iteracji więcej niż dwóch znaków naraz, whilepętla była nieco krótsza niż podejście funkcjonalne.

181 bajtów jako pełny program:

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
źródło
0

MATLAB, 103 bajty

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

Napisałem funkcję k, która przyjmuje ciąg s oraz liczbę całkowitą n jako dane wejściowe. na przykład:

k('Hello, World!',6)

daje

 E001R"31$E

Najbardziej irytującą rzeczą, nad którą musiałem się obejść, jest wyświetlanie zer wiodących podczas konwersji na bazę n . Usunięcie ich z tablicy, która miała zostać podzielona po co 2 znaku, kosztuje sporo bajtów. Nie jestem pewien, czy można zapisać więcej bajtów przy użyciu tego podejścia.

slvrbld
źródło
0

PHP - 286 bajtów

Wprowadź ciąg $si liczbę całkowitą $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)))));?>

Przekaż wartość do GET["s"].

niezdefiniowany
źródło