Tekel Sıkıştırma


17

Bir oyuncunun sırasının başlangıcında bir Tekel oyununun mevcut durumunu temsil eden bir dize verildiğinde , gerekli tüm verileri en küçük çıktıya sıkıştırın. Cevaplar çıktı boyutuna ve kaynak boyutuna göre değerlendirilecektir .

Not: Birçok bölgesel varyasyon vardır, ancak bu yayındaki mülk adlarına vb. Yapılan tüm referanslar bu panoya dayanmaktadır .


Giriş:

Giriş, ;ayrı bir dize olarak verilir . Bu dize, stdin, argümanlar vb. Gibi seçtiğiniz dilde geleneksel olan her şekilde programa verilir.

Biçimlendirilmemiş girdi şöyle görünür:

numPlayers                     (1 to 8)
whose turn                     (0 to numPlayers-1)
for each player:
    bankrupt?                  (true/false)
    money                      (0 to 2^16-1)
    get-out-of-jail-free cards (0 to 2)
    position                   (0 to 39) 
    jail turns                 (-1 to 2)
for 28 properties:
    owner                      (-1 to numPlayers-1)
    mortgaged?                 (true/false)
    improvement level          (0 to 5)
for 16 chance cards in deck:
    card index                 (-1 to 15)
for 16 community chest cards in deck:
    card index                 (-1 to 15)

Biçimlendirilmiş bir girdi örneği :

3;1;false;1546;0;14;-1;false;7692;1;10;1;true;1;false;1;1;false;0;0;true;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;0;1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;3;12;7;4;5;2;13;11;15;6;8;9;10;1;14;-1;

Yavaş yavaş çekildi:

3;1;

3 oyuncu var ve oyuncu 1'in sırası (sıfır endeksli, yani ikinci oyuncu)

Oyuncular

false;1546;0;14;-1;
false;7692;1;10;1;
true;

İlk oyuncu:

  • iflas değil
  • elinde 1546 dolar nakit var
  • 0 hapishaneden kurtulma kartına sahip
  • 14. pozisyonda (Virginia Ave)
  • hapiste değil

İkinci oyuncu ise hapiste ve bir tur için olmuştur. Neden olduğundan emin değilim , çünkü bir GOoJF kartı var, ama orada.

Üçüncü oyuncu iflas eder ve ne daha fazla bilgi ne de gereklidir.

Özellikleri

1;false;1;
1;false;0;
0;true;0;
-1;false;0;
-1;false;0;
-1;false;0;
...

Mülkler, Akdeniz'den başlayıp Boardwalk'ta biten, tahta çevresinde sıralanmıştır. Sahip olunamayan mülkler bu listeye dahil değildir, bu nedenle toplam 28 olacaktır. İyileştirme seviyesi 0onaylanmamış demektir. Düzeyi 1bir ev, 5bir otel için düzeye kadar . Bir -1sahip, herhangi bir oyuncuya ait olmadığı anlamına gelir.

Standart kurallara göre, ipotekli bir özellik olmalı ait olması ve must not geliştirilebilir. İyileştirilmiştir Bir özellik olmalıdır ait olması ve olmamalıdır ipotekli olması.

Ayrıca, bir mülkün iyileştirilmesi için bir oyuncunun tüm renk bloğuna sahip olması gerekir . Bu oyunun amaçları doğrultusunda, mülklerin "eşit olarak" geliştirilip iyileştirilmediğini umursamıyoruz.

Bu konumlar olduğunu unutmayın değil yukarıda verilen oyuncu pozisyonları ile aynı . Örneğin, 5pozisyondaki bir oyuncu listedeki üçüncü mülk olan Okuma Demiryolunda olacaktır (çünkü Go, Community Chest ve Gelir Vergisi sahiplenilemez). Oyuncu pozisyonları 0(Go) konumundan 39(Boardwalk) saat yönünde çalışır .

Kartlar

0;1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;
3;12;7;4;5;2;13;11;15;6;8;9;10;1;14;-1;

Şans ve Toplum Sandığı destelerinin her birinde 16 toplam kart bulunur. Sayılar, karıştırılmış olan destede göründükleri gibi sunulur. Bu örnek için, Şans destesinden çekilen ilk kart kart 0, ardından kart olacaktır 1(desteyi berbat eden kişi). Topluluk göğsünden çekti ilk kart kartıdır 3sonra 12.

Her kartın ne olduğu konusunda endişelenme Kart hariç, anlama geldiğinden (kart metni) 0. Bu deste için Get Out of Jail Free kartı. Bir oyuncunun sahibi varsa, listenin sonunda, olarak temsil edilir -1.


