Thursday, 11 February 2016

Reverse Double Linked List, Promote Node based on add/get(similar to LinkedHashMap)



public static void demoMyLinkedHashMap() {
SimpleLinkedList map = new SimpleLinkedList<>();
map.add(1);
map.add(2);
map.add(3);
map.add(4);
map.printAll();
map.print(1);
map.print(4);
map.print(9);
map.add(5);
map.printAll();
map.print(5);
map.insert(0, 1);
map.printAll();
map.print(5);
map.insert(0, 1);
map.insert(6, 6);
map.printAll();
map.print_last();
map.reverse();
map.printAll();
map.print_last();
map.reverse();
map.printAll();
map.print_last();
map.add(7);
map.printAll();
map.print_last();
}

package exercises;

public class SimpleLinkedList {
private class Node {
private T data = null;
private Node prev = null;
private Node next = null;

public Node(T data) {
this.setData(data);
this.setPrev(null);
this.setNext(null);
}

public T getData() {
return data;
}

public void setData(T data) {
this.data = data;
}

public Node getPrev() {
return prev;
}

public void setPrev(Node prev) {
this.prev = prev;
}

public Node getNext() {
return next;
}

public void setNext(Node next) {
this.next = next;
}
}

private Node root;
private Node current;

public void add(T data) {
if(this.root == null) {
this.root = new Node(data);
this.current = this.root;

return;
} else {
Node node = new Node(data);

node.setPrev(current);
current.setNext(node);
current = node;
}
}

/**
* ignore, will not promote node
* @param data
* @param position
*/
public void insert(T data, int position) {
Node pointer = this.getNode(position, false);

if(pointer == null || pointer.getData().equals(data)) {
System.out.println("Same data, Ignore");
return;
}

Node newNode = new Node(data);
newNode.setNext(pointer);
newNode.setPrev(pointer.getPrev());
pointer.setPrev(newNode);

if(newNode.getPrev() != null) {
newNode.getPrev().setNext(newNode);
} else {
root = newNode;
}
}

public T get(int position) {
Node pointer = this.getNode(position, true);

return (pointer == null) ? null : pointer.getData();
}

public void printAll() {
if(this.root == null) return;

for(Node pointer = root; pointer != null; pointer = pointer.getNext()) {
System.out.print(pointer.getData().toString());

if(pointer.getNext() != null) System.out.print("->");
else System.out.print("\n");
}
}

public void print(int position) {
if(this.root == null) return;

T pointer = this.get(position);
if(pointer == null) return;

System.out.println("Item at position : " + position + " is " + pointer.toString());
}

public void print_last() {
System.out.println("Last item is : " + current.getData().toString());
}

/**
* reverse relies on single recursion. method returns processed node
* Recursively traverse to end to make it 'root'. return r'oot'
* current next is its prev. its prev is returned processed node. return current
*/
public void reverse() {
if(this.root == this.current) return;

current = this.reverse(root);
}

private Node reverse(Node current) {
if(current.getNext() == null) {
root = current;
root.setNext(root.getPrev()); //Root next, should be its previous.
root.setPrev(null); //Root node previous should be null

return current;
}

Node prev = reverse(current.getNext()); //prev, last visited node

current.setNext(current.getPrev()); //curent.next should be its prev node
current.setPrev(prev); //current.prev should be last visited node

return current;
}

private void promote(Node accessed) {
if(accessed == null || accessed == current) return;

if(accessed.getPrev() != null) {
accessed.getPrev().setNext(accessed.getNext()); //previous node should point accessed's next
accessed.getNext().setPrev(accessed.getPrev());
} else {
root = accessed.getNext(); // accessed.prev is null only if its root node, so new root is accessed's next
root.setPrev(null); //root prev is always null;
}

current.setNext(accessed);
accessed.setPrev(current);
accessed.setNext(null);
current = accessed;
}

/**
* 1. Return NULL, If the root is null or position is invalid
* 2. While index < position && pointer != null
* move to pointer.next
* increment index
* @param position
* @param promote - to promote the node to front
* @return
*/
private Node getNode(int position, boolean promote) {
if(position <= 0) return null;

int index = 1;
Node pointer = root;

while(index < position && pointer != null) {
pointer = pointer.getNext();
index++;
}

if(promote && pointer != null) promote(pointer);

return pointer;
}
}


