ตัวละคร 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
Arcturus

เช่นเดียวกับ @Eridan กล่าวว่านี่เป็นการเข้ารหัสที่สูญเสียเนื่องจากลำดับคี่จะทำให้อักขระตัวสุดท้ายหลุดออกมา แม้ว่าฉันจะแน่ใจว่าผู้สังเกตการณ์ไม่รู้มันอาจเป็นวิธีการสื่อสารที่น่า
สะอิดสะเอียน

1
ขั้นตอนที่ 1 ทำให้เกิดความสับสน - ไม่จำเป็นต้องแปลงตัวอักษรเป็นเลขฐานสิบหก - ในตัวอย่าง: Hคือ ASCII 72 (ฐานสิบ) หรือ 48 (ฐานสิบหก) แต่สิ่งที่ฉันต้องการคือ 200 (ฐาน 6) ตัวอย่างแถวที่ 2 ทั้งหมดไม่มีประโยชน์และทำให้สับสนในความคิดของฉัน
edc65

คำตอบ:


5

Pyth - 22 ไบต์

หวังว่าจะเล่นกอล์ฟได้มากขึ้นตรงไปตรงมา

sfq3l`TmCid16csjRQCMz2

ลองมันออนไลน์ได้ที่นี่


q3l`Tเป็นสิ่งที่ยอดเยี่ยม
isaacg

ไม่ควรfgTdจะเพียงพอหรือ
Jakube


3

Bash + utils ทั่วไปของ 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

@Aaron -eงานนั่นจนกระทั่งสายป้อนคือ ลองecho -n "-e"
บาดเจ็บทางดิจิตอล

ประณามด่างอย่าง!
Aaron

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 มีอยู่เฉพาะใน Perm Permalink และมองไม่เห็นแม้กระทั่งที่นั่น
เดนนิส

ฉันหมายถึง ... ลบเป็นอักขระควบคุม แต่ไม่ใช่อักขระ 32 ตัวแรก เป็นหมายเลขอักขระ 127, 0x7F สำหรับผู้ที่ไม่คุ้นเคยกับ ASCII
wizzwizz4

ฉันไม่แน่ใจว่าฉันเข้าใจคำถามของคุณหรือไม่ คุณสงสัยหรือไม่ว่าฉันจะกรองจากเอาต์พุตหรือไม่?
เดนนิส

ใช่. คำอธิบายรหัสของคุณดูเหมือนจะไม่พูดว่าคุณกรองDELอักขระจากผลลัพธ์อย่างไร
wizzwizz4

2

JavaScript (ES6), 137 147

การใช้ฟังก์ชั่น verbose ส่วนใหญ่ที่มีอยู่ใน 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 ฉันไม่พบวิธีที่จะใช้คำใบ้ของคุณ (นอกเหนือจากการใช้ array comprehension นั่นคือ ES7) แต่คุณกดฉันเพื่อคิดใหม่ทั้งหมด ขอบคุณ. ฉันหวังว่าคุณจะรักษา +1 ของคุณแม้ว่าx=>x>=จะผ่านไปแล้ว
edc65

1
เกิดอะไรขึ้นกับการใช้ ES7
Ypnypn

1
@Ypnypn ฉันต้องการคำตอบที่สามารถทำงานได้แม้กับเครื่องมือ javascript subpar <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...])))))

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 ไบต์ )
Cristian Lupascu

@ w0lf นั่นจะเป็นการเข้ารหัสแบบ UTF-8 แต่เนื่องจากตัวละครทั้งหมดน้อยกว่า 256 ตัวเราจึงสามารถนับเป็นหนึ่งไบต์ได้อย่างปลอดภัย
Downgoat

1

ทับทิม 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}

การทดสอบแบบออนไลน์ที่นี่


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"]ส่งค่าไป

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.