Çıktı:

Oyun durumunun bir temsilini çıktı almalısınız (konsol, stdout veya dosya için). Bu, tüm bilgileri içermelidir gerekli oyun temsil etmek. Örneğin, geliştirilmemiş veya ipotek edilemedikleri için sahipsiz özellikleri atlayabilir (veya kısaltabilirsiniz). Giriş, dizinsiz bir liste olduğu için bunları atlayamaz.

Sıkıştırma, en kötü durum çıktı boyutunu hesaplayabileceğiniz şekilde yapılmalıdır. Bu, bazı sıkıştırma algoritmalarını diskalifiye edebilir (en kötü durumu kanıtlayamadıkça ve en kötü durum girdisine bir örnek vermedikçe).

Kaynak kodunuz mantıksız olmadığı sürece ayrıntılı değilse, oyunun nasıl temsil edildiğine ilişkin bir açıklama yapın. Golf programından ve sıkıştırılmış çıktıdan başka hiçbir şey içermeyen cevaplar önerilmez. Örneğin, belirli değerleri atlıyorsanız, bunların çıktıdan nasıl türetilebileceğini açıklayın.


Puanlama / Kurallar:

Puanlama, hem bit cinsinden en kötü durum sıkıştırma boyutuna hem de bayt cinsinden kaynak kodu boyutuna dayanır :

score = (outputBits * 2) + encoderSourceBytes

Tam bir cevap şunları içermelidir:

  • Çıktı örneği
  • Kodlayıcı kaynağı
  • Kod çözücü kaynağı (puana göre sayılmaz)

Tüm kodlayıcılar eksiksiz programlar ve standart boşluklar olmalıdır yasaktır. Yerleşik veya harici sıkıştırma kitaplıklarının kullanılması da yasaktır.

Kazanan, yukarıda tanımlandığı gibi en düşük puana sahip cevaptır .


Hm, neden bir kod çözücünün yanı sıra kodlamanın gerçekten çalıştığına (ve geri döndürülebilir) bir kanıt gerektirmiyor? Ayrıca dahili gzip sıkıştırması gibi şeyleri dahil etmeye ne dersiniz? Bu, en kötü durum sıkıştırma boyutunu bulmayı gerçekten zorlaştırır.
Martin Ender

@ m.buettner Düzenlendi. Sıkıştırma kitaplıkları ve en kötü durumun kanıtı hakkında biraz ekledim. Gerçekten bir kod çözücü uygulamak istemiyorum. Posterler çözümlerini kanıtlamak istiyorlarsa bunları içerebilir, ancak skora karşı sayılmaz.
Geobits

Oh evet, onları skora eklemeyi önermiyordum. Yine de kanıt olarak (çözülmemiş) bir kod çözücüye ihtiyacınız olabilir. Bu, gönderimlerin özel durumları ele alıp alamayacağını test etmeyi kolaylaştırır.
Martin Ender

@ m.buettner Mükemmel bir noktaya değindiniz. Kod çözücüler öyle.
Geobits

2
The second player is in jail, and has been for one turn. I'm not sure why, since he has a GOoJF card, but he's there.Hapiste olmak iyi bir oyun. Çünkü kira ödemezsiniz. :)
yeraltı monorayları

Yanıtlar:


4

(Bu soruyu dikkatime çeken bir cevap yakın zamanda düzenlendi ve eski bir soru olmasına rağmen denemeye karar verdim.)

Swift 1.2-1016 Puan (2 * 81 + 854)

Çıktı en kötü 81 baytta ve oyuncu miktarıyla değişiyor.

İki yöntemden biri işe yarıyor. Oyun Alanı sürümü biraz daha uzundur.

Bahçesi Sıkıştır

(Devraldı Input.txt yer Playground Documents Directory)

