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