// Path: app/src/main/java/hu/supercluster/gameoflife/game/cell/Cell.java
// public interface Cell {
//     public static final int STATE_ALIVE = 1;
//     public static final int STATE_DEAD = 0;
// 
//     void reset(int state);
//     long getId();
//     int getY();
//     int getX();
//     void setState(int state);
//     int getState();
//     boolean isAlive();
//     boolean isDead();
//     void onNeighborStateChange(int newState);
//     void setOverseer(Overseer overseer);
// }
// 
// Path: app/src/main/java/hu/supercluster/gameoflife/game/cell/SimpleCell.java
// public class SimpleCell implements Cell {
//     static final AtomicLong NEXT_ID = new AtomicLong(0);
//     final long id = NEXT_ID.getAndIncrement();
//     final int x;
//     final int y;
//     int state;
//     int neighborCount;
//     Overseer overseer;
// 
//     public SimpleCell(int x, int y, int state) {
//         this.x = x;
//         this.y = y;
//         this.state = state;
//     }
// 
//     @Override
//     public void setOverseer(Overseer overseer) {
//         this.overseer = overseer;
//     }
// 
//     @Override
//     public void reset(int state) {
//         this.state = state;
//         neighborCount = 0;
//     }
// 
//     @Override
//     public long getId() {
//         return id;
//     }
// 
//     @Override
//     public int getX() {
//         return x;
//     }
// 
//     @Override
//     public int getY() {
//         return y;
//     }
// 
//     @Override
//     public int getState() {
//         return state;
//     }
// 
//     @Override
//     public void setState(int newState) {
//         int oldState = this.state;
//         this.state = newState;
// 
//         if (newState != oldState && overseer != null) {
//             overseer.onCellStateChanged(new CellStateChange(this));
//         }
//     }
// 
//     @Override
//     public boolean isAlive() {
//         return !isDead();
//     }
// 
//     @Override
//     public boolean isDead() {
//         return state == STATE_DEAD;
//     }
// 
//     @Override
//     public void onNeighborStateChange(int newState) {
//         if (newState == STATE_DEAD) {
//             decreaseNeighborCount();
// 
//         } else {
//             increaseNeighborCount();
//         }
//     }
// 
//     void increaseNeighborCount() {
//         neighborCount++;
//     }
// 
//     void decreaseNeighborCount() {
//         neighborCount--;
//     }
// 
//     public int getNeighborCount() {
//         return neighborCount;
//     }
// 
//     @Override
//     public boolean equals(Object o) {
//         if (this == o) return true;
//         if (o == null || getClass() != o.getClass()) return false;
// 
//         SimpleCell that = (SimpleCell) o;
// 
//         if (neighborCount != that.neighborCount) return false;
//         if (state != that.state) return false;
//         if (x != that.x) return false;
//         if (y != that.y) return false;
// 
//         return true;
//     }
// 
//     @Override
//     public int hashCode() {
//         int result = x;
//         result = 31 * result + y;
//         result = 31 * result + state;
//         result = 31 * result + neighborCount;
//         return result;
//     }
// }
// 
// Path: app/src/main/java/hu/supercluster/gameoflife/game/grid/Grid.java
// public interface Grid<T extends Cell> extends Parcelable {
//     int getSizeX();
//     int getSizeY();
//     T getCell(int x, int y);
//     void putCell(T cell);
// }


import java.util.HashSet;
import java.util.Set;
import hu.supercluster.gameoflife.game.cell.Cell;
import hu.supercluster.gameoflife.game.cell.SimpleCell;
import hu.supercluster.gameoflife.game.grid.Grid;
    public NeighborCountBasedRule(String rule) {
        String[] split = rule.split("/");
        if (split.length != 2) {
            throw new IllegalArgumentException("Invalid rule string: " + rule);
        }

        try {
            survivalNbCounts = new HashSet<>();
            String survival = split[0];
            for (int i = 0; i < survival.length(); i++) {
                survivalNbCounts.add(Integer.valueOf(String.valueOf(survival.charAt(i))));
            }

            creationNbCounts = new HashSet<>();
            String creation = split[1];
            for (int i = 0; i < creation.length(); i++) {
                creationNbCounts.add(Integer.valueOf(String.valueOf(creation.charAt(i))));
            }

        } catch (NumberFormatException e) {
            throw new IllegalArgumentException("Invalid rule string: " + rule);
        }
    }

    public NeighborCountBasedRule(NeighborCountBasedRule other) {
        this.survivalNbCounts = new HashSet<>(other.survivalNbCounts);
        this.creationNbCounts = new HashSet<>(other.creationNbCounts);
    }

    @Override
