アスキーキャラクタージャンブル


24

印刷可能な文字(ASCII 20-7E)とn[2,16]の整数で構成される文字列を入力として受け取り、文字列に対して次の変更を実行するプログラムを作成します。

  • 文字列内の各文字はASCIIコードに変換されます(指定された例は16進数ですが、10進数も受け入れられます)。
  • ASCIIコードはベースに変換されn、一緒に連結されます。
  • 新しい文字列は1文字おきに分割されます。奇数の文字がある場合、最後の文字は完全に削除されます。
  • 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リソス

いつかこれをやる!
anOKsquirrel

@ΚριτικσιΛίθοςプログラムはすべての入力文字列に対して機能しますが、すべての出力文字列が一意ではありません。例えば、ベースでは7、文字列はJ手順を行くだろうJ> - 50- > 101- > 10- > (no output)、などだろう文字列KL
アークトゥルス

@Eridanが言ったように、これは奇数シーケンスが最後の文字を切り落とすため、損失の多い暗号化です。私は無知なオブザーバーに確信しているが、それはコミュニケーションの
卑劣

1
ステップ1はわかりにくい-文字を16進数に変換する必要はありません-例では:HASCII 72(10進数)または48(16進数)ですが、必要なのは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"
デジタルトラウマ

くそー、きれいに見つけた!
アーロン

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文字の1つではありません。ASCIIに慣れていない人のための文字番号127、0x7Fです。
-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)


+1x=>x>=
Ypnypn

[for(z of ...)if(...)...]代わりにmap(...).filter(...)
-Ypnypn

@Ypnypn(ES7である配列内包表記を使用する以外に)あなたのヒントを使用する方法を見つけられませんでしたが、あなたは私にそれをすべて再考するように圧力をかけました。THX。x=>x>=行っても+1を維持することを願っています
-edc65

1
ES7の使用の何が問題になっていますか?
Ypnypn

1
@Ypnypn下位の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

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±µ

比較的簡単ですが、楽しく短いです。私はおそらくいくつかのより多くの演算子でいくつかのより多くのキャラクターをたたくことができます。他のいくつかの新機能を使用して、いくつかのバイトを削減することもできます。

アンゴルフ&&説明

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

1
これは23 文字(29 バイト)の長さだと思います。
クリスチャンルパスク

@ w0lfこれはUTF-8エンコーディングで行われますが、すべての文字が256未満であるため、1バイトとして安全にカウントできます
-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]。一度に2文字以上を反復処理する場合、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))

入力として文字列sと整数nを受け取る関数kを書きました。例えば:

k('Hello, World!',6)

与える

 E001R"31$E

回避する必要があった最も厄介なことは、ベースnに変換するときにゼロが現れることです。2文字ごとに分割されるはずだった配列からこれらを取得するには、かなりのバイトがかかります。このアプローチを使用してさらにバイトを保存できるかどうかはわかりません。


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"]

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.