// Compressor e(inputFileName, outputFileName)
import Cocoa;typealias S=String;typealias U=UInt8;func e(a:S,b:S){var d=NSSearchPathForDirectoriesInDomains(.DocumentDirectory,.UserDomainMask, true)as![S],g=d[0],r=S(contentsOfFile:"\(g)/\(a)",encoding:4,error:nil)!.componentsSeparatedByString(";"),z=[U](count:4,repeatedValue:0),c=[U](),p:()->Int={r.removeAtIndex(0).toInt()!},f:()->Bool={r.removeAtIndex(0)=="true" ?true:false},j=U(p());c+=[(j<<4)|(U(p()))];for _ in 0..<j{if f(){c+=[255]}else{let(t,g,v)=(UInt16(p()),U(p()),U(p()));c+=[(U(p()))|(g<<2),v,U(t>>8),U(t&255)]}};for _ in 0..<28{c+=[(U(bitPattern:Int8(p()))<<4)|((f() ?1:0)<<3)|(U(p()))]};for h in 0..<16{let y=h>7 ?1:0,x=Int8(p()),w=Int8(p());c+=[(U(bitPattern:x)<<4)|(U(bitPattern:w)&15)];z[y]=z[y]<<1;if x == -1{z[y]|=1};z[y+1]=z[y+1]<<1;if w == -1{z[y+1]|=1}};NSData(bytes:c+z,length:c.count+4).writeToFile("\(g)/\(b)",atomically:true)}

// Decompressor d(inputFileName, outputFileName)
func d(a:S,b:S){var d = NSSearchPathForDirectoriesInDomains(.DocumentDirectory,.UserDomainMask,true)as![String],e=d[0],i=NSData(contentsOfFile:"\(e)/\(a)")!,n=[UInt8](count:i.length,repeatedValue:0),o="";i.getBytes(&n,length:i.length);let k=n.removeAtIndex(0),j=k>>4;o+="\(j);\(k&15);";for _ in 0..<j{let h=n.removeAtIndex(0);if h>>7 == 1{o+="true;";continue};let p=n.removeAtIndex(0),b=n.removeAtIndex(0),c=n.removeAtIndex(0);o+="false;\(UInt16(b)<<8|UInt16(c));\(h>>2);\(p);\(h&0b11);"};for _ in 0..<28{let p=Int8(bitPattern:n.removeAtIndex(0)),mortgage=((p>>3)&1)==1 ?"true":"false";o+="\(p>>4);\(mortgage);\(p&7);"};var m=[U](count:4,repeatedValue:0);for i in reverse(0..<4){m[i]=n.removeLast()};for h in 0..<16{var i=h>7 ?1:0,z=n.removeAtIndex(0),x=Int8(z>>4),y=Int8(z&15),isUnowned1=m[i]&128;m[i]=m[i]<<1;let isUnowned2=m[i+1]&128;m[i+1]=m[i+1]<<1;if isUnowned1 != 0 {x=(-1)};if isUnowned2 != 0 {y=(-1)};o+="\(x);\(y);"};o.writeToFile("\(e)/\(b)",atomically:true,encoding:4,error:nil)}

// Test function to compare the files
func t(a:S,b:S)->Bool{let d=NSSearchPathForDirectoriesInDomains(.DocumentDirectory,.UserDomainMask,true)as![String],c=d[0],i=S(contentsOfFile:"\(c)/\(a)",encoding:4,error:nil)!,j=S(contentsOfFile:"\(c)/\(b)",encoding:4,error:nil)!;return i==j}
// Usage
e("Input.txt", "Output.bin")  // Encode
d("Output.bin", "Output.txt") // Decode
t("Input.txt", "Output.txt")  // Test -> Should output 'true'

Compress.swift - kullanarak Terminal'de çalıştırswift Compress.swift

(Varsayılır Input.txtverildiDesktop )

