Aiutare l'agricoltore


10

Il contadino Jack è molto povero. Vuole illuminare tutta la sua fattoria ma con un costo minimo. Una lampada può illuminare la propria cella e anche i suoi otto vicini. Ha sistemato le lampade nel suo campo ma ha bisogno del tuo aiuto per scoprire se ha conservato o meno lampade extra.

Lampade extra: lampade che, rimuovendole dalla fattoria, non faranno alcuna differenza sul numero di celle illuminate. Inoltre, le lampade che indicherai non verranno rimosse una alla volta, ma verranno rimosse contemporaneamente.

Nota: l'unica azione che puoi eseguire è rimuovere alcune lampade. Non è possibile riorganizzare né inserire le lampade. Il tuo obiettivo finale è rimuovere il numero massimo di lampade in modo tale che ogni cella illuminata prima sia ancora accesa.

Aiuta Farmer Jack a individuare il numero massimo di lampade inutili in modo che possa usarle altrove.

Ingresso

Ti verranno date le dimensioni della prima riga del campo M e N. Seguono le seguenti M righe contenenti N caratteri che rappresentano ciascuno il campo.

'1' rappresenta la cella in cui è conservata la lampada.

'0' rappresenta una cella vuota.

Produzione

Devi generare un numero intero contenente il numero di lampade inutili.

Input di esempio:

3 3
100
010
001

Uscita campione:

2

Vincitore:

Dal momento che si tratta di codice golf, il vincitore sarà colui che completerà con successo il compito con almeno il numero di caratteri


@PeterTaylor Ho modificato il mio post. Hai ancora confusione?
user2369284

Molto meglio. Grazie.
Peter Taylor

possiamo supporre che l'input termina con una nuova riga?
John Dvorak,

1
Sembra fare i compiti.
Johannes,

1
Abbiamo la garanzia che le lampade di ingresso illumineranno l'intera azienda? Immagino di no ...
Keith Randall,

Risposte:


5

Mathematica 186 (goloso) e 224 (tutte le combinazioni)

Soluzione golosa

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]

Questo spegne le luci superflue una per una. Se la copertura della luce non diminuisce quando la luce si spegne, quella luce può essere eliminata. L'approccio avido è molto veloce e può gestire facilmente matrici di 15x15 e molto più grandi (vedi sotto). Restituisce una singola soluzione, ma non si sa se sia ottimale o meno. Entrambi gli approcci, nelle versioni golfate, restituiscono il numero di luci non utilizzate. Anche gli approcci non golfizzati mostrano le griglie, come di seguito.

Prima:

prima

Dopo:

dopo

Soluzioni ottimali che utilizzano tutte le combinazioni di luci (224 caratteri)

Grazie a @ Clément.

Versione non golfata con tutte le combinazioni di luci

fLa funzione di trasformazione morfologica utilizzata nelle sameCoverageQprelibatezze (valore = 1 anziché zero) il quadrato 3 x3 in cui risiede ogni luce. Quando una luce si trova vicino al bordo della fattoria, solo i quadrati (meno di 9) all'interno dei bordi di la fattoria viene contata. Non c'è eccesso di conto; un quadrato illuminato da più di una lampada viene semplicemente acceso. Il programma spegne ogni luce e verifica se la copertura complessiva dell'illuminazione nella fattoria è ridotta. In caso contrario, la luce viene eliminata.

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]conta il numero di celle contrassegnate. È usato per contare le luci e anche per contare le celle illuminate

sameCoverageQ[mat1, mat2] verifica se le celle illuminate in mat1 corrispondono al numero di celle illuminate in mat2.MorphologicalTransform [[mat] prende una matrice di luci e restituisce una matrice` delle celle che illuminano.

c[m1]prende tutte le combinazioni di luci da M1 e le verifica per la copertura. Tra quelli che hanno la massima copertura, seleziona quelli che hanno il minor numero di lampadine. Ognuna di queste è una soluzione ottimale.


Esempio 1:

Una configurazione 6x6

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

originale

Tutte le soluzioni ottimali.

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

risposte


Versione golfizzata che utilizza tutte le combinazioni di luci.

Questa versione calcola il numero di luci non utilizzate. Non visualizza le griglie.

c restituisce il numero di luci non utilizzate.

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]conta il numero di celle contrassegnate. È usato per contare le luci e anche per contare le celle illuminate

s[mat1, mat2] verifica se le celle illuminate in mat1 sono uguali al numero di celle illuminate in mat2.t [[mat] prende una matrice di luci e restituisce una matrice` delle celle che si accendono.

c[j]prende tutte le combinazioni di luci da j e le verifica per la copertura. Tra quelli che hanno la massima copertura, seleziona quelli che hanno il minor numero di lampadine. Ognuna di queste è una soluzione ottimale.

Esempio 2

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

griglia

È possibile salvare due luci pur avendo la stessa copertura luminosa. centimetro]

2


Non ho Mathematica a portata di mano, quindi non posso testare questo codice, ma penso che il tuo algoritmo sia errato, a meno che non abbia frainteso le tue spiegazioni. Se la mia comprensione è corretta, si basa su una strategia avida che dipende dall'ordine in cui viene elaborata la luce: ad esempio, a partire dalla lampada centrale nel tuo test case 3 * 3 rimuoverlo e lasciare le due luci laterali. Non mi aspetto che il particolare ordinamento che usi nell'implementazione lo renda corretto, ma al momento non ho un contro-esempio.
Clément,

