농부를 돕는


10

파머 잭은 매우 가난합니다. 그는 농장 전체를 밝히고 싶지만 최소한의 비용으로 조명을 원합니다. 램프는 8 개의 이웃뿐만 아니라 자체 셀을 비출 수 있습니다. 그는 자신의 분야에 램프를 배치했지만 추가 램프를 유지했는지 여부를 찾는 데 도움이 필요합니다.

여분의 램프 : 농장에서 꺼낼 때 점등되는 셀 수에는 차이가 없습니다. 또한 지시하는 램프는 하나씩 제거되지 않지만 동시에 제거됩니다.

참고 : 수행 할 수있는 유일한 조치는 일부 램프를 제거하는 것입니다. 램프를 재 배열하거나 삽입 할 수 없습니다. 최종 목표는 이전에 점등 된 모든 셀이 여전히 점등되도록 최대 수의 램프를 제거하는 것입니다.

Farmer Jack이 다른 곳에서 사용할 수 있도록 최대 개수의 쓸모없는 램프를 찾도록 도와주십시오.

입력

필드 MN 의 첫 번째 행 치수가 주어지며 다음 M 행은 각각 필드를 나타내는 N 개의 문자를 포함 합니다.

'1'은 램프가 유지되는 셀을 나타냅니다.

'0'은 빈 셀을 나타냅니다.

산출

쓸모없는 램프 수를 포함하는 정수를 출력해야합니다.

샘플 입력 :

3 3
100
010
001

샘플 출력 :

2

우승자:

코드 골프이기 때문에 우승자는 최소한의 문자로 작업을 성공적으로 완료하는 사람입니다.


@PeterTaylor 게시물을 편집했습니다. 여전히 혼란이 있습니까?
user2369284

훨씬 낫다. 감사.
피터 테일러

입력이 줄 바꿈으로 끝나는 것으로 가정 할 수 있습니까?
John Dvorak

1
이것은 숙제처럼 보입니다.
Johannes

1
입력 램프가 농장 전체를 밝게 비출 것입니까? 나는 추측하지 않을거야 ...
Keith Randall

답변:


5

Mathematica 186 (욕심쟁이) 및 224 (모든 조합)

욕심 솔루션

