using System;
using System.Collections.Generic;
namespace OpenHashingExample
{
	class Program
	{
		static void Main(string[] args)
		{
			var hashTable = new HashTable<int, string>(10);
			hashTable.Add(1, "one");
			hashTable.Add(2, "two");
			hashTable.Add(3, "three");
			hashTable.Add(11, "eleven");
			hashTable.Add(12, "twelve");
			hashTable.Add(13, "thirteen");
			Console.WriteLine("Value of key 1: " + hashTable.GetValue(1));
			Console.WriteLine("Value of key 11: " + hashTable.GetValue(11));
			Console.WriteLine("Value of key 2: " + hashTable.GetValue(2));
			Console.WriteLine("Value of key 12: " + hashTable.GetValue(12));
			Console.ReadLine();
		}
	}
	class HashTable<TKey, TValue>
	{
		private List<KeyValuePair<TKey, TValue>>[] _buckets;
		private int _capacity;
		public HashTable(int capacity)
		{
			_capacity = capacity;
			_buckets = new List<KeyValuePair<TKey, TValue>>[capacity];
			for (int i = 0; i < capacity; i++)
			{
				_buckets[i] = new List<KeyValuePair<TKey, TValue>>();
			}
		}
		public void Add(TKey key, TValue value)
		{
			int index = GetIndex(key);
			var keyValuePair = new KeyValuePair<TKey, TValue>(key, value);
			_buckets[index].Add(keyValuePair);
		}
		public TValue GetValue(TKey key)
		{
			int index = GetIndex(key);
			var bucket = _buckets[index];
			foreach (var keyValuePair in bucket)
			{
				if (keyValuePair.Key.Equals(key))
				{
					return keyValuePair.Value;
				}
			}
			throw new Exception("Key not found");
		}
		private int GetIndex(TKey key)
		{
			int hash = key.GetHashCode();
			int index = hash % _capacity;
			return index;
		}
	}
}