다이나믹 ASCII 인코더!


16

소개

일부 ASCII 문자는 요즘 너무 비쌉니다 ...

돈을 절약하기 위해 값 비싼 문자를 저렴한 문자로 인코딩하는 프로그램을 작성하기로 결정했습니다.

그러나 문자 가격은 자주 변경되므로 다른 문자를 인코딩하거나 디코딩해야 할 때마다 프로그램을 수정하고 싶지 않습니다! 보다 역동적 인 솔루션이 필요합니다.

도전

당신의 임무는 인코더디코더의 두 가지 프로그램을 작성 하는 것 입니다.

인코더는 다섯 개 저렴한 문자 목록, 단일 비싼 문자를 받아 들여야한다.

고가의 문자를 인코딩하는 저렴한 문자로 구성된 단일 문자열을 출력해야합니다.

이 문자열 저렴하게 유지하기 위해 4자를 초과 할 수 없습니다 . 그러나 인코딩에서 저렴한 문자를 모두 사용할 필요는 없으며 인코딩의 길이가 다를 수 있습니다.


디코더는 상기 인코더에 의해 출력 된 문자열 출력 비싼 문자를 수락한다.

디코더는 인코딩 된 문자열 이외의 입력을받지 않아야합니다. (유효한) 입력 조합에 대해 인코더 출력에서 ​​수정되지 않은 상태로 작동해야합니다. 다시 말해, 디코더 프로그램 은 어떤 문자가 비싸거나 저렴한 지 알지 못합니다.

채점

최단 결합 코드 승리!

노트

  • 모든 문자는 대문자 [A-Z], 소문자 [a-z]또는 숫자 [0-9]입니다.

  • 저렴한 문자 목록에는 중복 문자가 포함되지 않습니다. 저렴하고 비싸지 않은 캐릭터는 없습니다.

  • 인코더와 디코더는 같은 언어로 작성 될 필요는 없지만 가능합니다. 프로그램이나 함수를 작성할 수 있습니다.

  • 입력 및 출력은 사용자 언어에 적합한 형식 일 수 있습니다.

  • 두 프로그램은 변수 나 데이터를 공유 할 수 없습니다.

요약

  • 저렴한 문자와 값 비싼 문자를 인코더에 입력합니다.

  • 인코더는 고가의 문자를 인코딩하여 저렴한 문자의 문자열을 출력합니다.

  • 디코더에는 인코더의 출력이 주어지고 값 비싼 문자가 출력됩니다.

입력:     a, b, c, d, e     f

엔코더 가능성 :     a     eeee     caec

디코더 :     f


입력:     a, b, c, d, e     h

엔코더 가능성 :     bc     cea     eeaa

디코더 :     h


입력:     q, P, G, 7, C     f

엔코더 가능성 :     777     P7     PPCG

디코더 :     f


이것은 정말로 나일 수 있으며, 그렇다면이 질문에 대해 사과하지만 저렴한 문자로 메시지를 어떻게 정확하게 인코딩해야합니까? 5 개의 저렴한 문자에 ASCII 코드를 추가 하시겠습니까? 실제로,이 질문은 디코더가 생성 된 모든 인코딩 가능성을 디코딩해야하는 경우에만 기초를두고 있습니다.
cole

명확하게하려면 다음 인코더 가능성이 그래, 단지 예, 우리가 원하는대로 우리가 각 문자를 인코딩 할 수 있습니다?
Dennis

@Dennis 네, 그저 예일뿐입니다.
jrich

@Cole 실제 알고리즘을 포기하지 않으면 이것이 주요 도전이므로 가능하다고 생각합니다. 인코딩 할 수있는 고가의 문자는 62 개 뿐이며 A239914 에 따르면이 4 개의 ASCII 문자를 사용하여 최대 92 개의 문자를 인코딩 할 수 있습니다 . (이것에 대한 PhiNotPi의 샌드 박스 주석 덕분에 엄청나게 감사했습니다-인코딩 가능한 수를 정확하게 계산하지 못했습니다)
jrich

@UndefinedFunction 나는 당신이 의도 한 것을 지금 알고 있습니다 : Dennis의 질문은 내가 혼란 스러웠던 것에 대답했습니다.
cole

답변:


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 구문 시트가 있습니까? sourceforge에있는 것과 다른 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 개만 사용하기 때문입니다.

이들은 일회용입니다. 두 번째 코드를 입력하려면 다시 시작해야합니다. 인코딩하려면 입력에 쉼표 뒤의 공백이 필요합니다.

내가 생각한 것

첫 번째 질문은 "이 디코더는이 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

그러나 나는 그 아이디어를 어쨌든 좋아한다.

입력의 문자는 이미 관계가 있기 때문에이 두 가지를 결합 할 수 있다는 사실에 놀랐습니다.

작동 원리

참고 : 이것은 더 이상 골프 버전이 작동하는 방식이 아니지만 원리는 동일하게 유지되었습니다.

디코더의 경우 :

가장 큰 자릿수가 해당 숫자의 고유 자릿수보다 크지 않은 4 자리 숫자를 모두 포함하는 인덱스가 배열로 구성됩니다. 해당 조건을 충족하는 75 개의 서로 다른 4 자리 숫자가 있습니다. 나는 그것들을 구성하는 방법을 알아낼 수 없었기 때문에 그들을 무차별 대입했다. 나는 이것들을 발견하면서 고가의 문자를 우연한 순서로 할당합니다.

그런 다음 입력 문자열의 모든 문자를 숫자로 바꿉니다. 가장 작은 숫자 (예 : 'a'보다 'B'가 작음)는 1이되고, 두 번째 가장 작은 숫자는 2가됩니다. 따라서 최대 4까지입니다. 결과 문자열이됩니다.

그런 다음 해당 문자열을 인덱스로 갖는 배열 요소를 간단히 인쇄합니다.

인코더가 그에 따라 작동합니다.

사용하는 방법

awk bash line 명령으로 직접 코드를 복사하거나 두 개의 파일 "encode.awk"및 "decode.awk"를 작성하고 그에 따라 코드를 붙여 넣으십시오. 또는 en / decoding 후에 자동으로 종료되거나 끝에서 exit 명령을 제거하여 여러 번 사용할 수있는 다음 코드를 사용하는 것이 좋습니다.

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
이것은 독창적 인 약한 조합 (자릿수보다 크지 않은 숫자를 묘사 한)이 실행 가능한 접근법이라는 것을 알지 못한다는 점을 제외하고는 내 사고 과정과 매우 유사했습니다. 다음을 통과하는 데 도움이됩니다.
패트릭 로버츠
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.