เป็นไปได้ที่จะบีบอัดข้อมูลบางประเภทเช่นข้อความของมนุษย์หรือซอร์สโค้ดด้วยไวยากรณ์แบบเส้นตรง โดยทั่วไปคุณสร้างไวยากรณ์ที่ภาษามีคำเดียว - ข้อมูลที่ไม่ได้บีบอัด ในงานนี้คุณต้องเขียนโปรแกรมที่ใช้วิธีการประมวลผลข้อมูลนี้
อินพุต
อินพุตเป็นสตริงที่มีความยาวไม่เกิน 65535 ไบต์ มีการประกันว่าอินพุตนั้นตรงกับนิพจน์ทั่วไป[!-~]+
(เช่นอย่างน้อยหนึ่งตัวอักษร ASCII ที่พิมพ์ได้ซึ่งไม่รวมช่องว่าง)
ตัวอย่างอินพุตคือ
abcabcbcbcabcacacabcabab
เอาท์พุต
เอาท์พุทเป็นชุดของกฎที่เป็นไวยากรณ์ที่อธิบายว่าหนึ่งคำ (อินพุต) แต่ละ nonterminal จะแทนด้วยตัวเลขทศนิยมมากกว่า 9 สัญลักษณ์เริ่มต้นคือหมายเลขสัญลักษณ์สิบ เอาต์พุตตัวอย่างที่สอดคล้องกับอินพุตตัวอย่างได้รับด้านล่าง ไวยากรณ์ของมันจะอธิบายเพิ่มเติมด้านล่าง:
10=11 11 12 12 11 13 13 11 14 14
11=a 12
12=b c
13=a c
14=a b
แต่ละกฎมีรูปแบบที่<nonterminal>=<symbol> <symbol> ...
มีจำนวนของสัญลักษณ์ที่คั่นด้วยช่องว่างโดยพลการทางด้านขวา แต่ละเอาต์พุตที่ปฏิบัติตามข้อ จำกัด ต่อไปนี้และได้รับสตริงอินพุตที่ถูกต้อง
ข้อ จำกัด
เพื่อที่จะหยุดคนไม่ให้ทำสิ่งที่แปลกประหลาดมีข้อ จำกัด มากมายเกิดขึ้น:
แต่ละ nonterminal ต้องปรากฏอย่างน้อยสองครั้งทางด้านขวาของกฎ ตัวอย่างเช่นไวยากรณ์ต่อไปนี้สำหรับอินพุตไม่
abcabc
ถูกต้องเนื่องจากกฎ 12 ปรากฏเพียงครั้งเดียว:10=12 11=a b c 12=11 11
ไม่มีลำดับของสัญลักษณ์สองตัวที่อยู่ติดกันอาจปรากฏมากกว่าหนึ่งครั้งในด้านขวามือของกฎทั้งหมดยกเว้นว่ามีการทับซ้อนกัน ตัวอย่างเช่นไวยากรณ์ต่อไปนี้สำหรับอินพุตไม่
abcabcbc
ถูกต้องเนื่องจากลำดับbc
ปรากฏสองครั้ง:10=11 11 b c 11=a b c
ไวยากรณ์ที่ถูกต้องจะเป็น:
10=11 11 12 11=a 12 12=b c
โปรแกรมของคุณจะต้องสิ้นสุดในเวลาน้อยกว่าหนึ่งนาทีสำหรับแต่ละอินพุตที่ถูกต้องที่มีความยาวไม่เกิน 65535 ไบต์
ตามปกติคุณจะไม่สามารถใช้สิ่งอำนวยความสะดวกใด ๆ ในภาษาของคุณหรือฟังก์ชั่นห้องสมุดใด ๆ ที่ทำให้การแก้ปัญหาเล็กน้อยหรือใช้ส่วนใหญ่ของมัน
ตัวอย่างอินพุต
สร้างอินพุตตัวอย่างด้วยโปรแกรม C ต่อไปนี้
#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;
}
ตัวอย่างอินพุตที่สร้างโดยโปรแกรมข้างต้นมักจะไม่ส่งผลให้ได้ผลลัพธ์การบีบอัดที่ดี พิจารณาใช้ข้อความหรือซอร์สโค้ดของมนุษย์เป็นตัวอย่างอินพุต
เกณฑ์การชนะ
นี่คือรหัสกอล์ฟ โปรแกรมที่มีซอร์สโค้ดสั้นที่สุดชนะ สำหรับเครดิตพิเศษให้เขียนโปรแกรมที่สร้างอินพุตจากเอาต์พุตอีกครั้ง