/*
 * Permutation.h
 *
 *  Created on: 10. 2. 2017
 *      Author: Jan Travnicek
 */

#ifndef PERMUTATION_H_
#define PERMUTATION_H_

#include <alib/set>
#include <alib/vector>
#include <alib/map>
#include <alib/random>
#include <alib/algorithm>
#include <alib/foreach>

#include <global/GlobalData.h>

namespace common {

class Permutation {
public:
	template < class T >
	static ext::map < T, T > permutationMap ( const ext::set < T > & data ) {
		ext::vector < T > dataVector ( data.begin ( ), data.end ( ) );

		std::shuffle ( dataVector.begin ( ), dataVector.end ( ), ext::random_devices::semirandom );
		ext::map < T, T > permutation;
		for ( const ext::tuple < const T &, const T & > & fromToPair : ext::make_tuple_foreach ( data, dataVector ) ) {
			permutation.insert ( std::make_pair ( std::get < 0 > ( fromToPair ), std::get < 1 > ( fromToPair ) ) );
		}

		if(common::GlobalData::verbose)
			common::Streams::log << "permutation map: " << permutation << std::endl;

		return permutation;
	}
};

} /* namespace common */

#endif /* PERMUTATION_H_ */
