/****************************************/
/*	Autor: Piotr Doniec 4I1     		    */
/*	pdoniec@stud.elka.pw.edu.pl      	 */			
/*	Temat: biblioteka stl,				    */
/*	algorytmy	adjacent_find     		 */
/****************************************/

/*
	template <class ForwardIterator> 
		ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last);
 
	template <class ForwardIterator, class BinaryPredicate> 
		ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last, BinaryPredicate binary_pred);
  
	-- Parametry --
	* first - iterator wskazujący początek zakresu do przeszukania
	* last - iterator wskazujący koniec zakresu do przeszukania
	* binary_pred - opcjonalny argument, wskaźnik na funkcję dokonującej porównania
*/

#include<algorithm>
#include<list>
#include<iostream>
 
/**
 * Sprawdza czy następny element jest 2 razy większy od obecnego
 * Funkcja podana jako trzeci argument algorytmu adjacent_find
 * spowoduje że kryterium równości elementów będzie spełnione jeśli
 * element będzie 2 razy mniejszy od elementu po nim następującego
 */
bool twice (int elem1, int elem2 )
{
   return elem1 * 2 == elem2;
}
 

 
int main() {
 
  /**
   * inicjalizacja struktur danych do demonstracji działania
	* algorytmu
	*/
  std::list<int> L;
  std::list<int>::iterator result, iter;
 
  //L.push_back(160);
  L.push_back(80);
  L.push_back(160);
  L.push_back(60);
  L.push_back(50);
  L.push_back(40);
  L.push_back(10);
  L.push_back(20);
  L.push_back(20);
  
  for(iter = L.begin(); iter != L.end(); iter++) {
    std::cout << *iter << " ";
  }
  std::cout << std::endl;
  
  
  /**
   * Najprostsze wykorzystanie algorytmu adjacent_find(), sprawdzające 
	* czy istnieją para, indentycnych kolejno występujących elementów
	*/
  result = std::adjacent_find(L.begin(), L.end());
  if( result == L.end() ) {
    std::cout << "Nie istnieją dwa kolejne identyczne elementy" << std::endl;
  }
  else {
    std::cout << "Istenieją dwa kolejne identyczne elementy o wartości " << *result << std::endl;
  }
  
 
  /**
   * Wykorzystanie 3 argumentu algorytmu adjacent_find.
	* Dostarczona funkcja sprawdza czy istnieje para kolejnych elementów 
	* z których pierwszy ma wartość dwukrotnie większą od drugiego
	*/
  result = std::adjacent_find( L.begin(), L.end(), twice );
  if ( result == L.end() ) {
    std::cout << "Nie występuje para kolejnych elementów, w której jeden element jest dwukrotnie większy od drugiego" << std::endl;
  }
  else {
      std::cout << "Występuje para elementów w której jeden jest 2 razy większy od drugiego" << "\nWartości tych elementów" << *(result);
      std::cout << " oraz " << *(++result) << std::endl;
  }
  
  /**
   * Próba odnaleziena drugiej pary elementów spełaniającej warunek rowności zawarty w funkcji twice
	*/
  result = std::adjacent_find( result, L.end(), twice );
  if ( result == L.end() ) {
    std::cout << "Nie występuje para kolejnych elementów, w której jeden element jest dwukrotnie większy od drugiego" << std::endl;
  }
  else {
      std::cout << "Występuje para elementów w której jeden jest 2 razy większy od drugiego" << std::endl << "Wartości tych elementów: " << *(result);
      std::cout << " oraz " << *(++result) << std::endl;
  }
}