Aider l'agriculteur


10

Le fermier Jack est très pauvre. Il veut éclairer toute sa ferme mais avec un minimum de coûts. Une lampe peut éclairer sa propre cellule ainsi que ses huit voisins. Il a arrangé les lampes dans son domaine mais il a besoin de votre aide pour savoir s'il a gardé des lampes supplémentaires.

Lampes supplémentaires: Lampes qui, lors du retrait de la ferme, ne feront aucune différence avec le nombre de cellules allumées. De plus, les lampes que vous désignerez ne seront pas supprimées une par une, mais elles seront supprimées simultanément.

Remarque: la seule action que vous pouvez effectuer consiste à retirer certaines lampes. Vous ne pouvez ni réorganiser ni insérer des lampes. Votre objectif final est de supprimer le nombre maximum de lampes de sorte que chaque cellule qui a été allumée auparavant soit toujours allumée.

Aidez le fermier Jack à repérer le nombre maximum de lampes inutiles pour qu'il puisse les utiliser ailleurs.

Contribution

Vous recevrez dans les premières dimensions de la ligne du champ M et N .Next M lignes suivent contenant N caractères chacun représentant le champ.

«1» représente la cellule où la lampe est conservée.

'0' représente une cellule vide.

Production

Vous devez sortir un entier contenant le nombre de lampes inutiles.

Exemple d'entrée:

3 3
100
010
001

Exemple de sortie:

2

Gagnant:

Puisqu'il s'agit de golf de code, le gagnant sera celui qui réussira la tâche en moins de caractères


@PeterTaylor J'ai modifié mon message. Avez-vous encore une confusion?
user2369284

Bien mieux. Merci.
Peter Taylor

pouvons-nous supposer que l'entrée se termine par une nouvelle ligne?
John Dvorak

1
Cela ressemble à des devoirs.
Johannes

1
Sommes-nous garantis que les lampes d'entrée éclaireront toute la ferme? Je vais deviner non ...
Keith Randall

Réponses:


5

Mathematica 186 (gourmand) et 224 (toutes combinaisons)

Solution gourmande

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]

Cela éteint les lumières superflues une par une. Si la couverture lumineuse n'est pas diminuée lorsque la lumière s'éteint, cette lumière peut être éliminée. L'approche gourmande est très rapide et peut facilement gérer des matrices de 15x15 et bien plus grandes (voir ci-dessous). Il renvoie une seule solution, mais on ne sait pas si c'est optimal ou non. Les deux approches, dans les versions golfées, renvoient le nombre de lumières inutilisées. Les approches non golfées affichent également les grilles, comme ci-dessous.

Avant:

avant

Après:

après

Solutions optimales utilisant toutes les combinaisons de lumières (224 caractères)

Merci à @ Clément.

Version non golfée utilisant toutes les combinaisons de lumières

fLa fonction de transformation morphologique utilisée dans les sameCoverageQgâteries comme éclairé (valeur = 1 au lieu de zéro) le carré 3 x3 dans lequel chaque lumière réside. Lorsqu'une lumière est proche du bord de la ferme, seuls les carrés (moins de 9) à l'intérieur des limites de la ferme est comptée. Il n'y a pas de comptage excessif; un carré éclairé par plus d'une lampe est simplement allumé.Le programme éteint chaque lumière et vérifie si la couverture d'éclairage globale de la ferme est réduite.Si ce n'est pas le cas, cette lumière est éliminée.

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]compte le nombre de cellules marquées. Il est utilisé pour compter les lumières et aussi pour compter les cellules allumées

sameCoverageQ[mat1, mat2] teste si les cellules allumées dans mat1 sont égales au nombre de cellules allumées dans mat2.MorphologicalTransform [[mat] prend une matrice de lumières et renvoie une matrice` des cellules qu'elles éclairent.

c[m1]prend toutes les combinaisons de lumières de m1 et les teste pour la couverture. Parmi ceux qui ont la couverture maximale, il sélectionne ceux qui ont le moins d'ampoules. Chacun d'eux est une solution optimale.


Exemple 1:

Une configuration 6x6

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

original

Toutes les solutions optimales.

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

réponses


Version golfée utilisant toutes les combinaisons de lumières.

Cette version calcule le nombre de lumières inutilisées. Il n'affiche pas les grilles.

c renvoie le nombre de lumières inutilisées.

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]compte le nombre de cellules marquées. Il est utilisé pour compter les lumières et aussi pour compter les cellules allumées

s[mat1, mat2] teste si les cellules allumées dans mat1 sont égales au nombre de cellules allumées dans mat2.t [[mat] prend une matrice de lumières et renvoie une matrice` des cellules qu'elles éclairent.

c[j]prend toutes les combinaisons de lumières de j et les teste pour la couverture. Parmi ceux qui ont la couverture maximale, il sélectionne ceux qui ont le moins d'ampoules. Chacun d'eux est une solution optimale.

Exemple 2

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

la grille

Deux lumières peuvent être enregistrées tout en ayant la même couverture d'éclairage. cm]

2


Je n'ai pas Mathematica à portée de main, donc je ne peux pas tester ce code, mais je pense que votre algorithme est incorrect - sauf si j'ai mal compris vos explications. Si ma compréhension est correcte, elle repose sur une stratégie gourmande qui dépend de l'ordre dans lequel la lumière est traitée: par exemple, partir de la lampe du milieu dans votre cas de test 3 * 3 la retirerait et laisserait les deux lampes latérales. Je ne m'attends pas à ce que l'ordre particulier que vous utilisez dans l'implémentation le rende correct, mais je n'ai pas de contre-exemple pour le moment.
Clément le

Votre idée semble être qu'il peut être possible d'avoir 2 lumières superflues, a, b, dans la configuration d'origine, dont l'une est plus superflue que l'autre. Ainsi, il se peut qu'il y ait une meilleure économie réalisée si l'on est supprimé (d'abord). Je sens que cela ne pourrait pas arriver avec 3 lumières au total, mais cela pourrait en effet être possible avec un plus grand nombre de lumières. À l'origine, j'ai résolu le problème en testant toutes les combinaisons de lumières. C'est certainement optimal et donc idéal, mais je l'ai trouvé peu pratique avec un grand jeu de lumières.
DavidC du

