Pomoc rolnikowi

10

Farmer Jack jest bardzo biedny. Chce zapalić całą farmę, ale przy minimalnych kosztach. Lampa może oświetlić własną komórkę, a także ośmiu sąsiadów. Ustawił lampy na swoim polu, ale potrzebuje twojej pomocy w ustaleniu, czy zachował jakieś dodatkowe lampy.

Dodatkowe lampy: lampy, które po wyjęciu z gospodarstwa nie będą miały znaczenia dla liczby zapalonych komórek Ponadto lampy, które wskażesz, nie będą usuwane jeden po drugim, ale będą usuwane jednocześnie.

Uwaga: Jedyną czynnością, którą możesz wykonać, jest usunięcie niektórych lamp. Nie można zmieniać kolejności ani wstawiać lamp. Twoim ostatecznym celem jest usunięcie maksymalnej liczby lamp, tak aby każda komórka, która była wcześniej zapalona, ​​była nadal zapalona.

Pomóż farmerowi Jackowi wykryć maksymalną liczbę bezużytecznych lamp, aby mógł z nich korzystać w innym miejscu.

Wejście

Zostanie wyświetlony wymiar w pierwszym wierszu pola M i N. Kolejne linie M zawierają N znaków, z których każdy reprezentuje pole.

„1” oznacza komórkę, w której trzymana jest lampa.

„0” oznacza pustą komórkę.

Wynik

Musisz podać liczbę całkowitą zawierającą liczbę bezużytecznych lamp.

Przykładowe dane wejściowe:

3 3
100
010
001

Przykładowe dane wyjściowe:

2

Zwycięzca:

Ponieważ jest to golf golfowy, zwycięzcą będzie ten, który pomyślnie wykona zadanie w co najmniej liczbie znaków

użytkownik2369284
źródło
@PeterTaylor Zredagowałem swój post. Czy nadal masz zamieszanie?
user2369284
Dużo lepiej. Dzięki.
Peter Taylor
czy możemy założyć, że dane wejściowe kończą się nową linią?
John Dvorak
1
To wygląda jak praca domowa.
Johannes
1
Czy mamy gwarancję, że lampy wejściowe oświetlą całą farmę? Zgaduję, że nie ...
Keith Randall

Odpowiedzi:

5

Mathematica 186 (chciwy) i 224 (wszystkie kombinacje)

Chciwe rozwiązanie

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]

To wyłącza zbędne światła jeden po drugim. Jeśli zasięg światła nie zmniejsza się, gdy światło gaśnie, światło to można wyeliminować. Chciwe podejście jest bardzo szybkie i może z łatwością obsługiwać matryce 15 x 15 i znacznie większe (patrz poniżej). Zwraca pojedyncze rozwiązania, ale nie wiadomo, czy jest to optymalne, czy nie. Oba podejścia, w wersjach golfowych, zwracają liczbę nieużywanych świateł. Podejścia bez golfa również wyświetlają siatki, jak poniżej.

Przed:

przed

Po:

po

Optymalne rozwiązania wykorzystujące wszystkie kombinacje świateł (224 znaki)

Dzięki dzięki @ Clément.

Wersja bez golfa wykorzystująca wszystkie kombinacje świateł

f Funkcja transformacji morfologicznej stosowana w sameCoverageQtraktowanych jako oświetlonych (wartość = 1 zamiast zera) kwadracie 3 x 3, w którym znajduje się każde światło. Kiedy światło znajduje się w pobliżu krawędzi farmy, tylko kwadraty (mniej niż 9) w granicach farma jest liczona. Nie ma liczenia; kwadrat oświetlony przez więcej niż jedną lampę jest po prostu zapalony. Program wyłącza każde światło i sprawdza, czy całkowite pokrycie oświetlenia w gospodarstwie jest zmniejszone. Jeśli tak nie jest, światło to jest eliminowane.

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]zlicza liczbę oznaczonych komórek. Służy do zliczania świateł, a także do zliczania zapalonych komórek

