// Arup Guha
// 8/27/2026
// Sample Code Illustrating TreeSet, TreeMap and Custom Sorting

import java.util.*;

public class TestDS {

	public static void main(String[] args) {
		
		/*** Call whatever you want here. ***/
		
		//testTreeSet();
		//getVotes();
		//testCustomSort();
		testCatMap();
	}
	
	// Shows some TreeSet functionality.
	public static void testTreeSet() {
	
		// For testing.
		Random r = new Random();
		
		// Create the object.
		TreeSet<Integer> ts = new TreeSet<Integer>();
		
		// Add 20 things.
		for (int i=0; i<20; i++) {
			
			// Add something and print it.
			int x = r.nextInt(100);
			System.out.println("Adding "+x);
			ts.add(x);
			
			// Get these.
			Integer before = ts.lower(x);
			Integer after = ts.higher(x);
			
			// Printing if something exists before x in the set.
			if (before != null) 
				System.out.println("Immediately preceding "+x+" is "+before);
				
			// Same for after.
			if (after != null)
				System.out.println("Immediately succeeding "+x+" is "+after);
		}
		
		System.out.println("\n");
		
		// Pulls objects out in reverse order.
		ArrayList<Integer> res = new ArrayList<Integer>();
		while (ts.size() > 0)
			res.add(ts.pollLast());
		
		// Prints to prove...
		for (Integer x: res)
			System.out.print(x+" ");
		System.out.println();
	
	}
	
	// Example to illustrate TreeMap use.
	public static void getVotes() {
		
		// Read in number of votes.
		Scanner stdin = new Scanner(System.in);
		int numVotes = stdin.nextInt();
		
		// Create the map.
		TreeMap<String,Integer> map = new TreeMap<String,Integer>();
		
		// Go through votes.
		for (int i=0; i<numVotes; i++) {
			
			// Get a vote.
			String name = stdin.next();
			
			// Add a new entry with no votes.
			if (!map.containsKey(name))
				map.put(name, 0);
			
			// Add a vote for name.
			map.put(name, map.get(name)+1);
		}
		
		// Will print sorted by name (lexicographical order).
		for (String name: map.keySet())
			System.out.println(name+"\t"+map.get(name));
	}
	
	// Example of a TreeMap using a user built object as the key.
	public static void testCatMap() {
		
		// Cats will be mapped to their owners.
		TreeMap<Cat,String> ownerList = new TreeMap<Cat,String>();
		
		Scanner stdin = new Scanner(System.in);
		
		// Read in and add 5 cats to both data structures.
		for (int i=0; i<5; i++) {
			
			// Get Cat info, make Cat object.
			System.out.println("Enter name, cuteness and color.");
			String name = stdin.next();
			int cute = stdin.nextInt();
			String color = stdin.next();
			Cat tmp = new Cat(name, cute, color);
			
			// Get owner and add mapping.
			System.out.println("Who is the proud owner of this cat?");
			String owner = stdin.next();
			ownerList.put(tmp, owner);
		}
		
		// This will be sorted by the order we defined for Cats =)
		for (Cat c: ownerList.keySet())
			System.out.println(ownerList.get(c)+" owns "+c);
	}
	
	// Just tests custom sorting with Arrays and Collections.
	public static void testCustomSort() {
		
		// Create both an array and a list.
		Cat[] catArray = new Cat[5];
		ArrayList<Cat> catList = new ArrayList<Cat>();
		Scanner stdin = new Scanner(System.in);
		
		// Read in and add 5 cats to both data structures.
		for (int i=0; i<5; i++) {
			System.out.println("Enter name, cuteness and color.");
			String name = stdin.next();
			int cute = stdin.nextInt();
			String color = stdin.next();
			Cat tmp = new Cat(name, cute, color);
			catArray[i] = tmp;
			catList.add(tmp);
		}
		
		// Print original order of cats.
		for (int i=0; i<catArray.length; i++)
			System.out.println(catArray[i]);
		System.out.println();
		
		// Sort array.
		Arrays.sort(catArray);
		
		// Print sorted array.
		for (int i=0; i<catArray.length; i++)
			System.out.println(catArray[i]);
		System.out.println();
		
		// Print original order of cats in list.
		for (Cat c: catList)
			System.out.println(c);
		System.out.println();
		
		// Sort it.
		Collections.sort(catList);
		
		// Print sorted list.
		for (Cat c: catList)
			System.out.println(c);
		System.out.println();
	}

}

// Cat class...we implement Comparable<Cat> so we can put the Cat in an ordered
// data structure.
class Cat implements Comparable<Cat> {
	
	private String name;
	private int cuteness;
	private String furColor;
	
	// I never used this.
	public Cat() {
		name = "Felix";
		cuteness = 5;
		furColor = "brown";
	}
	
	// Standard constructor.
	public Cat(String n, int cute, String color) {
		name = n;
		cuteness = cute;
		furColor = color;
	}
	
	// We sort by cuteness high to low, then by name.
	public int compareTo(Cat other) {
		if (this.cuteness != other.cuteness)
			return other.cuteness - this.cuteness;
		return name.compareTo(other.name);
	}
	
	public String toString() {
		return name+" cuteness factor: "+cuteness+" fur color: "+furColor;
	}
}