jamesjlinden
11/6/2014 - 10:22 PM

login_logout_server

login_logout_server

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.Iterator;

/**
 * Skeleton for Interview Street coding challenge
 */
public class Solution {

	public static void PrintList(List<LoginEvent> events) {
		for (Iterator<LoginEvent> i = events.iterator();
			i.hasNext(); ) {
			LoginEvent currEvent = i.next();
			System.out.println(currEvent.getType() + " " 
				+ currEvent.getTimestamp());
		}
	}

	public static int computeMaxConcurrentLogins(List<LoginEvent> events) {
		int concurrentLogins = 0;
		int maxConcurrentLogins = 0;

		/* Deep copy list to cull processed events */
		ArrayList<LoginEvent> eventListCopy = new ArrayList<LoginEvent>(events);

		while (eventListCopy.size() > 0) {
			LoginEvent soonestEvent = null;
			/* Find the soonest event */
			for (Iterator<LoginEvent> currEventIter = eventListCopy.iterator();
				currEventIter.hasNext(); ) {
				LoginEvent currEvent = currEventIter.next();

				if (soonestEvent == null) {
					soonestEvent = currEvent;
				}

				/* Process the event with the soonest timestamp first,
				 * if they are equivalent, process LOGOUT events first
				 */
				if (currEvent.getTimestamp() < soonestEvent.getTimestamp()) {
					soonestEvent = currEvent;
				} else if (currEvent.getTimestamp() 
					== soonestEvent.getTimestamp()) {
					if (currEvent.getType() == LoginType.LOGOUT) {
						soonestEvent = currEvent;
					}
				}
			}

			System.out.println(soonestEvent.getType() + " " 
				+ soonestEvent.getTimestamp());
			/* Inc/dec concurrentLogins based on event type */
			if (soonestEvent != null) {
				if (soonestEvent.getType() == LoginType.LOGIN) {
					++concurrentLogins;
				} else if (soonestEvent.getType() == LoginType.LOGOUT) {
					--concurrentLogins;
				}

				/* Remove processed event from copied collection */
				Iterator<LoginEvent> currEventIter = null;
				for (currEventIter = eventListCopy.iterator();
					currEventIter.hasNext(); ) {
					LoginEvent currEvent = currEventIter.next();
					if (currEvent == soonestEvent) {
						break;
					}
				}
				if (currEventIter != null) { 
					currEventIter.remove();
				}
			}

			/* Track max concurrent logins */
			if (concurrentLogins > maxConcurrentLogins) {
				maxConcurrentLogins = concurrentLogins;
			}
		}

		return maxConcurrentLogins;
	}

	public enum LoginType {LOGIN, LOGOUT};

	public static class LoginEvent {
		private final LoginType type;
		private final long timestamp;

		public LoginEvent(LoginType type, long timestamp) {
			this.type = type;
			this.timestamp = timestamp;
		}

		public LoginType getType() {
			return type;
		}

		public long getTimestamp() {
			return timestamp;
		}
	}

	public static void main(String [] args) throws IOException {
		/* List<LoginEvent> loginEvents = readEvents(System.in); */
		List<LoginEvent> loginEvents = new ArrayList<LoginEvent>();
		loginEvents.add(new LoginEvent(LoginType.LOGIN, 0));
		loginEvents.add(new LoginEvent(LoginType.LOGIN, 60));
		loginEvents.add(new LoginEvent(LoginType.LOGIN, 30));
		loginEvents.add(new LoginEvent(LoginType.LOGOUT, 90));
		loginEvents.add(new LoginEvent(LoginType.LOGOUT, 60));
		loginEvents.add(new LoginEvent(LoginType.LOGOUT, 120));

		System.out.println(computeMaxConcurrentLogins(loginEvents));
	}

	public static List<LoginEvent> readEvents(InputStream in) throws IOException {
		Scanner scanner = new Scanner(in);
		List<LoginEvent> loginEvents = new ArrayList<LoginEvent>();
		while (scanner.hasNext()) {
			LoginType login = Enum.valueOf(LoginType.class, scanner.next());
			long timestamp = scanner.nextLong();
			loginEvents.add(new LoginEvent(login, timestamp));
		}
		return loginEvents;
	}
}