Dinamik ASCII Enkoder!


16

Giriş

Bazı ASCII karakterleri bugünlerde çok pahalı ...

Tasarruf etmek için pahalı karakterleri ucuz olanları kullanarak kodlayan bir program yazmaya karar verdiniz.

Ancak, karakter fiyatları sık sık değişir ve farklı bir karakteri her kodlamanız veya kodunu çözmeniz gerektiğinde programınızı değiştirmek istemezsiniz! Daha dinamik bir çözüme ihtiyacınız olacak.

Meydan okuma

Göreviniz iki program yazmaktır: kodlayıcı ve kod çözücü .

Kodlayıcı beş ucuz karakterlerin bir listesini ve tek pahalı karakterini kabul etmelidir.

Pahalı karakteri kodlayan ucuz karakterlerden oluşan tek bir dize çıkarmalıdır.

Bu dize , ucuz kalmak için 4 karakterden uzun olamaz . Bununla birlikte, kodlamadaki tüm ucuz karakterleri kullanmak zorunda değildir ve kodlamalar farklı uzunluklarda olabilir.


Dekoder kodlayıcı tarafından çıkarılan dize ve çıkış pahalı karakter kabul etmelidir.

Kod çözücü, kodlanmış dizeden başka hiçbir girişi kabul etmeyecektir. Herhangi bir (geçerli) giriş kombinasyonu için kodlayıcının çıkışından değiştirilmeden çalışması gerekir. Başka bir deyişle, kod çözücü programınız hangi karakterlerin pahalı veya ucuz olduğunu bilmiyor.

puanlama

En kısa kombine kod kazanır!

notlar

  • Tüm karakterler büyük harf [A-Z], küçük harf [a-z]veya rakamdan oluşur [0-9].

  • Ucuz karakterler listesi kopya içermez. Hiçbir karakter hem ucuz hem de pahalı olmayacaktır.

  • Kodlayıcı ve kod çözücünün aynı dilde yazılması gerekmez, ancak olabilir. Bir program veya işlev yazabilirsiniz.

  • Giriş ve çıkış dilinize uygun herhangi bir biçimde olabilir.

  • İki program herhangi bir değişken veya veri paylaşamaz.

özet

  • Kodlayıcıya bazı ucuz karakterler ve pahalı bir karakter girilir.

  • Enkoder pahalı karakteri kodlayan bir dizi ucuz karakter çıkarır.

  • Kod çözücü kodlayıcının çıktısını verir ve pahalı karakteri çıkarır.

Örnekler

Giriş:     a, b, c, d, e     f

Kodlayıcı Olanakları:     a     eeee     caec

dekoder:     f


Giriş:     a, b, c, d, e     h

Kodlayıcı Olanakları:     bc     cea     eeaa

dekoder:     h


Giriş:     q, P, G, 7, C     f

Kodlayıcı Olanakları:     777     P7     PPCG

dekoder:     f


Bu gerçekten ben olabilirim ve eğer öyleyse bu soru için özür dilerim, ama mesajınızı ucuz karakterlerle tam olarak nasıl kodlamanız gerekiyor? 5 ucuz karakter için ASCII kodlarının eklenmesi? Aslında, bu sorunun yalnızca kod çözücünüzün üretilen tüm kodlama olasılıklarının kodunu çözmesi gerekiyorsa bir temeli vardır.
cole

Açık olmak gerekirse: Enkoder Olanakları sadece örnektir ve her karakteri istediğimiz gibi kodlayabiliriz, değil mi?
Dennis

@Dennis Evet, bunlar sadece örnektir.
jrich

