Move TreeNode to the top, up, down and to the bottom C# - treeview

I have little knowledge on tree view. I want to be able to move the tree node to the top and to move up the tree node.
-Fruits
-Apples
-Oranges
-Bananas
-Watermelon
Below is the code i have try to implement.
First, i move the watermelon to the top, it work fine. Next when i try to move up Bananas, the index of the bananas will show -1. Is there anything else i do wrongly?
private void moveTopToolStripMenuItem_Click(object sender, EventArgs e)
{
TreeNode tv = new TreeNode();
TreeNode selectedNodeToMove = new TreeNode();
try
{
TreeNode parent = treeView.SelectedNode.Parent;
selectedNodeToMove = treeView.SelectedNode;
if (parent != null)
{
parent.Nodes.Remove(treeView.SelectedNode);
parent.Nodes[0] = selectedNodeToMove;
}
}
catch (Exception ex)
{
}
}
private void moveUpToolStripMenuItem_Click(object sender, EventArgs e)
{
TreeNode tv = new TreeNode();
TreeNode selectedNodeToMove = new TreeNode();
try
{
TreeNode parent = treeView.SelectedNode.Parent;
selectedNodeToMove = treeView.SelectedNode;
if (parent != null)
{
int index = parent.Nodes.IndexOf(treeView.SelectedNode);
if (index > 0)
{
tv = parent.Nodes[index - 1];
parent.Nodes.Remove(treeView.SelectedNode);
parent.Nodes.Remove(tv);
parent.Nodes.Insert(index - 1, selectedNodeToMove);
parent.Nodes.Insert(index, tv);
}
}
}
catch (Exception ex)
{
}
}

