using System.Collections.Generic;
public static void Main()
var zipcodes = new List<int>{ 90012,
var zipHashSet = new HashSet<int>();
var nodeDictionary = new Dictionary<int, DoublyLinkedListNode<int>>();
var zipLinkedList = new DoublyLinkedList<int>();
foreach (int zipcode in zipcodes) {
zipLinkedList.Add(zipcode);
nodeDictionary[zipcode] = zipLinkedList.Last;
var groupings = new HashSet<string>();
var node = zipLinkedList.First;
var bottomZipCode = node.Element;
var topZipCode = bottomZipCode;
while (zipHashSet.Contains(bottomZipCode-1)) {
var nodeToDel = nodeDictionary[bottomZipCode-1];
if (nodeToDel.Previous != null) {
nodeToDel.Previous.Next = nodeToDel.Next;
if (nodeToDel.Next != null){
nodeToDel.Next.Previous = nodeToDel.Previous;
var bottom = bottomZipCode.ToString();
while (zipHashSet.Contains(topZipCode+1)) {
var nodeToDel = nodeDictionary[topZipCode+1];
if (nodeToDel.Previous != null) {
nodeToDel.Previous.Next = nodeToDel.Next;
if (nodeToDel.Next != null){
nodeToDel.Next.Previous = nodeToDel.Previous;
var top = topZipCode.ToString();
groupings.Add(bottom + "-" + top);
foreach(var grouping in groupings){
Console.WriteLine(grouping);
public class DoublyLinkedListNode<T>
private DoublyLinkedListNode<T> next;
private DoublyLinkedListNode<T> previous;
public DoublyLinkedListNode(T element)
public DoublyLinkedListNode(T element, DoublyLinkedListNode<T> prevNode)
this.previous = prevNode;
get { return this.element; }
set { this.element = value; }
public DoublyLinkedListNode<T> Next
get { return this.next; }
set { this.next = value; }
public DoublyLinkedListNode<T> Previous
get { return this.previous; }
set { this.previous = value; }
public class DoublyLinkedList<T>
private DoublyLinkedListNode<T> head;
private DoublyLinkedListNode<T> tail;
public DoublyLinkedListNode<T> First { get { return head; } set { head = value; } }
public DoublyLinkedListNode<T> Last { get { return tail; } set { tail = value; } }
public DoublyLinkedList()
get { return this.count; }
if (index >= count || index < 0)
throw new ArgumentOutOfRangeException("Out of range!");
DoublyLinkedListNode<T> currentNode = this.head;
for (int i = 0; i < index; i++)
currentNode = currentNode.Next;
return currentNode.Element;
if (index >= count || index < 0)
throw new ArgumentOutOfRangeException("Out of range!");
DoublyLinkedListNode<T> currentNode = this.head;
for (int i = 0; i < index; i++)
currentNode = currentNode.Next;
currentNode.Element = value;
this.head = new DoublyLinkedListNode<T>(item);
DoublyLinkedListNode<T> newItem = new DoublyLinkedListNode<T>(item, tail);
public void Insert(T item, int index)
if (index >= count || index < 0)
throw new ArgumentOutOfRangeException("Out of range!");
var newItem = new DoublyLinkedListNode<T>(item);
var currentItem = this.head;
DoublyLinkedListNode<T> prevItem = null;
while (currentIndex < index)
currentItem = currentItem.Next;
newItem.Previous = this.head.Previous;
newItem.Next = this.head;
this.head.Previous = newItem;
else if (index == count - 1)
newItem.Previous = this.tail;
this.tail.Next = newItem;
newItem.Next = prevItem.Next;
newItem.Previous = currentItem.Previous;
currentItem.Previous = newItem;
public void Remove(object item)
DoublyLinkedListNode<T> currentItem = this.head;
DoublyLinkedListNode<T> prevItem = null;
while (currentItem != null)
if ((currentItem.Element != null &&
currentItem.Element.Equals(item)) ||
(currentItem.Element == null) && (item == null))
currentItem = currentItem.Next;
else if (prevItem == null)
this.head = currentItem.Next;
this.head.Previous = null;
else if (currentItem == tail)
currentItem.Previous.Next = null;
this.tail = currentItem.Previous;
currentItem.Previous.Next = currentItem.Next;
currentItem.Next.Previous = currentItem.Previous;
public void RemoveAt(int index)
if (index >= this.count || index < 0)
throw new ArgumentOutOfRangeException("Out of range!");
DoublyLinkedListNode<T> currentItem = this.head;
DoublyLinkedListNode<T> prevItem = null;
while (currentIndex < index)
currentItem = currentItem.Next;
else if (prevItem == null)
this.head = currentItem.Next;
this.head.Previous = null;
else if (index == count - 1)
prevItem.Next = currentItem.Next;
prevItem.Next = currentItem.Next;
currentItem.Next.Previous = prevItem;
public int indexOf(T item)
DoublyLinkedListNode<T> currentItem = this.head;
while (currentItem != null)
if (((currentItem.Element != null) && (item.Equals(currentItem.Element))) ||
((currentItem.Element == null) && (item == null)))
currentItem = currentItem.Next;
public bool Contains(T element)
int index = indexOf(element);
bool contains = (index != -1);