// Path: app/src/main/java/hu/supercluster/gameoflife/game/cell/Cell.java
// public interface Cell {
//     public static final int STATE_ALIVE = 1;
//     public static final int STATE_DEAD = 0;
// 
//     void reset(int state);
//     long getId();
//     int getY();
//     int getX();
//     void setState(int state);
//     int getState();
//     boolean isAlive();
//     boolean isDead();
//     void onNeighborStateChange(int newState);
//     void setOverseer(Overseer overseer);
// }
// 
// Path: app/src/main/java/hu/supercluster/gameoflife/game/cell/SimpleCell.java
// public class SimpleCell implements Cell {
//     static final AtomicLong NEXT_ID = new AtomicLong(0);
//     final long id = NEXT_ID.getAndIncrement();
//     final int x;
//     final int y;
//     int state;
//     int neighborCount;
//     Overseer overseer;
// 
//     public SimpleCell(int x, int y, int state) {
//         this.x = x;
//         this.y = y;
//         this.state = state;
//     }
// 
//     @Override
//     public void setOverseer(Overseer overseer) {
//         this.overseer = overseer;
//     }
// 
//     @Override
//     public void reset(int state) {
//         this.state = state;
//         neighborCount = 0;
//     }
// 
//     @Override
//     public long getId() {
//         return id;
//     }
// 
//     @Override
//     public int getX() {
//         return x;
//     }
// 
//     @Override
//     public int getY() {
//         return y;
//     }
// 
//     @Override
//     public int getState() {
//         return state;
//     }
// 
//     @Override
//     public void setState(int newState) {
//         int oldState = this.state;
//         this.state = newState;
// 
//         if (newState != oldState && overseer != null) {
//             overseer.onCellStateChanged(new CellStateChange(this));
//         }
//     }
// 
//     @Override
//     public boolean isAlive() {
//         return !isDead();
//     }
// 
//     @Override
//     public boolean isDead() {
//         return state == STATE_DEAD;
//     }
// 
//     @Override
//     public void onNeighborStateChange(int newState) {
//         if (newState == STATE_DEAD) {
//             decreaseNeighborCount();
// 
//         } else {
//             increaseNeighborCount();
//         }
//     }
// 
//     void increaseNeighborCount() {
//         neighborCount++;
//     }
// 
//     void decreaseNeighborCount() {
//         neighborCount--;
//     }
// 
//     public int getNeighborCount() {
//         return neighborCount;
//     }
// 
//     @Override
//     public boolean equals(Object o) {
//         if (this == o) return true;
//         if (o == null || getClass() != o.getClass()) return false;
// 
//         SimpleCell that = (SimpleCell) o;
// 
//         if (neighborCount != that.neighborCount) return false;
//         if (state != that.state) return false;
//         if (x != that.x) return false;
//         if (y != that.y) return false;
// 
//         return true;
//     }
// 
//     @Override
//     public int hashCode() {
//         int result = x;
//         result = 31 * result + y;
//         result = 31 * result + state;
//         result = 31 * result + neighborCount;
//         return result;
//     }
// }
// 
// Path: app/src/main/java/hu/supercluster/gameoflife/game/grid/Grid.java
// public interface Grid<T extends Cell> extends Parcelable {
//     int getSizeX();
//     int getSizeY();
//     T getCell(int x, int y);
//     void putCell(T cell);
// }


// Path: app/src/main/java/hu/supercluster/gameoflife/game/rule/NeighborCountBasedRule.java
import java.util.HashSet;
import java.util.Set;
import hu.supercluster.gameoflife.game.cell.Cell;
import hu.supercluster.gameoflife.game.cell.SimpleCell;
import hu.supercluster.gameoflife.game.grid.Grid;

    public NeighborCountBasedRule(String rule) {
        String[] split = rule.split("/");
        if (split.length != 2) {
            throw new IllegalArgumentException("Invalid rule string: " + rule);
        }

        try {
            survivalNbCounts = new HashSet<>();
            String survival = split[0];
            for (int i = 0; i < survival.length(); i++) {
                survivalNbCounts.add(Integer.valueOf(String.valueOf(survival.charAt(i))));
            }

            creationNbCounts = new HashSet<>();
            String creation = split[1];
            for (int i = 0; i < creation.length(); i++) {
                creationNbCounts.add(Integer.valueOf(String.valueOf(creation.charAt(i))));
            }

        } catch (NumberFormatException e) {
            throw new IllegalArgumentException("Invalid rule string: " + rule);
        }
    }

    public NeighborCountBasedRule(NeighborCountBasedRule other) {
        this.survivalNbCounts = new HashSet<>(other.survivalNbCounts);
        this.creationNbCounts = new HashSet<>(other.creationNbCounts);
    }

    @Override
    public int apply(Grid<SimpleCell> grid, int x, int y) {