Friday, 24 July 2015

Blocking queue using 'synchronized' block

public class MyBlockingQueue_Sync {
private Queue items = new LinkedList<>();
private Object lock = new Object();
public void put(String item) {
synchronized(lock) {
System.out.println("Writing");
this.items.add(item);
this.lock.notify();
System.out.println("Written");
}
}
public String get() {
synchronized(lock) {
System.out.println("Reading");
if(this.items.size() == 0) {
this.waitforput();
}
String item = this.items.poll();
System.out.println("Read");
return item;
}
}
void waitforput() {
try {
this.lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

}

My Blocking Queue using Lock interface

import java.util.*;
import java.util.concurrent.locks.*;

public class MyBlockingQueue {
private Queue items = new LinkedList<>();
private Lock lock = new ReentrantLock();
public void put(String item) {
try {
this.lock.lock();
System.out.println("Writing");
this.items.add(item);
}
finally {
this.lock.unlock();
System.out.println("Written");
}
}
public String get() {
try {
System.out.println("Reading");
this.tryLock();
return this.items.poll();
}
finally {
this.lock.unlock();
System.out.println("Read");
}
}
void tryLock() {
while(true) {
this.lock.lock();
if(this.items.size() == 0) {
this.lock.unlock();
sleep();
} else {
return;
}
}
}

private void sleep() {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
System.out.println("Interrupted");
}
}

}

Thursday, 23 April 2015

Lambda

@FunctionalInterface
interface SimpleCalculation{
double calculate(double arg);
}

class MyMath{
public double sin(double x){
return Math.sin(x);
}
}

public class Main {

public static void main(String[] args) {
SimpleCalculation fn = (double x) -> Math.sin(x);
MyMath mm = new MyMath();
System.out.println(something(fn, 10));
System.out.println(something((X) -> Math.sin(X), 10));
System.out.println(something(x -> Math.sin(x), 10)); // if only one parameter, no need for ()
System.out.println(something(Math::sin, 10)); //Method reference, if static ClassName::MethodName
System.out.println(something(mm::sin, 10)); //if instance method, instance::MethodName
}
static double something(SimpleCalculation cal, double value){
return cal.calculate(value);
}

}

Wednesday, 21 January 2015

Custom DispatchQueue with a Worker thread

public class DispatchQueue
    {
        Queue<Action> queue = new Queue<Action> ();
        static object key = new object ();
        SingleThreadDispatcher dispatcher;

        public DispatchQueue(SingleThreadDispatcher dispatcher) {
            this.dispatcher = dispatcher;
        }

        public void QueueWork(Action work){
            lock (key) {
                queue.Enqueue (work);
            }

            if (this.dispatcher.Executed) {
                this.dispatcher.Dispatch (this.Dequeue (), SynchronizationContext.Current, this.Callback);
            }
        }

        private Action Dequeue(){
            lock (key) {
                if (queue.Count <= 0) {
                    return null;
                }

                return queue.Dequeue ();
            }
        }

        private void Callback(object state) {
            var work = this.Dequeue ();

            if (work == null) return;

            this.dispatcher.Dispatch (work, SynchronizationContext.Current, this.Callback);
        }
    }


public class SingleThreadDispatcher
    {
        Task task = null;

        public void Dispatch(Action work, SynchronizationContext context, Action<object> callback) {
            if (work == null || context == null || callback == null || !this.Executed) {
                return;
            }

            Action safeWork = () => this.Execute (work);
            this.task = new Task (safeWork);
            this.task.ContinueWith ((result) => {
                context.Post(new SendOrPostCallback(callback), null);
            });

            this.task.Start ();
        }

        public bool Executed {
            get{
                return (task == null) || (task != null && task.IsCompleted);
            }
        }

        private void Execute(Action work)
        {
            try {
                work();
            }
            catch(Exception e) {
                //
            }
        }
    }

Tuesday, 30 September 2014

DFS

public class Node
    {
        public int Id { get; set; }

