İnsan metni veya kaynak kodu gibi bazı veri türlerini düz çizgi dilbilgisi ile sıkıştırmak mümkündür. Temel olarak, dili tam olarak bir sözcük olan sıkıştırılmamış veriler olan bir dilbilgisi oluşturursunuz. Bu görevde, bu veri sıkıştırma yöntemini uygulayan bir program yazmanız gerekir.
Giriş
Giriş, 65535 bayt uzunluğundan daha uzun olmayan bir dizedir. Girişin normal ifadeyle eşleşmesi garanti edilir [!-~]+
(örn. Boşluk hariç en az bir yazdırılabilir ASCII karakteri).
Örnek bir giriş
abcabcbcbcabcacacabcabab
Çıktı
Çıktı, tam olarak bir kelimeyi (girdi) tanımlayan bir dilbilgisi oluşturan bir dizi kuraldır. Her terminal dışı 9'dan büyük bir ondalık sayı ile gösterilir. Başlangıç sembolü on numaralı semboldür. Örnek girişe karşılık gelen bir örnek çıktı aşağıda verilmiştir; sözdizimi aşağıda daha ayrıntılı olarak açıklanmaktadır:
10=11 11 12 12 11 13 13 11 14 14
11=a 12
12=b c
13=a c
14=a b
Her kuralın <nonterminal>=<symbol> <symbol> ...
sağ tarafında isteğe bağlı boşlukla ayrılmış sayıda sembol bulunan bir form bulunur. Aşağıdaki kısıtlamalara uyan ve tam olarak girdi dizesini türeyen her çıktı geçerlidir.
Kısıtlamalar
İnsanların garip şeyler yapmasını engellemek için bir takım kısıtlamalar vardır:
Her terminal dışı bir kuralın sağ tarafında en az iki kez görünmelidir. Örneğin,
abcabc
kural 12 yalnızca bir kez göründüğünden , giriş için aşağıdaki dilbilgisi geçersizdir:10=12 11=a b c 12=11 11
Üst üste gelen iki sembol dizisi, üst üste binmeleri dışında, tüm kuralların sağ tarafında birden fazla görünemez. Örneğin
abcabcbc
, dizibc
iki kez göründüğü için giriş için aşağıdaki dilbilgisi geçersizdir :10=11 11 b c 11=a b c
Geçerli bir dilbilgisi:
10=11 11 12 11=a 12 12=b c
65535 bayttan uzun olmayan her geçerli giriş için programınızın bir dakikadan daha kısa sürede sonlanması gerekir.
Her zaman olduğu gibi, dilinizin herhangi bir özelliğini veya çözümü önemsiz hale getiren veya büyük bir kısmını uygulayan herhangi bir kütüphane işlevini kullanamazsınız.
Örnek giriş
Aşağıdaki C programıyla örnek girişi oluşturun.
#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;
}
Yukarıdaki program tarafından üretilen örnek girişi genellikle iyi sıkıştırma sonuçları ile sonuçlanmaz. Örnek metin olarak insan metni veya kaynak kodu kullanmayı düşünün.
Kazanma kriterleri
Bu kod golf; en kısa kaynak kodlu program kazanır. Ekstra kredi için, çıktıdan girişi yeniden yapılandıran bir program yazın.