sameCoverageQ[mat1, mat2] sprawdza, czy zapalone komórki w macie1 są równe liczbie zapalonych komórek w macie2.MorphologicalTransform [[mat] pobiera macierz świateł i zwraca macierz` komórek, które zapalają.

c[m1]pobiera wszystkie kombinacje świateł z m1 i testuje je pod kątem zasięgu. Spośród tych, które mają maksymalny zasięg, wybiera te, które mają najmniej żarówek. Każdy z nich jest optymalnym rozwiązaniem.


Przykład 1:

Konfiguracja 6x6

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

oryginalny

Wszystkie optymalne rozwiązania.

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

odpowiedzi


Wersja golfowa wykorzystująca wszystkie kombinacje świateł.

Ta wersja oblicza liczbę nieużywanych świateł. Nie wyświetla siatek.

c zwraca liczbę nieużywanych świateł.

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]zlicza liczbę oznaczonych komórek. Służy do zliczania świateł, a także do zliczania zapalonych komórek

s[mat1, mat2] sprawdza, czy zapalone komórki w macie1 są równe liczbie zapalonych komórek w macie2.t [[mat] pobiera macierz świateł i zwraca macierz` komórek, które zapalają.

c[j]pobiera wszystkie kombinacje świateł z j i testuje je pod kątem zasięgu. Spośród tych, które mają maksymalny zasięg, wybiera te, które mają najmniej żarówek. Każdy z nich jest optymalnym rozwiązaniem.

Przykład 2

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

krata

Dwa światła można zapisać, zachowując taki sam zasięg oświetlenia. cm]

2)

DavidC
źródło
Nie mam pod ręką Mathematiki, więc nie mogę przetestować tego kodu, ale myślę, że twój algorytm jest nieprawidłowy - chyba że źle zrozumiem twoje wyjaśnienia. Jeśli moje rozumowanie jest prawidłowe, opiera się na chciwej strategii, która zależy od kolejności przetwarzania światła: na przykład, zaczynając od środkowej lampy w twoim przypadku testowym 3 * 3, usuniesz ją i opuścisz dwie boczne lampy. Nie oczekuję, że konkretne uporządkowanie, którego używasz w implementacji, sprawia, że ​​jest poprawne, ale nie mam w tej chwili kontrprzykładu.
Clément
Wydaje się, że Twoim pomysłem jest posiadanie 2 zbędnych lampek, a, b, w oryginalnym ustawieniu, z których jedno jest bardziej zbędne niż drugie. Może się więc zdarzyć, że lepsza ekonomia zostanie osiągnięta, jeśli ktoś zostanie usunięty (pierwszy). Wydaje mi się, że nie mogłoby się to zdarzyć przy 3 światłach ogółem, ale może rzeczywiście być możliwe przy większej liczbie świateł. Początkowo rozwiązałem problem, testując wszystkie kombinacje świateł. Jest to z pewnością optymalne, a zatem idealne, ale uznałem, że jest to niepraktyczne z dużym zestawem świateł.
DavidC
@ Clément Pracuję nad rozwiązaniem, które przetestuje wszystkie możliwe kombinacje.
Trochę potrwa
Z pewnością tak będzie;) Ale należy się tego spodziewać: w obecnej sytuacji problem ten stanowi przykład minimalnego zestawu gwarancji - czyli NP. Ciekawym problemem jest jednak to, czy dodatkowe założenia (prawie wszystkie zestawy obejmujące, z wyjątkiem bocznych, mają tę samą liczność) pozwalają na wydajną implementację.
Clément
Podejrzewam, że chciwe rozwiązanie jest poprawne, jeśli przechodzisz po kolei w rzędach i kolumnach, ale jeszcze tego nie udowodniłem.
Aditsu odeszło, ponieważ SE to EVIL
3

Python, 309 znaków

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))

Działa przy użyciu masek bitowych. Lto lista świateł, gdzie każde światło jest reprezentowane przez liczbę całkowitą z (maksymalnie) 9 bitami ustawionymi dla jego wzorca światła. Następnie wyczerpująco wyszukujemy podzbiory tej listy, których bitowe - lub jest takie samo jak bitowe - lub całej listy. Najkrótszy podzbiór jest zwycięzcą.

m to maska, która zapobiega zawijaniu się bitów podczas zmiany biegów.

Keith Randall
źródło
Spróbuj podać program, który działa poprawnie. Java/C++ są bezpieczne dla wszelkiego rodzaju wcięć lub spacji, ale Python nie. Obrzucanie lub skracanie kodu to inna sprawa, ale dostarczanie programu, który się nie uruchamia, jest czymś innym.
user2369284
3
@ user2369284 o czym mówisz ?! Działa idealnie dobrze (z python 2)
aditsu zakończyło się, ponieważ SE to EVIL
@aditsu Mam python 3.
user2369284
1
@ user2369284 cóż, składnia wydruku jest inna, więc kończy się niepowodzeniem w Pythonie 3
aditsu zostało zakończone, ponieważ SE to EVIL
3

