Guest User

Untitled

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