Membantu Petani

10

Petani Jack sangat miskin. Dia ingin menyalakan seluruh pertaniannya tetapi dengan biaya minimum. Sebuah lampu dapat menerangi selnya sendiri dan juga delapan tetangganya. Dia telah mengatur lampu di bidangnya, tetapi dia membutuhkan bantuan Anda untuk mengetahui apakah dia menyimpan lampu tambahan atau tidak.

Lampu tambahan: Lampu yang dilepas dari pertanian tidak akan membuat perbedaan dengan jumlah sel yang menyala. Selain itu, lampu yang akan Anda tunjuk tidak akan dilepas satu per satu, tetapi akan dilepas secara bersamaan.

Catatan: Satu-satunya tindakan yang dapat Anda lakukan adalah melepas beberapa lampu. Anda tidak dapat mengatur ulang atau memasukkan lampu. Target akhir Anda adalah untuk menghapus jumlah lampu maksimum sehingga setiap sel yang dinyalakan sebelumnya masih menyala.

Bantu Farmer Jack dalam menemukan jumlah maksimum lampu yang tidak berguna sehingga ia dapat menggunakannya di tempat lain.

Memasukkan

Anda akan diberikan dalam dimensi baris pertama dari bidang M dan N .Selanjutnya M garis ikuti mengandung N karakter masing-masing mewakili lapangan.

'1' mewakili sel tempat lampu disimpan.

'0' mewakili sel kosong.

Keluaran

Anda harus mengeluarkan bilangan bulat yang berisi jumlah lampu tidak berguna.

Input sampel:

3 3
100
010
001

Output sampel:

2

Pemenang:

Karena ini adalah kode golf, pemenang akan menjadi orang yang akan berhasil menyelesaikan tugas dalam jumlah karakter paling sedikit

pengguna2369284
sumber
@PeterTaylor saya telah mengedit posting saya. Apakah Anda masih bingung?
user2369284
Jauh lebih baik. Terima kasih.
Peter Taylor
bisakah kita menganggap input berakhir dengan baris baru?
John Dvorak
1
Ini seperti pekerjaan rumah.
Johannes
1
Apakah kami dijamin bahwa lampu input akan menerangi seluruh lahan? Saya akan menebak tidak ...
Keith Randall

Jawaban:

5

Mathematica 186 (serakah) dan 224 (semua kombinasi)

Solusi Serakah

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]

Ini mematikan lampu berlebihan satu per satu. Jika cakupan cahaya tidak berkurang ketika lampu padam, lampu itu bisa dihilangkan. Pendekatan serakah sangat cepat dan dapat dengan mudah menangani matriks 15x15 dan jauh lebih besar (lihat di bawah). Ini mengembalikan solusi tunggal, tetapi tidak diketahui apakah itu optimal atau tidak. Kedua pendekatan, dalam versi golf, mengembalikan jumlah lampu yang tidak digunakan. Pendekatan un-golfed juga menampilkan grid, seperti di bawah ini.

Sebelum:

sebelum

Setelah:

setelah

Solusi Optimal menggunakan semua kombinasi lampu (224 karakter)

Terima kasih kepada @ Clément.

Versi ungolfed menggunakan semua kombinasi lampu

fFungsi transformasi morfologis yang digunakan dalam sameCoverageQperlakukan sebagai menyala (nilai = 1 bukannya nol) 3 x 3 persegi di mana setiap cahaya berada. Ketika cahaya berada di dekat tepi tambak, hanya kotak (kurang dari 9) dalam batas-batas pertanian dihitung. Tidak ada penghitungan yang berlebihan; kotak yang diterangi oleh lebih dari satu lampu cukup dinyalakan. Program mematikan setiap lampu dan memeriksa untuk melihat apakah keseluruhan cakupan pencahayaan di lahan berkurang. Jika tidak, lampu tersebut dihilangkan.

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]menghitung jumlah sel yang ditandai. Ini digunakan untuk menghitung lampu dan juga untuk menghitung sel yang menyala

