Skip to content

Commit

Permalink
Added java file for stayhome
Browse files Browse the repository at this point in the history
  • Loading branch information
pangiann committed Sep 17, 2020
1 parent dbeb02a commit cffb701
Show file tree
Hide file tree
Showing 5 changed files with 388 additions and 0 deletions.
Binary file removed stayhome/Stayhome.zip
Binary file not shown.
34 changes: 34 additions & 0 deletions stayhome/java/AirState.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import java.util.*;

public class AirState {
private int xplace, yplace;
private static int time = 0;
private static boolean infected = false;

public AirState(int x, int y, int t) {
xplace = x;
yplace = y;
}

public int getX() {
return xplace;
}
public int getY() {
return yplace;
}

public void infected() {
infected = true;
}
public int getTime() {
return time;
}
public boolean getInf() {
return infected;
}
public void initTime(int t) {
time = t;
}


}
67 changes: 67 additions & 0 deletions stayhome/java/CoronaState.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import java.util.*;

public class CoronaState {
// false = west, true = east
private int xplace, yplace;
private int time;
private CoronaState previous;

public CoronaState(int x, int y, int t, CoronaState p) {
xplace = x;
yplace = y;
time = t;
previous = p;
}

public boolean isFinal() {
return false;
}

public boolean isBad(char [][] grid, int N, int M) {
return xplace < 0 || xplace >= N
|| yplace < 0 || yplace >= M
|| grid[xplace][yplace] == 'X';

}





public Collection<CoronaState> next() {
Collection<CoronaState> states = new ArrayList<>();
//down
states.add(new CoronaState(xplace + 1, yplace, time + 2, this));
//left
states.add(new CoronaState(xplace, yplace - 1, time + 2, this));
//right
states.add(new CoronaState(xplace, yplace + 1, time + 2, this));
// up
states.add(new CoronaState(xplace - 1, yplace, time + 2, this));

return states;
}

public CoronaState getPrevious() {
return previous;
}

public int getX() {
return xplace;
}
public int getY() {
return yplace;
}

public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CoronaState other = (CoronaState) o;
return xplace == other.xplace && yplace == other.yplace;

}
public int hashCode() {
return Objects.hash(xplace, yplace);
}

}
68 changes: 68 additions & 0 deletions stayhome/java/SotirisState.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import java.util.*;

public class SotirisState {
// false = west, true = east
private int xplace, yplace;
private int time;
private SotirisState previous;

public SotirisState(int x, int y, int t, SotirisState p) {
xplace = x;
yplace = y;
time = t;
previous = p;
}

public boolean isFinal(int fx, int fy) {
return xplace == fx && yplace == fy;
}

public boolean isBad(char [][] grid, int N, int M, int [][] coronaTime) {
return xplace < 0 || xplace >= N
|| yplace < 0 || yplace >= M
|| grid[xplace][yplace] == 'X'
|| (coronaTime[xplace][yplace] != -1 && time >= coronaTime[xplace][yplace]);

}





public Collection<SotirisState> next() {
Collection<SotirisState> states = new ArrayList<>();
//down
states.add(new SotirisState(xplace + 1, yplace, time + 1, this));
//left
states.add(new SotirisState(xplace, yplace - 1, time + 1, this));
//right
states.add(new SotirisState(xplace, yplace + 1, time + 1, this));
// up
states.add(new SotirisState(xplace - 1, yplace, time + 1, this));

return states;
}

public SotirisState getPrevious() {
return previous;
}

public int getX() {
return xplace;
}
public int getY() {
return yplace;
}

public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
SotirisState other = (SotirisState) o;
return xplace == other.xplace && yplace == other.yplace;

}
public int hashCode() {
return Objects.hash(xplace, yplace);
}

}
219 changes: 219 additions & 0 deletions stayhome/java/Stayhome.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
import java.util.*;
import java . io .*;

public class Stayhome {

public static void main (String[] args) {
int N, M;
char[][] grid = new char[1000][1000];
ArrayList<AirState> airInfection = new ArrayList<AirState>();
CoronaState cor_initial = new CoronaState(0, 0, 0, null);
SotirisState sot_initial = new SotirisState(0, 0, 0, null);

//boolean air_inf = false;
int fx = 0;
int fy = 0;
int nl = 0;

try {
File input = new File(args[0]);
BufferedReader reader = new BufferedReader (new FileReader(input));
String line = null;
while ((line = reader.readLine()) != null) {
grid[nl] = line.toCharArray();
nl++;
}


} catch (Exception e) { // Bad practice !
System.out.println(" Something went wrong : " + e);
}
N = nl;
M = grid[0].length;
// find starting positions for sotiris, corona and the others
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if (grid[i][j] == 'W') {
cor_initial = new CoronaState(i, j, 0, null);
}
if (grid[i][j] == 'A') {
airInfection.add(new AirState(i, j, -1));

}
if (grid[i][j] == 'S') {
sot_initial = new SotirisState(i, j, 0, null);

}
if (grid[i][j] == 'T') {
fx = i;
fy = j;
}
}
}
// find corona virus spread array
int [][]covid = coronaBfs(grid, N, M, cor_initial, airInfection);