        public String Name { get; set; }

        public String Parent { get; set; }

        [JsonIgnore]
        public bool Visited { get; set; }

        [JsonIgnore]
        public List Children { get; set; }
    }

   public static class TreeManager
    {
        static Node tree = null;

        static TreeManager()
        {
            tree = new Node();
        }

        public static Node Get()
        {
            return tree;
        }
    }

    public static class TestData
    {
        static int id = 1;

        public static Node Initialise()
        {
            var root = TreeManager.Get();

            root.Id = Identifier;
            root.Name = "Root";

            root.Children = CreateDepartment();

            CreateChildren(root.Children, "aisle");
            CreateChildren(root.Children.SelectMany(c => c.Children).ToList(), "shelve");
            //CreateChildren(root.Children.SelectMany(c => c.Children).SelectMany(c => c.Children).ToList(), "sub_shelve");

            return root;
        }

        private static int Identifier
        {
            get
            {
                return id++;
            }
        }

        private static List CreateDepartment()
        {
            string[] departments = new string[]
                        {
                            "Fresh Food", "Level 1 Mos Test", "Food cupboard test",
                            "Frozen food", "Drinks", "Drugstore", "Baby", "Pets", "Home and entertainment"
                        };

            return Create(departments);
        }

        private static void CreateChildren(List nodes, string childName)
        {
            Random seeder = new Random(1);

            foreach (var node in nodes)
            {
                int looper = seeder.Next(1, 10);
                List names = new List();

                while ((looper--) > 0)
                {
                    names.Add(node.Name + "-" + childName + looper.ToString());
                }

                node.Children = new List();

                node.Children.AddRange(Create(names.ToArray()));
            }
        }

        private static List Create(string[] names)
        {
            List nodes = new List();

            foreach (var name in names)
            {
                nodes.Add(new Node { Id = Identifier, Name = name });
            }

            return nodes;
        }
    }

    //http://www.codeproject.com/Articles/32212/Introduction-to-Graph-with-Breadth-First-Search-BF
    //http://stackoverflow.com/questions/687731/breadth-first-vs-depth-first

    public static class DFSTraverse
    {
        static List orderedNodes = new List();

        public static void Traverse(Node tree)
        {
            orderedNodes.Clear();

            Stack stack = new Stack();

            tree.Visited = true;
            Push(stack, tree);
            Print(stack.Peek());

            while (!stack.IsEmpty())
            {
                Node node = GetChildNode(stack.Peek());

                if (node == null) stack.Pop();
                else
                {
                    node.Visited = true;
                    Push(stack, node, stack.Peek().Name);
                    Print(stack.Peek());
                }
            }
        }

        public static string OrderedList()
        {
            return JsonConvert.SerializeObject(orderedNodes);
        }

        public static Node RebuildHierarchy(Stack stack)
        {
            Node root = stack.Peek();

            BuildHierarchy(stack, stack.Pop());

            return root;
        }
       
        private static void BuildHierarchy(Stack stack, Node parent)
        {
            if (parent == null) return;

            Node addedNode = null;

            while (!stack.IsEmpty())
            {
                if (stack.Peek().Parent.Equals(parent.Name))
                {
                    if (parent.Children == null) parent.Children = new List();

                    addedNode = stack.Pop();
                    parent.Children.Add(addedNode);
                }
                else if (stack.Peek().Parent.Equals(addedNode.Name)) BuildHierarchy(stack, addedNode);
                else return;
            }
        }

        private static void AddToOrderedList(Node node)
        {
            orderedNodes.Add(node);
        }

        private static void Push(Stack stack, Node node, string parent = null)
        {
            stack.Push(node);

            node.Parent = parent;
            AddToOrderedList(node);
        }

        private static Node GetChildNode(Node node)
        {
            if (!node.Visited) return node;
            if (node.Children == null) return null;

            return node.Children.FirstOrDefault(n => n.Visited == false);
        }

        private static void Print(Node node)
        {
            Console.WriteLine(node.Id + ":" + node.Name);
        }

