Programcı Bahçesi


12

Programcı Bahçesi

Profesyonel bir yazılım geliştiricisi olarak, kendinizi güneşin sert yapay olmayan ışığına maruz bırakma riski taşıyamazsınız, ancak aynı zamanda çiçekler için yumuşak bir noktaya sahip olursunuz ve bahçenizi tüm yıl boyunca iyi durumda tutmak istersiniz.

Bu amaçla, evinizin dibindeki çiçek tarhını toplamak için her ay bir bahçıvan kiralanır. Ancak bahçıvanın işini düzgün bir şekilde yaptığından emin olmanız ve çalışkan adam için uygun bir ödeme yapmanız gerekir. Doğal olarak bir yazılım çözümü en iyisidir.

Giriş

Programınız, çiçek tarhını güncel göründüğü haliyle ve kaldırılması gereken öğelerin ayrıntılarını tanımlayan girdi ile beslenecektir. Program, dağınıklıktan yoksun bahçe çıktısını almalı ve bahçıvanların ödemesinin bir dökümünü yazdırmalıdır. Giriş, STDIN'den veya tek bir komut satırı bağımsız değişkeni olarak olabilir.

İlk girdi satırı biçimindedir

width height unwanted_item_type_count

widthçiçek tarhının genişliği nerede , çiçek tarhının heightyüksekliği (her ikisi de ASCII karakterlerinde) ve unwanted_item_type_countbahçeden kaldırılacak bir tür öğenin açıklamasını içeren kaç satır izleyeceğini size söyler.

İstenmeyen her öğe türü için her satır formattadır

width height string_representation name fee_per_item

burada widthürünün genişliği, heightürünün yükseltir (ASCII karakter hem de), string_representationsatır sonları ürünün dize gösterimidir, name(boşluk çizgi ile değiştirilir) ürünün tipi için bir tanımlayıcı ve fee_per_itembahçıvanın her bir öğenin çıkarılması için ne kadar ödenmesi gerektiğidir.

Örneğin

3 2 .R.\|/ rouge_flower 3

Kaldırılması rouge_flower3 maliyeti olan bir öğe türünü temsil eder ve şöyle görünür:

.R.
\|/

Öğeler boşluk içermeyecek ve hiçbir öğenin tamamen noktalardan oluşan bir sınırı olamaz ve dize temsili de açıklanan tam boyutta olacaktır. Bu nedenle, aşağıdakilerin tümü geçersiz girdilerdir:

3 1 ( ) space 0
1 1 . dot 0
2 1 .! bang 0
3 2 .@.\|/. plant 0

Ancak 0'ın geçerli bir ücret olduğunu unutmayın (ücretler her zaman -1'den büyük tamsayılar olacaktır).

Çiçek tarhının ağırlıklı olarak .boşluklardan ziyade noktalardan ( ) oluştuğunu ve beyaz boşlukları tüm girişler için sınırlama olarak güvenle kullanabileceğinizi unutmayın. Çiçeklik her zaman noktaların kendisi ile sınırlıdır.

İstenmeyen öğe türleri listelendikten sonra, verilen genişlik ve yükseklikte çiçek tarhının ASCII temsili gelir.

Çıktı

Çıktı STDOUT'a veya diliniz desteklemiyorsa uygun bir alternatif olmalıdır.

Çıktı, çiçek tarhının bir çıktısıyla başlar, ancak tüm istenmeyen öğeler çıkarıldığında (noktalarla değiştirilir), böylece nasıl görünmesi gerektiğini görebilir ve bahçıvanın işini yaptığını kontrol edebilirsiniz. Çiçek tarhındaki her bir öğe bir nokta dikdörtgeni ile çevrelenecek ve bir bitişik öğe olacaktır (yani , öğenin içinde ayırma noktası olmayacaktır ). Örneğin

.....
.#.#.
.....

2 ayrı ürün gösterir

.....
.\@/.
.....

1 öğe gösterir

......
.#....
....|.
....|.
.o--/.
......