Java 6-509 bajtów

Podjąłem pewne założenia dotyczące limitów i rozwiązałem problem, jak stwierdzono w tym czasie.

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

Uruchom tak: java F <inputfile 2>/dev/null

aditsu przestało działać, ponieważ SE jest ZŁEM
źródło
Niezupełnie krótki, ale pasuje do sektora dyskowego: p Mogę później spróbować innego języka.
Aditsu zakończyło się, ponieważ SE to EVIL
@aditsu Jak to zrobić w systemie Windows?
user2369284
1
@ user2369284: Nie rozumiem, jak możesz zrobić 0011111100 za pomocą tylko 2 lamp. Musisz pokryć 8 komórek światłem, a każda lampa może zrobić maksymalnie 3.
Keith Randall
@ user2369284 być może java F <inputfile 2>nul, jeśli to się nie powiedzie, java F <inputfilezignoruj ​​wyjątek. Również nie będzie działać z java 7.
aditsu zostało zakończone, ponieważ SE to EVIL
@aditsu Naprawdę przepraszam. To był błąd w literówce. Twój program działa poprawnie.
user2369284
1

c ++ - 477 bajtów

#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;}
Hax0r778
źródło
1

Ruby, 303

[zostało to zakodowane, aby odpowiedzieć na poprzednią wersję pytania; przeczytaj notatkę poniżej]

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

Konwertowanie na tablice logiczne, a następnie porównywanie dzielnic pod kątem zmian.

Ograniczenie (?): Maksymalna wielkość pola gospodarstwa wynosi 1000 x 1000. Problem mówi „Farmer Jack jest bardzo biedny”, więc zakładam, że jego farma nie jest większa. ;-) Ograniczenie można usunąć, dodając 2 znaki.

UWAGA: odkąd zacząłem to kodować, wydaje się, że wymagania dotyczące pytań uległy zmianie. Dodano następujące wyjaśnienie „lampy, które wskażesz, nie będą usuwane jeden po drugim, ale będą usuwane jednocześnie” . Niejasność pierwotnego pytania pozwoliła mi zaoszczędzić trochę kodu, testując usuwanie pojedynczych lamp. Dlatego moje rozwiązanie nie będzie działać dla wielu przypadków testowych w nowych wymaganiach. Jeśli będę miał czas, naprawię to. Nie mogę. Proszę nie głosować za tą odpowiedzią, ponieważ inne odpowiedzi tutaj mogą być w pełni zgodne.

Darren Stone
źródło
1

APL, 97 znaków / bajtów *

Przyjmuje środowisko A ⎕IO←1i ⎕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←⍎⍞

Wersja bez golfa:

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

Zgadzam się, że więcej przypadków testowych byłoby lepszych. Oto losowy:

Wejście:

5 5
10001
01100
00001
11001
00010

Wyjście (lampy bezużyteczne):

5

Układ z lampami min (brak w wersji golfowej):

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 może być zapisany we własnym (starszym) jednobajtowym zestawie znaków, który odwzorowuje symbole APL na górne 128 bajtów. Dlatego do celów oceniania program N znaków, który używa tylko znaków ASCII i symboli APL, można uznać za N-bajtowy.

Tobia
źródło
0

C ++ 5.806 bajtów

Nie jest to jeszcze zoptymalizowane pod kątem rozmiaru. Ale ponieważ jest niewielu uczestników, na razie zostawię to.

FarmersField Header:

#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);
};

}

FarmersField 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);
}

}

I zestaw testów pokazujących, że kod robi to, co został zbudowany:

#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());
 }
Johannes
źródło
Podaj narzędzie testowe, które korzysta z bibliotek zewnętrznych.
user2369284
0

3420 bajtów Perla

Nie jest to rozwiązanie dla golfistów, ale ten problem był dla mnie interesujący:

#!/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 został wyjęty, abym mógł pokazać konkretne testy)

Hunter McMillen
źródło
0

Python - 305 bajtów

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()
Blckknght
źródło