www.pudn.com > sudoku.rar > CombinationIterator.cs


//-------------------------------------------------------------------------- 
//  
//  Copyright (c) Microsoft Corporation.  All rights reserved.  
//  
//  File: CombinationIterator.cs 
// 
//  Description: Allows for iteration through all combinations from an array. 
//  
//-------------------------------------------------------------------------- 
 
using System; 
using System.Collections; 
 
namespace Microsoft.Sudoku.Techniques 
{ 
	/// An IEnumerable for combinations. 
	internal sealed class CombinationIterator : IEnumerable, IEnumerator 
	{ 
		/// The current indices. 
		private int [] _indices; 
		/// The number K of items to choose. 
		private int _size; 
		/// The numbers to choose from. 
		private int [] _numbers; 
 
		/// Initializes the iterator. 
		/// The number of items to choose. 
		/// The numbers from which to choose. 
		public CombinationIterator(int size, int [] numbers) 
		{ 
			_size = size; 
			_numbers = numbers; 
		} 
 
		/// Gets the enumerator. 
		/// This enumerator. 
		public IEnumerator GetEnumerator() { return this; } 
 
		/// Resets the enumerator. 
		public void Reset() { _indices = null; } 
 
		private int [] _result; 
 
		/// Gets the current combination. 
		public object Current 
		{ 
			get 
			{ 
				for(int i=0; i<_indices.Length; i++) 
				{ 
					_result[i] = _numbers[_indices[i]]; 
				} 
				return _result; 
			} 
		} 
 
		/// Moves to the next combination. 
		/// A value indicating if there are more combinations from which to choose. 
		public bool MoveNext() 
		{ 
			if (_indices == null) 
			{ 
				_indices = new int[_size]; 
				_result = new int[_size]; 
				for(int i=0; i<_indices.Length; i++) _indices[i] = i; 
				return true; 
			} 
			else 
			{ 
				if (_indices[0] >= _numbers.Length-_size) return false; 
 
				// Find the next position to be incremented 
				int pos; 
				for(pos=_indices.Length-1;  
					pos > 0 && _indices[pos] == _numbers.Length - _size + pos; 
					pos--); 
 
				// Increment the position 
				_indices[pos]++; 
 
				// Increment everything else 
				for (int j = pos; j < _size - 1; j++) _indices[j+1] = _indices[j]+1; 
 
				return true; 
			} 
		} 
	} 
}