Có thể nén một số loại dữ liệu, chẳng hạn như văn bản của con người hoặc mã nguồn, với các ngữ pháp đường thẳng. Về cơ bản, bạn tạo một ngữ pháp có ngôn ngữ có chính xác một từ - dữ liệu không nén. Trong tác vụ này, bạn phải viết một chương trình thực hiện phương pháp tính toán dữ liệu này.
Đầu vào
Đầu vào là một chuỗi có độ dài không quá 65535 byte. Nó được đảm bảo rằng đầu vào khớp với biểu thức chính quy [!-~]+
(tức là ít nhất một ký tự ASCII có thể in được, ngoại trừ khoảng trắng).
Một ví dụ đầu vào là
abcabcbcbcabcacacabcabab
Đầu ra
Đầu ra là một tập hợp các quy tắc tạo thành một ngữ pháp mô tả chính xác một từ (đầu vào). Mỗi nonterminal được ký hiệu bằng một số thập phân lớn hơn 9. Biểu tượng bắt đầu là ký hiệu số mười. Một đầu ra ví dụ tương ứng với đầu vào ví dụ được đưa ra dưới đây; cú pháp của nó được mô tả thêm dưới đây:
10=11 11 12 12 11 13 13 11 14 14
11=a 12
12=b c
13=a c
14=a b
Mỗi quy tắc có dạng <nonterminal>=<symbol> <symbol> ...
với một số ký hiệu được phân tách bằng khoảng trắng tùy ý ở phía bên phải. Mỗi đầu ra tuân theo các hạn chế sau và xuất phát chính xác chuỗi đầu vào là hợp lệ.
Những hạn chế
Để ngăn mọi người làm những việc lạ, một số hạn chế đang diễn ra:
Mỗi nonterminal phải xuất hiện ít nhất hai lần ở bên phải của quy tắc. Chẳng hạn, ngữ pháp sau đây cho đầu vào
abcabc
là bất hợp pháp vì quy tắc 12 chỉ xuất hiện một lần:10=12 11=a b c 12=11 11
Không có chuỗi hai biểu tượng liền kề có thể xuất hiện nhiều hơn một lần ở tất cả các phía bên phải của tất cả các quy tắc, ngoại trừ nếu chúng trùng nhau. Chẳng hạn, ngữ pháp sau đây cho đầu vào
abcabcbc
là bất hợp pháp vì chuỗibc
xuất hiện hai lần:10=11 11 b c 11=a b c
Một ngữ pháp hợp lệ sẽ là:
10=11 11 12 11=a 12 12=b c
Chương trình của bạn phải chấm dứt sau chưa đầy một phút cho mỗi đầu vào hợp lệ không dài hơn 65535 byte.
Như thường lệ, bạn không được sử dụng bất kỳ phương tiện ngôn ngữ nào hoặc bất kỳ chức năng thư viện nào làm cho giải pháp trở nên tầm thường hoặc thực hiện một phần lớn ngôn ngữ đó.
Đầu vào mẫu
Tạo đầu vào mẫu với chương trình C sau.
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv) {
unsigned int i,j = 0,k;
if (argc != 3
|| 2 != sscanf(argv[1],"%u",&i)
+ sscanf(argv[2],"%u",&k)) {
fprintf(stderr,"Usage: %s seed length\n",argv[0]);
return EXIT_FAILURE;
}
srand(i);
while(j < k) {
i = rand() & 0x7f;
if (i > 34 && i != 127) j++, putchar(i);
}
return EXIT_SUCCESS;
}
Đầu vào mẫu được tạo bởi chương trình trên thường sẽ không cho kết quả nén tốt. Xem xét sử dụng văn bản của con người hoặc mã nguồn làm đầu vào ví dụ.
Tiêu chí chiến thắng
Đây là mã golf; chương trình có mã nguồn ngắn nhất sẽ thắng. Để có thêm tín dụng, hãy viết chương trình tái tạo đầu vào từ đầu ra.