Lập trình viên của vườn


12

Lập trình viên của vườn

Là một nhà phát triển phần mềm chuyên nghiệp, bạn không thể mạo hiểm tiếp xúc với ánh sáng phi nhân tạo của mặt trời, nhưng bạn cũng có một điểm mềm cho hoa và muốn giữ cho khu vườn của bạn luôn trong tình trạng tốt quanh năm.

Để kết thúc này, một người làm vườn được thuê mỗi tháng để dọn dẹp các bồn hoa dưới chân nhà của bạn. Tuy nhiên, bạn cần chắc chắn rằng người làm vườn đang thực hiện công việc của mình đúng cách và đưa ra một khoản thanh toán phù hợp cho người làm việc chăm chỉ. Đương nhiên một giải pháp phần mềm là tốt nhất.

Đầu vào

Chương trình của bạn sẽ được cung cấp đầu vào mô tả các thảm hoa như hiện tại và chi tiết về các mục cần phải loại bỏ. Chương trình phải xuất ra khu vườn không có sự lộn xộn và in ra một khoản chi trả cho những người làm vườn. Đầu vào có thể là từ STDIN hoặc là một đối số dòng lệnh.

Dòng đầu tiên có định dạng

width height unwanted_item_type_count

trong đó widthchiều rộng của thảm hoa, heightlà chiều cao của thảm hoa (cả hai ký tự ASCII) và unwanted_item_type_countcho bạn biết có bao nhiêu dòng sau sẽ chứa mô tả về một loại vật phẩm sẽ bị xóa khỏi vườn.

Mỗi dòng cho mỗi loại mặt hàng không mong muốn có định dạng

width height string_representation name fee_per_item

trong đó widthchiều rộng của mục, heightlà chiều cao của mục (cả hai ký tự ASCII), string_representationlà biểu diễn chuỗi của mục không ngắt dòng, namelà định danh cho loại mục (khoảng trắng sẽ được thay thế bằng dấu gạch dưới) và fee_per_itemlà người làm vườn phải trả bao nhiêu cho việc loại bỏ từng loại vật phẩm.

Ví dụ

3 2 .R.\|/ rouge_flower 3

Đại diện cho một loại mục tên rouge_flower, chi phí 3 để loại bỏ, và trông như thế này:

.R.
\|/

Các mục sẽ không chứa khoảng trắng và không có mục nào có thể có đường viền bao gồm các dấu chấm và biểu diễn chuỗi cũng sẽ có kích thước chính xác được mô tả. Do đó, tất cả những điều sau đây là đầu vào không hợp lệ:

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

Lưu ý rằng 0 tuy nhiên là một khoản phí hợp lệ (phí sẽ luôn là số nguyên lớn hơn -1).

Cũng lưu ý rằng thảm hoa chủ yếu được tạo thành từ các dấu chấm ( .) chứ không phải là khoảng trắng và bạn có thể sử dụng khoảng trắng một cách an toàn làm phân định cho tất cả các đầu vào. Các thảm hoa luôn được giới hạn bởi các dấu chấm chính nó.

Sau khi các loại vật phẩm không mong muốn được liệt kê, sau đó đến đại diện ASCII của thảm hoa có chiều rộng và chiều cao nhất định.

Đầu ra

Đầu ra phải là STDOUT hoặc thay thế phù hợp nếu ngôn ngữ của bạn không hỗ trợ nó.

Đầu ra bắt đầu bằng một bản in ra khỏi thảm hoa, nhưng với tất cả các mục không mong muốn được loại bỏ (thay thế bằng dấu chấm), vì vậy bạn có thể thấy nó sẽ xuất hiện như thế nào và kiểm tra người làm vườn đã thực hiện công việc của mình. Mỗi vật phẩm trong bồn hoa sẽ được bao quanh bởi một hình chữ nhật các chấm và sẽ là một vật phẩm liền kề nhau (tức là sẽ không có các chấm riêng biệt bên trong vật phẩm). Ví dụ

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

hiển thị 2 mục riêng biệt

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

hiển thị 1 mục

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

