Dem Bauern helfen

10

Bauer Jack ist sehr arm. Er will seine ganze Farm beleuchten, aber mit minimalen Kosten. Eine Lampe kann sowohl ihre eigene Zelle als auch ihre acht Nachbarn beleuchten. Er hat die Lampen auf seinem Feld arrangiert, aber er braucht Ihre Hilfe, um herauszufinden, ob er zusätzliche Lampen aufbewahrt hat oder nicht.

Zusätzliche Lampen: Lampen, die beim Entfernen von der Farm keinen Einfluss auf die Anzahl der beleuchteten Zellen haben. Außerdem werden die Lampen, auf die Sie zeigen, nicht einzeln entfernt, sondern gleichzeitig.

Hinweis: Sie können nur einige Lampen entfernen. Sie können Lampen weder neu anordnen noch einsetzen. Ihr letztes Ziel ist es, die maximale Anzahl von Lampen so zu entfernen, dass jede zuvor beleuchtete Zelle noch leuchtet.

Helfen Sie Farmer Jack dabei, die maximale Anzahl nutzloser Lampen zu erkennen, damit er sie an anderer Stelle verwenden kann.

Eingang

Sie werden in den ersten Zeilenabmessungen des Feldes M und N angegeben. Es folgen die nächsten M Zeilen mit N Zeichen, die jeweils das Feld darstellen.

'1' steht für die Zelle, in der die Lampe aufbewahrt wird.

'0' steht für eine leere Zelle.

Ausgabe

Sie müssen eine Ganzzahl ausgeben, die die Anzahl der unbrauchbaren Lampen enthält.

Beispieleingabe:

3 3
100
010
001

Beispielausgabe:

2

Gewinner:

Da es sich um Codegolf handelt, ist der Gewinner derjenige, der die Aufgabe mit der geringsten Anzahl von Zeichen erfolgreich abschließt

user2369284
quelle
@ PeterTaylor Ich habe meinen Beitrag bearbeitet. Hast du noch eine Verwirrung?
user2369284
Viel besser. Vielen Dank.
Peter Taylor
Dürfen wir annehmen, dass die Eingabe mit einem Zeilenumbruch endet?
John Dvorak
1
Das sieht nach Hausaufgaben aus.
Johannes
1
Ist uns garantiert, dass die Eingangslampen die gesamte Farm beleuchten? Ich werde nein raten ...
Keith Randall

Antworten:

5

Mathematica 186 (gierig) und 224 (alle Kombinationen)

Gierige Lösung

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]

Dadurch werden überflüssige Lichter nacheinander ausgeschaltet. Wenn die Lichtabdeckung beim Erlöschen des Lichts nicht verringert wird, kann dieses Licht eliminiert werden. Der gierige Ansatz ist sehr schnell und kann problemlos Matrizen von 15x15 und viel größer verarbeiten (siehe unten). Es gibt eine einzelne Lösung zurück, aber es ist nicht bekannt, ob dies optimal ist oder nicht. Beide Ansätze geben in den Golfversionen die Anzahl der nicht verwendeten Lichter zurück. Nicht-Golf-Ansätze zeigen auch die Gitter wie unten an.

Vor:

Vor

Nach:

nach

Optimale Lösungen mit allen Lichtkombinationen (224 Zeichen)

Mit Dank an @ Clément.

Ungolfed Version mit allen Lichtkombinationen

fDie morphologische Transformationsfunktion, die in sameCoverageQbehandelt wird, behandelt das 3 x 3-Quadrat, in dem sich jedes Licht befindet, als beleuchtet (Wert = 1 statt Null). Wenn sich ein Licht in der Nähe des Randes der Farm befindet, befinden sich nur die Quadrate (weniger als 9) innerhalb der Grenzen von Die Farm wird gezählt. Es gibt keine Überzählung. Ein Quadrat, das von mehr als einer Lampe beleuchtet wird, wird einfach beleuchtet. Das Programm schaltet jedes Licht aus und prüft, ob die Gesamtbeleuchtung der Farm verringert ist. Ist dies nicht der Fall, wird dieses Licht eliminiert.

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]zählt die Anzahl der markierten Zellen. Es wird verwendet, um die Lichter und auch die beleuchteten Zellen zu zählen