sameCoverageQ[mat1, mat2] menguji apakah sel-sel yang menyala di mat1 sama dengan jumlah sel-sel yang menyala di mat2.MorphologicalTransform [[mat] mengambil matriks cahaya dan mengembalikan matriks` sel yang mereka nyalakan.

c[m1]mengambil semua kombinasi lampu dari m1 dan mengujinya untuk cakupan. Di antara mereka yang memiliki jangkauan maksimum, ia memilih yang memiliki bola lampu paling sedikit. Masing-masing adalah solusi optimal.


Contoh 1:

Pengaturan 6x6

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

asli

Semua solusi optimal.

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

jawaban


Versi golf menggunakan semua kombinasi lampu.

Versi ini menghitung jumlah lampu yang tidak digunakan. Itu tidak menampilkan grid.

c mengembalikan jumlah lampu yang tidak digunakan.

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]menghitung jumlah sel yang ditandai. Ini digunakan untuk menghitung lampu dan juga untuk menghitung sel yang menyala

s[mat1, mat2] menguji apakah sel-sel yang menyala di mat1 sama dengan jumlah sel-sel yang menyala di mat2.t [[mat] mengambil matriks cahaya dan mengembalikan matriks` sel-sel yang mereka nyalakan.

c[j]mengambil semua kombinasi lampu dari j dan mengujinya untuk cakupan. Di antara mereka yang memiliki jangkauan maksimum, ia memilih yang memiliki bola lampu paling sedikit. Masing-masing adalah solusi optimal.

Contoh 2

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

kisi

Dua lampu dapat disimpan dengan cakupan pencahayaan yang sama. c [m]

2

DavidC
sumber
Saya tidak memiliki Mathematica, jadi saya tidak dapat menguji kode ini, tetapi saya pikir algoritme Anda salah - kecuali saya salah memahami penjelasan Anda. Jika pemahaman saya benar, itu bergantung pada strategi serakah yang bergantung pada urutan pemrosesan cahaya: misalnya, mulai dari lampu tengah dalam kotak uji 3 * 3 Anda akan melepasnya dan meninggalkan dua lampu samping. Saya tidak berharap bahwa pemesanan khusus yang Anda gunakan dalam implementasi membuatnya benar, tetapi saya tidak memiliki contoh tandingan saat ini.
Clément
Gagasan Anda sepertinya adalah memungkinkan untuk memiliki 2 lampu berlebihan, a, b, dalam pengaturan awal, yang salah satunya lebih berlebihan dari yang lain. Jadi, mungkin ada ekonomi yang lebih baik dicapai jika seseorang dihapus (pertama). Saya merasakan bahwa ini tidak dapat terjadi dengan total 3 lampu, tetapi memang mungkin dengan jumlah lampu yang lebih banyak. Saya awalnya memecahkan masalah dengan menguji semua kombinasi lampu. Ini tentu saja optimal dan karenanya ideal, tetapi saya merasa tidak praktis dengan seperangkat lampu besar.
DavidC
@ Clément Saya sedang mengerjakan solusi yang akan menguji semua kemungkinan kombinasi. Akan butuh waktu ...
DavidC
Itu pasti akan;) Tapi itu yang diharapkan: seperti yang terjadi masalah ini adalah contoh dari set penutup minimum - yaitu NP. Apakah asumsi tambahan (hampir semua perangkat penutup, kecuali yang lateral, memiliki kardinalitas yang sama) memungkinkan implementasi yang efisien merupakan masalah yang menarik.
Clément
Saya sangat curiga solusi serakah itu benar jika Anda melakukan secara berurutan dengan baris dan kolom, tetapi saya belum membuktikannya.
Aditsu berhenti karena SE adalah JAHAT
3

Python, 309 karakter

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

Bekerja menggunakan bitmask. Ladalah daftar lampu, di mana setiap cahaya diwakili oleh bilangan bulat dengan (hingga) 9 bit yang diatur untuk pola cahayanya. Kemudian kami mencari subset dari daftar ini yang bitwise-nya atau sama dengan bitwise-atau seluruh daftar. Subset terpendek adalah pemenang.

m adalah topeng yang mencegah sampul bit saat bergeser.

Keith Randall
sumber
Silakan coba untuk menyediakan program yang berjalan dengan benar. Java / C++ aman untuk segala jenis lekukan atau jarak tetapi Python tidak. Melakukan kesalahan atau mempersingkat kode adalah hal lain tetapi menyediakan program yang tidak berjalan adalah hal lain.
user2369284
3
@ user2369284 apa yang kamu bicarakan ?! Ini berfungsi dengan baik (dengan python 2)
aditsu berhenti karena SE adalah JAHAT
@aditsu Saya punya python 3.
user2369284
1
@ user2369284 baik, sintaks cetak berbeda sehingga gagal dalam python 3
aditsu berhenti karena SE adalah JAHAT
3