là không hợp lệ, vì trong khi đá (#) có thể được khớp, con rắn (bạn không thể nói đó là rắn?) không thể vì đá cản trở yêu cầu xung quanh các chấm.

...
\@.
...

Điều này cũng không hợp lệ, vì ốc sên nằm ở rìa của thảm hoa và cạnh phải luôn được giới hạn bởi các dấu chấm trong một đầu vào hợp lệ.

Sau này, cần có một danh sách của từng loại mặt hàng không mong muốn, đưa ra số lượng, chi phí cho mỗi mặt hàng và chi phí cho tất cả các mặt hàng (tính * chi phí cho mỗi mặt hàng), theo định dạng:

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

Sau này, cần có một dòng duy nhất cho tổng chi phí (tổng chi phí cho các mục không mong muốn):

total cost <total_cost>

Thí dụ

Đối với đầu vào này

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

Chương trình sẽ tạo ra đầu ra này

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

Đầu ra phải được kết thúc bằng ngắt dòng.

Đây là môn đánh gôn, có thể là đoạn mã ngắn nhất sẽ thắng.

Trường hợp kiểm tra bổ sung

Chỉnh sửa: điều này được sử dụng để chứa Unicode, không được phép trong thảm hoa, quá hiện đại. Điều này đã được khắc phục, xin lỗi về điều đó.

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

Đầu ra dự kiến:

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

Chúng tôi có thể giả sử hộp giới hạn của từng mục không mong muốn là chính xác? Đó là, không có đường viền trong mô tả của mục là dấu chấm đầy đủ?
John Dvorak

@JanDvorak có, đó có vẻ là một hạn chế đủ hợp lý. Tôi sẽ thêm câu hỏi đó vào câu hỏi và tôi sẽ mượn từ ngữ của bạn với giả định rằng bạn sẽ không phiền khi tôi làm như vậy.
VisualMelon

Con ốc cũng sẽ bò theo hướng khác chứ? \@@/ví dụ .. Hoặc họ bị ràng buộc chỉ về phía tây vĩnh viễn?
Han Soopol

@SickDimension các mục không mong muốn chỉ nên được khớp chính xác như chúng được mô tả, các phép quay và lật khác biệt không nên được khớp. Điều này không loại trừ khả năng một con ốc sên sẽ bò theo hướng khác, nhưng không ai được trả tiền để loại bỏ chúng trong ví dụ.
VisualMelon

Câu trả lời:


3

Perl - 636

Chắc chắn có một số golf có thể được thực hiện. Và có lẽ cách tốt hơn để làm điều đó quá.

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

635 ký tự + 1 cho -Ccờ để xử lý euro.

Nếu bạn có đầu vào được lưu trữ trong input.txtbạn có thể chạy nó với:

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

Đây là phiên bản deparsed. Tôi đã đi qua và thêm một số ý kiến ​​để giúp giải thích mọi thứ. Có lẽ đôi khi tôi sẽ làm cho tên biến trở nên dễ đọc hơn. Có thể có một số trường hợp cạnh này không hoạt động nhưng ít nhất nó cũng hoạt động với các ví dụ.

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
}

Hãy đề nghị cải tiến!


Công việc tuyệt vời và tôi sợ rằng mình đã phạm tội, tôi đã xác định rằng vườn hoa sẽ là ASCII, và sau đó rất phấn khích và đưa Unicode vào ví dụ - Tôi sẽ thay đổi ví dụ để nó chỉ là ASCII, xin lỗi vì đã làm việc cho bạn.
VisualMelon

1
@VisualMelon thật thú vị khi tìm hiểu làm thế nào để có một lớp lót hoạt động với unicode. Tôi đã không biết về -Clá cờ trước đó. Dù sao tôi cũng sẽ để nó tương thích vì nó chỉ khác nhau 1 ký tự.
hmatt1

0

Python 3, 459 byte

    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)

Giả sử đầu vào sẽ được đưa ra dưới dạng danh sách các chuỗi.


Tôi thích ~Hmánh khóe; Tôi không thể kiểm tra điều này ngay bây giờ, nhưng tôi sẽ cố gắng thực hiện sau ngày hôm nay.
VisualMelon

Tôi dường như không thể có được điều này để chạy chính xác ( ValueError: not enough values to unpack (expected 3, got 1), python 3.6.6); bạn có thể cung cấp một liên kết TIO hoặc một số mô tả về cách chạy nó. Tôi nghĩ rằng nó có thể bẻ cong các quy tắc bằng cách giả sử đầu vào là tất cả trên một dòng, nhưng tôi không hoàn toàn rõ ràng về điều đó trong câu hỏi nên tôi sẽ không phàn nàn.
VisualMelon

@VisualMelon - bah, tôi có thể đã sao chép / dán một cái gì đó không chính xác. Tôi không thể đến TIO tại nơi làm việc, vì vậy tôi sẽ kiểm tra công việc của mình và đăng một liên kết sau ngày hôm nay.
Triggernometry
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.