using System;
using System.Collections.Generic;
public class Test
{
public static void Main()
{
var c = new Counter<int>();
c.Increment(1);
c.Increment(2);
c.Increment(1);
c.Increment(1);
foreach (var kvp in c) {
Console.WriteLine(kvp);
}
}
public class Counter<T> : IEnumerable<KeyValuePair<T, int>> {
private Dictionary<T, int> counts = new Dictionary<T, int>();
public void Increment(T key) {
int current;
bool exists = counts.TryGetValue(key, out current);
if (exists) {
counts[key]++;
}
else {
counts[key] = 1;
}
}
IEnumerator<KeyValuePair<T, int>>
IEnumerable<KeyValuePair<T, int>>.GetEnumerator() {
return ((IEnumerable<KeyValuePair<T, int>>) counts).GetEnumerator();
}
System.Collections.IEnumerator
System.Collections.IEnumerable.GetEnumerator() {
return counts.GetEnumerator();
}
}
}
dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYzsKIApwdWJsaWMgY2xhc3MgVGVzdAp7CiAgICAgICAgcHVibGljIHN0YXRpYyB2b2lkIE1haW4oKQogICAgICAgIHsKICAgICAgICAgICB2YXIgYyA9IG5ldyBDb3VudGVyPGludD4oKTsKICAgICAgICAgICBjLkluY3JlbWVudCgxKTsKICAgICAgICAgICBjLkluY3JlbWVudCgyKTsKICAgICAgICAgICBjLkluY3JlbWVudCgxKTsKICAgICAgICAgICBjLkluY3JlbWVudCgxKTsKICAgICAgICAgICBmb3JlYWNoICh2YXIga3ZwIGluIGMpIHsKICAgICAgICAgICAgICAgQ29uc29sZS5Xcml0ZUxpbmUoa3ZwKTsKICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBjbGFzcyBDb3VudGVyPFQ+IDogSUVudW1lcmFibGU8S2V5VmFsdWVQYWlyPFQsIGludD4+IHsKICAgICAgICBwcml2YXRlIERpY3Rpb25hcnk8VCwgaW50PiBjb3VudHMgPSBuZXcgRGljdGlvbmFyeTxULCBpbnQ+KCk7CiAKICAgICAgICBwdWJsaWMgdm9pZCBJbmNyZW1lbnQoVCBrZXkpIHsKICAgICAgICAgICAgaW50IGN1cnJlbnQ7CiAgICAgICAgICAgIGJvb2wgZXhpc3RzID0gY291bnRzLlRyeUdldFZhbHVlKGtleSwgb3V0IGN1cnJlbnQpOwogICAgICAgICAgICBpZiAoZXhpc3RzKSB7CiAgICAgICAgICAgICAgICBjb3VudHNba2V5XSsrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgY291bnRzW2tleV0gPSAxOwogICAgICAgICAgICB9CiAgICAgICAgfQogCiAgICAgICAgSUVudW1lcmF0b3I8S2V5VmFsdWVQYWlyPFQsIGludD4+CiAgICAgICAgICAgIElFbnVtZXJhYmxlPEtleVZhbHVlUGFpcjxULCBpbnQ+Pi5HZXRFbnVtZXJhdG9yKCkgewogICAgICAgICAgICByZXR1cm4gKChJRW51bWVyYWJsZTxLZXlWYWx1ZVBhaXI8VCwgaW50Pj4pIGNvdW50cykuR2V0RW51bWVyYXRvcigpOwogICAgICAgIH0KIAogICAgICAgIFN5c3RlbS5Db2xsZWN0aW9ucy5JRW51bWVyYXRvcgogICAgICAgICAgICBTeXN0ZW0uQ29sbGVjdGlvbnMuSUVudW1lcmFibGUuR2V0RW51bWVyYXRvcigpIHsKICAgICAgICAgICAgcmV0dXJuIGNvdW50cy5HZXRFbnVtZXJhdG9yKCk7CiAgICAgICAgfQogICAgfQp9