개크, 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
나는 이것을 프로그래밍 퍼즐로 더 많이 보았다. 잘 문서화되고 읽을 수있는 코드에서 더 많은 것을 배울 수 있기 때문에 여기에있는 거의 모든 것이 골치 거리는 것은 조금 슬프다 고 생각합니다. 그러나 그것은 단지 제 의견입니다. 그리고 나는 그것을 요청한 것처럼 골프했다;)