La tua idea sembra essere che potrebbe essere possibile avere 2 luci superflue, a, b, nella configurazione originale, una delle quali è più superflua dell'altra. Quindi, potrebbe essere che si ottenga una migliore economia se ne viene rimossa (prima). Sento che ciò non potrebbe accadere con 3 luci totali, ma potrebbe effettivamente essere possibile con un numero maggiore di luci. Inizialmente ho risolto il problema testando tutte le combinazioni di luci. Questo è certamente ottimale e quindi ideale, ma l'ho trovato poco pratico con un ampio set di luci.
David C

@ Clément Sto lavorando a una soluzione che metterà alla prova tutte le possibili combinazioni.
Ci

Lo farà sicuramente;) Ma è prevedibile: per ora questo problema è un'istanza della copertura minima impostata - che è NP. Se i presupposti aggiuntivi (quasi tutti i set di copertura, tranne quelli laterali, hanno la stessa cardinalità) consentono un'implementazione efficiente è un problema interessante.
Clément,

Sospetto fortemente che la soluzione golosa sia corretta se si passa in sequenza da righe e colonne, ma non l'ho ancora dimostrato.
Aditsu ha smesso perché SE è MALE

3

Python, 309 caratteri

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

Funziona con maschere di bit. Lè un elenco di luci, in cui ogni luce è rappresentata da un numero intero con (fino a) 9 bit impostati per il suo schema di luci. Quindi cerchiamo esaustivamente sottoinsiemi di questo elenco il cui bit per bit - o è uguale al bit per bit - o dell'intero elenco. Il sottoinsieme più breve è il vincitore.

m è una maschera che impedisce l'avvolgimento dei bit durante lo spostamento.


Prova a fornire un programma che funzioni correttamente. Java / C++ sono sicuri per qualsiasi tipo di rientro o spaziatura, ma Python non lo è. Opprimere o abbreviare il codice è un'altra cosa, ma fornire un programma che non viene eseguito è un'altra.
user2369284,

3
@ user2369284 di cosa stai parlando ?! Funziona perfettamente (con Python 2)
aditsu smetti perché SE è MALE

@aditsu I have python 3.
user2369284

1
@ user2369284 bene, la sintassi di stampa è diversa, quindi non funziona in Python 3
aditsu ha chiuso perché SE è MALE

3

Java 6 - 509 byte

Ho formulato alcune ipotesi sui limiti e risolto il problema come dichiarato in questo momento.

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

Esegui in questo modo: java F <inputfile 2>/dev/null


Non esattamente breve, ma si adatta a un settore del disco: p Potrei provare una lingua diversa in seguito.
Aditsu ha smesso perché SE è MALE

@aditsu Come farlo funzionare su Windows?
user2369284

1
@ user2369284: Non vedo come si può fare 0011111100 con solo 2 lampade. Devi coprire 8 celle di luce e ogni lampada può fare al massimo 3.
Keith Randall

@utente forse user2369284 java F <inputfile 2>nul, se fallisce java F <inputfilee ignora l'eccezione. Inoltre non funzionerà con Java 7.
Aditsu ha chiuso perché SE è MALE

@aditsu Mi dispiace davvero. È stato un errore di battitura. Il tuo programma funziona correttamente.
user2369284,

1

c ++ - 477 byte

#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

Ruby, 303

[questo è stato codificato per rispondere a una versione precedente della domanda; leggi la nota sotto]

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

Conversione in array di booleani e confronto dei quartieri per i cambiamenti.

Limitazione (?): La dimensione massima del campo dell'azienda agricola è 1.000 x 1.000. Il problema afferma che "Farmer Jack è molto povero", quindi presumo che la sua fattoria non sia più grande. ;-) La limitazione può essere rimossa aggiungendo 2 caratteri.

NOTA: da quando ho iniziato a scrivere questo codice, sembra che i requisiti della domanda siano cambiati. È stato aggiunto il seguente chiarimento "le lampade che indicherai non verranno rimosse una per una, ma verranno rimosse contemporaneamente" . L'ambiguità della domanda originale mi ha permesso di salvare un po 'di codice testando la rimozione di singole lampade. Pertanto, la mia soluzione non funzionerà per molti casi di test in base ai nuovi requisiti. Se avrò tempo, lo risolverò. Potrei non. Si prega di non votare questa risposta poiché altre risposte qui potrebbero essere completamente conformi.


1

APL, 97 caratteri / byte *

Assume una ⎕IO←1e ⎕ML←3ambiente APL.

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

Versione non golfata:

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

Concordo sul fatto che più casi di test sarebbero migliori. Eccone uno casuale:

Ingresso:

5 5
10001
01100
00001
11001
00010

Uscita (lampade inutili):

5

Layout con min lampade (non incluso nella versione golfed):

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 può essere scritto nel proprio set di caratteri a byte singolo (legacy) che associa i simboli APL ai valori superiori di 128 byte. Pertanto, ai fini del calcolo del punteggio, un programma di N caratteri che utilizza solo caratteri ASCII e simboli APL può essere considerato lungo N byte.


0

C ++ 5.806 byte

Questo non è ancora ottimizzato per le dimensioni. Ma poiché ci sono pochi concorrenti, per ora lo lascerò a quello.

Intestazione FarmersField:

#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 FarmersField:

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

}

E una serie di test per dimostrare che il codice fa ciò per cui è stato creato:

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

Fornire un'utilità di test che utilizza librerie esterne.
user2369284,


0

Perl 3420 byte

Non è una soluzione per il golf, ma ho riscontrato questo problema interessante:

#!/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 è stato rimosso in modo da poter mostrare test concreti)


0

Python - 305 byte

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()
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.