プログラマーズガーデン


12

プログラマーズガーデン

プロのソフトウェア開発者であるあなたは、太陽の厳しい非人工光にさらされる危険を冒すことはできませんが、花のためのソフトスポットもあり、一年中庭を良い状態に保ちたいです。

このため、毎月庭師を雇って家のふもとの花壇をきれいにします。ただし、庭師が仕事を適切に行っていることを確認し、勤勉な仲間に適切な支払いをする必要があります。当然、ソフトウェアソリューションが最適です。

入力

プログラムには、現在表示されている花壇を説明する入力と、削除する必要があるアイテムの詳細が入力されます。プログラムは、乱雑さのない庭を出力し、庭師の支払いの内訳を印刷する必要があります。入力は、STDINからのものでも、単一のコマンドライン引数としてでもかまいません。

入力の最初の行は次の形式です

width height unwanted_item_type_count

ここwidthで、花壇の幅、花壇heightの高さ(両方ともASCII文字)、およびunwanted_item_type_count庭から削除するアイテムの種類の説明を含む行の数を示します。

不要な種類のアイテムの各行は次の形式です

width height string_representation name fee_per_item

ここwidthで、アイテムの幅、アイテムheightの高さ(両方ともASCII文字)、string_representation改行なしのアイテムの文字列表現、アイテムnameのタイプの識別子(スペースはアンダースコアに置き換えられます)、およびfee_per_item各タイプのアイテムの除去に対して庭師に支払う必要がある金額です。

例えば

3 2 .R.\|/ rouge_flower 3

nameのアイテムタイプをrouge_flower表します。これは、削除に3コストがかかり、次のようになります。

.R.
\|/

アイテムにはスペースが含まれず、すべてのアイテムにドットのみで構成される境界線を含めることはできません。また、文字列表現も正確なサイズになります。したがって、次のすべては無効な入力です。

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

ただし、0は有効な料金です(料金は常に-1より大きい整数です)。

また、花壇は主に.スペースではなくドット()で構成されており、すべての入力の区切りとして空白を安全に使用できることに注意してください。花壇は常にドット自体に囲まれています。

不要なアイテムタイプがリストされた後、指定された幅と高さの花壇のASCII表現が表示されます。

出力

出力はSTDOUTであるか、言語がサポートしていない場合は適切な代替である必要があります。

出力は花壇のプリントアウトから始まりますが、不要なアイテムはすべて削除(ドットに置き換え)されるため、どのように表示されるかを確認し、庭師が仕事をしたことを確認できます。花壇の各アイテムはドットの長方形で囲まれ、1つの連続したアイテムになります(つまり、アイテム内に分離するドットはありません)。例えば

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

2つの別々のアイテムを示しています

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

1個のアイテムを表示

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

石(#)を一致させることはできますが、石は必要なドットの周囲に干渉するため、ヘビ(ヘビであるとはわかりませんか?)は無効です。

...
\@.
...

これも無効です。カタツムリは花壇の端にあり、有効な入力では常に端をドットで区切る必要があります。

その後、不要なアイテムの各タイプのリストが表示され、カウント、アイテムごとのコスト、およびすべてのアイテムのコスト(カウント*アイテムごとのコスト)が次の形式で表示されます。

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

この後、合計コスト(不要なアイテムのコストの合計)を生成する単一の行があるはずです。

total cost <total_cost>

例

この与えられた入力に対して

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

プログラムはこの出力を生成するはずです

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

出力は改行で終了する必要があります。

これはコードゴルフです。最短のコードが勝つかもしれません。

追加のテストケース

編集:これはユニコードを含んでいたが、これは花壇では許可されておらず、あまりにも現代的である。これは修正されました。ごめんなさい。

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
.........................
........@................
....$..\|/...........@...
............|.......\|/..
...#.......\@/...........
.........................
.........................
......@.......@......@...
.....\|/....\\|//...\|/..
.............\|/.........
.#....................#..
.........$.......|.......
...\/.......\/..\@/..\/..
..\\//.....\\//.....\\//.
.........................

期待される出力:

.........................
........@................
.......\|/...........@...
....................\|/..
.........................
.........................
.........................
......@..............@...
.....\|/............\|/..
.........................
.........................
.........................
...\/.......\/.......\/..
..\\//.....\\//.....\\//.
.........................
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

不要な各アイテムの境界ボックスが正確であると想定できますか?つまり、アイテムの説明に完全なドットの境界線はありませんか?
— ジョンド

@JanDvorakはい、それは合理的な十分な制約のようです。それを質問に追加し、あなたが私のことを気にしないという仮定であなたの言葉遣いを借ります。
— VisualMelon 14

カタツムリも異なる方向にcっていますか?\@そして@/、例えば..彼らは永遠に西を指すようにバインドされていますか?
— ハンソローネ2014

@SickDimension不要なアイテムは、記述されているとおりに正確に一致する必要があります。個別の回転と反転は一致しません。これは、カタツムリが他の方向にcraう可能性を排除するものではありませんが、この例ではカタツムリを除去するための支払いは行われていません。
— VisualMelon 14

回答:


3

Perl-636

できることは間違いなくいくつかあります。そしておそらくそれを行うより良い方法も。

<>;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"}

-Cユーロを処理するフラグの635文字+ 1 。

入力が保存されている場合は、次のコマンドでinput.txt実行できます。

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"}'

これが、分解されたバージョンです。私は調べて、物事の説明に役立つコメントを追加しました。たぶん、変数名をもっと読みやすくするつもりです。これではうまくいかない場合もありますが、少なくとも例では動作します。

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
}

改善点をお気軽にご提案ください!


いい仕事だ、私は罪を犯したのではないかと思う。花壇がASCIIになるように指定してから、例にUnicodeを入れて興奮させた。君は。
— VisualMelon 14

1
@VisualMelonは、Unicodeで1ライナーを使用する方法を学ぶのが面白かったです。私は-Cこの前に旗について知りませんでした。とにかく互換性を保つために残しておきます。違いは1文字だけだからです。
— hmatt1 14

0

Python 3、459バイト

    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)

入力が文字列のリストとして与えられると仮定します。


私は~Hトリックが好きです。私は今これをテストすることはできませんが、私は今日後でテストしようとします。
— VisualMelon

これを正しく実行することはできません(ValueError: not enough values to unpack (expected 3, got 1)python 3.6.6)。TIOリンクまたはその実行方法に関する説明を提供できますか。入力がすべて1行であると仮定してルールを曲げているのではないかと思いますが、質問ではそれについて完全には明確ではなかったので、文句を言いません。
— VisualMelon

@VisualMelon-ああ、私はおそらく何かを間違ってコピー/パスタしました。仕事でTIOにアクセスできないので、仕事をチェックして、今日中にリンクを投稿します。
— トリガー測定
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.