ASCII символов беспорядок


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 байта
Аарон

@ Аарон Это работает, пока строка ввода не будет -e. Попробуйтеecho -n "-e"
Цифровая травма

Черт, приятно заметили!
Аарон

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 <troll on> like 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...])))))

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

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

Если функция разрешена:

Mathematica, 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

Python 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.