@ Clément Je travaille sur une solution qui testera toutes les combinaisons possibles.
Cela

Ce sera certainement le cas;) Mais c'est normal: en l'état, ce problème est une instance de la couverture minimale définie - qui est NP. La question de savoir si les hypothèses supplémentaires (presque tous les ensembles de revêtement, à l'exception des ensembles latéraux, ont la même cardinalité) permet une mise en œuvre efficace est un problème intéressant.
Clément

Je soupçonne fortement que la solution gourmande est correcte si vous passez séquentiellement par lignes et colonnes, mais je ne l'ai pas encore prouvée.
aditsu quitte car SE est EVIL le

3

Python, 309 caractères

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

Fonctionne avec des bitmasks. Lest une liste des lumières, où chaque lumière est représentée par un entier avec (jusqu'à) 9 bits définis pour son motif lumineux. Ensuite, nous recherchons exhaustivement les sous-ensembles de cette liste dont le bit à bit ou est le même que le bit à bit ou de la liste entière. Le sous-ensemble le plus court est le gagnant.

m est un masque qui empêche le bouclage des bits lors du décalage.


Veuillez essayer de fournir un programme qui s'exécute correctement.Java/C++ sont sûrs pour tout type d'indentation ou d'espacement, mais Python ne l'est pas.Obfusquer ou raccourcir du code est une autre chose, mais fournir un programme qui ne s'exécute pas en est une autre.
user2369284

3
@ user2369284 de quoi parlez-vous?! Cela fonctionne parfaitement bien (avec python 2)
aditsu quitte car SE est EVIL le

@aditsu J'ai python 3.
user2369284

1
@ user2369284 bien, la syntaxe d'impression est différente donc elle échoue en python 3
aditsu quitte car SE est EVIL le

3

Java 6 - 509 octets

J'ai fait quelques hypothèses sur les limites et résolu le problème comme indiqué à ce moment.

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

Courez comme ceci: java F <inputfile 2>/dev/null


Pas exactement court, mais tient dans un secteur de disque: p Je pourrai essayer une autre langue plus tard.
aditsu quitte car SE est EVIL le

@aditsu Comment faire fonctionner cela sur Windows?
user2369284

1
@ user2369284: Je ne vois pas comment faire 0011111100 avec seulement 2 lampes. Vous devez recouvrir 8 cellules de lumière, et chaque lampe peut en faire au plus 3.
Keith Randall

@ user2369284 peut java F <inputfile 2>nul- être , si cela échoue alors java F <inputfileet ignorez l'exception. De plus, il ne fonctionnera pas avec java 7.
aditsu quitte car SE est EVIL le

@aditsu Je suis vraiment désolé. C'était une erreur de frappe. Votre programme fonctionne correctement.
user2369284

1

c ++ - 477 octets

#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

Rubis, 303

[ceci a été codé pour répondre à une version précédente de la question; lire la note ci-dessous]

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

Conversion en tableaux de booléens, puis comparaison des quartiers pour les changements.

Limitation (?): La taille maximale du champ de la ferme est de 1 000 x 1 000. Le problème indique que «le fermier Jack est très pauvre», je suppose donc que sa ferme n'est pas plus grande. ;-) La limitation peut être supprimée en ajoutant 2 caractères.

REMARQUE: depuis que j'ai commencé à coder cela, il semble que les exigences de la question aient changé. La clarification suivante a été ajoutée: "les lampes que vous désignerez ne seront pas supprimées une par une, mais elles seront supprimées simultanément" . L'ambiguïté de la question d'origine m'a permis de sauvegarder du code en testant les suppressions de lampes individuelles . Ainsi, ma solution ne fonctionnera pas pour de nombreux cas de test sous les nouvelles exigences. Si j'ai le temps, je vais arranger ça. Je ne devrais pas. Veuillez ne pas voter positivement, car les autres réponses ici peuvent être entièrement conformes.


1

APL, 97 caractères / octets *

Suppose un environnement ⎕IO←1et ⎕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←⍎⍞

Version non golfée:

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

Je suis d'accord que plus de cas de test seraient mieux. En voici un au hasard:

Contribution:

5 5
10001
01100
00001
11001
00010

Sortie (lampes inutiles):

5

Disposition avec lampes min (non inclus dans la version golf):

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 peut être écrit dans son propre jeu de caractères à un octet (hérité) qui mappe les symboles APL aux 128 octets supérieurs. Par conséquent, aux fins de la notation, un programme de N caractères qui utilise uniquement des caractères ASCII et des symboles APL peut être considéré comme long de N octets.


0

C ++ 5,806 octets

Ce n'est pas encore optimisé pour la taille. Mais comme il y a peu de candidats, je vais en rester là pour l'instant.

En-tête 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);
};

}

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

}

Et un ensemble de tests pour montrer que le code fait ce pour quoi il a été conçu:

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

Veuillez fournir un utilitaire de test qui utilise des bibliothèques externes.
user2369284


0

Perl 3420 octets

Pas une solution de golf, mais j'ai trouvé ce problème intéressant:

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

(Les E / S ont été retirées pour que je puisse montrer des tests concrets)


0

Python - 305 octets

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()
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.