ASCII Персонаж Jumble


24

Напишіть програму, яка приймає за свій вхід рядок, що складається з символів для друку (ASCII 20-7E) та цілого числа nв [2,16] і виконує наступні зміни в рядку.

  • Кожен символ у рядку перетворюється у його ASCII-код (приклади, наведені у шістнадцятковій формі, хоча база 10 також прийнятна).
  • Коди ASCII перетворюються на базові nі об'єднуються разом.
  • Новий рядок розділений усіма іншими символами. Якщо є непарна кількість символів, то останній символ повністю видаляється.
  • Друкуючі коди ASCII (у базі 16) перетворюються назад у їхні символи, тоді як коди ASCII, що не друкуються, видаляються.
  • Отриманий рядок друкується.

Тестовий випадок

Вхідні дані

Hello, World!
6

Кроки

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

Вихід цієї програми є E001R"31$E.


Це кодовий гольф, тому застосовуються стандартні правила. Виграє найкоротший код у байтах.


Цей алгоритм кодування може бути корисним для надсилання секретних повідомлень!
Kritixi Lithos

Треба робити це колись!
anOKsquirrel

@ ΚριτικσιΛίθος, хоча програма працює для кожного можливого вхідного рядка, не кожен вихідний рядок є унікальним. Наприклад, у базі 7, рядок проходив Jби через кроки J-> 50-> 101-> 10-> (no output), як і рядок Kабо L.
Арктур

Як сказав @Eridan, це шифрування втрат, оскільки непарні послідовності вимикають останнього символу. Хоча я впевнений неосвіченому спостерігачеві, це може бути химерним способом спілкування :)
DoctorHeckle

1
Крок 1 заплутаний - не потрібно перетворювати символи в шістнадцятковий - у прикладі: HASCII 72 (десятковий) або 48 (шістнадцятковий), але те, що мені потрібно, - 200 (основа 6). Весь рядок 2 у прикладі, на мій погляд, марний і заплутаний
edc65

Відповіді:




3

Bash + загальні утиліти 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'

Я думаю , ви могли б скоротити printf %s "$1"в , echo -n "$1"щоб зберегти 2 байти
Аарон

@Aaron Це працює до введення рядка -e. Спробуйтеecho -n "-e"
Digital Trauma

Чорт, добре помічений!
Аарон

2

CJam, 24 байти

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

Зауважте, що між 'і між ними є символ DEL (0x7F) ,. Спробуйте його в Інтернеті в інтерпретаторі CJam .

Як це працює

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.

А що з символом DEL ...? Схоже, ви працювали над цим, але я не бачу цього у вашому поясненні!
wizzwizz4

StackExchange фільтрує недруковані символи. Символ DEL присутній лише в постійній посилання, і навіть там непомітний.
Денніс

Я маю на увазі ... Видалити - це контрольний символ, але це не один із перших 32 символів. Це символ символу 127, 0x7F, для людей, які не знайомі з ASCII.
wizzwizz4

Я не впевнений, що зрозумів ваше запитання. Вам цікаво, як я фільтрую його на виході?
Денніс

Так. Твоє пояснення коду, схоже, не говорить про те, як ви фільтруєте DELсимвол з виводу.
wizzwizz4

2

JavaScript (ES6), 137 147

Використання найбільш багатослівних функцій, доступних у 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 заx=>x>=
Ypnypn

Я думаю, що ви можете зберегти кілька байт, скориставшись [for(z of ...)if(...)...]замістьmap(...).filter(...)
Ypnypn

@Ypnypn Я не знайшов способу використати вашу підказку (окрім використання розуміння масиву, який є ES7), але ви натискали на мене, щоб все це переосмислити. Дякую. Сподіваюся, ви збережете +1, навіть якщо x=>x>=пішов
edc65

1
Що не так з використанням ES7?
Ypnypn

1
@Ypnypn Я вважаю за краще відповідь, яка може працювати навіть з двигунами JavaScript Javascript <troll on> як Chrome </ troll off>
edc65

1

Джулія, 118 байт

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

Безголівки:

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

Математика, 134 байти

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

Якщо функція дозволена:

Математика, 112 байт

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

1

TeaScript, 23 байти

TeaScript - це JavaScript для гольфу

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

Відносно прямий, але приємно короткий. Я, мабуть, можу покатати ще кілька персонажів з деякими іншими операторами. Кілька інших нових функцій також можуть бути використані для скорочення деяких байтів.

Ungolfed && Пояснення

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

1
Я вважаю, що це 23 символи (29 байт ).
Крістіан Лупаску

@ w0lf Це було б з кодуванням UTF-8, але оскільки всіх символів менше 256, ми можемо сміливо рахувати їх як один байт
Downgoat


1

Пітон 2, 174 байти

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

Спробуйте тут

Насправді не найкращий інструмент для роботи. Оскільки Python не має функції перетворення в довільну базу, мені довелося реалізувати свою власну. Принаймні, це було весело - особливо знайти [незначно] коротший вираз для цифр, ніж "0123456789ABCDEF"[n%b]. Для повторення двох символів одночасно я виявив, що whileцикл трохи коротший, ніж функціональний підхід.

181 байт як повноцінна програма:

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 байти

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

Я написав функцію k, яка приймає рядок s та ціле n як вхідні дані. наприклад:

k('Hello, World!',6)

дає

 E001R"31$E

Найбільш дратівлива річ, яку мені довелося обійти, - це провідні нулі, що з’являються при переході на базу n . Виведення з масиву, який потрібно було розділити після кожного другого символу, коштувало досить багато байтів. Не впевнений, чи можна зберегти більше байтів за допомогою цього підходу.


0

PHP - 286 байт

Помістіть рядок $sі ціле число $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)))));?>

Передайте значення в GET["s"].

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.