chim ưng, 163 + 165 = 328
Đã thử nghiệm với gawk 4.1.1, nhưng cũng nên hoạt động trong các phiên bản gawk cũ hơn. Cần phải sửa đổi một chút (kéo dài) để làm việc với mawk.
bộ mã hóa (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]]}
bộ giải mã (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)}
Vâng, nó hoạt động, nhưng tôi biết rằng đây có thể không phải là cách tiếp cận tốt nhất cho việc này. Tôi không biết bức thư rẻ tiền thứ năm dùng để làm gì, vì tôi chỉ sử dụng bốn.
Đây chỉ là cho sử dụng duy nhất. Nếu bạn muốn nhập mã thứ hai, bạn phải khởi động lại chúng. Các khoảng trắng sau dấu phẩy được yêu cầu trong đầu vào để mã hóa.
Những gì tôi nghĩ về
Câu hỏi đầu tiên của tôi là "Bộ giải mã có thể nhận được gì từ 4 ký tự này?" (Tôi sẽ gọi chúng là a, b, c và d) và ý tưởng ban đầu của tôi là lấy 6 bit Thông tin từ các mối quan hệ sau:
a>b
a>c
a>d
b>c
b>d
c>d
Wow, 6 bit, thật hoàn hảo! Tôi nghĩ rằng đó là thiên tài, nhưng thử nghiệm cho thấy điều này sẽ không hoạt động. Chỉ có 24 kết hợp có thể. Chỉ trích.
Bước tiếp theo là cố gắng đếm, dựa trên những gì tôi đã biết. Vì vậy, chữ cái đầu tiên xuất hiện trong chuỗi sẽ trở thành 0, sau đó chữ cái thứ hai được giới thiệu trong chuỗi sẽ trở thành 1 và cứ thế. Nhưng nó sẽ không mang lại cho tôi tất cả các cách kết hợp 62 cần thiết.
0000
0001
0010
0011
0012
0100
0101
0102
0110
0111
0112
0120
0121
0122
0123
Nhưng dù sao tôi cũng thích ý tưởng đó.
Chà, sau đó tôi nhận ra rằng tôi có thể kết hợp cả hai, bởi vì các nhân vật trong đầu vào đã có quan hệ và tôi sẽ không phải đợi cho đến khi chúng được giới thiệu để cho chúng một giá trị.
Làm thế nào nó hoạt động
Lưu ý: Đây không còn chính xác là cách các phiên bản golf hoạt động, nhưng nguyên tắc vẫn giữ nguyên.
Đối với bộ giải mã:
Một mảng được xây dựng, có chỉ mục chứa tất cả bốn số có chữ số lớn nhất không lớn hơn số chữ số riêng biệt trong số đó. Có 75 số bốn chữ số khác nhau đáp ứng điều kiện đó. Tôi vũ phu ép buộc họ, bởi vì cho đến nay tôi không thể tìm ra cách nào để xây dựng chúng, và tôi không chắc điều này sẽ ngắn hơn để làm trong awk. Trong khi tôi tìm thấy chúng, tôi gán cho chúng các ký tự đắt tiền theo thứ tự asciibory.
Sau đó, tôi thay thế mọi ký tự từ chuỗi đầu vào bằng một chữ số. Nhỏ nhất (ví dụ: 'B' nhỏ hơn 'a') trở thành 1, nhỏ nhất thứ hai trở thành 2, và lên đến 4. Tất nhiên, nó phụ thuộc vào số lượng ký tự khác nhau trong đầu vào, chữ số cao nhất trong chuỗi kết quả sẽ là.
Sau đó, tôi chỉ cần in phần tử mảng, có chuỗi đó là một chỉ mục.
Bộ mã hóa hoạt động tương ứng.
Cách sử dụng
Sao chép mã trực tiếp trong lệnh awk bash line hoặc tạo hai tệp "encode.awk" và "decode.awk" và dán mã tương ứng. Hoặc thậm chí tốt hơn là sử dụng mã sau, tự động thoát ra sau khi giải mã hoặc có thể được sử dụng nhiều lần bằng cách loại bỏ lệnh thoát ở cuối.
mã hóa.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
}
giải mã.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
}
Dưới đây là một ví dụ sử dụng:
me@home:~/$ awk -f encode.awk
w, 0, R, 1, d X
10R1
me@home:~/$ awk -f decode.awk
10R1
X
Hãy nhớ rằng không gian sau mỗi dấu phẩy là bắt buộc, nếu bạn sử dụng các phiên bản golf.
Nếu bạn muốn, bạn có thể sử dụng tập lệnh ngắn và bẩn này để tạo một số dữ liệu mẫu
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)
}
}
và làm một cái gì đó buồn cười như
me@home:~/$ awk -f gen.awk|awk -f encode.awk|awk -f decode.awk|sort -u|wc -l
62
Tôi đã xem điều này nhiều hơn như một câu đố lập trình. Tôi nghĩ rằng có một chút buồn, rằng hầu hết mọi thứ ở đây đều được đánh gôn, bởi vì bạn có thể học được nhiều hơn từ mã tài liệu tốt, có thể đọc được, nhưng đó chỉ là ý kiến của tôi. Và tôi đã chơi nó như yêu cầu;)