Created
August 15, 2019 07:14
-
-
Save Runemoro/a025c584a5396958bdf71bfa14d86dd0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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