class Exo1 {
    public static void main(String[] arg){
	// Question 1
	int [][][][]tab;

	// Question 2
	{
	    int val = 0;
	    tab = new int[2][][][];
	    for(int i = 0; i < 2; i++)
		tab[i] = new int[2][][];
	    for(int i = 0; i < 2; i++)
		for(int j = 0; j < 2; j++)
		    tab[i][j] = new int[2][];
	    for(int i = 0; i < 2; i++)
		for(int j = 0; j < 2; j++)
		    for(int k = 0; k < 2; k++) {
			tab[i][j][k] = new int[2];
			for(int l = 0; l <2; l++)
			    tab[i][j][k][l] = val++;
		}
	}
	/* Note : pour l'initialisation du tableau, ne sont pas acceptables les réponses
	 * comme :
	 * tab[0][0][0][0][0] =  0;
	 * tab[0][0][0][0][1] =  1;
	 * ...
	 * tab[0][1][0][0][1] =  9;
	 * ...
	 * tab[1][1][1][1][1] = 15;
	 * En effet, si c'est presque supportable pour 15 valeurs, il suffit de se
	 * demander si la stratégie serait correcte avec 10.000 valeurs...
	 * L'un des buts de l'informatique est justement d'automatiser autant que
	 * possible les opérations à effectuer; donc initialiser chaque élément
	 * au cas par cas, n'est pas raisonnable. Il FAUT trouver une stratégie (un
	 * algorithme) permettant d'initialiser le tableau.
	 */
	{
	    /* Variante question 2 */
	       int val = 0;
	       tab = new int[2][2][2][2];
	       for(int i = 0; i < 2; i++)
		   for(int j = 0; j < 2; j++)
		       for(int k = 0; k < 2; k++) {
			   for(int l = 0; l <2; l++)
			       tab[i][j][k][l] = val++;
		       }
	}
	{
	    /* Variante question 2 (anticipation de la question 3!!!) */
	    tab = new int[2][2][2][2];
	    for (int i=0,val=0; i<16; i++,val++)
		tab[i/8][i%8/4][i%4/2][i%2] = val;
	}
	{
	    /* Variante question 2
	     * Attention ici la réponse est déjà partiellement fausse mais
	     * acceptable par la structure obtenue à la fin car
	     * nécessairement les références a-o sont dans la pile mais ne le
	     * devraient pas. Dans le diagramme a-o sont des valeurs symboliques
	     * pas des références (il ne peut y avoir de référence dans le tas)
	     */
	    int [] h = new int[2]; h[0] =  0; h[1] =  1;
	    int [] i = new int[2]; i[0] =  2; i[1] =  3;
	    int [] j = new int[2]; j[0] =  4; j[1] =  5;
	    int [] k = new int[2]; k[0] =  6; k[1] =  7;
	    int [] l = new int[2]; l[0] =  8; l[1] =  9;
	    int [] m = new int[2]; m[0] = 10; m[1] = 11;
	    int [] n = new int[2]; n[0] = 12; n[1] = 13;
	    int [] o = new int[2]; o[0] = 14; o[1] = 15;

	    int [][] d = new int[2][]; d[0] = h; d[1] = i;
	    int [][] e = new int[2][]; e[0] = j; e[1] = k;
	    int [][] f = new int[2][]; f[0] = l; f[1] = m;
	    int [][] g = new int[2][]; g[0] = n; g[1] = o;

	    int [][][] b = new int[2][][]; b[0] = d; b[1] = e;
	    int [][][] c = new int[2][][]; c[0] = f; c[1] = g;

	    tab = new int[2][][][]; tab[0] = b; tab[1] = c;
	}
	{
	    /* Variante question 2
	     * Sauriez-vous critiquer cette solution ?
	     */
	    int []h = {  0,  1 };
	    int []i = {  2,  3 };
	    int []j = {  4,  5 };
	    int []k = {  6,  7 };
	    int []l = {  8,  9 };
	    int []m = { 10, 11 };
	    int []n = { 12, 13 };
	    int []o = { 14, 15 };

	    int [][]d = { h, i };
	    int [][]e = { j, k };
	    int [][]f = { l, m };
	    int [][]g = { n, o };

	    int [][][]b = { d, e };
	    int [][][]c = { f, g };

	    int [][][][]a = { b, c };
	    tab = a;
	}
	{
	    /* Variante question 2 : sauriez-vous faire plus court ? */
	    int [][][][]tableau = {
		{{{0,1},{2,3}},{{4,5},{6,7}}},{{{8,9},{10,11}},{{12,13},{14,15}}}
	    };
	}


	// Question 3
	System.out.println(tab[0][1][1][1]);
	System.out.println(tab[1][0][1][1]);
	int position = 9;
	System.out.println(tab[position/8][position%8/4][position%4/2][position%2]);
	/* Note : n'est pas acceptable une réponse indiquant une expression comme :
	 * tab[0][1][1][1]=7
	 * car ceci est une expression d'affectation! Ce qui est demandé est une
	 * expression dont la valeur est 7 soit tab[0][1][1][1] ou comme
	 * dans la réponse donnée, une instruction affichant la valeur de l'expression.
	 * N'est pas acceptable non plus :
	 * tab[0][1][1][1]==7
	 * car la valeur de cette expression est un booléen (vrai ou faux) et
	 * certainement pas la valeur attendue l'entier 7.
	 */

	// Question 4 : c’est la valeur de tab qui ne peut pas etre modifiee
	// par une fonction du fait du passsage par valeur et de
	// l’impossibilit de dereferencer une variable en Java

	// Question 5
	modifier(tab, 1, 0 , 1 , 1, 100);
	// ou (variante)
	modifier(tab, 11, 100);
    }
    public static void modifier(int[][][][]t, int i, int j, int k, int l,int v){
	t[i][j][k][l] += v;
    }
    // variante...
    public static void modifier(int[][][][]t, int n,int v) {
	t[n/8][n%8/4][n%4/2][n%2] += v;
    }
}