sameCoverageQ[mat1, mat2] testet, ob die beleuchteten Zellen in mat1 der Anzahl der beleuchteten Zellen in mat2 entsprechen. MorphologicalTransform [[mat] nimmt eine Lichtmatrix und gibt eine Matrix der Zellen auf, die sie beleuchten.

c[m1]Nimmt alle Lichtkombinationen von m1 und testet sie auf Abdeckung. Unter denjenigen mit der maximalen Abdeckung werden diejenigen ausgewählt, die die wenigsten Glühbirnen haben. Jedes davon ist eine optimale Lösung.


Beispiel 1:

Ein 6x6 Setup

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

Original

Alle optimalen Lösungen.

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

Antworten


Golfversion mit allen Lichtkombinationen.

Diese Version berechnet die Anzahl der nicht verwendeten Lichter. Die Gitter werden nicht angezeigt.

c Gibt die Anzahl der nicht verwendeten Lichter zurück.

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]zählt die Anzahl der markierten Zellen. Es wird verwendet, um die Lichter und auch die beleuchteten Zellen zu zählen

s[mat1, mat2] testet, ob die beleuchteten Zellen in mat1 der Anzahl der beleuchteten Zellen in mat2 entsprechen. t [[mat] nimmt eine Lichtmatrix und gibt eine Matrix` der Zellen zurück, die sie beleuchten.

c[j]Nimmt alle Lichtkombinationen von j und testet sie auf Abdeckung. Unter denjenigen mit der maximalen Abdeckung werden diejenigen ausgewählt, die die wenigsten Glühbirnen haben. Jedes davon ist eine optimale Lösung.

Beispiel 2

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

Gitter

Bei gleicher Lichtabdeckung können zwei Lichter gespeichert werden. cm]

2

DavidC
quelle
Ich habe Mathematica nicht zur Hand, daher kann ich diesen Code nicht testen, aber ich denke, Ihr Algorithmus ist falsch - es sei denn, ich habe Ihre Erklärungen falsch verstanden. Wenn mein Verständnis richtig ist, beruht es auf einer gierigen Strategie, die von der Reihenfolge abhängt, in der das Licht verarbeitet wird: Wenn Sie beispielsweise von der mittleren Lampe in Ihrem 3 * 3-Testfall ausgehen, wird es entfernt und die beiden Seitenlampen bleiben. Ich erwarte nicht, dass die bestimmte Reihenfolge, die Sie in der Implementierung verwenden, korrekt ist, aber ich habe derzeit kein Gegenbeispiel.
Clément
Ihre Idee scheint zu sein, dass es möglich sein könnte, zwei überflüssige Lichter, a, b, im ursprünglichen Setup zu haben, von denen eines überflüssiger ist als das andere. Es kann also sein, dass eine bessere Wirtschaftlichkeit erzielt wird, wenn eine entfernt wird (zuerst). Ich spüre, dass dies mit insgesamt 3 Lichtern nicht passieren könnte, aber es kann tatsächlich mit einer größeren Anzahl von Lichtern möglich sein. Ich habe das Problem ursprünglich gelöst, indem ich alle Lichtkombinationen getestet habe. Dies ist sicherlich optimal und somit ideal, aber ich fand es mit einem großen Satz von Lichtern unpraktisch.
DavidC
@ Clément Ich arbeite an einer Lösung, die alle möglichen Kombinationen testet. Wird eine Weile dauern ...
DavidC
Es wird sicher sein;) Aber das ist zu erwarten: So wie es aussieht, ist dieses Problem ein Beispiel für die minimale festgelegte Deckung - das ist NP. Es ist jedoch ein interessantes Problem, ob die zusätzlichen Annahmen (fast alle Abdeckungssätze mit Ausnahme der seitlichen haben dieselbe Kardinalität) eine effiziente Implementierung ermöglichen.
Clément
Ich vermute sehr, dass die gierige Lösung richtig ist, wenn Sie nacheinander nach Zeilen und Spalten gehen, aber ich habe es noch nicht bewiesen.
Aditsu beendet, weil SE am
3

Python, 309 Zeichen

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

Funktioniert mit Bitmasken. List eine Liste der Lichter, wobei jedes Licht durch eine ganze Zahl mit (bis zu) 9 Bits dargestellt wird, die für sein Lichtmuster gesetzt sind. Dann suchen wir ausführlich nach Teilmengen dieser Liste, deren bitweise - oder die gleiche wie die bitweise - oder der gesamten Liste ist. Die kürzeste Teilmenge ist der Gewinner.

m ist eine Maske, die das Umlaufen der Bits beim Verschieben verhindert.

Keith Randall
quelle
Bitte versuchen Sie, ein Programm bereitzustellen, das korrekt ausgeführt wird. Java / C++ sind für jede Art von Einrückung oder Abstand sicher, Python jedoch nicht. Das Verschleiern oder Verkürzen von Code ist eine andere Sache, aber das Bereitstellen eines Programms, das nicht ausgeführt wird, ist eine andere.
user2369284
3
@ user2369284 wovon redest du?! Es funktioniert einwandfrei (mit Python 2)
Aditsu beenden, weil SE am
@aditsu Ich habe Python 3.
user2369284
1
@ user2369284 Nun, die Drucksyntax ist anders, so dass es in Python 3 fehlschlägt
Aditsu beenden, weil SE am
3

Java 6 - 509 Bytes

Ich machte einige Annahmen über die Grenzen und löste das Problem, wie zu diesem Zeitpunkt angegeben.

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

Laufen Sie so: java F <inputfile 2>/dev/null

Aditsu beenden, weil SE böse ist
quelle
Nicht gerade kurz, passt aber in einen Festplattensektor: p Ich kann später eine andere Sprache ausprobieren.
Aditsu beendet, weil SE am
@aditsu Wie funktioniert das unter Windows?
user2369284
1
@ user2369284: Ich sehe nicht, wie Sie 0011111100 mit nur 2 Lampen tun können. Sie müssen 8 Zellen mit Licht bedecken, und jede Lampe kann höchstens 3 tun.
Keith Randall
@ user2369284 vielleicht java F <inputfile 2>nul, wenn das dann fehlschlägt java F <inputfileund ignoriere die Ausnahme. Auch läuft es nicht mit Java 7.
Aditsu beenden, weil SE am
@aditsu Es tut mir wirklich leid. Das war ein Tippfehler. Ihr Programm funktioniert korrekt.
user2369284
1

c ++ - 477 Bytes

#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
quelle
1

Ruby, 303

[Dies wurde codiert, um eine frühere Version der Frage zu beantworten. Anmerkung unten lesen]

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

Konvertieren in Boolesche Arrays und anschließendes Vergleichen von Nachbarschaften auf Änderungen.

Einschränkung (?): Die maximale Feldgröße der Farm beträgt 1.000 x 1.000. Problem besagt "Farmer Jack ist sehr arm", also gehe ich davon aus, dass seine Farm nicht größer ist. ;-) Einschränkung kann durch Hinzufügen von 2 Zeichen aufgehoben werden.

HINWEIS: Seit ich mit dem Codieren begonnen habe, haben sich anscheinend die Anforderungen an die Fragen geändert. Die folgende Klarstellung wurde hinzugefügt „die Lampen Sie zeigen werden nicht einzeln entfernt werden, aber sie werden gleichzeitig entfernt werden“ . Die Mehrdeutigkeit der ursprünglichen Frage ermöglichte es mir, Code zu testen, indem ich einzelne Lampenentfernungen testete. Daher funktioniert meine Lösung unter den neuen Anforderungen für viele Testfälle nicht. Wenn ich Zeit habe, werde ich das beheben. Ich darf nicht. Bitte stimmen Sie dieser Antwort nicht zu, da andere Antworten hier möglicherweise vollständig konform sind.

Darren Stone
quelle
1

APL, 97 Zeichen / Bytes *

Nimmt eine ⎕IO←1und ⎕ML←3APL-Umgebung an.

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

Ungolfed Version:

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

Ich stimme zu, dass mehr Testfälle besser wären. Hier ist eine zufällige:

Eingang:

5 5
10001
01100
00001
11001
00010

Ausgang (nutzlose Lampen):

5

Layout mit min Lampen (nicht in der Golfversion enthalten):

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 kann in einem eigenen ( alten) Einzelbyte -Zeichensatz geschrieben werden, der APL-Symbole den oberen 128-Byte-Werten zuordnet
. Für die Bewertung kann daher ein Programm mit N Zeichen , das nur ASCII-Zeichen und APL-Symbole verwendet, als N Byte lang angesehen werden.

Tobia
quelle
0

C ++ 5.806 Bytes

Dies ist noch nicht für die Größe optimiert. Aber da es nur wenige Teilnehmer gibt, werde ich es vorerst dabei belassen.

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

}

Und eine Reihe von Tests, um zu zeigen, dass der Code das tut, wofür er erstellt wurde:

#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
quelle
Bitte geben Sie ein Testdienstprogramm an, das externe Bibliotheken verwendet.
user2369284
0

Perl 3420 Bytes

Keine Golflösung, aber ich fand dieses Problem interessant:

#!/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 wurde herausgenommen, damit ich konkrete Tests zeigen konnte)

Hunter McMillen
quelle
0

Python - 305 Bytes

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
quelle