Java 6 - 509 byte

Saya membuat beberapa asumsi tentang batasan dan menyelesaikan masalah seperti yang dinyatakan saat ini.

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

Jalankan seperti ini: java F <inputfile 2>/dev/null

aditsu berhenti karena SE adalah JAHAT
sumber
Tidak persis pendek, tetapi cocok di sektor disk: p Saya dapat mencoba bahasa yang berbeda nanti
Aditsu berhenti karena SE adalah JAHAT
@aditsu Bagaimana cara membuatnya di windows?
user2369284
1
@ user2369284: Saya tidak melihat bagaimana Anda dapat melakukan 0011111100 hanya dengan 2 lampu. Anda perlu menutupi 8 sel dengan cahaya, dan setiap lampu dapat melakukan paling banyak 3.
Keith Randall
@ user2369284 mungkin java F <inputfile 2>nul, jika itu gagal maka java F <inputfileabaikan pengecualian. Juga tidak akan berjalan dengan java 7.
aditsu berhenti karena SE adalah JAHAT
@ aditsu Saya benar-benar minta maaf. Itu kesalahan ketik. Program Anda berfungsi dengan benar.
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;}
Hax0r778
sumber
1

Ruby, 303

[ini diberi kode untuk menjawab versi pertanyaan sebelumnya; baca catatan di bawah]

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

Mengkonversi ke array Boolean dan kemudian membandingkan lingkungan untuk perubahan.

Batasan (?): Ukuran bidang pertanian maksimum adalah 1.000 x 1.000. Masalahnya menyatakan "Petani Jack sangat miskin" jadi saya berasumsi pertaniannya tidak lebih besar. ;-) Batasan dapat dihapus dengan menambahkan 2 karakter.

CATATAN: Sejak saya mulai mengkode ini, tampaknya persyaratan pertanyaan berubah. Klarifikasi berikut telah ditambahkan "lampu yang akan Anda tunjuk tidak akan dilepas satu per satu, tetapi akan dilepas secara bersamaan" . Ketidakjelasan pertanyaan awal memungkinkan saya untuk menyimpan beberapa kode dengan menguji setiap pemindahan lampu. Dengan demikian, solusi saya tidak akan berfungsi untuk banyak kasus uji di bawah persyaratan baru. Jika saya punya waktu, saya akan memperbaikinya. Saya mungkin tidak. Tolong jangan terbalikkan jawaban ini karena jawaban lain di sini mungkin sepenuhnya sesuai.

Darren Stone
sumber
1

APL, 97 karakter / byte *

Mengasumsikan a ⎕IO←1dan ⎕ML←3lingkungan 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←⍎⍞

Versi tidak disatukan:

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

Saya setuju bahwa lebih banyak kasus uji akan lebih baik. Ini yang acak:

Memasukkan:

5 5
10001
01100
00001
11001
00010

Output (lampu tidak berguna):

5

Tata letak dengan lampu minimal (tidak termasuk dalam versi 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 dapat ditulis dalam charset byte tunggal (lama) yang memetakan simbol APL ke nilai 128 byte atas. Oleh karena itu, untuk tujuan penilaian, program karakter N yang hanya menggunakan karakter ASCII dan simbol APL dapat dianggap sebagai panjang N byte.

Tobia
sumber
0

C ++ 5.806 Bytes

Ini belum dioptimalkan untuk ukuran. Tetapi karena ada beberapa kontestan saya akan membiarkannya untuk saat ini.

Header Petani:

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

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

}

Dan serangkaian tes untuk menunjukkan bahwa kode melakukan apa yang harus dilakukan:

#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
sumber
Harap berikan utilitas pengujian yang menggunakan perpustakaan eksternal.
user2369284
Itu adalah GTest: code.google.com/p/googletest/downloads/list
Johannes
0

Perl 3420 byte

Bukan solusi golf, tapi saya menemukan masalah ini menarik:

#!/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 dikeluarkan sehingga saya bisa menunjukkan tes konkret)

Hunter McMillen
sumber
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()
Blckknght
sumber