        private static bool IsEmpty(this Stack stack)
        {
            return stack.Count <= 0;
        }
    }

   class Program
    {
        const string file = "Naviagtion.txt";

        static void DemoDFSTraverse(Node root)
        {
            DFSTraverse.Traverse(root);

            if (File.Exists(file)) File.Delete(file);
           
            File.WriteAllText(file, DFSTraverse.OrderedList());
        }

        static Node RebuildHierarchy()
        {
            var result = JsonConvert.DeserializeObject(File.ReadAllText(file));

            Stack node = new Stack(result.Reverse());

            return DFSTraverse.RebuildHierarchy(node);
        }

        static bool AreEquals(Node node1, Node node2)
        {
            if (node1.Id == node2.Id && node1.Name.Equals(node2.Name))
            {
                int item = 0;

                if (node1.Children == null && node2.Children == null) return true;

                foreach (var node in node1.Children)
                {
                    var otherNode1 = node1.Children[item];
                    var otherNode2 = node2.Children[item];

                    item++;

                    return AreEquals(otherNode1, otherNode2);
                }
            }

            return false;
        }

        static void Main(string[] args)
        {
            Node originalNode = TestData.Initialise();

            DemoDFSTraverse(originalNode);
            Node rebuilededNode = RebuildHierarchy();

            Console.WriteLine(AreEquals(originalNode, rebuilededNode));
           
            Console.Clear();
            DemoDFSTraverse(rebuilededNode);

            Console.ReadLine();
        }


Monday, 1 September 2014

Json.Net - Sample functions

Just for my reference

namespace MyJsonExample
{
    public class Movies
    {
        public Movie[] All { get; set; }
    }
    public class Movie
    {
        public String Name { get; set; }
        public DateTime ReleasedOn { get; set; }
        [JsonIgnore]
        public String Director { get; set; }
        public MovieRating Rating { get; set; }
    }
    public enum MovieRating
    {
        R,
        U,
        PG
    }
    public static class Demo
    {
        public static string Serialize()
        {
            Movie m = new Movie { Director = "Suresh", Name = "First Movie", ReleasedOn = DateTime.Now, Rating = MovieRating.PG };
            return JsonConvert.SerializeObject(m);
        }
        public static string SerializeArray()
        {
            Movie m1 = new Movie { Director = "Suresh", Name = "First Movie1", ReleasedOn = DateTime.Now, Rating = MovieRating.PG };
            Movie m2 = new Movie { Director = "Suresh", Name = "First Movie2", ReleasedOn = DateTime.Now, Rating = MovieRating.R };
            Movie[] movies = new Movie[] { m1, m2 };
            Movies ms = new Movies { All = movies };
            return JsonConvert.SerializeObject(ms);
        }
        public static void Deserialize(string m)
        {
            var movie = JsonConvert.DeserializeObject(m);
            movie.ToString();
        }
        public static void ParseMovie(string m)
        {
            var movie = JObject.Parse(m);
            var name = movie["Name"];
        }
        public static void ParseMovies(string m)
        {
            var movies = JObject.Parse(m);
            var all = movies["All"];
            var name = all[0]["Name"];
            name = all[1]["Name"];
        }
        public static void ParseMoviesUsingLinq(string m)
        {
            var movies = JObject.Parse(m);
            var all = movies["All"];
            var movienames = (from movie in all
                              select (string)movie["Name"]).ToList();
            var movienames2 = (from movie in movies["All"]
                              select new { N = (string)movie["Name"], R = movie["Rating"]});
            foreach (var moviename in movienames)
            {
                Console.WriteLine(moviename);
            }
            foreach (var moviename in movienames2)
            {
                Console.WriteLine(moviename.N + ":" + moviename.R);
            }
        }
        public static string SerializeEnum()
        {
            Movie m1 = new Movie { Director = "Suresh", Name = "First Movie1", ReleasedOn = DateTime.Now, Rating = MovieRating.PG };
            return JsonConvert.SerializeObject(m1, new Newtonsoft.Json.Converters.StringEnumConverter());
        }
    }
}