Skip to content

Instantly share code, notes, and snippets.

@Runemoro
Created August 15, 2019 07:14
Show Gist options
  • Save Runemoro/a025c584a5396958bdf71bfa14d86dd0 to your computer and use it in GitHub Desktop.
Save Runemoro/a025c584a5396958bdf71bfa14d86dd0 to your computer and use it in GitHub Desktop.
package lp;
import it.unimi.dsi.fastutil.longs.LongArrayList;
import it.unimi.dsi.fastutil.longs.LongList;
import java.util.Arrays;
public class ArrayLevelPropagator extends LevelPropagator {
private static final int MARKER = -1;
private final int[][] data;
private final int levelCount;
private final int width;
private final int height;
public ArrayLevelPropagator(int levelCount, int width, int height) {
super(levelCount, 10, 10);
this.levelCount = levelCount;
data = new int[width][height];
this.width = width;
this.height = height;
for (int[] row : data) {
Arrays.fill(row, levelCount - 1);
}
}
public int[][] data() {
applyPendingUpdates(Integer.MAX_VALUE);
return data.clone();
}
public void lower(int x, int y, int value) {
updateLevel(-1, getId(x, y), value, true);
}
public void reset(int x, int y) {
resetLevel(getId(x, y));
}
private long[] getNeighbors(long id) {
int x = getX(id);
int y = getY(id);
LongList neighbors = new LongArrayList(8);
for (int xo = -1; xo <= 1; xo++) {
for (int yo = -1; yo <= 1; yo++) {
if (xo == 0 && yo == 0) {
continue;
}
int nx = x + xo;
int ny = y + yo;
if (nx >= 0 && nx < width && ny >= 0 && ny < height) {
neighbors.add(getId(nx, ny));
}
}
}
return neighbors.toLongArray();
}
private int getX(long id) {
return (int) (id % width);
}
private int getY(long id) {
return (int) (id / width);
}
private long getId(int x, int y) {
return x + y * width;
}
@Override
protected boolean isMarker(long id) {
return id == MARKER;
}
@Override
protected int recalculateLevel(long id, long excludedId, int maxLevel) {
int level = maxLevel;
level = Math.min(level, getPropagatedLevel(-1, id, getLevel(-1)));
for (long neighbor : getNeighbors(id)) {
if (neighbor != excludedId) {
level = Math.min(level, getPropagatedLevel(neighbor, id, getLevel(neighbor)));
}
}
return level;
}
@Override
protected void propagateLevel(long id, int level, boolean decrease) { // update neighbors?
for (long neighbor : getNeighbors(id)) {
propagateLevel(id, neighbor, level, decrease);
}
}
@Override
protected int getLevel(long id) {
if (id == -1) {
return levelCount;
}
return data[getX(id)][getY(id)];
}
@Override
protected void setLevel(long id, int level) {
data[getX(id)][getY(id)] = level;
}
@Override
protected int getPropagatedLevel(long sourceId, long targetId, int level) {
if (sourceId == MARKER) {
return levelCount;
}
return level + 1;
}
}
class ArrayLevelPropagatorTest {
public static void main(String[] args) {
ArrayLevelPropagator lp = new ArrayLevelPropagator(10, 10, 10);
print(lp.data());
lp.lower(5, 5, 4);
print(lp.data());
lp.lower(2, 2, 5);
print(lp.data());
lp.reset(2, 2);
print(lp.data());
lp.reset(5, 5);
print(lp.data());
}
private static void print(int[][] data) {
for (int[] row : data) {
for (int value : row) {
System.out.print(value + " ");
}
System.out.println();
}
System.out.println();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment