Guest User

Untitled

a guest
Jan 23rd, 2018
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 9.89 KB | None | 0 0
  1. package ieee;
  2.  
  3. import java.io.BufferedReader;
  4. import java.io.File;
  5. import java.io.FileNotFoundException;
  6. import java.io.FileReader;
  7. import java.io.IOException;
  8. import java.util.ArrayList;
  9. import java.util.LinkedList;
  10.  
  11. import org.w3c.dom.NodeList;
  12.  
  13. public class IEEE_D
  14. {
  15.     private static ArrayList<TNode> route_ = new ArrayList<TNode>();
  16.     private static ArrayList<TNode> nodes_ = new ArrayList<TNode>();
  17.    
  18.     public static int bestRouteCost_ = Integer.MAX_VALUE;
  19.     public static char[][] map_;
  20.    
  21.     public static void main(String[] args)
  22.     {
  23.         IPoint startPoint = null;
  24.         IPoint endPoint = null;
  25.        
  26.         ArrayList<IPoint> keyPointList = new ArrayList<IPoint>();
  27.         ArrayList<IPoint> doorPointList = new ArrayList<IPoint>();
  28.        
  29.         SimpleFileReader reader = new SimpleFileReader("ieee_d" + File.separator + "input2.txt");
  30.         String currentLine = reader.nextLine();
  31.        
  32.         int rowCount, columnCount;
  33.         String[] line = currentLine.split(" ");
  34.         rowCount = Integer.parseInt(line[0]);
  35.         columnCount = Integer.parseInt(line[1]);
  36.        
  37.         map_ = new char[columnCount][rowCount];
  38.        
  39.         int y = 0;
  40.         currentLine = reader.nextLine();
  41.         while(currentLine != null)
  42.         {
  43.             char[] lineChars = currentLine.toCharArray();
  44.             for(int x = 0; x < lineChars.length; ++x)
  45.             {
  46.                 map_[x][y] = lineChars[x];
  47.                 if(lineChars[x] == 'K')
  48.                     keyPointList.add(new IPoint(x, y));
  49.                 else if(lineChars[x] == 'D')
  50.                     doorPointList.add(new IPoint(x, y));
  51.                 else if(lineChars[x] == 'S')
  52.                     startPoint = new IPoint(x, y);
  53.                 else if(lineChars[x] == 'E')
  54.                     endPoint = new IPoint(x, y);
  55.             }
  56.             currentLine = reader.nextLine();
  57.             ++y;
  58.         }
  59.        
  60.         //make nodes for each point of interest
  61. //      ArrayList<TNode> nodes = new ArrayList<TNode>(keyPointList.size());
  62.        
  63.         TNode startNode = new TNode(TNode.Type.S, startPoint);
  64.         TNode endNode = new TNode(TNode.Type.E, endPoint);
  65.        
  66.         nodes_.add(startNode);
  67.         for(IPoint point : keyPointList)
  68.         {
  69.             nodes_.add(new TNode(TNode.Type.K, point));
  70.         }
  71.         for(IPoint point : doorPointList)
  72.         {
  73.             nodes_.add(new TNode(TNode.Type.D, point));
  74.         }
  75.         nodes_.add(endNode);
  76.        
  77.         //Depth first that shit. Lowest is bestest
  78.         depthFirst(startNode, 0, 0);
  79.         System.out.print(bestRouteCost_);
  80.     }
  81.    
  82.     public static void depthFirst(TNode startNode, int keys, int cost)
  83.     {
  84.         route_.add(startNode);
  85.        
  86.         startNode.connectedNodes_.clear();
  87.         for(TNode jNode : nodes_)
  88.         {
  89.             if(startNode.equals(jNode) || startNode.isConnected(jNode)) continue;
  90.             Route route = Astar(startNode.position_, jNode.position_);
  91.             if(route == null) continue; //no connection exists
  92.             else
  93.             {
  94.                 startNode.connect(jNode, route.path_.size() - 1);
  95.             }
  96.         }
  97.        
  98.         int currentKeyCount = keys;
  99.         int routeLength = cost;
  100.  
  101.         TNode currentNode = startNode;
  102.         if(currentNode.type_ == TNode.Type.E)
  103.         {
  104.             //found the end point, check route cost
  105.             if(routeLength < bestRouteCost_) bestRouteCost_ = routeLength;
  106.             route_.remove(route_.indexOf(startNode));
  107.             return;
  108.         }
  109.         //check if this node has a key, to add to our count
  110.         else if(currentNode.type_ == TNode.Type.K) ++currentKeyCount;
  111.         //or is a door, to use up keys
  112.         else if(currentNode.type_ == TNode.Type.D)
  113.         {
  114.             //switch to an open door
  115.             currentNode.type_ = TNode.Type.O;
  116.             map_[currentNode.position_.x_][currentNode.position_.y_] = 'O';
  117.             --currentKeyCount;
  118.         }
  119.        
  120.         for(int i = 0; i < currentNode.connectedNodes_.size(); ++i)
  121.         {
  122.             TNode nextNode = currentNode.connectedNodes_.get(i);
  123.             int weight = currentNode.weights_.get(i);
  124.            
  125.             //check if the next node is visited already
  126.             if(route_.contains(nextNode)) continue;
  127.             //check if the next node is a door, to make sure we have enough keys
  128.             if(nextNode.type_ == TNode.Type.D && currentKeyCount == 0) continue;
  129.            
  130.             depthFirst(nextNode, currentKeyCount, cost + weight);
  131.         }
  132.  
  133.         //we can't do tail recursion here since we need to reset the state of door nodes after we finish with them
  134.         if(currentNode.type_ == TNode.Type.O)
  135.         {
  136.             //switch to a closed door
  137.             currentNode.type_ = TNode.Type.D;
  138.             map_[currentNode.position_.x_][currentNode.position_.y_] = 'D';
  139.         }
  140.        
  141.         route_.remove(route_.indexOf(startNode));
  142.     }
  143.    
  144.     public static char getTile(IPoint point)
  145.     {
  146.         if(point.x_ >= map_.length || point.y_ >= map_.length) return '#';
  147.         return map_[point.x_][point.y_];
  148.     }
  149.    
  150.     public static char getTile(int x, int y)
  151.     {
  152.         if(x >= map_.length || y >= map_.length) return 'x';
  153.         return map_[x][y];
  154.     }
  155.    
  156.     private static Route Astar(IPoint start, IPoint end)
  157.     {
  158.         int doorBetweenCount = 0;
  159.         ANode startNode = new ANode(start, null);
  160.         ArrayList<ANode> closedSet = new ArrayList<ANode>();
  161.         ArrayList<ANode> openSet = new ArrayList<ANode>();
  162.         openSet.add(startNode);
  163.        
  164.         startNode.g_ = 0;
  165.         startNode.h_ = getDistance(start, end);
  166.         startNode.f_ = startNode.g_ + startNode.h_;
  167.  
  168.         while(!openSet.isEmpty())
  169.         {
  170.             //pick smallest f from openSet
  171.             int maxF = Integer.MAX_VALUE;
  172.             ANode currentNode = null;
  173.             for(ANode node : openSet)
  174.             {
  175.                 if(node.f_ < maxF)
  176.                 {
  177.                     maxF = node.f_;
  178.                     currentNode = node;
  179.                 }
  180.             }
  181.             if(currentNode.point_.equals(end))
  182.             {
  183.                 return buildRoute(currentNode, doorBetweenCount);
  184.             }
  185.             //remove node from openSet and add to closed
  186.             openSet.remove(currentNode);
  187.             closedSet.add(currentNode);
  188.            
  189.             //get adjacent squares, ignore doors unless it is the end point
  190.             IPoint lookingPoint;
  191.             ANode newNode;
  192.             char lookingChar;
  193.            
  194.             for(int i = 0; i < 4; ++i)
  195.             {
  196.                 //check left, right, up and down
  197.                 int xOffset = 0, yOffset = 0;
  198.                 if(i == 0) xOffset = -1;
  199.                 else if(i == 1) xOffset = +1;
  200.                 else if(i == 2) yOffset = -1;
  201.                 else if(i == 3) yOffset = +1;
  202.                
  203.                 lookingChar = getTile(currentNode.point_.x_ + xOffset, currentNode.point_.y_ + yOffset);
  204.                 if(lookingChar != '#') //add to openSet
  205.                 {
  206.                     lookingPoint = new IPoint(currentNode.point_.x_ + xOffset, currentNode.point_.y_ + yOffset);
  207.                     //shitty hack, check if it's a door
  208.                     if(lookingChar == 'D' && !lookingPoint.equals(end)) continue;
  209.                    
  210.                     newNode = new ANode(lookingPoint, currentNode);
  211.                     if(closedSet.contains(newNode)) continue;
  212.                    
  213.                     //yeah this is sloppy but I don't care
  214.                     newNode.g_ = currentNode.g_ + 1;
  215.                     newNode.h_ = getDistance(lookingPoint, end);
  216.                     newNode.f_ = newNode.g_ + newNode.h_;
  217.                     if(!openSet.contains(newNode))
  218.                         openSet.add(newNode);
  219.                     else
  220.                     {
  221.                         ANode existing = openSet.get(openSet.indexOf(newNode));
  222.                         if(existing.g_ < newNode.g_)
  223.                         {
  224.                             existing.g_ = newNode.g_;
  225.                             existing.f_ = existing.g_ + existing.h_;
  226.                             existing.parent_ = currentNode;
  227.                         }
  228.                     }
  229.                        
  230.                 }
  231.             }
  232.         }
  233.         return null;
  234.     }
  235.  
  236.     private static Route buildRoute(ANode currentNode, int doorBetweenCount)
  237.     {
  238.         Route newRoute = new Route(currentNode.point_, doorBetweenCount);
  239.         ANode parent = currentNode.parent_;
  240.         while(parent != null)
  241.         {
  242.             newRoute.add(parent.point_);
  243.             parent = parent.parent_;
  244.         }
  245.         return newRoute;
  246.     }
  247.  
  248.     private static int getDistance(IPoint start, IPoint end)
  249.     {
  250.         return Math.abs((end.x_ - start.x_)) + Math.abs((end.y_ - start.y_));
  251.     }
  252. }
  253.  
  254. class ANode
  255. {
  256.     public ANode parent_;
  257.     public int g_ = 0;
  258.     public int h_ = 0;
  259.     public int f_ = 0;
  260.     public IPoint point_;
  261.    
  262.     public ANode(IPoint point, ANode parent)
  263.     {
  264.         point_ = point;
  265.         parent_ = parent;
  266.     }
  267.    
  268.     @Override
  269.     public boolean equals(Object obj)
  270.     {
  271.         if(obj instanceof ANode)
  272.         {
  273.             return point_.equals(((ANode) obj).point_);
  274.         }
  275.         return false;
  276.     }
  277.    
  278.     @Override
  279.     public String toString()    
  280.     {
  281.         return point_.toString();
  282.     }
  283. }
  284.  
  285. class TNode
  286. {
  287.     public static enum Type {S, K, D, E, O};
  288.     public IPoint position_;
  289.     public Type type_;
  290.     ArrayList<TNode> connectedNodes_;
  291.     ArrayList<Integer> weights_;
  292.    
  293.     public TNode(Type type, IPoint position)
  294.     {
  295.         type_ = type;
  296.         position_ = position;
  297.         connectedNodes_ = new ArrayList<TNode>();
  298.         weights_ = new ArrayList<Integer>();
  299.     }
  300.  
  301.     public boolean isConnected(TNode node)
  302.     {
  303.         return connectedNodes_.contains(node);
  304.     }
  305.    
  306.     public void connect(TNode node, int weight)
  307.     {
  308.         connectedNodes_.add(node);
  309.         weights_.add(weight);
  310.     }
  311.    
  312.     @Override
  313.     public boolean equals(Object obj)
  314.     {
  315.         if(obj instanceof TNode)
  316.         {
  317.             return position_.equals(((TNode) obj).position_);
  318.         }
  319.         return false;
  320.     }
  321.    
  322.     @Override
  323.     public String toString()
  324.     {
  325.         return type_.toString() + ":" + position_.toString();
  326.     }
  327.    
  328.     @Override
  329.     public int hashCode()
  330.     {
  331.         return position_.hashCode();
  332.     }
  333. }
  334.  
  335. class Route
  336. {
  337.     public ArrayList<IPoint> path_;
  338.     public int doorCount_ = 0;
  339.    
  340.     public Route(IPoint startPos, int doorCount)
  341.     {
  342.         doorCount_ = doorCount;
  343.         path_ = new ArrayList<IPoint>();
  344.         path_.add(startPos);
  345.     }
  346.    
  347.     public void add(IPoint point)
  348.     {
  349.         path_.add(point);
  350.     }
  351.    
  352.     @Override
  353.     public String toString()
  354.     {
  355.         return path_.toString();
  356.     }
  357. }
  358.  
  359. class IPoint
  360. {
  361.     public int x_, y_;
  362.    
  363.     public IPoint(int x, int y)
  364.     {
  365.         x_ = x;
  366.         y_ = y;
  367.     }
  368.    
  369.     public IPoint()
  370.     {
  371.         x_ = 0;
  372.         y_ = 0;
  373.     }
  374.    
  375.     @Override
  376.     public String toString()
  377.     {
  378.         return (x_ + "," + y_);
  379.     }
  380.    
  381.     @Override
  382.     public boolean equals(Object p)
  383.     {
  384.         if(p instanceof IPoint)
  385.         {
  386.             if(((IPoint) p).x_ == x_ && ((IPoint) p).y_ == y_)
  387.                 return true;
  388.         }
  389.         return false;
  390.     }
  391.    
  392.     @Override
  393.     public int hashCode()
  394.     {
  395.         return toString().hashCode();
  396.     }
  397. }
  398.  
  399. class SimpleFileReader
  400. {
  401.     private File file_;
  402.     private BufferedReader reader_;
  403.    
  404.     public SimpleFileReader(String fileName)
  405.     {
  406.         file_ = new File(fileName);
  407.         try
  408.         {
  409.             reader_ = new BufferedReader(new FileReader(file_));
  410.         }
  411.         catch (FileNotFoundException e)
  412.         {
  413.             e.printStackTrace();
  414.         }
  415.     }
  416.        
  417.     public String nextLine()
  418.     {
  419.         String line = null;
  420.         try
  421.         {
  422.             line = reader_.readLine();
  423.            
  424.             if(line == null)
  425.                 reader_.close();
  426.            
  427.             return line;
  428.         }
  429.         catch (IOException e)
  430.         {
  431.             e.printStackTrace();
  432.         }
  433.        
  434.         return line;
  435.     }
  436. }
Add Comment
Please, Sign In to add comment