프로그래머의 정원


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유형의 식별자 (공백은 밑줄로 바 will) 및 fee_per_item각 유형의 항목을 제거 할 때 정원사가 지불해야하는 금액입니다.

예를 들어

3 2 .R.\|/ rouge_flower 3

rouge_flower제거 할 비용이 3 인 name의 항목 유형을 나타 냅니다.

.R.
\|/

항목은 공백을 포함하지 않으며 항목이 완전히 점으로 구성된 테두리를 가질 수 없으며 문자열 표현도 정확한 크기로 표시됩니다. 따라서 다음은 모두 유효하지 않은 입력입니다.

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

그러나 0은 유효한 수수료입니다 (수수료는 항상 -1보다 큰 정수임).

화단은 주로 .공백이 아닌 점 ( ) 으로 구성 되며 모든 입력의 공백으로 공백을 안전하게 사용할 수 있습니다. 화단은 항상 점 자체로 묶여 있습니다.

원치 않는 항목 유형이 나열되면 주어진 너비와 높이의 화단의 ASCII 표현이 제공됩니다.

산출

출력은 STDOUT으로, 또는 언어가 지원하지 않는 경우 적절한 대안이어야합니다.

출력은 화단의 인쇄물로 시작되지만 원치 않는 모든 항목이 제거되고 (점으로 대체 됨) 정원사가 자신의 작업을 수행 한 방법을 확인하고 확인할 수 있습니다. 화단의 각 항목은 사각형의 점으로 둘러싸여 있으며 하나의 연속 된 항목이됩니다 (즉 , 항목 안에 분리 점은 없습니다 ). 예를 들어

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

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

원치 않는 각 항목의 경계 상자가 정확하다고 가정 할 수 있습니까? 즉, 항목 설명의 테두리가 완전히 점이 아닙니까?
John Dvorak

@ JanDvorak 예, 그것은 충분한 제약이있는 것 같습니다. 나는 그것을 질문에 추가하고, 당신이 내 마음에 들지 않을 것이라는 가정에 대해 당신의 말을 빌릴 것입니다.
VisualMelon

달팽이도 다른 방향으로 크롤링됩니까? \@그리고 @/예를 들어 .. 아니면 그들이 영원히 서쪽 지점에 바인딩?
한 솔론

@SickDimension 원치 않는 항목은 설명 된대로 정확하게 일치해야하며 뚜렷한 회전 및 반전은 일치해서는 안됩니다. 이것은 달팽이가 다른 방향으로 기어 다닐 가능성을 배제하지는 않지만 예제에서 달팽이를 제거 할 사람은 아무도 없습니다.
VisualMelon

답변:


3

펄-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가되도록 지정하고 모든 흥분하고 예제에 유니 코드를 넣었습니다. 예제를 변경하여 ASCII 일뿐입니다. 당신.
VisualMelon

1
@VisualMelon 하나의 라이너로 유니 코드를 사용하는 방법을 배우는 것이 흥미 롭습니다. 나는 -C전에 깃발 에 대해 몰랐다 . 어쨌든 1 문자 차이이기 때문에 호환되도록 남겨 두겠습니다.
hmatt1

0

파이썬 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 링크 또는이를 실행하는 방법에 대한 설명을 제공 할 수 있습니다. 나는 입력이 모두 한 줄에 있다고 가정하여 규칙을 왜곡 할 수 있다고 생각하지만, 질문에서 그것에 대해 완전히 명확하지 않았으므로 불평하지 않을 것입니다.
VisualMelon

@ VisualMelon-bah, 아마도 복사 / 파스타를 잘못 입력했을 것입니다. 직장에서 TIO에 갈 수 없으므로 오늘 업무를 확인하고 링크를 게시하겠습니다.
Triggernometry
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.