t=MorphologicalTransform;n@w_:=Flatten@w~Count~1
p_~w~q_:=n[p~t~Max]==n[q~t~Max]
g@m_:=Module[{l=m~Position~1,r,d=m},While[l!={},If[w[m,r=ReplacePart[d,#-> 0]&    
[l[[1]]]],d=r];l=Rest@l];n@m-n@d]

불필요한 조명을 하나씩 끕니다. 조명이 꺼 졌을 때 조명 범위가 줄어들지 않으면 해당 조명을 제거 할 수 있습니다. 욕심 많은 접근 방식은 매우 빠르며 15x15 이상의 행렬을 쉽게 처리 할 수 ​​있습니다 (아래 참조). 단일 솔루션을 반환하지만 이것이 최적인지 아닌지는 알 수 없습니다. 골프 버전에서는 두 가지 방법 모두 사용되지 않은 조명의 수를 반환합니다. 골프화되지 않은 접근 방식은 아래와 같이 그리드를 표시합니다.

전에:

전에

후:

후

모든 조명 조합 (224 자)을 사용하는 최적의 솔루션

@ Clément 덕분에.

모든 조명 조합을 사용하는 언 골프 버전

f에 사용 된 형태 변환 함수 sameCoverageQ는 각 조명이 상주하는 3 x3 정사각형을 조명 (0 대신 값 = 1)으로 처리합니다. 농장은 계산됩니다. 두 개 이상의 램프로 켜진 사각형은 단순히 켜집니다. 프로그램은 각 조명을 끄고 팜의 전체 조명 범위가 감소되었는지 확인합니다. 그렇지 않으면 조명이 제거됩니다.

nOnes[w_]:=Count[Flatten@w,1]
sameCoverageQ[m1_,m2_]:=nOnes[MorphologicalTransform[m1,Max]]==
  nOnes[MorphologicalTransform[m2,Max]]

(*draws a grid with light bulbs *)
h[m_]:=Grid[m/.{1-> Style[\[LightBulb],24],0-> ""},Frame-> All,ItemSize->{1,1.5}]

c[m1_]:=GatherBy[Cases[{nOnes[MorphologicalTransform[ReplacePart[Array[0&,Dimensions[m1]],
#/.{{j_Integer,k_}:> {j,k}-> 1}],Max]],#,Length@#}&/@(Rest@Subsets[Position[m1,1]]),
{nOnes[MorphologicalTransform[m1,Max]],_,_}],Last][[1,All,2]]

nOnes[matrix]플래그 지정된 셀 수를 계산합니다. 조명을 세고 조명 된 셀을 세는 데 사용됩니다.

sameCoverageQ[mat1, mat2] mat1의 조명 된 셀이 mat2의 조명 된 셀 수와 같은지 여부를 테스트합니다. MorphologicalTransform [[mat]은 조명 행렬을 가져 와서 조명 된 셀의 행렬을 반환합니다.

c[m1]m1에서 모든 조명 조합을 취해 적용 범위를 테스트합니다. 최대 적용 범위를 가진 것 중에서 전구가 가장 적은 것을 선택합니다. 이들 각각은 최적의 솔루션입니다.


예 1 :

6x6 설정

(*all the lights *)
m=Array[RandomInteger[4]&,{6,6}]/.{2-> 0,3->0,4->0}
h[m]

기발한

모든 최적의 솔루션.

(*subsets of lights that provide full coverage *)
h/@(ReplacePart[Array[0&,Dimensions[m]],#/.{{j_Integer,k_}:> {j,k}-> 1}]&/@(c[m]))

대답


모든 조명 조합을 사용한 골프 버전.

이 버전은 사용되지 않은 조명의 수를 계산합니다. 그리드를 표시하지 않습니다.

c 사용되지 않은 조명의 수를 반환합니다.

n@w_:=Flatten@w~Count~1;t=MorphologicalTransform;
c@r_:=n@m-GatherBy[Cases[{n@t[ReplacePart[Array[0 &,Dimensions[r]],#
/.{{j_Integer,k_}:> {j,k}-> 1}],Max],#,Length@#}&/@(Rest@Subsets[r~Position~1]),
{n[r~t~Max],_,_}],Last][[1,1,3]]

n[matrix]플래그 지정된 셀 수를 계산합니다. 조명을 세고 조명 된 셀을 세는 데 사용됩니다.

s[mat1, mat2] mat1의 조명 된 셀이 mat2의 조명 된 셀 수와 같은지 여부를 테스트합니다.

c[j]j의 모든 조명 조합을 취해 적용 범위를 테스트합니다. 최대 적용 범위를 가진 것 중에서 전구가 가장 적은 것을 선택합니다. 이들 각각은 최적의 솔루션입니다.

실시 예 2

m=Array[RandomInteger[4]&,{6,6}]/.{2-> 0,3->0,4->0};
m//Grid

그리드

동일한 조명 범위를 유지하면서 두 개의 조명을 저장할 수 있습니다. 센티미터]

2


필자는 Mathematica를 가지고 있지 않으므로이 코드를 테스트 할 수 없지만 설명을 잘못 이해하지 않으면 알고리즘이 잘못되었다고 생각합니다. 내가 이해 한 것이 맞다면, 빛이 처리되는 순서에 의존하는 탐욕스러운 전략에 의존합니다. 예를 들어, 3 * 3 테스트 케이스의 중간 램프에서 시작하면 그것을 제거하고 두 개의 측면 램프를 남겨 둡니다. 구현에 사용하는 특정 순서가 올바른 것으로 기대하지는 않지만 현재로서는 반대의 예가 없습니다.
Clément

귀하의 아이디어는 원래 설정에서 2 개의 불필요한 조명 (a, b)을 가질 수 있으며 그중 하나가 다른 것보다 더 불필요하다는 것 같습니다. 따라서 하나가 제거되면 (먼저) 더 나은 경제가 이루어질 수 있습니다. 나는 이것이 총 3 개의 조명으로 발생할 수는 없지만 실제로 많은 수의 조명으로 가능할 수 있다고 생각합니다. 원래 조명의 모든 조합을 테스트하여 문제를 해결했습니다. 이것은 확실히 최적이므로 이상적이지만, 큰 조명 세트에서는 비실용적이라는 것을 알았습니다.
DavidC

@ Clément 가능한 모든 조합을 테스트하는 솔루션을 개발 중입니다. 시간이 좀 걸릴 것입니다.
DavidC

확실하게;) 그러나 그것은 예상됩니다. 이것이 의미하는 바와 같이,이 문제는 최소 설정 커버의 인스턴스 인 NP입니다. 추가적인 가정 (측면을 제외한 거의 모든 커버링 세트가 동일한 카디널리티를 가짐)이 효율적인 구현을 허용하는지 여부는 흥미로운 문제입니다.
Clément

행과 열로 순차적으로 갈 경우 욕심 많은 해결책이 올바른 것으로 생각하지만 아직 입증되지 않았습니다.
SE가 EVIL이기 때문에 Aditsu 종료

3

파이썬, 309 자

import sys
I=sys.stdin.readlines()[1:]
X=len(I[0])
L=[]
m=p=1
for c in''.join(I):m|=('\n'!=c)*p;L+=('1'==c)*[p<<X+1|p<<X|p<<X-1|p*2|p|p/2|p>>X-1|p>>X|p>>X+1];p*=2
O=lambda a:m&reduce(lambda x,y:x|y,a,0)
print len(L)-min(bin(i).count('1')for i in range(1<<len(L))if O(L)==O(x for j,x in enumerate(L)if i>>j&1))

비트 마스크를 사용하여 작동합니다. L각 라이트는 라이트 패턴으로 설정된 최대 9 비트의 정수로 표시됩니다. 그런 다음 비트 단위 또는 전체 목록의 비트 단위와 동일한이 목록의 하위 집합을 철저하게 검색합니다. 가장 짧은 하위 집합이 승자입니다.

m 시프 팅시 비트의 랩 어라운드를 방지하는 마스크입니다.


올바르게 실행되는 프로그램을 제공하십시오 .Java / C ++는 모든 종류의 들여 쓰기 또는 간격에 안전하지만 Python은 아닙니다. 폐쇄 또는 단축 코드는 다른 것이지만 실행되지 않는 프로그램을 제공하는 것은 다른 것입니다.
user2369284

3
무슨 소리 야?! 그것은 완벽하게 잘 작동합니다 (python 2와 함께)
SE는 EVIL이기 때문에 aditsu quit

@aditsu 저는 파이썬 3을 가지고 있습니다.
user2369284

1
이 파이썬 3에서 실패 있도록 @ user2369284 아니라, 인쇄 구문은 다릅니다
SE 악이기 때문에 aditsu 종료

3

자바 6-509 바이트

나는 현재 한계에 대해 몇 가지 가정을하고 문제를 해결했다.

import java.util.*;enum F{X;{Scanner s=new Scanner(System.in);int m=s.nextInt(),n=s.nextInt(),i=m,j,k=0,l=0,r=0,o,c,x[]=new int[30],y[]=x.clone();int[][]a=new
int[99][99],b;while(i-->0){String t=s.next();for(j=n;j-->0;)if(t.charAt(j)>48){x[l]=i;y[l++]=j;}}for(;k<l;++k)for(i=9;i-->0;)a[x[k]+i/3][y[k]+i%3]=1;for(k=1<<l;k-->0;){b=new
int[99][99];for(j=c=l;j-->0;)if((k&1<<j)>0)for(c--,i=9;i-->0;)b[x[j]+i/3][y[j]+i%3]=1;for(o=i=0;i++<m;)for(j=0;j++<n;)o|=a[i][j]^b[i][j];r=c-o*c>r?c:r;}System.out.println(r);}}

다음과 같이 실행하십시오. java F <inputfile 2>/dev/null


정확히 짧지는 않지만 디스크 섹터에 맞습니다 .p 나중에 다른 언어를 시도 할 수 있습니다.
SE 악이기 때문에 aditsu 종료

@aditsu Windows에서이 작업을 수행하는 방법?
user2369284

1
@ user2369284 : 2 개의 램프로 0011111100을 수행하는 방법을 모르겠습니다. 8 개의 셀을 빛으로 가려야하며 각 램프는 최대 3 개를 수행 할 수 있습니다.
Keith Randall

@ user2369284 아마도 java F <inputfile 2>nul실패 java F <inputfile하면 예외를 무시하십시오. 또한 자바 7에서는 실행되지 않습니다.
SE가 EVIL이기 때문에 aditsu quit

@aditsu 정말 죄송합니다. 오타 오류였습니다. 프로그램이 올바르게 작동합니다.
user2369284

1

C ++-477 바이트

#include <iostream>
using namespace std;int main(){
int c,i,j,m,n,p,q=0;cin>>m>>n;
int f[m*n],g[m*n],h[9]={0,-1,1,-m-1,-m,-m+1,m-1,m,m+1};
for(i=0;i<m*n;i++){f[i]=0;g[i]=0;do{c=getchar();f[i]=c-48;}while(c!='0'&&c!='1');}
for(i=0;i<m*n;i++)if(f[i])for(j=0;j<9;j++)if(i+h[j]>=0&&i+h[j]<m*n)g[i+h[j]]++;
for(i=0;i<m*n;i++)if(f[i]){p=0;for(j=0;j<9;j++)if(i+h[j]>=0&&i+h[j]<m*n)if(g[i+h[j]]<2)p++;if(p==0){for(j=0;j<9;j++)if(i+h[j]>=0&&i+h[j]<m*n)g[i+h[j]]--;q++;}}cout<<q<<endl;}

1

루비, 303

[이것은 이전 버전의 질문에 답변하도록 코딩되었습니다; 아래의 메모를 읽으십시오]

def b(f,m,n,r)b=[!1]*1e6;(n..n+m*n+m).each{|i|b[i-n-2,3]=b[i-1,3]=b[i+n,3]=[1]*3if f[i]};b[r*n+r+n+1,n];end
m,n=gets.split.map(&:to_i)
f=[!1]*n
m.times{(?0+gets).chars{|c|f<<(c==?1)if c>?*}}
f+=[!u=0]*n*n
f.size.times{|i|g=f.dup;g[i]?(g[i]=!1;u+=1if m.times{|r|break !1if b(f,m,n,r)!=b(g,m,n,r)}):0}
p u

부울 배열로 변환 한 다음 주변 값을 비교하여 변경합니다.

제한 (?) : 최대 팜 필드 크기는 1,000 x 1,000입니다. 문제는 "농장 잭은 매우 가난하다"고 말하며 그의 농장이 더 크지 않다고 가정합니다. ;-) 2 개의 문자를 추가하여 제한을 제거 할 수 있습니다.

참고 : 이 코딩을 시작한 이후 질문 요구 사항이 변경된 것으로 보입니다. 다음 설명이 추가되었습니다. "표시 할 램프는 하나씩 제거되지 않지만 동시에 제거됩니다 . " 원래 질문의 모호성은 개별 램프 제거 를 테스트하여 일부 코드를 저장할 수있었습니다 . 따라서 내 솔루션은 새로운 요구 사항에 따라 많은 테스트 사례에서 작동하지 않습니다. 시간이 있으면이 문제를 해결하겠습니다. 나는하지 않을 수 있습니다. 여기에있는 다른 답변은 완전히 호환 될 수 있으므로이 답변을 찬성하지 마십시오 .


1

APL, 97 자 / 바이트 *

⎕IO←1⎕ML←3APL 환경을 가정 합니다.

m←{s↑⊃∨/,v∘.⊖(v←⍳3)⌽¨⊂0⍪0⍪0,0,s⍴⍵}⋄n-⌊/+/¨t/⍨(⊂m f)≡¨m¨(⊂,f)\¨t←⊂[1](n⍴2)⊤⍳2*n←+/,f←⍎¨⊃{⍞}¨⍳↑s←⍎⍞

언 골프 버전 :

s ← ⍎⍞                                         ⍝ read shape of field
f ← ⍎¨ ⊃ {⍞}¨ ⍳↑s                              ⍝ read original field (lamp layout)
n ← +/,f                                       ⍝ original number of lamps
c ← ⊂[1] (n⍴2) ⊤ ⍳2*n                          ⍝ all possible shutdown combinations
m ← {s↑ ⊃ ∨/ ,v ∘.⊖ (v←⍳3) ⌽¨ ⊂ 0⍪0⍪0,0, s⍴⍵}  ⍝ get lighted cells given a ravelled field
l ← m¨ (⊂,f) \¨ c                              ⍝ map of lighted cells for every combination
k ← c /⍨ (⊂ m f) ≡¨ l                          ⍝ list of successful combinations
u ← ⌊/ +/¨ k                                   ⍝ min lamps used by a successful comb.
⎕ ← n-u                                        ⍝ output number of useless lamps

⎕ ← s⍴ ⊃ (⊂,f) \¨ (u= +/¨ k) / k               ⍝ additional: print the layout with min lamps

더 많은 테스트 사례가 더 나을 것이라는 데 동의합니다. 다음은 무작위입니다.

입력:

5 5
10001
01100
00001
11001
00010

출력 (무용 한 램프) :

5

최소 램프가있는 레이아웃 (골프 버전에는 포함되지 않음) :

0 0 0 0 1
0 1 0 0 0
0 0 0 0 0
0 1 0 0 1
0 0 0 0 0

* : APL 기호를 상위 128 바이트 값에 매핑하는 자체 (레거시) 단일 바이트 문자 집합으로
APL을 작성할 수 있습니다. 따라서 스코어링을 위해 ASCII 문자와 APL 기호 만 사용하는 N 문자 프로그램은 N 바이트 길이로 간주 될 수 있습니다.


0

C ++ 5.806 바이트

아직 크기에 최적화되지 않았습니다. 그러나 참가자가 거의 없기 때문에 지금은 그대로 두겠습니다.

농민들 필드 헤더 :

#pragma once

namespace FarmersLand
{

class FarmersField
{
private:
    unsigned _m_size, _n_size;
    int * _lamp, * _lumination;
    char * _buffer;
    void _illuminate(unsigned m, unsigned n);
    void _deluminate(unsigned m, unsigned n);
    void _removeLamp(unsigned m, unsigned n);
    void _setLamp(unsigned m, unsigned n);
    int _canRemoveLamp(unsigned m, unsigned n);
    int _coordsAreValid(unsigned m, unsigned n);
    int _getLuminationLevel(unsigned m, unsigned n);
    int * _allocIntArray(unsigned m, unsigned n);
    int _coordHelper(unsigned m, unsigned n);
public:
    FarmersField(char * input[]);
    FarmersField(const FarmersField & field);
    ~FarmersField(void);
    int RemoveLamps(void);
    char * Cstr(void);
};

}

농민 현장 CPP :

#include "FarmersField.h"
#include <stdio.h>


namespace FarmersLand
{

void FarmersField::_illuminate(unsigned m, unsigned n)
{
    if(this -> _coordsAreValid(m,n))
    {
        ++this -> _lumination[this -> _coordHelper(m,n)];
    }
}

void FarmersField::_deluminate(unsigned m, unsigned n)
{
    if(this -> _coordsAreValid(m,n))
    {
        --this -> _lumination[this -> _coordHelper(m,n)];
    }
}

void FarmersField::_removeLamp(unsigned m, unsigned n)
{
    if(this -> _coordsAreValid(m,n))
    {
        unsigned mi_start = (m == 0) ? 0 : m - 1;
        unsigned mi_end = m + 1;
        unsigned ni_start = (n == 0) ? 0 : n - 1;
        unsigned ni_end = n + 1;

        for(unsigned mi = mi_start; mi <= mi_end; ++mi)
        {
            for(unsigned ni = ni_start; ni <= ni_end; ++ni)
            {
                this -> _deluminate(mi, ni);
            }
        }
        --this -> _lamp[this -> _coordHelper(m,n)];
    }
}

void FarmersField::_setLamp(unsigned m, unsigned n)
{
    if(this -> _coordsAreValid(m,n))
    {
        unsigned mi_start = (m == 0) ? 0 : m - 1;
        unsigned mi_end = m + 1;
        unsigned ni_start = (n == 0) ? 0 : n - 1;
        unsigned ni_end = n + 1;

        for(unsigned mi = mi_start; mi <= mi_end; ++mi)
        {
            for(unsigned ni = ni_start; ni <= ni_end; ++ni)
            {
                this -> _illuminate(mi, ni);
            }
        }
        ++this -> _lamp[this -> _coordHelper(m,n)];
    }
}

int FarmersField::_canRemoveLamp(unsigned m, unsigned n)
{
    unsigned can = 1;
    unsigned mi_start = (m == 0) ? 0 : m - 1;
    unsigned mi_end =   (m == (this->_m_size - 1)) ? m : m + 1;
    unsigned ni_start = (n == 0) ? 0 : n - 1;
    unsigned ni_end =   (n == (this->_n_size - 1)) ? n : n + 1;

    for(unsigned mi = mi_start; mi <= mi_end; ++mi)
    {
        for(unsigned ni = ni_start; ni <= ni_end; ++ni)
        {
            if( 1 >= this -> _getLuminationLevel(mi, ni) )
            {
                can = 0;
            }
        }
    }
    return can;
}

int FarmersField::_coordsAreValid(unsigned m, unsigned n)
{
    return m < this -> _m_size && n < this -> _n_size;
}

int FarmersField::_getLuminationLevel(unsigned m, unsigned n)
{
    if(this -> _coordsAreValid(m,n))
    {
        return this -> _lumination[this -> _coordHelper(m,n)];
    }
    else
    {
        return 0;
    }
}

int * FarmersField::_allocIntArray(unsigned m, unsigned n)
{
    int * a = new int[m * n];
    for(unsigned i = 0; i < m*n; ++i)
    {
        a[i] = 0;
    }
    return a;
}

int FarmersField::_coordHelper(unsigned m, unsigned n)
{
    return m * this -> _n_size + n;
}

int FarmersField::RemoveLamps(void)
{
    int r = 0;
    for(unsigned m = 0 ; m < this -> _m_size; ++m)
    {
        for(unsigned n = 0 ; n < this -> _n_size; ++n)
        {
            if(this -> _canRemoveLamp(m,n))
            {
                ++r;
                this -> _removeLamp(m,n);
            }
        }
    }
    return r;
}

char * FarmersField::Cstr(void)
{
    unsigned size = this -> _m_size * this -> _n_size + _m_size ;
    unsigned target = 0;
    delete(this -> _buffer);
    this -> _buffer = new char[ size ];
    for(unsigned m = 0 ; m < this -> _m_size; ++m)
    {
        for(unsigned n = 0 ; n < this -> _n_size; ++n)
        {
            this -> _buffer[target++] =  (0 == this -> _lamp[this -> _coordHelper(m,n)])? '0' : '1';
        }
        this -> _buffer[target++] = '-'; 
    }
    this -> _buffer[size - 1 ] = 0;
    return this -> _buffer;
}

FarmersField::FarmersField(char * input[])
{
    sscanf_s(input[0], "%u %u", &this -> _m_size, &this -> _n_size);

    this -> _lamp = this -> _allocIntArray(this -> _m_size, this -> _n_size);
    this -> _lumination = this -> _allocIntArray(this -> _m_size, this -> _n_size);
    this -> _buffer = new char[1];

    for(unsigned m = 0 ; m < this -> _m_size; ++m)
    {
        for(unsigned n = 0 ; n < this -> _n_size; ++n)
        {
            if('0' != input[m+1][n])
            {
                this -> _setLamp(m,n);
            }
        }
    }
}

FarmersField::FarmersField(const FarmersField & field)
{
    this -> _m_size = field._m_size;
    this -> _n_size = field._n_size;

    this -> _lamp = this -> _allocIntArray(this -> _m_size, this -> _n_size);
    this -> _lumination = this -> _allocIntArray(this -> _m_size, this -> _n_size);
    this -> _buffer = new char[1];

    for(unsigned m = 0 ; m < this -> _m_size; ++m)
    {
        for(unsigned n = 0 ; n < this -> _n_size; ++n)
        {
            if(0 != field._lamp[this -> _coordHelper(m,n)])
            {
                this -> _setLamp(m,n);
            }
        }
    }

}

FarmersField::~FarmersField(void)
{
    delete(this -> _lamp);
    delete(this -> _lumination);
    delete(this -> _buffer);
}

}

그리고 코드가 빌드 된 작업을 수행함을 보여주는 일련의 테스트 :

#include "../../Utility/GTest/gtest.h"

#include "FarmersField.h"

TEST(FarmersField, Example1) 
{
    using namespace FarmersLand;
    char * input[] = {"3 3", "100", "010", "001"};
    FarmersField f(input);
    EXPECT_STREQ("100-010-001", f.Cstr());
    EXPECT_EQ(2, f.RemoveLamps());
    EXPECT_STREQ("000-010-000", f.Cstr());
}

TEST(FarmersField, Example2) 
{
    using namespace FarmersLand;
    char * input[] = {"3 6", "100000", "010000", "001000"};
    FarmersField f(input);
    EXPECT_STREQ("100000-010000-001000", f.Cstr());
    EXPECT_EQ(1, f.RemoveLamps());
    EXPECT_STREQ("000000-010000-001000", f.Cstr());
 }

TEST(FarmersField, Example3) 
{
    using namespace FarmersLand;
    char * input[] = {"6 3", "100", "010", "001", "000", "000", "000",};
    FarmersField f(input);
    EXPECT_STREQ("100-010-001-000-000-000", f.Cstr());
    EXPECT_EQ(1, f.RemoveLamps());
    EXPECT_STREQ("000-010-001-000-000-000", f.Cstr());
 }

TEST(FarmersField, Example4) 
{
    using namespace FarmersLand;
    char * input[] = {"3 3", "000", "000", "000",};
    FarmersField f(input);
    EXPECT_STREQ("000-000-000", f.Cstr());
    EXPECT_EQ(0, f.RemoveLamps());
    EXPECT_STREQ("000-000-000", f.Cstr());
 }

TEST(FarmersField, Example5) 
{
    using namespace FarmersLand;
    char * input[] = {"3 3", "111", "111", "111",};
    FarmersField f(input);
    EXPECT_STREQ("111-111-111", f.Cstr());
    EXPECT_EQ(8, f.RemoveLamps());
    EXPECT_STREQ("000-010-000", f.Cstr());
 }

TEST(FarmersField, Example6) 
{
    using namespace FarmersLand;
    char * input[] = {"6 6", "100001", "001010", "001001", "001010", "110000", "100001",};
    FarmersField f(input);
    EXPECT_STREQ("100001-001010-001001-001010-110000-100001", f.Cstr());
    EXPECT_EQ(6, f.RemoveLamps());
    EXPECT_STREQ("100011-001010-000000-000010-010000-000001", f.Cstr());
 }

외부 라이브러리를 사용하는 테스트 유틸리티를 제공하십시오.
user2369284


0

펄 3420 바이트

골프 솔루션은 아니지만이 문제가 흥미 롭습니다.

#!/usr/bin/perl
use strict;
use warnings; 

{
   package Farm; 
   use Data::Dumper; 

   # models 8 nearest neighbors to position i,j forall i,j
   my $neighbors = [ [-1, -1],
                     [-1,  0],
                     [-1, +1], 
                     [ 0, -1], 
                     # current pos 
                     [ 0,  1], 
                     [+1, -1], 
                     [+1,  0], 
                     [+1, +1] ];

   sub new { 
      my ($class, %attrs) = @_; 
      bless \%attrs, $class;
   }  

   sub field { 
      my $self = shift;
      return $self->{field};
   }

   sub rows {
      my $self = shift;
      return $self->{rows};
   }

   sub cols {
      my $self = shift;
      return $self->{cols};
   }
   sub adjacents {
      my ($self, $i, $j) = @_;

      my @adjs; 
   NEIGHBORS:
      for my $neighbor ( @$neighbors ) {
         my ($imod, $jmod) = ($neighbor->[0] + $i, $neighbor->[1] + $j); 
         next NEIGHBORS 
            if $imod >= $self->rows || $jmod >= $self->cols;

         # push neighbors
         push @adjs, 
            $self->field->[$imod]->[$jmod];

      }

      return @adjs;
   }

   sub islit { 
      my ($lamp) = @_;

      return defined $lamp && $lamp == 1;
   }

   sub can_remove_lamp { 
      my ($self, $i, $j) = @_; 

      return scalar grep { islit($_) } $self->adjacents($i, $j);
   }

   sub remove_lamp { 
      my ($self, $i, $j) = @_;

      $self->field->[$i]->[$j] = 0;
   }

   sub remove_lamps {
      my ($self) = @_; 

      my $removed = 0;
      for my $i ( 0 .. @{ $self->field } - 1) {
         for my $j ( 0 .. @{ $self->field->[$i] } - 1 ) { 
            next unless islit( $self->field->[$i]->[$j] ); 

            if( $self->can_remove_lamp($i, $j) ) {
               $removed++; 
               $self->remove_lamp($i, $j);
            }
         }
      }

      return $removed;
   }

   1;
}

{ # Tests
   use Data::Dumper;
   use Test::Deep;
   use Test::More; 

   { # 3x3 field
      my $farm = Farm->new( rows  => 3,
                            cols  => 3,
                            field => [ [1,0,0],
                                       [0,1,0],
                                       [0,0,1]
                                     ]
      );

      is( 2, 
          $farm->remove_lamps,
          'Removed 2 overlapping correctly'
      );

      is_deeply( $farm->field, 
                 [ [0,0,0],
                   [0,0,0],
                   [0,0,1],
                 ],
                 'Field after removing lamps matches expected'
      );

   }

   { # 5x5 field
      my $farm = Farm->new( rows  => 5,
                            cols  => 5,
                            field => [ [0,0,0,0,0],
                                       [0,1,0,0,0],
                                       [0,0,1,0,0],
                                       [0,0,0,0,0],
                                       [0,0,0,0,0]
                                     ]
      );

      is( 1, 
          $farm->remove_lamps,
          'Removed 1 overlapping lamp correctly'
      );

      is_deeply( $farm->field,
                 [ [0,0,0,0,0],
                   [0,0,0,0,0],
                   [0,0,1,0,0],
                   [0,0,0,0,0],
                   [0,0,0,0,0],
                 ],
                 'Field after removing lamps matches expected'
      );
   }
}

(구체적인 테스트를 보여주기 위해 I / O가 취해졌습니다)


0

파이썬-305 바이트

import sys,itertools
w,h=map(int,input().split());w+=1
l=[i for i,c in enumerate(sys.stdin.read())if c=="1"]
f=lambda l:{i+j for i in l for j in(0,1,-1,w-1,w,w+1,1-w,-w,-w-1)if(i+j+1)%w}&set(range(w*h))
for n in range(1,len(l)):
 for c in itertools.combinations(l,n):
  if f(c)^f(l):print(len(l)-n);exit()
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.