import java.util.*;

/**
 * Correction du partiel (24-03-2014)
 * Exercice numéro 2 - Les piles.
 */
public class Piles {
  public static Stack<Integer> getFreshStack() {
    Stack<Integer> s = new Stack<Integer>();
    s.push(3); s.push(4); s.push(9); s.push(9); s.push(8); s.push(5);
    s.push(3); s.push(3); s.push(3); s.push(7); s.push(6); s.push(0);
    s.push(0); s.push(1);
    return s;
  }
  public static void dupliquerTous(Stack<Integer> s) {
    Stack<Integer> t = new Stack<Integer>();
    while (!s.empty()) { t.push(t.push(s.pop())); }
    while (!t.empty()) { s.push(t.pop()); }
  }
  public static void dupliquerFond(Stack<Integer> s) {
    Stack<Integer> t = new Stack<Integer>();
    while (!s.empty()) { t.push(s.pop()); }
    if (!t.empty()) { s.push(s.push(t.pop())); }
    while (!t.empty()) { s.push(t.pop()); }    
  }
  public static void dupliquerUn(Stack<Integer> s,int k) {
    Stack<Integer> t = new Stack<Integer>();
    while (!s.empty()) { t.push(s.pop()); }
    int indice = 1;
    while (!t.isEmpty() && indice!=k) { s.push(t.pop()); indice++; }
    if (!t.empty()) { s.push(s.push(t.pop())); }
    while (!t.empty()) { s.push(t.pop()); }    
  }
  public static void filtrerElement(Stack<Integer> s,int v) {
    Stack<Integer> t = new Stack<Integer>();
    while (!s.empty()) { int valeur = s.pop(); if (valeur!=v) t.push(valeur); }
    while (!t.empty()) { s.push(t.pop()); }    
  }
  public static void filtrerMultiple(Stack<Integer> s,int v) {
    Stack<Integer> t = new Stack<Integer>();
    while (!s.empty()) { int valeur = s.pop(); if (valeur%v!=0) t.push(valeur); }
    while (!t.empty()) { s.push(t.pop()); }    
  }
  public static void supprimerDuplicata(Stack<Integer> s) {
    Stack<Integer> t = new Stack<Integer>();
    if (!s.isEmpty()) {
      int oldValue = s.pop(); // get a new fresh value
      while (!s.empty()) {             // pop values
        int value = s.pop();
        if (oldValue==value) continue; // not a fresh value, play it again sam
        t.push(oldValue);              // a fresh one! push back the old fresh
        oldValue = value;              // swap old and new fresh
      }
      t.push(oldValue);       // ok push back the last fresh value
    }
    while (!t.empty()) { s.push(t.pop()); }    
  }
  public static void main(String []a) {
    Stack<Integer> s = null;

    System.out.println("1)");
    s = getFreshStack();
    System.out.println("avant dupliquerTous "+s);
    dupliquerTous(s);
    System.out.println("après dupliquerTous "+s);
    s = new Stack<Integer>();
    System.out.println("avant dupliquerTous "+s);
    dupliquerTous(s);
    System.out.println("après dupliquerTous "+s);

    System.out.println("2)");
    s = getFreshStack();
    System.out.println("avant dupliquerFond "+s);
    dupliquerFond(s);
    System.out.println("après dupliquerFond "+s);
    s = new Stack<Integer>();
    System.out.println("avant dupliquerFond "+s);
    dupliquerFond(s);
    System.out.println("après dupliquerFond "+s);

    System.out.println("3)");
    s = getFreshStack();
    System.out.println("avant dupliquerUn (2)"+s);
    dupliquerUn(s,2);
    System.out.println("après dupliquerUn (2)"+s);
    s = getFreshStack();
    System.out.println("avant dupliquerUn (30)"+s);
    dupliquerUn(s,30);
    System.out.println("après dupliquerUn (30)"+s);
    s = new Stack<Integer>();
    System.out.println("avant dupliquerUn (30)"+s);
    dupliquerUn(s,30);
    System.out.println("après dupliquerUn (30)"+s);

    System.out.println("4)");
    s = getFreshStack();
    System.out.println("avant filtrerElement (3)"+s);
    filtrerElement(s,3);
    System.out.println("après filtrerElement (3)"+s);
    s = getFreshStack();
    System.out.println("avant filtrerElement (100)"+s);
    filtrerElement(s,100);
    System.out.println("après filtrerElement (100)"+s);
    s = new Stack<Integer>();
    System.out.println("avant filtrerElement (3)"+s);
    filtrerElement(s,3);
    System.out.println("après filtrerElement (3)"+s);

    System.out.println("5)");
    s = getFreshStack();
    System.out.println("avant filtrerMultiple (3)"+s);
    filtrerMultiple(s,3);
    System.out.println("après filtrerMultiple (3)"+s);
    s = getFreshStack();
    System.out.println("avant filtrerMultiple (100)"+s);
    filtrerMultiple(s,100);
    System.out.println("après filtrerMultiple (100)"+s);
    s = new Stack<Integer>();
    System.out.println("avant filtrerMultiple (3)"+s);
    filtrerMultiple(s,3);
    System.out.println("après filtrerMultiple (3)"+s);

    System.out.println("6)");
    s = getFreshStack();
    System.out.println("avant supprimerDuplicata "+s);
    supprimerDuplicata(s);
    System.out.println("après supprimerDuplicata "+s);
    supprimerDuplicata(s);
    System.out.println("après supprimerDuplicata (seconde fois) "+s);
    s = new Stack<Integer>();;
    System.out.println("avant supprimerDuplicata "+s);
    supprimerDuplicata(s);
    System.out.println("après filtrerMultiple "+s);
    s.push(5);
    System.out.println("avant supprimerDuplicata "+s);
    supprimerDuplicata(s);
    System.out.println("après filtrerMultiple "+s);
    s.push(5);
    System.out.println("avant supprimerDuplicata "+s);
    supprimerDuplicata(s);
    System.out.println("après filtrerMultiple "+s);
  }
}