// find sotiris final position
SotirisState kapa = sotirisVsCorona(sot_initial, grid, covid, N, M, fx, fy);
String path;
if (kapa == null) {
System.out.print("IMPOSSIBLE\n");
}
else {
path = findPath(kapa);
System.out.println(path.length());
System.out.println(path);
}



}
public static int[][] coronaBfs(char [][]grid, int N, int M, CoronaState virus, ArrayList<AirState> initialStates) {
int[][] time = new int[N][M];
Queue<CoronaState> remaining = new ArrayDeque<>();
Set<CoronaState> seen = new HashSet<>();
AirState gen_air = new AirState(-1, -1, -1);
int air_time, cor_time;
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
time[i][j] = -1;
}
}
// if airports exist get first one to have access to static vars of airstate class
if (initialStates.size() != 0)
gen_air = initialStates.get(0);

// push to queue
remaining.add(virus);
seen.add(virus);
time[virus.getX()][virus.getY()] = 0;
while (true) {
// nowhere to go and virus has arrived to airport but other airports not infected yet
if (remaining.isEmpty() && gen_air.getTime() != 0 && gen_air.getInf() != true) {
// infect all airports
gen_air.infected();
for (AirState a : initialStates) {
int x = a.getX();
int y = a.getY();
if (time[x][y] == -1 && (x != virus.getX() || y != virus.getY())) {
time[x][y] = gen_air.getTime() + 5;
CoronaState c = new CoronaState(x, y, gen_air.getTime() + 5, virus);
remaining.add(c);
seen.add(c);

}
}
continue;
}
// nowhere to go, no airports to push -> bye bye...
else if (remaining.isEmpty()) {
break;
}
virus = remaining.remove();

air_time = gen_air.getTime();

cor_time = time[virus.getX()][virus.getY()];

// virus' first time in airport
// enable air_time
if (air_time == 0 && grid[virus.getX()][virus.getY()] == 'A') {
gen_air.initTime(cor_time);
}
// necessary air_time passed, virus now infects all airports
if (air_time != 0 && cor_time - air_time == 4) {
gen_air.infected();
for (AirState a : initialStates) {


int x = a.getX();
int y = a.getY();
if (time[x][y] == -1 && (x != virus.getX() || y != virus.getY())) {
time[x][y] = air_time + 5;
CoronaState c = new CoronaState(x, y, air_time + 5, virus);
remaining.add(c);
seen.add(c);
}
}
}
// find neighbors and infect them
for (CoronaState n : virus.next()) {
if (!seen.contains(n) && !n.isBad(grid, N, M)) {
remaining.add(n);
seen.add(n);
time[n.getX()][n.getY()] = time[virus.getX()][virus.getY()] + 2;
}
}


}
return time;

}



private static SotirisState sotirisVsCorona(SotirisState initial, char [][]grid, int[][] covid, int N, int M, int fx, int fy) {

Queue<SotirisState> remaining = new ArrayDeque<>();
Set<SotirisState> seen = new HashSet<>();
remaining.add(initial);
seen.add(initial);
while (!remaining.isEmpty()) {
SotirisState s = remaining.remove();
int x = s.getX();
int y = s.getY();
if (s.isFinal(fx, fy)) return s;

for (SotirisState n : s.next()) {
// check if sotiris is not as fast as corona or this grid is a 'X' and other bad situations
if (!seen.contains(n) && !n.isBad(grid, N, M, covid)) {
remaining.add(n);
seen.add(n);
}
}

}
return null;

}

private static String findPath(SotirisState s){
// go to all previous sotiris states from final pos to start pos
SotirisState previous = s.getPrevious();
SotirisState current = s;
ArrayList<Character> path = new ArrayList<Character>();

while(previous != null){
path.add(findMove(previous, current));
current = previous;
previous = current.getPrevious();
}

StringBuilder builder = new StringBuilder();
for(int i = path.size() - 1; i >= 0; i--){
builder.append(path.get(i));
}
return builder.toString();
}

private static char findMove(SotirisState a, SotirisState b){
// be careful we want the best lexicographically move
int x1 = a.getX(), y1 = a.getY();
int x2 = b.getX(), y2 = b.getY();
if(y1 == y2){
if (x2 == x1 + 1){
return 'D';
}
return 'U';
}
else {
if(y2 == y1 + 1){
return 'R';
}
return 'L';
}
}


}

0 comments on commit cffb701

Please sign in to comment.