/*  Carrés latins
	(C) 2009 Jean-Paul Davalan
*/
function bij(t, n) {
	for(var i=n-1; i>=0; i--) {
		var u = Math.floor((n)*Math.random())
		var b = t[i]
		t[i] = t[u]
                t[u] = b
	}
        return t
}

var nl;
var idl, testidl
function carrelatin() {
	nl = parseInt(document.flat.n.value)
	document.flat.n.value = nl
	if(testidl==true) {
		clearTimeout(idl)
	}
	testidl=true
	document.getElementById("clat").innerHTML = "<span class='carre'>Recherche en cours pour n = "+nl+"</span><br>"
	idl = setTimeout(clatin,10)
}
function add(k) {
	var n = parseInt(document.flat.n.value)+k
	if(n<=1) n=1
	document.flat.n.value=n
	carrelatin()
}
function clatin() {
	if(testidl==false) {
		clearTimeout(idl)
		return
	}
	var n = nl
	var symetrique=false, idempotent=0, listeidempotents=""
	var mat = []
	for(var i=0; i<n; i++) mat[i]=[]
	for(var i=0; i<n; i++) mat[0][i] = i
	mat[0] = bij(mat[0], n)
	
	var test = true
	for(var i=1; test && i<n; i++) {

		for(var j=0; test && j<n; j++) {
			var t = []
			for(var u=0; u<n; u++) t[u]=0
			for(var u=0; u<j; u++) t[mat[i][u]] = 1
			for(var u=0; u<i; u++) t[mat[u][j]] = 1
			test = false
			for(var r=0; test ==false && r<n; r++) {
				if(t[r]==0) test = true
			}
			var k = Math.floor(n*Math.random())

			var r, c;
			for(r=k; r < n+k; r++) {
				c = r % n
				if(t[c] == 0) {
					mat[i][j] = c;
					break;
				}
			}

		}
	}
	if(test== true) {
		testidl=false
		var reduct = document.flat.red.checked
		if(reduct==true) {
//alert("réduit")
			// colonnes
			var a, u, k, r
			for(var j=0; j<n; j++) {
				for(r=j; r<n; r++) {
					if(mat[0][r]==j) {
						k=r;
						break;
					}
				}
				if(k!=j) {
					for(i=0; i<n; i++) {
						u=mat[i][k]
						mat[i][k] = mat[i][j]
						mat[i][j] = u
					}
				}
			}
			// lignes
			for(var i=0; i<n; i++) {
				for(r=i; r<n; r++)
					if(mat[r][0]==i) {
						k=r
						break;
					}
				if(k!=i) {
					for(j=0; j<n; j++) {
						u=mat[k][j]
						mat[k][j]=mat[i][j]
						mat[i][j]=u
					}
				}
			}
		}
                symetrique=true
                for(var i=0; symetrique && i<n; i++) {
                      for(var j=i+1; symetrique && j<n; j++) {
                              if(mat[i][j]!=mat[j][i]) symetrique=false
                     }
                 }
                 idempotent=0
                 for(var i=0; i<n; i++) {
                      if(mat[i][i]==i) {
				idempotent++
				listeidempotents += alpha[i]+" "
		      }
		 }
		//neutres
		// à gauche
		var neutres=0
		var sneutres=""
		var eltneutre=[]
		for(var j=0; j<n; j++) {
			var ng=true
			for(var i=0; ng && i<n; i++) {
				if(mat[i][j]!=i) ng=false
			}
			if(ng==true) {
				sneutres += alpha[j]+" est élément neutre à droite.<br>"
				eltneutre[1]=alpha[j]
				neutres++
				break;
			}
		}
		for(var i=0; i<n; i++) {
			var ng=true
			for(var j=0; ng && j<n; j++) {
				if(mat[i][j]!=j) ng=false
			}
			if(ng==true) {
				sneutres += alpha[i]+" est élément neutre à gauche.<br>"
				eltneutre[0]=alpha[i]
				neutres++
                                break;
                        }
                }
		var associatif=true
		for(var i=0; associatif && i<n; i++) {
			for(var j=0; associatif && j<n; j++) {
				for(var k=0; associatif && k<n; k++) {
					if(mat[mat[i][j]][k] != mat[i][mat[j][k]]) associatif=false
				}
			}
		}

		var s=""
		for(var i=0; i<n; i++) {
			s += "<span class='carre'>"
			for(var j=0; j<n; j++) {
				s += alpha[mat[i][j]]+"&nbsp;&nbsp;"
			}
			s += "</span>"
			s += "<br>"
		}
		s = "<br>" + s + "<br>"
		if(symetrique) {
			s += "Le carré latin est symétrique.<br>"
		}
		if(idempotent>0) {
			if(idempotent==n) {
				s += "Tous les éléments sont idempotents.<br>"
			} else if(idempotent==1) {
				s += "L'élément "+listeidempotents+" est idempotent.<br>"
			} else if(idempotent>1) {
				s += "Les éléments "+listeidempotents+"sont idempotents.<br>"
			}
		}
		if(neutres==2 && eltneutre[0]==eltneutre[1]) {
			s += eltneutre[0]+" est élément neutre.<br>"
		} else if(neutres >0) {
			s += sneutres
		}
		if(associatif) {
			s += "La loi est associative.<br>"
		}
		if(associatif && neutres==2 && eltneutre[0]==eltneutre[1]) {
			if(symetrique) {
				s += "La loi est une loi de groupe commutatif.<br>"
			} else {
				s += "La loi est une loi de groupe non commutatif.<br>"
			}
		}
		document.getElementById("clat").innerHTML = s

	}
	idl = setTimeout(clatin, 10)
}

function groupelatin() {
        var n = parseInt(document.flat.n.value)
	nl=n
        document.flat.n.value = n
	var t = []
	for(var i=0; i<n; i++) t[i]=i
	t = bij(t, n)
        if(testidl==true) {
                clearTimeout(idl)
        }
	var reduct = document.flat.red.checked
	var mat = []
	if(reduct) {
		for(var i=0; i<n; i++) {
			mat[i] = []
			for(var j=0; j<n; j++) {
	                        mat[i][j] = (i+j)%n
        	        }
		}
	} else {
		var  mat0 = [], mat1 = []
		for(var i=0; i<n; i++) {
			mat[i] = []
			mat0[i] = []
			mat1[i] = []
	
			for(var j=0; j<n; j++) {
				mat0[i][j] = (i+j)%n
			}
		}
		
		t = bij(t, n)
		for(var i=0; i<n; i++) {
			for(var j=0; j< n; j++)	{
				mat1[i][j] = mat0[t[i]][j]
			}
		}
		t = bij(t, n)
	        for(var i=0; i<n; i++) {
                	for(var j=0; j< n; j++) {
        	                mat[i][j] = mat1[i][t[j]]
	                }
        	}
		delete(mat0)
		delete(mat1)
		delete(t)
 	}
                var s=""
                for(var i=0; i<n; i++) {
			s += "<span class='carre'>"
                        for(var j=0; j<n; j++) {
                                s += alpha[mat[i][j]]+"&nbsp;&nbsp;"
                        }
                        s += "</span><br>"
                }
                s = "<br>" + s + "<br>"

                document.getElementById("clat").innerHTML = s

			
}