// Compressor - 854 Bytes
import Cocoa;typealias S=String;typealias U=UInt8;func e(a:S,b:S){var d=NSSearchPathForDirectoriesInDomains(.DesktopDirectory,.UserDomainMask, true)as![S],g=d[0],r=S(contentsOfFile:"\(g)/\(a)",encoding:4,error:nil)!.componentsSeparatedByString(";"),z=[U](count:4,repeatedValue:0),c=[U](),p:()->Int={r.removeAtIndex(0).toInt()!},f:()->Bool={r.removeAtIndex(0)=="true" ?true:false},j=U(p());c+=[(j<<4)|(U(p()))];for _ in 0..<j{if f(){c+=[255]}else{let(t,g,v)=(UInt16(p()),U(p()),U(p()));c+=[(U(p()))|(g<<2),v,U(t>>8),U(t&255)]}};for _ in 0..<28{c+=[(U(bitPattern:Int8(p()))<<4)|((f() ?1:0)<<3)|(U(p()))]};for h in 0..<16{let y=h>7 ?1:0,x=Int8(p()),w=Int8(p());c+=[(U(bitPattern:x)<<4)|(U(bitPattern:w)&15)];z[y]=z[y]<<1;if x == -1{z[y]|=1};z[y+1]=z[y+1]<<1;if w == -1{z[y+1]|=1}};NSData(bytes:c+z,length:c.count+4).writeToFile("\(g)/\(b)",atomically:true)}
// Decompressor
func d(a:S,b:S){var d = NSSearchPathForDirectoriesInDomains(.DesktopDirectory,.UserDomainMask,true)as![String],e=d[0],i=NSData(contentsOfFile:"\(e)/\(a)")!,n=[UInt8](count:i.length,repeatedValue:0),o="";i.getBytes(&n,length:i.length);let k=n.removeAtIndex(0),j=k>>4;o+="\(j);\(k&15);";for _ in 0..<j{let h=n.removeAtIndex(0);if h>>7 == 1{o+="true;";continue};let p=n.removeAtIndex(0),b=n.removeAtIndex(0),c=n.removeAtIndex(0);o+="false;\(UInt16(b)<<8|UInt16(c));\(h>>2);\(p);\(h&0b11);"};for _ in 0..<28{let p=Int8(bitPattern:n.removeAtIndex(0)),mortgage=((p>>3)&1)==1 ?"true":"false";o+="\(p>>4);\(mortgage);\(p&7);"};var m=[U](count:4,repeatedValue:0);for i in reverse(0..<4){m[i]=n.removeLast()};for h in 0..<16{var i=h>7 ?1:0,z=n.removeAtIndex(0),x=Int8(z>>4),y=Int8(z&15),isUnowned1=m[i]&128;m[i]=m[i]<<1;let isUnowned2=m[i+1]&128;m[i+1]=m[i+1]<<1;if isUnowned1 != 0 {x=(-1)};if isUnowned2 != 0 {y=(-1)};o+="\(x);\(y);"};o.writeToFile("\(e)/\(b)",atomically:true,encoding:4,error:nil)}
func t(a:S,b:S)->Bool{let d=NSSearchPathForDirectoriesInDomains(.DesktopDirectory,.UserDomainMask,true)as![String],c=d[0],i=S(contentsOfFile:"\(c)/\(a)",encoding:4,error:nil)!,j=S(contentsOfFile:"\(c)/\(b)",encoding:4,error:nil)!;return i==j}
e("Input.txt", "Output.bin")
d("Output.bin", "Output.txt")
println(t("Input.txt", "Output.txt"))

Örnek Giriş / Çıkış

3;1;false;1534;0;14;0;false;34;1;10;1;true;1;false;1;1;false;0;0;true;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;0;1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;3;12;6;9;4;-1;4;8;4;2;9;5;11;10;14;7;

.

31 00 0E 05 FE 05 0A 00 22 FF 11 10 08 F0 F0 F0
F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 
F0 F0 F0 F0 F0 F0 01 23 45 67 89 AB CD EF 3C 69 
4F 48 42 95 BA E7 00 00 20 00

4

Saf C (3592 puan)

Çıktı 182 bayttır. Boyut O (1), bu yüzden en kötü durum bu.

Bu, dosyaları okumak için sscanf'i yoğun olarak kullanır ve yapıları diske atar.

Örneğinizde 28 özellik bulunmadığından girişi biraz değiştirmek zorunda kaldım.

Değişkenler için, onları ne olduğunun ilk harfinden ya da bu çelişirse ikinci (veya sonraki) harften adlandırdım. Örneğin, Oyun, pLayer, pRoperty, vb.

sıkıştır. c (680 bayt):

#import <stdio.h>
#import <stdint.h>
#define T(X) for(int i=0;i<(X);i++)
typedef uint8_t U;typedef struct{U p;U t;U a[16];U e[16];}G;typedef struct{U b;uint16_t m;U c;U p;U t;}L;typedef struct{int8_t o;U m;U i;}R;G g;L l[8];R r[28];main(){FILE *f=fopen("input.txt","r");fscanf(f,"%d;%d;",&g.p,&g.t);T(g.p){l[i].b=(fgetc(f)=='t');while(fgetc(f)!=';');if(!l[i].b){fscanf(f,"%d;%d;%d;%d;",&l[i].m,&l[i].c,&l[i].p,&l[i].t);}}T(28){fscanf(f,"%d;",&r[i].o);r[i].m=(fgetc(f)=='t');while(fgetc(f)!=';');fscanf(f,"%d;",&r[i].i);}T(16){fscanf(f,"%d;",&g.a[i]);}T(16){fscanf(f,"%d;",&g.e[i]);}f=fopen("c.dat","w");fwrite(&g,sizeof(G),1,f);fwrite(&l,sizeof(L),8,f);fwrite(&r,sizeof(R),28,f);}

sıkıştırmak. c (önceden golf)

