Допомога фермеру


10

Фермер Джек дуже бідний. Він хоче запалити всю свою ферму, але з мінімальними витратами. Лампа може висвітлювати власну камеру, а також вісім своїх сусідів. Він влаштував світильники на своєму полі, але йому потрібна ваша допомога, щоб з’ясувати, чи зберігав він чи ні зайві світильники.

Додаткові світильники: Лампи, які при вилученні з ферми не матимуть ніякої різниці в кількості освітлених комірок. Крім того, лампи, які ви вкажете, не будуть зніматися одна за одною, але вони будуть вийматися одночасно.

Примітка. Єдина дія, яку ви можете виконати, - це зняти деякі лампи. Не можна ні переставляти, ні вставляти лампи. Ваша кінцева мета - зняти максимальну кількість ламп, щоб кожна клітина, яка була запалена раніше, все ще запалювала.

Допоможіть Фермеру Джеку в виявленні максимальної кількості непотрібних ламп, щоб він міг їх використовувати в іншому місці.

Вхідні дані

Ви будете вказані в розмірах першого рядка поля M і N. Наступні рядки M наступні, що містять N символів, кожен з яких представляє поле.

'1' позначає клітинку, де зберігається лампа.

'0' являє собою порожню комірку.

Вихідні дані

Ви повинні вивести ціле число, що містить кількість непотрібних ламп.

Зразок введення:

3 3
100
010
001

Вибірка зразка:

2

Переможець:

Оскільки це код гольфу, переможцем стане той, хто успішно виконає завдання щонайменше кількості символів


@PeterTaylor Я змінив своє повідомлення. У вас все ще є плутанина?
користувач2369284

Значно краще. Дякую.
Пітер Тейлор

може ми припустимо, що вхід закінчується новим рядком?
Іван Дворак

1
Це виглядає як домашнє завдання.
Йоганнес

1
Ми гарантуємо, що вхідні лампи освітлюють всю ферму? Я збираюся здогадатися ні ...
Кіт Рендалл

Відповіді:


5

Mathematica 186 (жадібний) та 224 (усі комбінації)

Жадібне рішення

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]

Це вимикає зайві вогні по черзі. Якщо освітленість не зменшиться, коли світло згасне, це світло може бути ліквідовано. Жадібний підхід дуже швидкий і може легко обробляти матриці розміром 15x15 і набагато більше (див. Нижче). Він повертає єдине рішення, але невідомо, оптимально це чи ні. Обидва підходи, у версіях для гольфу, повертають кількість невикористаних вогнів. Підходи без волейболу також відображають сітки, як показано нижче.

Перед:

раніше

Після:

після

Оптимальні рішення з використанням усіх комбінацій світла (224 символів)

З вдячністю @ Clément.

Безгольова версія з використанням усіх комбінацій вогнів

fМорфологічна функція перетворення, що використовується в обробці як запалене sameCoverageQ(значення = 1 замість нуля), 3 х3 квадрат, в якому проживає кожне світло. Коли світло знаходиться біля краю ферми, тільки кордони (менше 9) у межах господарство рахується. Перенарахування немає; квадратний індикатор, освітлений декількома лампами, просто горить. Програма вимикає кожне світло і перевіряє, чи зменшується загальне освітлення на фермі. Якщо це не так, це світло усувається.

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]підраховує кількість позначених комірок. Він використовується для підрахунку вогнів, а також для підрахунку освітлених комірок

sameCoverageQ[mat1, mat2] перевіряє, чи освітлені клітини в mat1 дорівнює кількості освітлених комірок в mat2.MorphologicalTransform [[mat] приймає матрицю вогнів і повертає матрицю` клітин, які вони загоряються.

c[m1]бере всі комбінації вогнів з m1 і випробовує їх на охоплення. Серед тих, хто має максимальне покриття, він вибирає ті, у яких є найменші лампочки. Кожне з них - оптимальне рішення.


Приклад 1:

Налаштування 6x6

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

оригінальний

Всі оптимальні рішення.

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

відповіді


Гольф-версія з використанням усіх комбінацій вогнів.

Ця версія розраховує кількість невикористаних вогнів. Він не відображає сітки.

c повертає кількість невикористаних вогнів.

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]підраховує кількість позначених комірок. Він використовується для підрахунку вогнів, а також для підрахунку освітлених комірок

s[mat1, mat2] перевіряє, чи освітлені клітини в mat1 дорівнює кількості освітлених комірок в mat2.t [[mat] приймає матрицю вогнів і повертає матрицю` клітин, які вони загоряються.

c[j]бере всі комбінації вогнів з j і перевіряє їх на охоплення. Серед тих, хто має максимальне покриття, він вибирає ті, у яких є найменші лампочки. Кожне з них - оптимальне рішення.

Приклад 2

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

сітка

Два світла можна зберегти, маючи однакове освітлення. см]

2


У мене немає Mathematica під рукою, тому я не можу перевірити цей код, але я думаю, що ваш алгоритм невірний - якщо я неправильно зрозумів ваші пояснення. Якщо я розумію правильно, вона покладається на жадібну стратегію, яка залежить від порядку оброблення світла: наприклад, починаючи із середньої лампи у вашому тестовому випадку 3 * 3, вилучите її та залиште дві бічні лампи. Я не сподіваюсь, що певне замовлення, яке ви використовуєте в реалізації, робить його правильним, але зараз я не маю зустрічного прикладу.
Клімент