@Kole Gerçek bir algoritma vermeden , buradaki asıl zorluk, bunun mümkün olduğuna inanıyorum. Kodlamak için sadece 62 olası pahalı harf vardır ve A239914'e göre bu 4 ascii karakteriyle 92'ye kadar kodlanabilir . (PhiNotPi'nin bunun için sandbox yorumuna çok teşekkürler - Tam olarak kaçının kodlanabileceğini hesaplamadım)
jrich

@UndefinedFunction Şimdi ne istediğini anlıyorum: Dennis'in sorusu kafam karıştığım şeyi yanıtladı.
cole

Yanıtlar:


5

Pyth, 46 bayt

Enkoder, 22 bayt

@smfql{Td^<Szd4S4-Cw48

Kod çözücü, 24 bayt

C+48xsmfql{Td^<sS{zd4S4z

Vay canına, bu mükemmel uyuyor. 75 farklı karakter kombinasyonu ve 75 karakter aralığı.
Jakube

Ben değiştirmek düşünüyorum S4ile Tve her iki programda her biri bir bayt kaydedin.
Jakube


4

gawk, 163 + 165 = 328

Gawk 4.1.1 ile test edilmiştir, ancak eski gawk sürümlerinde de çalışmalıdır. Mawk ile çalışmak için biraz değiştirilmesi (uzatılması) gerekir.

kodlayıcı (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]]}

kod çözücü (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)}

İşe yarıyor, ama bunun bunun için en iyi yaklaşım olmayabileceğinin farkındayım. Beşinci ucuz mektubun ne için olduğu hakkında hiçbir fikrim yok, çünkü sadece dört tane kullanıyorum.

Bunlar sadece tek kullanımlıktır. İkinci bir kod girmek isterseniz, bunları yeniden başlatmanız gerekir. Kodlama için girişte virgüllerden sonraki boşluklar gereklidir.

Hakkında ne düşündüm

İlk sorum "Bu 4 karakterden bir kod çözücü ne elde edebilirdi?" (Onlara a, b, c ve d diyeceğim) ve ilk fikrim aşağıdaki ilişkilerden 6 bit Bilgi almaktı:

a>b
a>c
a>d
b>c
b>d
c>d

Vay canına, 6 bit, bu mükemmel! Bunun dahi olduğunu düşündüm, ancak testler bunun işe yaramayacağını gösterdi. Sadece 24 olası kombinasyon vardır. Lanet olsun.

Bir sonraki adım, zaten bildiklerime dayanarak saymaya çalışıyordu. Böylece, dizede görünen ilk harf 0 olur, sonra dizeye eklenen ikinci harf 1 olur ve bu şekilde devam eder. Ama bu beni gereken 62 kombinasyona kadar getirmeyecekti.

0000
0001
0010
0011
0012
0100
0101
0102
0110
0111
0112
0120
0121
0122
0123

Ama yine de fikri seviyorum.

O zaman bu ikisini birleştirebileceğim beni vurdu, çünkü girişteki karakterlerin zaten ilişkileri var ve onlara bir değer vermek için tanıtılıncaya kadar beklemek zorunda kalmayacaktım.

Nasıl çalışır

Not: Bu artık golf versiyonlarının tam olarak nasıl çalıştığı değil, prensip aynı kaldı.

Kod çözücü için:

Dizini, en büyük basamağı bu sayıdaki ayrı basamak sayısından büyük olmayan dört basamaklı sayıların tümünü içeren bir dizi oluşturulur. Bu koşulu karşılayan 75 farklı dört basamaklı sayı vardır. Onları zorluyorum, çünkü şimdiye kadar onları inşa etmenin bir yolunu bulamadım ve bunun awk içinde yapmanın daha kısa olacağından emin değilim. Bunları bulduğumda onlara pahalı karakterleri asciibetik sırayla atarım.

Sonra girdi dizesindeki her karakteri bir rakamla değiştiriyorum. En küçük (örneğin 'a' dan 'B' küçüktür) 1 olur, en küçük ikinci 2 olur ve bu şekilde 4 olur. Tabii ki girişte kaç farklı karakter olduğuna, en yüksek rakamın ortaya çıkan dize olacaktır.

Sonra sadece bu dizeyi bir dizin olarak içeren dizi elemanını yazdırıyorum.

Kodlayıcı buna göre çalışır.

Nasıl kullanılır

Kodu doğrudan bir awk bash line komutuna kopyalayın veya iki dosya "encode.awk" ve "decode.awk" yapın ve kodu uygun şekilde yapıştırın. Ya da en / kod çözme işleminden sonra otomatik olarak çıkan veya sonunda çıkış komutunu kaldırarak birden çok kez kullanılabilen aşağıdaki kodu daha iyi kullanın.

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
}

İşte bir kullanım örneği:

me@home:~/$ awk -f encode.awk
w, 0, R, 1, d X
10R1
me@home:~/$ awk -f decode.awk
10R1
X

Golf versiyonlarını kullanırsanız, her virgülden sonra boşluk bırakılması gerektiğini unutmayın.

İsterseniz, bu kısa ve kirli komut dosyasını bazı örnek veriler oluşturmak için kullanabilirsiniz

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)
    }
}

ve komik bir şey yap

me@home:~/$ awk -f gen.awk|awk -f encode.awk|awk -f decode.awk|sort -u|wc -l
62

Bunu daha çok bir programlama bulmacası olarak gördüm. Bence biraz üzücü, buradaki hemen hemen her şey golf oynuyor, çünkü iyi belgelenmiş, okunabilir koddan çok daha fazlasını öğrenebilirsiniz, ama bu sadece benim düşüncem. Ve ben istendiği gibi golf;)


nasıl test edilir? lütfen bazı örnekleri paylaşın.
Shravan Yadav

Harika açıklama için +1! Bu soruna yaklaşmanın birçok farklı yolu var gibi görünüyor :)
jrich

1
Bu, düşünce sürecime çok benziyordu, ancak benzersiz zayıf kombinasyonların (en büyük rakamın rakam miktarından daha büyük olmadığını tanımladığınız) kaba zorlamayı fark etmedim, uygulanabilir bir yaklaşımdı. Takip etmek için şeref.
Patrick Roberts
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.