Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.util.*;
- import java.io.*;
- import java.math.*;
- class Cell {
- int x;
- int y;
- char type;
- public Cell(int x, int y, char type) {
- this.x = x;
- this.y = y;
- this.type = type;
- }
- @Override
- public String toString() {
- return "(" + this.x + ", " + this.y + ", " + this.type + ")";
- }
- }
- class RobotState {
- int x;
- int y;
- char dir;
- public RobotState(int x, int y, char dir) {
- this.x = x;
- this.y = y;
- this.dir = dir;
- }
- @Override
- public boolean equals(Object o) {
- if (o == this) {
- return true;
- }
- if (!(o instanceof RobotState)) {
- return false;
- }
- RobotState r = (RobotState)o;
- return (r.x == this.x && r.y == this.y && r.dir == this.dir);
- }
- @Override
- public int hashCode() {
- int result = 17;
- result = 31 * result + this.x;
- result = 31 * result + this.y;
- result = 31 * result + this.dir;
- return result;
- }
- }
- class Arrow {
- int x;
- int y;
- char dir;
- public Arrow(int x, int y, char dir) {
- this.x = x;
- this.y = y;
- this.dir = dir;
- }
- public Arrow(int x, int y, int dir) {
- this.x = x;
- this.y = y;
- switch (dir) {
- case 0:
- this.dir = 'U';
- break;
- case 1:
- this.dir = 'D';
- break;
- case 2:
- this.dir = 'L';
- break;
- case 3:
- this.dir = 'R';
- break;
- case 4:
- this.dir = '.';
- default:
- this.dir = '.';
- break;
- }
- }
- @Override
- public String toString() {
- return this.x + " " + this.y + " " + this.dir;
- }
- @Override
- public boolean equals(Object o) {
- if (o == this) {
- return true;
- }
- if (!(o instanceof Arrow)) {
- return false;
- }
- Arrow r = (Arrow)o;
- return (r.x == this.x && r.y == this.y);
- }
- @Override
- public int hashCode() {
- int result = 19;
- result = 37 * result + this.x;
- result = 37 * result + this.y;
- return result;
- }
- }
- class Robot {
- int x;
- int y;
- char dir;
- boolean active = true;
- ArrayList<RobotState> states = new ArrayList<RobotState>();
- public Robot(int x, int y, char dir) {
- this.x = x;
- this.y = y;
- this.dir = dir;
- }
- public void addState(RobotState rs) {
- states.add(rs);
- }
- public boolean visitedBefore(RobotState rs) {
- return states.contains(rs);
- }
- public void kill() {
- this.active = false;
- }
- }
- class Simulation {
- Grid grid;
- int simsRun = 0;
- public Simulation(Grid grid) {
- this.grid = grid;
- }
- public int getNumValidCells() {
- return this.grid.validCells.size();
- }
- public Cell getValidCell(int index) {
- return this.grid.validCells.get(index);
- }
- public String getArrowString() {
- return this.grid.getArrows();
- }
- public void addArrowsToGrid(ArrayList<Arrow> arrows) {
- for (Arrow a : arrows) {
- this.grid.addArrow(a);
- }
- }
- public void reset() {
- this.grid.reset();
- }
- public int play() {
- while(this.grid.takeTurn()) {}
- simsRun++;
- return this.grid.score;
- }
- }
- class Grid {
- Cell[][] cells = new Cell[10][19];
- Cell[][] uneditedCells = new Cell[10][19];
- ArrayList<Robot> robots = new ArrayList<Robot>();
- ArrayList<Robot> uneditedRobots = new ArrayList<Robot>();
- ArrayList<Cell> validCells = new ArrayList<Cell>();
- ArrayList<Cell> allCells = new ArrayList<Cell>();
- ArrayList<Arrow> arrows = new ArrayList<Arrow>();
- int turn = 0;
- int score = 0;
- public int getValidCells() {
- return this.validCells.size();
- }
- public void addCell(Cell cell) {
- this.cells[cell.y][cell.x] = cell;
- this.uneditedCells[cell.y][cell.x] = new Cell(cell.x, cell.y, cell.type);
- this.allCells.add(cell);
- if (cell.type == '.') {
- this.validCells.add(cell);
- }
- }
- public void reset() {
- //System.err.println("Reset() called");
- for (int y = 0; y < 10; y++) {
- for (int x = 0; x < 19; x++) {
- this.cells[y][x].x = this.uneditedCells[y][x].x;
- this.cells[y][x].y = this.uneditedCells[y][x].y;
- this.cells[y][x].type = this.uneditedCells[y][x].type;
- }
- }
- for (Robot r : this.uneditedRobots) {
- this.robots.add(new Robot(r.x, r.y, r.dir));
- }
- this.turn = 0;
- this.score = 0;
- this.arrows.clear();
- //System.err.println(this.cells);
- }
- public void addRobot(Robot robot) {
- this.uneditedRobots.add(new Robot(robot.x, robot.y, robot.dir));
- this.robots.add(robot);
- }
- public void addArrow(Arrow arrow) {
- this.cells[arrow.y][arrow.x].type = arrow.dir;
- this.arrows.add(arrow);
- }
- public String getArrows() {
- String res = "";
- for (int i = 0; i < this.arrows.size(); i++) {
- if (i == 0) {
- res += this.arrows.get(i).toString();
- } else {
- res += " " + this.arrows.get(i).toString();
- }
- }
- return res;
- }
- public boolean takeTurn() {
- Iterator<Robot> robotIter = this.robots.iterator();
- //Increment score based on number of robots still active
- this.score += this.robots.size();
- //Increment turn by one
- this.turn++;
- // System.err.println("--------- " + this.turn + " ------------");
- // System.err.println("Size: " + this.robots.size());
- // System.err.println("Score: " + this.score);
- // System.err.println();
- //Temp Cell
- Cell c;
- //If it is the first turn, let robots change dir if they are on an arrow
- if (this.turn == 1) {
- while (robotIter.hasNext()) {
- Robot robot = robotIter.next();
- RobotState firstState = new RobotState(robot.x, robot.y, robot.dir);
- robot.addState(firstState);
- c = this.cells[robot.y][robot.x];
- if (c.type != '.') {
- robot.dir = c.type;
- }
- }
- }
- //Move robots by one cell in the dir they are facing, wrap to other side if off-grid
- for (Robot robot : this.robots) {
- switch (robot.dir) {
- case 'U':
- robot.y--;
- if (robot.y < 0) {
- robot.y = 9;
- }
- break;
- case 'D':
- robot.y++;
- if (robot.y > 9) {
- robot.y = 0;
- }
- break;
- case 'L':
- robot.x--;
- if (robot.x < 0) {
- robot.x = 18;
- }
- break;
- case 'R':
- robot.x++;
- if (robot.x > 18) {
- robot.x = 0;
- }
- break;
- default:
- break;
- }
- }
- robotIter = this.robots.iterator();
- //Change dir of robots if they are on an arrow
- while (robotIter.hasNext()) {
- Robot robot = robotIter.next();
- c = this.cells[robot.y][robot.x];
- if (c.type != '.') {
- robot.dir = c.type;
- }
- }
- RobotState currState;
- robotIter = this.robots.iterator();
- //Mark robots for death
- while (robotIter.hasNext()) {
- Robot robot = robotIter.next();
- c = this.cells[robot.y][robot.x];
- currState = new RobotState(robot.x, robot.y, robot.dir);
- //System.err.println(c);
- if (c.type == '#') {
- robot.kill();
- //System.err.println("Robot Fell");
- } else if (robot.states.contains(currState)) {
- robot.kill();
- //System.err.println("Robot Repeated");
- } else {
- robot.addState(currState);
- //System.err.println(robot.states.size());
- }
- }
- ArrayList<Robot> tempRobots = new ArrayList<Robot>();
- for (Robot r : this.robots) {
- if (r.active) {
- tempRobots.add(r);
- }
- }
- this.robots = tempRobots;
- //System.err.println(this.score);
- // if (!(this.robots.size() != 0)) {
- // System.err.println("---New Sim---");
- // }
- return this.robots.size() != 0;
- }
- }
- class Manager {
- Simulation sim;
- Grid grid;
- long startTime;
- public Manager(Grid grid, long startTime) {
- this.grid = grid;
- this.startTime = startTime;
- this.sim = new Simulation(this.grid);
- }
- public void putArrowsOnGrid(ArrayList<Arrow> arrows) {
- this.sim.addArrowsToGrid(arrows);
- }
- public String getArrowString() {
- return this.sim.getArrowString();
- }
- public ArrayList<State> generateNewStates(State state) {
- ArrayList<State> newStates = new ArrayList<State>();
- Random random = new Random();
- int chance1 = 0;
- ArrayList<Arrow> tempArrows;
- int randIndex;
- Arrow lookArrow;
- boolean add = false;
- int size = state.arrows.size();
- if (size == 0) {
- add = true;
- }
- Arrow tempArrow;
- for (int i = 0; i < 30; i++) {
- state.shuffle();
- chance1 = random.nextInt(100);
- tempArrows = new ArrayList<Arrow>();
- //Flip one arrow, possibly delete it.
- if (chance1 < 30 && !add) {
- randIndex = random.nextInt(size);
- for (int a = 0; a < size; a++) {
- tempArrow = state.arrows.get(a);
- if (a != randIndex) {
- tempArrows.add(new Arrow(tempArrow.x, tempArrow.y, tempArrow.dir));
- } else {
- tempArrows.add(new Arrow(tempArrow.x, tempArrow.y, random.nextInt(10)));
- }
- }
- }
- //Flip 2 arrows, possibly delete them.
- else if (chance1 < 60 && !add) {
- randIndex = random.nextInt(size);
- for (int a = 0; a < size; a++) {
- tempArrow = state.arrows.get(a);
- if (a != randIndex && a != randIndex + 1) {
- tempArrows.add(new Arrow(tempArrow.x, tempArrow.y, tempArrow.dir));
- } else {
- tempArrows.add(new Arrow(tempArrow.x, tempArrow.y, random.nextInt(10)));
- }
- }
- }
- //Add an arrow, possibly
- else if (chance1 < 80 && !add) {
- randIndex = random.nextInt(state.grid.getValidCells());
- for (int a = 0; a < size; a++) {
- tempArrow = state.arrows.get(a);
- tempArrows.add(new Arrow(tempArrow.x, tempArrow.y, tempArrow.dir));
- }
- randIndex = random.nextInt(state.grid.getValidCells());
- lookArrow = new Arrow(state.grid.validCells.get(randIndex).x, state.grid.validCells.get(randIndex).y, random.nextInt(10));
- if (!tempArrows.contains(lookArrow) && lookArrow.dir != '.') {
- tempArrows.add(lookArrow);
- }
- }
- //Add up to 5 arrows
- else {
- for (int a = 0; a < size; a++) {
- tempArrow = state.arrows.get(a);
- tempArrows.add(new Arrow(tempArrow.x, tempArrow.y, tempArrow.dir));
- }
- for (int r = 0; r < 5; r++) {
- randIndex = random.nextInt(state.grid.getValidCells());
- lookArrow = new Arrow(state.grid.validCells.get(randIndex).x, state.grid.validCells.get(randIndex).y, random.nextInt(10));
- if (!tempArrows.contains(lookArrow) && lookArrow.dir != '.') {
- tempArrows.add(lookArrow);
- }
- }
- }
- newStates.add(new State(this.sim.grid, tempArrows, this.scoreArrows(tempArrows)));
- }
- return newStates;
- }
- public int scoreArrows(ArrayList<Arrow> arrows) {
- this.sim.reset();
- this.putArrowsOnGrid(arrows);
- int score = this.sim.play();
- //System.err.println(score);
- return score;
- }
- public ScoreAndString getHillClimbArrows(long startTime) {
- String bestArrowString = "";
- this.sim.reset();
- State initialState = new State(this.sim.grid, this.generateRandArrows(), this.sim.play());
- ArrayList<State> newStates = this.generateNewStates(initialState);
- State bestNewState = this.getBestState(newStates);
- while(System.currentTimeMillis() - startTime < 490) {
- newStates = this.generateNewStates(bestNewState);
- bestNewState = this.getBestState(newStates);
- }
- this.sim.reset();
- this.putArrowsOnGrid(bestNewState.arrows);
- bestArrowString = this.sim.grid.getArrows();
- ScoreAndString sas = new ScoreAndString(bestArrowString, this.sim.play());
- this.sim.reset();
- return sas;
- }
- public State getBestState(ArrayList<State> states) {
- Collections.sort(states);
- return states.get(states.size() - 1);
- }
- public ArrayList<Arrow> generateRandArrows() {
- ArrayList<Arrow> arrows = new ArrayList<Arrow>();
- Random random = new Random();
- int numValidCells = this.sim.getNumValidCells();
- for (int i = 0; i < random.nextInt(numValidCells); i++) {
- Cell c = this.sim.getValidCell(random.nextInt(numValidCells));
- arrows.add(new Arrow(c.x, c.y, random.nextInt(4)));
- }
- return arrows;
- }
- }
- class ScoreAndString {
- String arrowString;
- int score;
- public ScoreAndString(String aString, int score) {
- this.arrowString = aString;
- this.score = score;
- }
- }
- class State implements Comparable<State> {
- ArrayList<Arrow> tempArrows;
- ArrayList<Arrow> arrows = new ArrayList<Arrow>();
- int score;
- Grid grid;
- public State(Grid grid, ArrayList<Arrow> arrows, int score) {
- this.grid = grid;
- this.tempArrows = arrows;
- this.score = score;
- for (int i = 0; i < this.tempArrows.size(); i++) {
- Arrow tempArrow = this.tempArrows.get(i);
- if (tempArrow.dir != '.') {
- this.arrows.add(new Arrow(tempArrow.x, tempArrow.y, tempArrow.dir));
- }
- }
- }
- public void shuffle() {
- Collections.shuffle(this.arrows);
- }
- public int compareTo(State anotherInstance) {
- return this.score - anotherInstance.score;
- }
- }
- class Player {
- public static void main(String args[]) {
- Scanner in = new Scanner(System.in);
- Grid grid = new Grid();
- final long startTime = System.currentTimeMillis();
- for (int y = 0; y < 10; y++) {
- String line = in.nextLine();
- char[] charArr = line.toCharArray();
- for (int x = 0; x < charArr.length; x++) {
- Cell c = new Cell(x, y, charArr[x]);
- grid.addCell(c);
- }
- }
- int robotCount = in.nextInt();
- for (int i = 0; i < robotCount; i++) {
- int x = in.nextInt();
- int y = in.nextInt();
- String direction = in.next();
- Robot r = new Robot(x, y, direction.charAt(0));
- grid.addRobot(r);
- }
- Manager manager = new Manager(grid, startTime);
- String bestArrows = "";
- int bestScore = 1;
- ScoreAndString sas;
- for (int i = 0; i < 2; i++) {
- sas = manager.getHillClimbArrows(System.currentTimeMillis());
- System.err.println(sas.score + ": " + sas.arrowString);
- if (sas.score > bestScore) {
- bestScore = sas.score;
- bestArrows = sas.arrowString;
- }
- }
- System.out.println(bestArrows);
- final long endTime = System.currentTimeMillis();
- System.err.println("Time for program " + (endTime - startTime));
- System.err.println("Sims Run: " + manager.sim.simsRun);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement