ตัวเข้ารหัส ASCII แบบไดนามิก!


16

บทนำ

วันนี้อักขระ ASCII บางตัวแพงมาก ...

เพื่อเป็นการประหยัดเงินคุณได้ตัดสินใจเขียนโปรแกรมที่เข้ารหัสอักขระที่มีราคาแพงโดยใช้โปรแกรมที่ไม่แพง

อย่างไรก็ตามราคาตัวละครเปลี่ยนแปลงบ่อยและคุณไม่ต้องการแก้ไขโปรแกรมของคุณทุกครั้งที่คุณจำเป็นต้องเข้ารหัสหรือถอดรหัสอักขระที่แตกต่างกัน! คุณจะต้องแก้ปัญหาแบบไดนามิกมากขึ้น

ท้าทาย

งานของคุณคือการเขียนโปรแกรมที่สอง: การเข้ารหัสและถอดรหัส

โปรแกรมเปลี่ยนไฟล์ควรยอมรับรายชื่อตัวละครราคาไม่แพงห้าตัวและตัวอักษรตัวเดียวที่มีราคาแพง

มันควรส่งออกสายเดียวที่ประกอบด้วยอักขระที่ไม่แพงซึ่งเข้ารหัสอักขระที่มีราคาแพง

สตริงนี้ อาจมีความยาวไม่เกิน 4 ตัวอักษรเพื่อให้ราคาไม่แพง อย่างไรก็ตามไม่จำเป็นต้องใช้อักขระที่ไม่แพงทั้งหมดในการเข้ารหัสและการเข้ารหัสอาจมีความยาวต่างกัน


ถอดรหัสควรจะยอมรับสตริงออกมาโดยการเข้ารหัสและการส่งออกเป็นตัวละครที่มีราคาแพง

ตัวถอดรหัสจะต้องไม่รับอินพุตอื่นนอกจากสตริงที่เข้ารหัส มันจะต้องทำงานไม่ถูกแก้ไขจากเอาท์พุทของเครื่องเข้ารหัสสำหรับการรวมกันของอินพุต (ถูกต้อง) กล่าวอีกนัยหนึ่งโปรแกรมถอดรหัสของคุณ ไม่ทราบว่าอักขระตัวใดที่มีราคาแพงหรือไม่แพง

เกณฑ์การให้คะแนน

รหัสรวมที่สั้นที่สุดชนะ!

หมายเหตุ

  • ตัวละครทุกตัวจะมีตัวอักษรพิมพ์ใหญ่ทั้ง[A-Z]ตัวอักษรตัวพิมพ์เล็กหรือหมายเลข[a-z][0-9]

  • รายการของตัวละครที่ไม่แพงจะไม่มีการซ้ำซ้อน ตัวละครจะไม่มีทั้งราคาไม่แพงและแพง

  • ตัวเข้ารหัสและตัวถอดรหัสไม่จำเป็นต้องเขียนในภาษาเดียวกัน แต่สามารถเป็นได้ คุณสามารถเขียนโปรแกรมหรือฟังก์ชั่น

  • อินพุตและเอาต์พุตอาจอยู่ในรูปแบบที่เหมาะสมสำหรับภาษาของคุณ

  • โปรแกรมทั้งสองไม่สามารถแบ่งปันตัวแปรหรือข้อมูลใด ๆ

สรุป

  • ป้อนข้อมูลของอักขระที่ไม่แพงบางตัวและอักขระที่มีราคาแพงได้รับการเข้ารหัส

  • เอ็นโค้ดเดอร์แสดงสตริงอักขระที่ไม่แพงและเข้ารหัสอักขระราคาแพง

  • ถอดรหัสจะได้รับเอาท์พุทของเครื่องเข้ารหัสและส่งออกอักขระที่มีราคาแพง

ตัวอย่าง

การป้อนข้อมูล:     a, b, c, d, e     f

ความเป็นไปได้ของ Encoder:     a     eeee     caec

ถอดรหัส:     f


การป้อนข้อมูล:     a, b, c, d, e     h

ความเป็นไปได้ของ Encoder:     bc     cea     eeaa

ถอดรหัส:     h


การป้อนข้อมูล:     q, P, G, 7, C     f

ความเป็นไปได้ของ Encoder:     777     P7     PPCG

ถอดรหัส:     f


นี่อาจเป็นฉันจริง ๆ และฉันขอโทษสำหรับคำถามนี้ถ้าเป็นเช่นนั้น แต่คุณจะเข้ารหัสข้อความของคุณด้วยอักขระที่ไม่แพงได้อย่างไร การเพิ่มรหัส ASCII สำหรับอักขระราคาไม่แพง 5 ตัวหรือไม่ ที่จริงแล้วคำถามนี้มีพื้นฐานถ้าตัวถอดรหัสของคุณต้องถอดรหัสสำหรับความเป็นไปได้การเข้ารหัสทั้งหมดที่สร้างขึ้น
โคล

เพื่อความชัดเจน: ความเป็นไปได้ของ Encoder เป็นเพียงตัวอย่างและเราสามารถเข้ารหัสอักขระแต่ละตัวตามที่เราต้องการใช่ไหม
เดนนิส