Taş (#) eşleştirilebilirken, yılan (yılan olduğunu söyleyemez miydiniz?) geçersizdir, çünkü taş noktaların gerekli çevresini engeller.

...
\@.
...

Salyangoz çiçek yatağının kenarında olduğu için ve kenar her zaman geçerli bir girişteki noktalarla sınırlandırılmalıdır.

Bundan sonra, sayımı, öğe başına maliyeti ve tüm öğelerin maliyetlerini (sayı * öğe başına maliyet) veren her istenmeyen öğe türünün bir biçimde listelenmesi gerekir:

<count> <name> at <cost_per_item> costs <cost>

Bundan sonra, toplam maliyeti veren (istenmeyen öğelerin maliyetlerinin toplamı) tek bir satır olmalıdır:

total cost <total_cost>

Misal

Verilen bu girdi için

25 18 3
4 2 .\/.\\// weeds 5
2 1 \@ snails 2
1 1 # stones 1
.........................
.\@/.................\@..
............\/...........
......O....\\//..^|^.....
.#...\|/.........^|^.....
..................|......
.................\|/.....
..\@.....\/...........#..
........\\//....#........
....*....................
...\|/......\/......\@/..
...........\\//..........
..................*......
.......\@/.......\|/.....
...O.....................
..\|/.......*............
.......#...\|/....\@.....
.........................

Program bu çıktıyı üretmelidir

.........................
.\@/.....................
.........................
......O..........^|^.....
.....\|/.........^|^.....
..................|......
.................\|/.....
.........................
.........................
....*....................
...\|/..............\@/..
.........................
..................*......
.......\@/.......\|/.....
...O.....................
..\|/.......*............
...........\|/...........
.........................
3 weeds at 5 costs 15
3 snails at 2 costs 6
4 stones at 1 costs 4
total cost 25

Çıkış gereken bir satır kesintisi ile sonlandırılabilir.

Bu kod golf, en kısa kod kazanabilir.

Ek test durumu

Düzenleme: Bu, çiçek tarhında izin verilmeyen çok modern olan Unicode'u içeriyordu. Bu düzeltildi, üzgünüm.

25 15 5
5 3 ..@..\\|//.\|/. overgrown_plants 3
5 3 @-o....|...\|/. semi-articulated_plant 4
3 2 .|.\@/ mutant_plants 5
1 1 $ dollars 0
1 1 # stones 1
.........................
........@................
....$..\|/...........@...
............|.......\|/..
...#.......\@/...........
.........................
.........................
......@.......@......@...
.....\|/....\\|//...\|/..
.............\|/.........
.#....................#..
.........$.......|.......
...\/.......\/..\@/..\/..
..\\//.....\\//.....\\//.
.........................

Beklenen çıktı:

.........................
........@................
.......\|/...........@...
....................\|/..
.........................
.........................
.........................
......@..............@...
.....\|/............\|/..
.........................
.........................
.........................
...\/.......\/.......\/..
..\\//.....\\//.....\\//.
.........................
1 overgrown_plants at 3 costs 3
0 semi-articulated_plants at 4 costs 0
2 mutant_plants at 5 costs 10
2 dollars at 0 costs 0
3 stones at 1 costs 3
total cost 16

Her istenmeyen öğenin sınırlayıcı kutusunun kesin olduğunu varsayabilir miyiz? Yani, öğenin açıklamasında hiçbir sınır tamamen nokta değil mi?
John Dvorak

@ JanDvorak evet, bu yeterince makul bir kısıt gibi görünüyor. Bunu soruya ekleyeceğim ve bunu yapmamın sakıncası olmayacağı varsayımına dair ifadelerini ödünç alacağım.
VisualMelon

Salyangoz da farklı yöne mi sürülecek? \@ve @/mesela .. Yoksa ebediyen batıya mı işaret ediyorlar?
Han Soalone

@SickDimension, istenmeyen öğelerin yalnızca açıklandığı gibi tam olarak eşleştirilmesi, farklı döndürmeler ve döndürmeler eşleştirilmemesi gerekir. Bu, bir salyangozun diğer yönde sürünme olasılığını engellemez, ancak örnekte bunları kaldırmak için kimseye ödeme yapılmaz.
VisualMelon

Yanıtlar:


3

Perl - 636

Kesinlikle yapılabilecek biraz daha golf var. Ve muhtemelen bunu yapmanın daha iyi yolları.

<>;while(<>){if(/ /){chomp;push@v,$_}else{$t.=$_}}for(@v){r(split/ /)}say$t.$y."total cost $u";sub r{my($e,$w,$c,$h,$z)=@_;($i,$f,$q,$d)=(1,0,0,"."x$e);@m=($c=~/($d)/g);@l=split/\n/,$t;while($i>0){($g,$j)=(1,0);for(0..$#l){if($j==0&&$l[$_]=~/^(.*?)\.\Q$m[$j]\E\./){$j++;$l="."x length$1}elsif($j<@m&&$l[$_]=~/^$l\.\Q$m[$j]\E\./){$j++}elsif($j>0){$l[$_-1]=~s!.\Q$m[$j-1]\E.!" ".$m[$j-1]=~s/\./ /gr." "!e;($j,$g)=(0,0)}if($j==@m){$k=$j;for($f=$_;$f>$_-$j;$f--){$k--;$o="."x length$m[$k];$l[$f]=~s/^($l)\.\Q$m[$k]\E\./$1.$o./}($g,$j)=(0,0);$q++}}if($g){$i--}}$t=join("\n",@l)."\n";$t=~s/ /./g;$p=$z*$q;$u+=$p;$y.="$q $h at $z costs $p\n"}

Euroyu -Cişlemek için bayrak için 635 karakter + 1 .

Girdiyi sakladıysanız, input.txtaşağıdakilerle çalıştırabilirsiniz:

cat input.txt | perl -C -E'<>;while(<>){if(/ /){chomp;push@v,$_}else{$t.=$_}}for(@v){r(split/ /)}say$t.$y."total cost $u";sub r{my($e,$w,$c,$h,$z)=@_;($i,$f,$q,$d)=(1,0,0,"."x$e);@m=($c=~/($d)/g);@l=split/\n/,$t;while($i>0){($g,$j)=(1,0);for(0..$#l){if($j==0&&$l[$_]=~/^(.*?)\.\Q$m[$j]\E\./){$j++;$l="."x length$1}elsif($j<@m&&$l[$_]=~/^$l\.\Q$m[$j]\E\./){$j++}elsif($j>0){$l[$_-1]=~s!\Q$m[$j-1]\E!$m[$j-1]=~s/\./ /gr!e;($j,$g)=(0,0)}if($j==@m){$k=$j;for($f=$_;$f>$_-$j;$f--){$k--;$o="."x length$m[$k];$l[$f]=~s/^($l)\.\Q$m[$k]\E\./$1.$o./}($g,$j)=(0,0);$q++}}if($g){$i--}}$t=join("\n",@l)."\n";$t=~s/ /./g;$p=$z*$q;$u+=$p;$y.="$q $h at $z costs $p\n"}'

İşte ayrılan sürüm. Ben geçtim ve bazı şeyleri açıklamaya yardımcı olacak yorumlar ekledim Belki de değişken isimleri bazen daha okunabilir hale getireceğim. Bunun işe yaramadığı bazı kenar durumlar olabilir, ancak en azından örneklerle çalışır.

BEGIN { # These are the features we get with -C and -E flags
    $^H{'feature_unicode'} = q(1); # -C gives us unicode
    $^H{'feature_say'} = q(1); # -E gives us say to save 1 character from print
    $^H{'feature_state'} = q(1);
    $^H{'feature_switch'} = q(1);
}
<ARGV>; # throw away the first line
while (defined($_ = <ARGV>)) { # read the rest line by line
    if (/ /) { # if we found a space (the garden doesn't have spaces in it)
        chomp $_; # remove the newline
        push @v, $_; # add to our array
    }
    else { # else, we construct the garden
        $t .= $_;
    }
}
foreach $_ (@v) { # call the subroutine r by splitting our input lines into arguments
    r(split(/ /, $_, 0)); # the arguments would be like r(3,2,".R.\|/","rouge_flower",3)
}
say $t . $y . "total cost $u"; # print the cost at the end

# this subroutine removes weeds from the garden and counts them
sub r {
    BEGIN {
        $^H{'feature_unicode'} = q(1);
        $^H{'feature_say'} = q(1);
        $^H{'feature_state'} = q(1);
        $^H{'feature_switch'} = q(1);
    }
    my($e, $w, $c, $h, $z) = @_; # get our arguments
    ($i, $f, $q, $d) = (1, 0, 0, '.' x $e); # initialize some variables
    @m = $c =~ /($d)/g; # split a string like this .R.\|/ into .R. and \|/
    @l = split(?\n?, $t, 0); # split the garden into lines to process line by line
    while ($i > 0) {
        ($g, $j) = (1, 0);
        foreach $_ (0 .. $#l) { # go through the garden
            if ($j == 0 and $l[$_] =~ /^(.*?)\.\Q$m[$j]\E\./) { # this matches the top part of the weed. \Q and \E make it so the weed isn't intepreted as a regex. Capture the number of dots in front of it so we know where it is
                ++$j;
                $l = '.' x length($1); # this is how many dots we have
            }
            elsif ($j < @m and $l[$_] =~ /^$l\.\Q$m[$j]\E\./) { # capture the next line
                ++$j;
            }
            elsif ($j > 0) { # if we didn't match we have to reset
                $l[$_ - 1] =~ s[.\Q$m[$j - 1]\E.][' ' . $m[$j - 1] =~ s/\./ /rg . ' ';]e; # this line replaces the dots next to the weed and in the weed with spaces
                # to mark it since it didn't work but the top part matches
                # that way when we repeat we go to the next weed
                ($j, $g) = (0, 0);
            }
            if ($j == @m) { # the whole weed has been matched
                $k = $j;
                for ($f = $_; $f > $_ - $j; --$f) { # remove the weed backwards line by line
                    --$k;
                    $o = '.' x length($m[$k]);
                    $l[$f] =~ s/^($l)\.\Q$m[$k]\E\./$1.$o./; 
                }
                ($g, $j) = (0, 0);
                ++$q;
            }
        }
        if ($g) {
            --$i; # all the weeds of this type are gone
        }
    }
    $t = join("\n", @l) . "\n"; # join the garden lines back together
    $t =~ s/ /./g; # changes spaces to dots 
    $p = $z * $q; # calculate cost
    $u += $p; # add to sum
    $y .= "$q $h at $z costs $p\n"; #get message
}

İyileştirmeler önermekten çekinmeyin!


İyi iş çıkardım ve günah işlediğimden korkuyorum, çiçek tarhının ASCII olacağını belirttim ve sonra tüm heyecanlandım ve Unicode'u örneğe koydum - örneği değiştireceğim, böylece sadece ASCII, iş yaptığım için üzgünüm sen.
VisualMelon

1
@VisualMelon, unicode ile çalışmak için bir astarın nasıl alınacağını öğrenmek ilginçti. Bundan -Cönce bayrağı bilmiyordum . Sadece 1 karakterlik bir fark olduğu için yine de uyumlu olacak şekilde orada bırakacağım.
hmatt1

0

Python 3, 459 bayt

    from re import*
E=input()
W,H,C=map(int,E[0].split())
B,T,O='\n'.join(E[~H:]),0,''
for L in E[1:~H]:
 w,h,s,n,c=L.split();w,h,c=map(int,(w,h,c));r,t='.'*(w+2),0;a=[r]+['.%s.'%s[i:i+w]for i in range(0,w*h,w)]+[r]
 for L in['(%s)'%'\\n'.join('.{%d})%s(.*'%(i,escape(b))for b in a)for i in range(W)]:t+=len(findall(L,B));B=sub(L,r.join('\\%d'%b for b in range(1,h+4)),B,MULTILINE)
 O+='%d %s at %d costs %d\n'%(t,n,c,t*c);T+=t*c
print(B+O+'total cost',T)

Girdinin bir dize listesi olarak verileceğini varsayar.


~HHile hoşuma gidiyor ; Bunu şimdi test edemiyorum, ama bugün daha sonra yapmaya çalışacağım.
VisualMelon

Bu doğru çalıştırmak için elde edemez gibi görünmüyor ( ValueError: not enough values to unpack (expected 3, got 1), python 3.6.6); bir TIO bağlantısı veya nasıl çalıştırılacağına ilişkin bir açıklama sağlayabilir misiniz? Bence girişin tek bir satırda olduğunu varsayarak kuralları bükebiliriz, ama bu konuda tamamen net değildim, bu yüzden şikayet etmeyeceğim.
VisualMelon

@VisualMelon - bah, muhtemelen / makarna yanlış bir şey kopyaladım. İş yerinde TIO'ya ulaşamıyorum, bu yüzden işimi kontrol edip bugün daha sonra bir bağlantı göndereceğim.
Triggernometry
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.