Sekmeleri genişlet (expand (1) uygulamasını uygula)


10

Bu seferki göreviniz expand(1), sekmeleri boşluklara genişleten POSIX yardımcı programının bir varyantını uygulamaktır .

Programınız bir sekme noktası belirtimi almak ve daha sonra standart girişteki girişi okumak ve girişteki sekme karakterlerini bir sonraki sekmeye ulaşmak için uygun boşluklarla değiştirmektir. Sonuç standart çıktıya yazılmalıdır .

Tabstop teknik özellikleri

Bir tabstop özellikleri tek bir numara ya da tabstops virgülle ayrılmış liste ya oluşur. Tek bir sayı olması durumunda, sayıları virgülle ayrılmış bir listede gerçekleşmiş gibi tekrarlanır (örn . 4Gibi davranır 4,8,12,16,20,...). Virgülle ayrılmış listedeki her giriş isteğe bağlı olarak a ile işaretlenmiş bir pozitif tamsayıdır +. Bir +önek, virgülle ayrılmış listedeki önceki değerle göreli bir farkı gösterir. Listedeki ilk değer mutlak olmalıdır (yani önceden düzeltilmemiş). Sekmeler, bir sonraki boşluk olmayan karakterin sütununu (genişletilmiş sekmeyi izleyerek) belirtir ve en soldaki sütun 0 sayısı olarak alınır. Sekmeler her zaman en az bir boşluğa genişlemelidir.

Giriş çıkış

Tabstop belirtimi, programa ilk komut satırı parametresi olarak alınmalı veya kendi takdirinize bağlı olarak standarttan ilk girdi satırı (bir satırsonu tarafından sonlandırılır) olarak okunmalıdır. Sekme yeri okunduktan sonra, EOF işlenip genişletilene kadar kalan giriş (önceki durumda tüm girişler). Genişletilmiş çıktı standart çıktıya yazılacaktır.

Tüm genişletilmiş tablaların ve tüm girdilerin maksimum 80 sütun genişliğinde olduğu varsayılır. Tüm genişletilmiş sekme tablaları kesinlikle artıyor.


Misal

Tabstop spesifikasyonu girişe 4,6,+2,+8eşdeğerdir 4,6,8,16ve her iki girişle birlikte

ab<Tab>c
<Tab><Tab>d<Tab>e<Tab>f

içine genişletilmiş ( bir boşluğu gösterir)

ab␣␣c
␣␣␣␣␣␣d␣e␣␣␣␣␣␣␣f

01234567890123456   (Ruler for the above, not part of the output)
          1111111

Puanlama saf ; en kısa kod kazanır.

Yanıtlar:


2

GolfScript ( 77 75 karakter)

n/(','/{'+'/{~t++}*~:t}%81,{t*}%+:T;{[0\{.9={;T{1$>}?(.)@-' '*}*\)}/;]n+}/;

Tabspec ayrıştırma işleminden oldukça memnunum.

# Split on commas
','/
# For each element:
{
    # Split on '+'
    '+'/
    # We now have either ["val"] or ["" "val"]
    # The clever bit: fold
    # Folding a block over a one-element array gives that element, so ["val"] => "val"
    # Folding a block over a two-element array puts both elements on the stack and executes,
    # so ["" "val"]{~t++}* evaluates as
    #     "" "val" ~t++
    # which evaluates val, adds the previous value, and concatenates with that empty string
    {~t++}*
    # Either way we now have a string containing one value. Eval it and assign to t
    ~:t
}%

Sonra 80 sütunun sonuna ulaşacak kadar güvende kalana kadar son öğenin katlarını ekliyorum:

81,{t*}%+

Bu, yalnızca bir tabstop belirtildiğinde istenen davranışı verir ve aksi takdirde yalnızca spesifikasyonun belirtmediği durumlarda geçerlidir. (NB, sekme duraklarının listesini 0'a daldırır ve sonra son ayrıştırılan öğeyi tekrarlar, ancak bu önemsizdir, çünkü listeyi kullanmaya gelince, geçerli konumdan daha büyük ilk öğeyi ararım).

Gerisi oldukça basit.


2

Yakut 161 145

Girişin ilk satırındaki sekme durağı özelliğini okur.

i=t=[]
gets.scan(/(\+)?(\d+)/){t<<i=$2.to_i+($1?i:0)}
81.times{|j|t<<j*i}
while gets
$_.sub!$&," "*(t.find{|s|s>i=$`.size}-i)while~/\t/
print
end

edit: Tek bir sayının sekme noktası teknik özelliklerinin de düzgün çalışması için son okunan sekme durdurmasının tekrarlanmasını sağlayan iki satır eklendi

ison ayrıştırılan sekmeyi durdurmak için geçici bir değişkendir. tsatırdan ayrıştırılan tabstobs listesidir gets.scan. İyi bir ölçüm için, son ayrıştırılmış sekme tablasının 81 katını ekliyoruz. while getsartık giriş kalmayıncaya kadar döngü devam ediyor. Her girdi satırı için boşluklar için sekmeler kullanırız, her seferinde bir sekme olur, çünkü boşlukları ekledikçe dize hareket eder ve doğru sekmeyi yeniden hesaplamamız gerekir.


Ruby'yi gerçekten bilmiyorum, ama x+($1?i:0)daha kısa olarak yazabilir misin $1?x+i:x?
Timwi

@Timwi Nope! Ruby üçlü operatörle biraz garip. Genellikle oraya bir yere boşluk koymanız gerekir, çünkü iki nokta üst üste ( :) bir sembolün başlangıcını da işaretleyebilir , ancak bir sembol bir rakamla başlayamadığından, :0boşluk olmadan tamamdır. Ya da başka birşey. Bu garip. Parantezler de çok önemli.
daniero

Bu sekmeli tarama bana hatalı görünüyor. Gelen t<<x+($1?i:0);i=xilk deyimi değişmez x, değil mi? Sanırım tersine çevirmen gereki=x+($1?i:0);t<<i
Peter Taylor

1
Aslında, ilk iki satırı değiştirerek 16 tasarruf edebilirsiniz i=t=[]( iilk seferinde gerekmeyeceği garanti edilir); tab-stop ayrıştırmasını basitleştirmek {t<<i=$2.to_i+($1?i:0)}ve ltamamen ortadan kaldırmak ( izaten bu değeri tutar). Ancak sekme durmak umurumda değil güzel bir artış kesinlikle artar: bu size 4 karakter kazandırır ve ben 2 kurtarmak için ödünç alabilirim.
Peter Taylor

@PeterTaylor Giriş için teşekkürler! Doğrudan buggy değildi, ama kesinlikle biraz şişkin. Kendinizi böyle bir koda kör olarak bakmak çok kolay buluyorum.
daniero

1

C, 228 karakter

İşte işleri başlatmak için bir C çözümü. Burada hala bir sürü golf var (tüm ifs ve fors ve putchars ... 'a bakın). Örnek test çantasının yanı sıra aynı girişle 4ve 8sekme spesifikasyonu için test edilmiştir .

S[99],i;L,C;main(v){for(v=1;v;)v=scanf("+%d",&C),v=v>0?C+=L:scanf("%d",&C),
v&&(S[L=C]=++i,getchar());for(;i==1&&C<80;)S[C+=L]=1;for(C=L=0;C=~getchar();)
if(C+10)putchar(~C),L+=C+11?1:-L;else for(putchar(32);!S[++L];)putchar(32);}
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.