@Dennis ใช่นั่นเป็นเพียงตัวอย่าง
กริช

@ โคลโดยไม่ต้องแจกอัลกอริทึมจริงเพราะนี่คือความท้าทายหลักที่นี่ฉันเชื่อว่ามันเป็นไปได้ มีเพียง 62 ตัวอักษรที่มีราคาแพงไปได้ที่จะมีการเข้ารหัสและด้วยเหล่าตัวละคร 4 ASCII ถึง 92 สามารถเข้ารหัสตามA239914 (ขอบคุณมากที่แสดงความคิดเห็น Sandbox PhiNotPi สำหรับคนนี้ - ฉันไม่ได้คำนวณว่ากี่อาจจะเข้ารหัส)
jrich

@Undefined ฟังก์ชั่นฉันรู้ว่าสิ่งที่คุณตั้งใจ: คำถามของเดนนิสตอบสิ่งที่ฉันสับสน
โคล

คำตอบ:


5

Pyth, 46 ไบต์

ตัวเข้ารหัส 22 ไบต์

@smfql{Td^<Szd4S4-Cw48

ถอดรหัส 24 ไบต์

C+48xsmfql{Td^<sS{zd4S4z

ว้าวที่เหมาะอย่างสมบูรณ์แบบ 75 ชุดค่าผสมที่แตกต่างกันและชุดช่วง 75
Jakube

ฉันคิดว่าคุณสามารถแทนที่S4ด้วยTและบันทึกแต่ละไบต์ในทั้งสองโปรแกรม
Jakube

7

CJam, 55 50 48 47 ไบต์

ตัวเข้ารหัส24 22 21 ไบต์

l$:L4m*{$L|L=},rc'0-=

ลองออนไลน์

ตัวถอดรหัส31 28 27 26 ไบต์

4_m*{$4,|4,=},l_$_|f#a#'0+

ลองออนไลน์


คุณมีแผ่นงาน CJam หรือไม่? หนึ่งในซอร์สโค้ดและชีท PDF อื่น ๆ ไม่มีอักขระทั้งหมดที่คุณใช้เช่น'
Luminous

'ไม่ใช่ผู้ประกอบการ คุณสามารถค้นหาได้ในหน้าไวยากรณ์
Dennis

4

เหยี่ยว, 163 + 165 = 328

ทดสอบกับ gawk 4.1.1 แต่ควรทำงานใน gawk เวอร์ชั่นเก่าเช่นกัน จำเป็นต้องได้รับการแก้ไขเล็กน้อย (ยาวขึ้น) เพื่อทำงานกับ mawk

เข้ารหัส (163):

{for(gsub(", ",_);sprintf("%c",++r)!=$NF;asort(a))split($1,a,_);r-=r>64?53:46;for(k=4^5;r-=_~i;j=_)for(i=++k;gsub(++j,_,i);)split(k,b,_);for(j in b)printf a[b[j]]}

ถอดรหัส (165):

{split($1,a,_);for(i in a)d[a[i]]=a[i];asort(d);for(k=4^5;c!~$1;x+=_~i){i=++k;for(c=j=_;gsub(++j,_,i);split(k,b,_));for(g in b)c=c d[b[g]]}printf"%c",x+(x>10?54:47)}

มันใช้งานได้ แต่ฉันรู้ว่านี่อาจไม่ใช่วิธีที่ดีที่สุดสำหรับสิ่งนี้ ฉันไม่รู้ว่าตัวอักษรราคาไม่แพงตัวที่ห้านั้นเป็นเพราะฉันใช้แค่สี่ตัวเท่านั้น

สิ่งเหล่านี้มีไว้สำหรับการใช้งานเพียงครั้งเดียวเท่านั้น หากคุณต้องการป้อนรหัสที่สองคุณต้องเริ่มต้นใหม่ ช่องว่างหลังจากเครื่องหมายจุลภาคจำเป็นต้องใช้ในการป้อนข้อมูลในการเข้ารหัส

สิ่งที่ฉันคิดเกี่ยวกับ

คำถามแรกของฉันคือ "ตัวถอดรหัสจะได้อะไรจากอักขระ 4 ตัวนี้" (ฉันจะเรียกพวกเขาว่า a, b, c และ d) และความคิดเริ่มต้นของฉันคือรับข้อมูล 6 บิตจากความสัมพันธ์ต่อไปนี้:

a>b
a>c
a>d
b>c
b>d
c>d

ว้าว 6 บิตนั่นยอดเยี่ยมมาก! ฉันคิดว่ามันเป็นอัจฉริยะ แต่การทดสอบแสดงให้เห็นว่านี่จะไม่ทำงาน มีเพียง 24 ชุดค่าผสมที่เป็นไปได้ ประณาม.

ขั้นตอนต่อไปคือการพยายามนับตามสิ่งที่ฉันรู้แล้ว ดังนั้นตัวอักษรตัวแรกที่ปรากฏในสตริงจะกลายเป็น 0 ดังนั้นตัวอักษรตัวที่สองที่แนะนำในสตริงจะกลายเป็น 1 เป็นต้น แต่มันจะไม่นำพาฉันไปสู่ชุดค่าผสม 62 อย่างที่ฉันต้องการ

0000
0001
0010
0011
0012
0100
0101
0102
0110
0111
0112
0120
0121
0122
0123

แต่ฉันชอบความคิด แต่อย่างใด

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

มันทำงานอย่างไร

หมายเหตุ: นี่ไม่ใช่วิธีการทำงานของรุ่น golfed อีกต่อไป แต่หลักการยังคงเหมือนเดิม

สำหรับตัวถอดรหัส:

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

จากนั้นฉันจะแทนที่อักขระทุกตัวจากสตริงอินพุตด้วยตัวเลข ขนาดเล็กที่สุด (ตัวอย่างเช่น 'B' เล็กกว่า 'a') กลายเป็น 1, ขนาดเล็กที่สุดที่สองกลายเป็น 2 และอื่น ๆ จนถึง 4 แน่นอนขึ้นอยู่กับจำนวนอักขระที่แตกต่างกันในอินพุตสิ่งที่ตัวเลขสูงสุดใน สตริงผลลัพธ์จะเป็น

จากนั้นฉันก็พิมพ์องค์ประกอบอาร์เรย์ซึ่งมีสตริงนั้นเป็นดัชนี

เครื่องเข้ารหัสทำงานตาม

วิธีใช้

ให้คัดลอกรหัสโดยตรงในคำสั่ง awk bash line หรือสร้างสองไฟล์ "encode.awk" และ "decode.awk" และวางรหัสตามนั้น หรือดียิ่งขึ้นใช้รหัสต่อไปนี้ซึ่งออกโดยอัตโนมัติหลังจาก en / ถอดรหัสหรือสามารถใช้หลายครั้งโดยการลบคำสั่งออกในตอนท้าย

encode.awk

{
    if(!x) # only do first time
        for(i=1e3;i++<5e3;delete a)
        {
            for(m=j=0;p=substr(i,++j,1);p>m?m=p:0)++a[p];
            length(a)>=m&&i!~0?c[(x>9?55:48)+x++]=i:_
        }
    r=u=_; # clear reused variables 
    for(gsub(",",FS);sprintf("%c",++r)!=$NF;); # more flexible concerning
    --NF;                                      # spaces in input
    split($0,b);
    asort(b);
    split(c[r],a,_);
    for(j in a)u=u b[a[j]]; # prettier printing than golfed version
    print u
    exit # <=== remove to encode input file
}

decode.awk

{
    if(!x) # only do first time 
        for(i=1e3;i++<5e3;delete a)
        {
            for(m=j=0;p=substr(i,++j,1);p>m?m=p:_)++a[p];
            length(a)>=m&&i!~0?c[i]=sprintf("%c",(x>9?55:48)+x++):_
        }
    delete t; delete d; o=_; # clear reused variables 
    split($1,a,_);
    for(i in a)t[a[i]]=1;
    for(i in t)d[++y]=i;
    asort(d);
    for(i in a)for(j in d)if(d[j]~a[i])o=o j;
    print c[o]
    exit # <=== remove to encode input file
}

นี่คือตัวอย่างการใช้งาน:

me@home:~/$ awk -f encode.awk
w, 0, R, 1, d X
10R1
me@home:~/$ awk -f decode.awk
10R1
X

โปรดจำไว้ว่าต้องใช้พื้นที่หลังจากแต่ละเครื่องหมายจุลภาคหากคุณใช้เวอร์ชันที่ตีกอล์ฟ

หากคุณต้องการคุณสามารถใช้สคริปต์สั้นและสกปรกนี้เพื่อสร้างข้อมูลตัวอย่าง

BEGIN{
    for(srand();i++<1000;)
    {
        erg="";
        for(j=0;j++<5;)
        {
            while(erg~(a[j]=substr(c="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",rand()*62+1,1)));
            erg=erg a[j]
        }
        print a[1]", "a[2]", "a[3]", "a[4]", "a[5](rand()>.5?" ":rand()>.5?"  ":"   ")substr(c,rand()*62+1,1)
    }
}

และทำสิ่งที่ตลกเช่น

me@home:~/$ awk -f gen.awk|awk -f encode.awk|awk -f decode.awk|sort -u|wc -l
62

ฉันเห็นสิ่งนี้มากกว่าเป็นตัวต่อการเขียนโปรแกรม ฉันคิดว่ามันน่าเศร้านิดหน่อยที่เกือบทุกอย่างในที่นี้จะถูกตีกอล์ฟเพราะคุณสามารถเรียนรู้ได้มากขึ้นจากรหัสที่อ่านง่าย แต่เป็นเพียงความคิดเห็นของฉัน และฉันก็เล่นกอล์ฟตามที่ขอ;)


วิธีทดสอบ โปรดแบ่งปันตัวอย่าง
Shravan Yadav

+1 สำหรับคำอธิบายที่ยอดเยี่ยม! ดูเหมือนว่ามีหลายวิธีที่จะเข้าถึงปัญหานี้ :)
jrich

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