i manage to come out with the answer and it is working. Just want to share if anyone is looking on this.
private void moveTopToolStripMenuItem_Click(object sender, EventArgs e)
{
TreeNode selectedNodeToMove = new TreeNode();
try
{
int index = -1;
TreeNode parent = treeView.SelectedNode.Parent;
TreeNode node= this.treeView.SelectedNode.Clone() as TreeNode;
if (parent != null)
{
for (int j = 0; j < this.treeView.SelectedNode.Parent.Nodes.Count; j++)
{
if (this.treeView.SelectedNode == this.treeView.SelectedNode.Parent.Nodes[j])
{
index = j;
break;
}
}
this.treeView.BeginUpdate();
this.treeView.SelectedNode.Parent.Nodes.Insert(0, node);
this.treeView.SelectedNode.Parent.Nodes.RemoveAt(index + 1);
this.treeView.EndUpdate();
this.treeView.SelectedNode = node;
this.treeView.Select();
}
}
catch (Exception ex)
{
}
}
private void moveUpToolStripMenuItem_Click(object sender, EventArgs e)
{
TreeNode tv = new TreeNode();
TreeNode selectedNodeToMove = new TreeNode();
try
{
TreeNode parent= treeView.SelectedNode.Parent;
TreeNode node= this.treeView.SelectedNode.Clone() as TreeNode;
if (parent != null)
{
int index = -1;
for (int j = 0; j < parent.Nodes.Count; j++)
{
if (this.treeView.SelectedNode == parent.Nodes[j])
{
index = j;
break;
}
}
this.treeView_.BeginUpdate();
this.treeView.SelectedNode.Parent.Nodes.Insert(index - 1, node);
this.treeView.SelectedNode.Parent.Nodes.RemoveAt(index + 1);
this.treeView.EndUpdate();
this.treeView.SelectedNode = node;
this.treeView.Select();
}
catch (Exception ex)
{
}
}
private void moveDownToolStripMenuItem_Click(object sender, EventArgs e)
{
TreeNode tv = new TreeNode();
TreeNode selectedNodeToMove = new TreeNode();
try
{
TreeNode parent = treeView.SelectedNode.Parent;
TreeNode node = this.treeView.SelectedNode.Clone() as TreeNode;
selectedNodeToMove = treeView.SelectedNode;
if (parent != null)
{
int index = -1;
for (int j = 0; j < parent.Nodes.Count; j++)
{
if (this.treeView.SelectedNode == parent.Nodes[j])
{
index = j;
break;
}
}
this.treeView.BeginUpdate();
this.treeView.SelectedNode.Parent.Nodes.RemoveAt(index);
this.treeView.SelectedNode.Parent.Nodes.Insert(index + 1, node);
this.treeView.EndUpdate();
this.treeView.SelectedNode = node;
this.treeView.Select();
}
catch (Exception ex)
{
}
}
private void moveBottomToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
TreeNode parent = treeView.SelectedNode.Parent;
TreeNode node = this.treeView.SelectedNode.Clone() as TreeNode;
if (parent != null)
{
int index = -1;
for (int j = 0; j < parent.Nodes.Count; j++)
{
if (this.treeView.SelectedNode == parent.Nodes[j])
{
index = j;
break;
}
}
if (index != parent.Nodes.Count - 1)
{
this.treeView.BeginUpdate();
this.treeView.SelectedNode.Parent.Nodes.Insert(parent.Nodes.Count, node);
this.treeView.SelectedNode.Parent.Nodes.RemoveAt(index);
this.treeView.EndUpdate();
this.treeView.SelectedNode = node;
this.treeView.Select();
}
catch (Exception ex)
{
}
}

Related

Adding Object[] method to main()

I am trying to pass this method through my main() function but The loadMap already has the bufferreader so I am trying to use that rather than creating my own new buffer reader. How can I do this?
public static void main(String args[]) {
//throw exceptions here if args is empty
filename = args[0];
System.out.println(MapIO.loadMap(filename)[0]);
System.out.println(MapIO.loadMap(filename)[1]);
if (args.length < 1) {
System.err.println("Usage:\n" +"java CrawlGui mapname");
System.exit(1);
}
List<String> names=new LinkedList<String>();
try (BufferedReader reader = new BufferedReader(new FileReader(new
File(filename)))) {
String line;
while ((line = reader.readLine()) != null)
names.add(line);
System.out.println(names);
} catch (IOException e) {
e.printStackTrace();
}
MapIO.loadMap(filename);
launch(args);
}
/** Read information from a file created with saveMap
* #param filename Filename to read from
* #return null if unsucessful. If successful, an array of two Objects.
[0] being the Player object (if found) and
[1] being the start room.
* #detail. Do not add the player to the room they appear in, the caller
will be responsible for placing the player in the start room.
*/
public static Object[] loadMap(String filename) {
Player player = null;
try {
BufferedReader bf = new BufferedReader(
new FileReader(filename));
String line = bf.readLine();
int idcap = Integer.parseInt(line);
Room[] rooms = new Room[idcap];
for (int i = 0; i < idcap; ++i) {
line = bf.readLine();
if (line == null) {
return null;
}
rooms[i] = new Room(line);
}
for (int i = 0; i < idcap; ++i) { // for each room set up exits
line = bf.readLine();
int exitcount=Integer.parseInt(line);
for (int j=0; j < exitcount; ++j) {
line = bf.readLine();
if (line == null) {
return null;
}
int pos = line.indexOf(' ');
if (pos < 0) {
return null;
}
int target = Integer.parseInt(line.substring(0,pos));
String exname = line.substring(pos+1);
try {
rooms[i].addExit(exname, rooms[target]);
} catch (ExitExistsException e) {
return null;
} catch (NullRoomException e) {
return null;
}
}
}
for (int i = 0;i<idcap;++i) {
line = bf.readLine();
int itemcount = Integer.parseInt(line);
for (int j = 0; j < itemcount; ++j) {
line = bf.readLine();
if (line == null) {
return null;
}
Thing t = decodeThing(line, rooms[0]);
if (t == null) {
return null;
}
if (t instanceof Player) { // we don't add
player = (Player)t; // players to rooms
} else {
rooms[i].enter(t);
}
}
}
Object[] res = new Object[2];
res[0] = player;
res[1] = rooms[0];
return res;
} catch (IOException ex) {
return null;
} catch (IndexOutOfBoundsException ex) {
return null;
} catch (NumberFormatException nfe) {
return null;
}
}
You shouldn't do anything in main() other than call launch(). Move all the other startup code to your start() method. You can get the content of the args array using getParameters().getRaw():
#Override
public void start(Stage primaryStage) {
//throw exceptions here if args is empty
filename = getParameters().getRaw().get(0);
System.out.println(MapIO.loadMap(filename)[0]);
System.out.println(MapIO.loadMap(filename)[1]);
if (args.length < 1) {
System.err.println("Usage:\n" +"java CrawlGui mapname");
System.exit(1);
}
List<String> names=new LinkedList<String>();
try (BufferedReader reader = new BufferedReader(new FileReader(new
File(filename)))) {
String line;
while ((line = reader.readLine()) != null)
names.add(line);
System.out.println(names);
} catch (IOException e) {
e.printStackTrace();
}
Object[] whateverThisThingIs = MapIO.loadMap(filename);
// Now you have access to everything you need, at the point where you need it.
// existing start() code goes here...
}
public static void main(String args[]) {
launch(args);
}

Insertion Sort for Singly Linked List [EXTERNAL]

I'm not sure where to start, but this is messy. Basically I need to write an Insertion Sort method for singly linked list - which causes enough problems, because usually for Insertion Sort - you're supposed to go through array/list elements backwards - which implementing into a singly linked list seems pointless, because the point of it - is that you're only capable of going forwards in the list and in addition to that -> I need to execute "swap" operations externally, which I do not completely understand how to perform that while using list structure.
This is my ArrayClass and Swap method that I used:
class MyFileArray : DataArray
{
public MyFileArray(string filename, int n, int seed)
{
double[] data = new double[n];
length = n;
Random rand = new Random(seed);
for (int i = 0; i < length; i++)
{
data[i] = rand.NextDouble();
}
if (File.Exists(filename)) File.Delete(filename);
try
{
using (BinaryWriter writer = new BinaryWriter(File.Open(filename,
FileMode.Create)))
{
for (int j = 0; j < length; j++)
writer.Write(data[j]);
}
}
catch (IOException ex)
{
Console.WriteLine(ex.ToString());
}
}
public FileStream fs { get; set; }
public override double this[int index]
{
get
{
Byte[] data = new Byte[8];
fs.Seek(8 * index, SeekOrigin.Begin);
fs.Read(data, 0, 8);
double result = BitConverter.ToDouble(data, 0);
return result;
}
}
public override void Swap(int j, double a)
{
Byte[] data = new Byte[16];
BitConverter.GetBytes(a).CopyTo(data, 0);
fs.Seek(8 * (j + 1), SeekOrigin.Begin);
fs.Write(data, 0, 8);
}
}
And this is my Insertion Sort for array:
public static void InsertionSort(DataArray items)
{
double key;
int j;
for (int i = 1; i < items.Length; i++)
{
key = items[i];
j = i - 1;
while (j >= 0 && items[j] > key)
{
items.Swap(j, items[j]);
j = j - 1;
}
items.Swap(j, key);
}
}
Now I somehow have to do the same exact thing - however using Singly Linked List, I'm given this kind of class to work with (allowed to make changes):
class MyFileList : DataList
{
int prevNode;
int currentNode;
int nextNode;
public MyFileList(string filename, int n, int seed)
{
length = n;
Random rand = new Random(seed);
if (File.Exists(filename)) File.Delete(filename);
try
{
using (BinaryWriter writer = new BinaryWriter(File.Open(filename,
FileMode.Create)))
{
writer.Write(4);
for (int j = 0; j < length; j++)
{
writer.Write(rand.NextDouble());
writer.Write((j + 1) * 12 + 4);
}
}
}
catch (IOException ex)
{
Console.WriteLine(ex.ToString());
}
}
public FileStream fs { get; set; }
public override double Head()
{
Byte[] data = new Byte[12];
fs.Seek(0, SeekOrigin.Begin);
fs.Read(data, 0, 4);
currentNode = BitConverter.ToInt32(data, 0);
prevNode = -1;
fs.Seek(currentNode, SeekOrigin.Begin);
fs.Read(data, 0, 12);
double result = BitConverter.ToDouble(data, 0);
nextNode = BitConverter.ToInt32(data, 8);
return result;
}
public override double Next()
{
Byte[] data = new Byte[12];
fs.Seek(nextNode, SeekOrigin.Begin);
fs.Read(data, 0, 12);
prevNode = currentNode;
currentNode = nextNode;
double result = BitConverter.ToDouble(data, 0);
nextNode = BitConverter.ToInt32(data, 8);
return result;
}
To be completely honest - I'm not sure neither how I'm supposed to implement Insertion Sort nor How then translate it into an external sort. I've used this code for not external sorting previously:
public override void InsertionSort()
{
sorted = null;
MyLinkedListNode current = headNode;
while (current != null)
{
MyLinkedListNode next = current.nextNode;
sortedInsert(current);
current = next;
}
headNode = sorted;
}
void sortedInsert(MyLinkedListNode newnode)
{
if (sorted == null || sorted.data >= newnode.data)
{
newnode.nextNode = sorted;
sorted = newnode;
}
else
{
MyLinkedListNode current = sorted;
while (current.nextNode != null && current.nextNode.data < newnode.data)
{
current = current.nextNode;
}
newnode.nextNode = current.nextNode;
current.nextNode = newnode;
}
}
So if someone could maybe give some kind of tips/explanations - or maybe if you have ever tried this - code examples how to solve this kind of problem, would be appreciated!
I actually have solved this fairly recently.
Here's the code sample that you can play around with, it should work out of the box.
public class SortLinkedList {
public static class LinkListNode {
private Integer value;
LinkListNode nextNode;
public LinkListNode(Integer value, LinkListNode nextNode) {
this.value = value;
this.nextNode = nextNode;
}
public Integer getValue() {
return value;
}
public void setValue(Integer value) {
this.value = value;
}
public LinkListNode getNextNode() {
return nextNode;
}
public void setNextNode(LinkListNode nextNode) {
this.nextNode = nextNode;
}
#Override
public String toString() {
return this.value.toString();
}
}
public static void main(String...args) {
LinkListNode f = new LinkListNode(12, null);
LinkListNode e = new LinkListNode(11, f);
LinkListNode c = new LinkListNode(13, e);
LinkListNode b = new LinkListNode(1, c);
LinkListNode a = new LinkListNode(5, b);
print(sort(a));
}
public static void print(LinkListNode aList) {
LinkListNode iterator = aList;
while (iterator != null) {
System.out.println(iterator.getValue());
iterator = iterator.getNextNode();
}
}
public static LinkListNode sort(LinkListNode aList){
LinkListNode head = new LinkListNode(null, aList);
LinkListNode fringePtr = aList.getNextNode();
LinkListNode ptrBeforeFringe = aList;
LinkListNode findPtr;
LinkListNode prev;
while(fringePtr != null) {
Integer valueToInsert = fringePtr.getValue();
findPtr = head.getNextNode();
prev = head;
while(findPtr != fringePtr) {
System.out.println("fringe=" + fringePtr);
System.out.println(findPtr);
if (valueToInsert <= findPtr.getValue()) {
LinkListNode tmpNode = fringePtr.getNextNode();
fringePtr.setNextNode(findPtr);
prev.setNextNode(fringePtr);
ptrBeforeFringe.setNextNode(tmpNode);
fringePtr = ptrBeforeFringe;
break;
}
findPtr = findPtr.getNextNode();
prev = prev.getNextNode();
}
fringePtr = fringePtr.getNextNode();
if (ptrBeforeFringe.getNextNode() != fringePtr) {
ptrBeforeFringe = ptrBeforeFringe.getNextNode();
}
}
return head.getNextNode();
}
}
From a high level, what you are doing is you are keeping track of a fringe ptr, and you are inserting a node s.t. the it is in the correct spot in the corresponding sublist.
For instance, suppose I have this LL.
3->2->5->4
The first iteration, I have fringePtr at 2, and I want to insert 2 somewhere in the sublist that's before the fringe ptr, so I basically traverse starting from head going to the fringe ptr until the value is less than the current value. I also have a previous keeping track of the previous ptr (to account for null, I have a sentinel node at the start of my traversal so I can insert it at the head).
Then, when I see that it's less than the current, I know I need to insert it next to the previous, so I have to:
use a temporary ptr to keep track of my previous's current next.
bind previuos's next to my toInsert node.
bind my toInsert node's next to my temp node.
Then, to continue, you just advance your fringe ptr and try again, basically building up a sublist that is sorted as you move along until fringe hits the end.
i.e. the iterations will look like
1. 3->2->5->4
^
2. 2->3->5->4
^
3. 2->3->5->4
^
4. 2->3->4->5 FIN.

Red-Black Tree Deletion Partially Working

I implemented a red black tree in c++ with find, insert and delete. The delete only works for right side nodes and for the root node. I can't figure out why it isn't working for any of the left side nodes. Here is my code:
Node* searchNode(Node* root, int value){
Node* temp = root;
while (temp != NULL){
if (temp->val == value){
return temp;
}
else if (temp->val < value){
temp = temp->right;
}
else if (temp->val > value){
temp = temp->left;
}
}
}
Node* sibling(Node* node){
if ((node == NULL) || (node->parent == NULL)){
return NULL;
}
if (node == node->parent->left){
return node->parent->right;
}
else{
return node->parent->left;
}
}
Node* maxNode(Node* node){
while (node->right != NULL){
node = node->left;
}
return node;
}
void replaceNode(Node* old, Node* new_node){
if (old->parent == NULL){
old = new_node;
}
else{
if (old == old->parent->left){
old->parent->left = new_node;
}
else{
old->parent->right = new_node;
}
}
if (new_node != NULL){
new_node->parent = old->parent;
}
}
void deleteNode(Node* root, int value){
Node* child;
Node* temp = searchNode(root, value);
if (temp == NULL){
return;
}
if (temp->left != NULL&&temp->right != NULL){
Node* pred = maxNode(temp->right);
temp->val = pred->val;
temp = pred;
}
if (temp->left == NULL || temp->right == NULL){
if (temp->right == NULL && temp->left == NULL){
child = temp;
}
else if (temp->right == NULL){
child = temp->left;
}
else{
child = temp->right;
}
}
if (temp->color == 1){
temp->color = child->color;
delete_case1(root, child);
}
replaceNode(temp, child);
delete temp;
}
void delete_case6(Node* root, Node* n)
{
Node *s = sibling(n);
s->color = n->parent->color;
n->parent->color = 1;
if (n == n->parent->left) {
s->right->color = 1;
rotate_left(root, n->parent);
}
else {
s->left->color = 1;
rotate_right(root, n->parent);
}
}
void delete_case5(Node* root, Node* n)
{
Node *s = sibling(n);
if (s->color == 1) {
if ((n == n->parent->left) &&(s->right->color == 1) &&(s->left->color == 0)) {
s->color = 0;
s->left->color = 1;
rotate_right(root, s);
}else if ((n == n->parent->right) &&(s->left->color == 1) &&(s->right->color == 0)) {
s->color = 0;
s->right->color = 1;
rotate_left(root, s);
}
}
delete_case6(root, n);
}
void delete_case4(Node* root, Node* n)
{
Node *s = sibling(n);
if ((n->parent->color == 0) && (s->color == 1) && (s->left->color == 1) && (s->right->color == 1)) {
s->color = 0;
n->parent->color = 1;
}
else{
delete_case5(root, n);
}
}
void delete_case3(Node* root, Node* n){
Node* s = sibling(n);
if ((n->parent->color == 1) &&(s->color == 1) &&(s->left->color == 1) &&(s->right->color == 1)) {
s->color = 0;
delete_case1(root, n->parent);
}
else
delete_case4(root, n);
}
void delete_case2(Node* root, Node* n){
Node *s = sibling(n);
if (s->color == 0){
n->parent->color = 0;
s->color = 1;
if (n == n->parent->left){
rotate_left(root, n->parent);
}
else if (n == n->parent->right){
rotate_right(root, n->parent);
}
}
delete_case3(root, n);
}
void delete_case1(Node* root,Node* n){
if (n->parent != NULL){
delete_case2(root,n);
}
}
void main(){
ABTree* ABtree=new ABTree;
ABtree->root = NULL;
insertTree(ABtree->root, 15);
insertTree(ABtree->root, 8);
insertTree(ABtree->root, 2);
insertTree(ABtree->root, 9);
insertTree(ABtree->root, 10);
insertTree(ABtree->root, 12);
insertTree(ABtree->root, 18);
insertTree(ABtree->root, 25);
insertTree(ABtree->root, 20);
printTree(ABtree->root);
Node* search=searchNode(ABtree->root, 18);
cout << endl;
cout << search->val<<endl;
deleteNode(ABtree->root, 8);
printTree(ABtree->root);
}
For example if i want to delete either 8/9/2 the program crashes at delete_case4 at the if statement.
Thanks in advance!

Optimizations for Solitaire SPOJ

Problem Code: SOLIT
Problem Link: http://www.spoj.com/problems/SOLIT/
I tried solving the SPOJ problem Solitaire. However, I ended up with a TLE (Time Limit Exceeded). My current solution is taking around 2 seconds to execute. I have no idea how to optimize my solution further in order to reduce the time. So, I would be grateful for any help in this regard.
Link to my solution: https://ideone.com/eySI91
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
class Solitaire {
enum Direction {
TOP, RIGHT, DOWN, LEFT;
};
static class Piece {
int row, col;
public Piece(int row, int col) {
this.row = row;
this.col = col;
}
#Override
public boolean equals(Object o)
{
if (!(o instanceof Piece))
return false;
Piece p = (Piece)o;
return (row==p.row && col==p.col);
}
#Override
public int hashCode()
{
return (row*10 + col)%11;
}
}
static class State {
HashSet<Piece> pieces;
public State() {
pieces = new HashSet<>(11);
}
public State(State s) {
pieces = new HashSet<>(11);
for (Piece p: s.pieces)
pieces.add(new Piece(p.row, p.col));
}
#Override
public boolean equals(Object o) {
if (!(o instanceof State))
return false;
State s = (State) o;
if (pieces.size()!=s.pieces.size())
return false;
for (Piece p: pieces)
{
if (!s.pieces.contains(p))
return false;
}
return true;
}
#Override
public int hashCode() {
final int MOD = 1000000007;
long code = 0;
for (Piece p: pieces) {
code = (code + p.hashCode())%MOD;
}
return (int) code;
}
#Override
public String toString()
{
String res = "";
for (Piece p: pieces)
res = res + " (" + p.row + ", " + p.col + ")";
return res;
}
public int getCloseness(State s)
{
int medianRow=0, medianCol=0, sMedianRow=0, sMedianCol=0;
for (Piece p: pieces)
{
medianRow+=p.row;
medianCol+=p.col;
}
medianRow/=4;
medianCol/=4;
for (Piece p: s.pieces)
{
sMedianRow+=p.row;
sMedianCol+=p.col;
}
sMedianRow/=4;
sMedianCol/=4;
int closeness = ((sMedianCol-medianCol)*(sMedianCol-medianCol)) + ((sMedianRow-medianRow)*(sMedianRow-medianRow));
return closeness;
}
}
static State makeMove(State curr, Piece piece, Direction dir, HashSet<State> visited) {
if (dir == Direction.TOP) {
if (piece.row==1)
return null;
if (curr.pieces.contains(new Piece(piece.row-1, piece.col)))
{
if (piece.row==2 || curr.pieces.contains(new Piece(piece.row-2, piece.col)))
return null;
else
{
State newState = new State(curr);
newState.pieces.remove(new Piece(piece.row, piece.col));
newState.pieces.add(new Piece(piece.row-2, piece.col));
if (visited.contains(newState))
return null;
else
return newState;
}
}
else
{
State newState = new State(curr);
newState.pieces.remove(new Piece(piece.row, piece.col));
newState.pieces.add(new Piece(piece.row-1, piece.col));
if (visited.contains(newState))
return null;
else
return newState;
}
}
else if (dir == Direction.RIGHT) {
if (piece.col==8)
return null;
if (curr.pieces.contains(new Piece(piece.row, piece.col+1)))
{
if (piece.col==7 || curr.pieces.contains(new Piece(piece.row, piece.col+2)))
return null;
else
{
State newState = new State(curr);
newState.pieces.remove(new Piece(piece.row, piece.col));
newState.pieces.add(new Piece(piece.row, piece.col+2));
if (visited.contains(newState))
return null;
else
return newState;
}
}
else
{
State newState = new State(curr);
newState.pieces.remove(new Piece(piece.row, piece.col));
newState.pieces.add(new Piece(piece.row, piece.col+1));
if (visited.contains(newState))
return null;
else
return newState;
}
}
else if (dir == Direction.DOWN) {
if (piece.row==8)
return null;
if (curr.pieces.contains(new Piece(piece.row+1, piece.col)))
{
if (piece.row==7 || curr.pieces.contains(new Piece(piece.row+2, piece.col)))
return null;
else
{
State newState = new State(curr);
newState.pieces.remove(new Piece(piece.row, piece.col));
newState.pieces.add(new Piece(piece.row+2, piece.col));
if (visited.contains(newState))
return null;
else
return newState;
}
}
else
{
State newState = new State(curr);
newState.pieces.remove(new Piece(piece.row, piece.col));
newState.pieces.add(new Piece(piece.row+1, piece.col));
if (visited.contains(newState))
return null;
else
return newState;
}
}
else // dir == Direction.LEFT
{
if (piece.col==1)
return null;
if (curr.pieces.contains(new Piece(piece.row, piece.col-1)))
{
if(piece.col==2 || curr.pieces.contains(new Piece(piece.row, piece.col-2)))
return null;
else
{
State newState = new State(curr);
newState.pieces.remove(new Piece(piece.row, piece.col));
newState.pieces.add(new Piece(piece.row, piece.col-2));
if (visited.contains(newState))
return null;
else
return newState;
}
}
else
{
State newState = new State(curr);
newState.pieces.remove(new Piece(piece.row, piece.col));
newState.pieces.add(new Piece(piece.row, piece.col-1));
if (visited.contains(newState))
return null;
else
return newState;
}
}
}
static boolean isReachableInEightMoves(State src, State target) {
Queue<State> q = new LinkedList<>();
HashSet<State> visited = new HashSet<>();
int closeness = src.getCloseness(target);
q.add(src);
int moves = 0;
while (!q.isEmpty() && moves <= 8) {
int levelNodes = q.size();
for (int i = 0; i < levelNodes; i++) {
State curr = q.remove();
if (curr.equals(target))
return true;
if (moves==8)
continue;
visited.add(curr);
for (Piece p: curr.pieces)
{
State newState = makeMove(curr, p, Direction.TOP, visited);
if (newState!=null)
{
int newCloseness = newState.getCloseness(target);
if (closeness>=newCloseness)
{
closeness=newCloseness;
visited.add(newState);
q.add(newState);
}
}
newState = makeMove(curr, p, Direction.RIGHT, visited);
if (newState!=null)
{
int newCloseness = newState.getCloseness(target);
if (closeness>=newCloseness)
{
closeness=newCloseness;
visited.add(newState);
q.add(newState);
}
}
newState = makeMove(curr, p, Direction.DOWN, visited);
if (newState!=null)
{
int newCloseness = newState.getCloseness(target);
if (closeness>=newCloseness)
{
closeness=newCloseness;
visited.add(newState);
q.add(newState);
}
}
newState = makeMove(curr, p, Direction.LEFT, visited);
if (newState!=null)
{
int newCloseness = newState.getCloseness(target);
if (closeness>=newCloseness)
{
closeness=newCloseness;
visited.add(newState);
q.add(newState);
}
}
}
}
moves++;
}
return false;
}
public static void main(String[] args) throws IOException {
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(FileDescriptor.out), "ASCII"));
CustomScanner sc = new CustomScanner();
int t = sc.nextInt();
long start = System.currentTimeMillis();
while (t-- > 0) {
State src = new State(), target = new State();
for (int i = 0; i < 4; i++) {
src.pieces.add(new Piece(sc.nextInt(), sc.nextInt()));
}
for (int i = 0; i < 4; i++) {
target.pieces.add(new Piece(sc.nextInt(), sc.nextInt()));
}
if (isReachableInEightMoves(src, target))
out.write("YES");
else
out.write("NO");
out.newLine();
}
long end = System.currentTimeMillis();
out.write("Time to execute = " + Double.toString((end-start)/1000d));
out.flush();
}
static class CustomScanner {
BufferedReader br;
StringTokenizer st;
public CustomScanner() {
br = new BufferedReader(new InputStreamReader(System.in));
}
private String next() {
while (st == null || !st.hasMoreElements()) {
try {
st = new StringTokenizer(br.readLine());
} catch (IOException e) {
e.printStackTrace();
}
}
return st.nextToken();
}
public int nextInt() {
return Integer.parseInt(next());
}
public long nextLong() {
return Long.parseLong(next());
}
public double nextDouble() {
return Double.parseDouble(next());
}
public String nextLine() {
String str = "";
try {
str = br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return str;
}
}
}
Some notes regarding the implementation:-
I am just doing a simple bfs traversal where each node is a state of
the board.
I have defined a function called getCloseness() which measures the closeness of two different states. It is basically the square of the distance between the centroids of the two states. A centroid of a state is the sum of all row values of each piece divided by 4 and the same for columns.
After calculating each state, I am checking if the closeness of this new state is lesser than or equal to the current closeness.
If it is not closer, then I will simply discard the new discovered state.
If it is closer, then I will update the closeness value and insert this new state into the Queue for future processing.
This process terminates when either the queue becomes empty or a state is discovered which is same as the target state.
The above approach takes approximately 1-3 seconds for cases where a minimum of 7 moves are required. I would be grateful if you can tell me how I can further optimize this solution.
The expected time according to the problem is 0.896s.

Tree Postorder Traversal performance

I tried to work on my own to get iterative postorder traversal. My solution got Time Limited Exceeded in Leetcode Online Judge
public List<Integer> postorderTraversalIterativel(TreeNode root) {
List<Integer> ret = new LinkedList<Integer>();
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode cur = root;
while (cur != null || !stack.isEmpty()) {
if (cur != null) {
stack.push(cur);
cur = cur.left;
} else {
TreeNode parent = stack.peek(), child = null;
if (parent.right == null) {
// pop hard
stack.pop();
while (parent.right == child && !stack.isEmpty()) {
child = parent;
ret.add(child.val);
parent = stack.pop();
}
} else {
cur = parent.right;
}
}
}
return ret;
}
while the official implementation from wikipedia could pass the test.
public List<Integer> postorderTraversalIterativel(TreeNode root) {
List<Integer> ret = new LinkedList<Integer>();
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode cur = root, lastVisited = null;
while (cur != null || !stack.isEmpty()) {
if (cur != null) {
stack.push(cur);
cur = cur.left;
} else {
TreeNode parent = stack.peek();
if (parent.right != null && lastVisited != parent.right) {
// make sure pop all the node has right child of the
// previous pop
cur = parent.right;
} else {
stack.pop();
ret.add(parent.val);
lastVisited = parent;
}
}
}
return ret;
}
by inspecting the code, I am unable to see why my implementation is slower than the official one. Could anyone point out what's happening? (It's possible that my solution is logically wrong, but the one failed my solution in timing I have unit tested, and the unit test finishes quick ...). Any comments are welcome.
public void testPostorderTraversal1() {
TreeNode root = new TreeNode(3);
TreeNode right = new TreeNode(1);
TreeNode rightLeft = new TreeNode(2);
root.right = right;
right.left = rightLeft;
List<Integer> list = new LinkedList<Integer>();
list.add(2);
list.add(1);
list.add(3);
assertEquals(list.toString(), sut.postorderTraversal(root).toString());
}
public void testPostorderTraversal2() {
TreeNode root = new TreeNode(1);
TreeNode right = new TreeNode(2);
root.right = right;
List<Integer> list = new LinkedList<Integer>();
list.add(2);
list.add(1);
assertEquals(list.toString(), sut.postorderTraversal(root).toString());
}
Your code has possible to do Infinite loop.
Your 'testPostorderTraversal1' unitest is not finish.
If there is any node that has right child node that has left child node, can't finish.

Resources