Здається, ваша ідея полягає в тому, що в початковій установці можливо мати 2 зайвих світильника, a, b, один з яких є зайвим, ніж інший. Таким чином, можливо, що краща економіка досягається, якщо її зняти (першою). Я відчуваю, що цього не могло статися при загальній кількості 3-х вогнів, але, можливо, це можливо з більшою кількістю вогнів. Я спочатку вирішив проблему, випробувавши всі комбінації вогнів. Це, безумовно, оптимально і, таким чином, ідеально, але я вважав це недоцільним із великим набором вогнів.
DavidC

@ Clément Я працюю над рішенням, яке перевірить усі можливі комбінації. Пройде певний час ...
DavidC

Це, безумовно, буде;) Але цього варто очікувати: на даний момент ця проблема є примірником мінімального встановленого покриття - що є NP. Чи є додаткові припущення (майже всі набори покриття, крім бічних, мають однакову кардинальність), дозволяють забезпечити ефективну реалізацію, хоча це цікава проблема.
Клімент

Я сильно підозрюю, що жадібне рішення є правильним, якщо ви йдете послідовно за рядками та стовпцями, але я цього ще не довів.
aditsu кинути, тому що SE - EVIL

3

Пітон, 309 символів

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

Працює з використанням бітових масок. L- це перелік вогнів, де кожне світло представлене цілим числом (до) 9 біт, встановлених для його світлового малюнка. Тоді ми проводимо вичерпний пошук підмножини цього списку, чий побітовий перебіг - або такий же, як і порозрядний - або всього списку. Найкоротший підмножина - переможець.

m - це маска, яка запобігає загортанню шматочків при зміщенні.


Будь ласка, спробуйте надати програму, яка працює правильно.Java/C++ є безпечною для будь-якого відступу або пробілів, але Python не є. Забруднення або скорочення коду - інша річ, але надання програми, яка не працює, - це інша.
user2369284

3
@ user2369284 про що ти говориш ?! Це прекрасно працює (з python 2)
aditsu вийшов, тому що SE

@aditsu У мене python 3.
user2369284

1
@ user2369284 добре, синтаксис друку відрізняється, тому він не працює в python 3
aditsu кине, тому що SE - EVIL

3

Java 6 - 509 байт

Я зробив кілька припущень щодо меж і вирішив проблему, про яку говорилося в цей час.

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

Бігайте так: java F <inputfile 2>/dev/null


Не зовсім короткий, але підходить до сектору дисків: p Можу пізніше спробувати іншу мову.
aditsu кинути, тому що SE - EVIL

@aditsu Як зробити цю роботу на Windows?
user2369284

1
@ user2369284: Я не бачу, як можна зробити 0011111100 лише з 2 лампами. Вам потрібно накрити 8 осередків світлом, і кожна лампа може зробити максимум 3.
Кіт Рандалл

@ user2369284 можливо java F <inputfile 2>nul, якщо це не вдасться, java F <inputfileі ігноруйте виняток. Крім того, він не працюватиме з java 7.
aditsu кинеться тому, що SE - EVIL

@aditsu Мені дуже шкода. Це була помилка друку. Ваша програма працює правильно.
user2369284

1

c ++ - 477 байт

#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

Рубі, 303

[це було закодовано для відповіді на попередню версію питання; читати замітку нижче]

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

Перетворення в масиви булевих і порівняння мікрорайонів для змін.

Обмеження (?): Максимальний розмір поля ферми - 1000 х 1000. Проблемний стан "Фермер Джек дуже бідний", тому я припускаю, що його ферма не більша. ;-) Обмеження можна зняти, додавши 2 знаки.

ПРИМІТКА. Оскільки я почав кодувати це, видається, що запитання змінилися. Додано наступне уточнення: "лампи, які ви вкажете, не будуть зніматися одна за одною, але вони будуть вийматися одночасно" . Неоднозначність оригінального запитання дозволила мені зберегти деякий код, випробувавши окремі лампи. Таким чином, моє рішення не буде працювати для багатьох тестових випадків за новими вимогами. Якщо у мене буде час, я це виправлю. Я не можу. Будь ласка, не підтримуйте цю відповідь, оскільки інші відповіді тут можуть повністю відповідати.


1

APL, 97 символів / байт *

Передбачає середовище AP ⎕IO←1та ⎕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←⍎⍞

Негольована версія:

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

Я згоден, що більше тестових випадків було б краще. Ось випадковий:

Вхід:

5 5
10001
01100
00001
11001
00010

Вихід (марні лампи):

5

Схема з міні-лампами (не входить у версію для гольфу):

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 може бути записаний у власному (застарілому) однобайтовому наборі, який відображає символи APL до верхніх значень 128 байт. Таким чином, з метою підрахунку, програма з N символів, яка використовує лише символи ASCII та символи APL, може вважатися довжиною N байтами.


0

C ++ 5.806 байт

Це ще не оптимізовано для розміру. Але оскільки учасників небагато, я поки що покину це.

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

}

І набір тестів, які показують, що код робить те, що він був побудований, щоб зробити:

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

Будь ласка, надайте програму тестування, яка використовує зовнішні бібліотеки.
user2369284


0

Perl 3420 байт

Не рішення для гольфу, але мені ця проблема була цікава:

#!/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 було знято, щоб я міг показати конкретні тести)


0

Python - 305 байт

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()
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.