#include "m.h"

#define NEXT_FIELD b=strchr(b,';')+1;

G g;
L l[8];
R r[28];

char a[1024];
char *b = a;

main() {
    FILE *i = fopen("input.txt", "r");
    fgets(a, 1024, i);
    fclose(i);

    sscanf(b, "%d;%d;", &g.p, &g.t);
    NEXT_FIELD NEXT_FIELD

    TIMES(g.p) {
        l[i].b = (*b == 't'); NEXT_FIELD
        if(!l[i].b) {
            sscanf(b, "%d;%d;%d;%d;", &l[i].m, &l[i].c, &l[i].p, &l[i].t);
            NEXT_FIELD NEXT_FIELD NEXT_FIELD NEXT_FIELD
        }
    }

    TIMES(28) {
        sscanf(b, "%d;", &r[i].o); NEXT_FIELD
        r[i].m = (*b == 't'); NEXT_FIELD
        sscanf(b, "%d;", &r[i].i); NEXT_FIELD
    }

    TIMES(16) {
        sscanf(b, "%d", &g.a[i]);
        NEXT_FIELD
    }

    TIMES(16) {
        sscanf(b, "%d", &g.e[i]);
        NEXT_FIELD
    }

    FILE *c = fopen("c.dat", "w");
    fwrite(&g, sizeof(G), 1, c);
    fwrite(&l, sizeof(L), 8, c);
    fwrite(&r, sizeof(R), 28, c);
    fclose(c);
}

dekompresyon.c :

#import <stdio.h>
#import <stdint.h>

#define T(X) for(int i = 0; i < (X); i++)
typedef uint8_t U;

typedef struct {
    U p;
    U t;
    U a[16];
    U e[16];
} G;
typedef struct {
    U b;
    uint16_t m;
    U c;
    U p;
    U t;
} L;
typedef struct {
    int8_t o;
    U m;
    U i;
} R;

G g;
L l[8];
R r[28];

main() {
    FILE *c = fopen("c.dat", "r");
    fread(&g, sizeof(G), 1, c);
    fread(&l, sizeof(L), 8, c);
    fread(&r, sizeof(R), 28, c);
    fclose(c);

    FILE *d = fopen("output.txt", "w");

    fprintf(d, "%d;%d;", g.p, g.t);
    T(g.p) {
        fprintf(d, "%s;", l[i].b ? "true" : "false");
        if(!l[i].b){
            fprintf(d, "%d;%d;%d;%d;", l[i].m, l[i].c, l[i].p, l[i].t);
        }
    }
    T(28) {
        fprintf(d, "%d;%s;%d;", r[i].o, r[i].m ? "true" : "false", r[i].i);
    }
    T(16) { fprintf(d, "%d;", g.a[i] != 255 ? g.a[i] : -1); }
    T(16) { fprintf(d, "%d;", g.e[i] != 255 ? g.e[i] : -1); }

    fclose(d);
}

Giriş / çıkış :

3;1;false;1546;0;14;0;false;7692;1;10;1;true;1;false;1;1;false;0;0;true;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;-1;false;0;0;1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;3;12;7;4;5;2;13;11;15;6;8;9;10;1;14;-1;

Sıkıştırılmış (182 bayt):

0301 0001 0203 0405 0607 0809 0a0b 0c0d
0e0f 030c 0704 0502 0d0b 0f06 0809 0a01
0eff 0000 0a06 000e 0000 0000 0c1e 010a
0100 0100 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0100 0101 0000 0001 00ff 0000 ff00
00ff 0000 ff00 00ff 0000 ff00 00ff 0000
ff00 00ff 0000 ff00 00ff 0000 ff00 00ff
0000 ff00 00ff 0000 ff00 00ff 0000 ff00
00ff 0000 ff00 00ff 0000 ff00 00ff 0000
ff00 00ff 0000 

Koş!

$ make compress decompress && ./compress && ./decompress && md5 input.txt output.txt
MD5 (input.txt) = fa655a5a17d67b188424ab0dcfdfb825
MD5 (output.txt) = fa655a5a17d67b188424ab0dcfdfb825

Teşekkürler, biraz kaydetmek için başlığı devirdim ve bayt saymak için puanımı sabit.
wjl

Görünüşe göre çalışma uzunluğu kodlamasıyla bazı baytları kaydedebilirsiniz. Bunun ne kadar mümkün olduğundan emin değilim, ancak bunu bir kaçış baytı ile yaparsanız, tekrar etmeyen verilerle de iyi yapmalıdır. Heh.
cjfaure
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.