/* rythm.js  -  Pavages ryhmiques parfaits -
 *
 * complémént du programme rythm.java de calcul des p.r.p.
 *
 * un pavage rythmique parfait est un :
 * recouvrement exact de l'ens. des k*n premiers naturels par n suites
 * arithmétiques finies de k termes et de raisons toutes différentes
 *
 * (ou partition de [0, k*n-1] en n parties de k éléments en progression
 * arithmétique, les raisons de ces progr. étant toutes différentes)
 *
 * (C) Jean-Paul Davalan Concarneau Décembre 2004 <jpdvl@wanadoo.fr>
 *
 * RYTHM.JS is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * RYTHM.JS is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with rythm.java; see the file COPYING.  If not, write to
 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 *
19 8 2
4 0 4;1 1 2;8 3 11;5 5 10;3 6 9;6 7 13;7 8 15;2 12 14
4 1 1 8 4 5 3 6 7 3 5 8 2 6 2 7
1 10 11;2 21 23;3 15 18;4 9 13;5 14 19;6 16 22;7 17 24;8 12 20;

 */
var results = new Array(), suite=[], sols,pos, maxsols=20, mode=0;
var sel, n, k;

function prpr(s) {
	var t;
	var u = s+"";
	if(sols <= maxsols) {
		results[sols] = u;
		t = u.split(/\n/g);
		pos = sols;
		sols++;
	}
	if(sols==1) document.frm.ar.value="";
	document.frm.ar.value += "> "+t[2]+"\n";
	if(sols==1) {
		//traite(0);
		//traits(0);
		var sk = new Skolem(results[0]);
		sk.affsystem();
		sk.traits();
		sk.diffsystem();
		sk.blocks();
	}
}

function Skolem(s) {
	this.a = s.split(/\n/g);
	var b = this.a[0].split(/\s+/g);
	
	this.n = parseInt(b[1]);
	this.k = parseInt(b[2]);

	this.selts=this.a[1].split(/\;/g);
	this.elts=[]
	for(var i=0; i<this.n; i++)
                this.elts[i] = this.selts[i].split(/\s+/g);
	//alert(this.elts[0])
	this.ssystem=this.a[3].split(/\;/g);
	//alert(this.ssystem)
	this.system=[];
	for(var i=0; i<this.n; i++) {
		this.ssystem[i] = this.ssystem[i].replace(/^\s+/,"")
		this.ssystem[i] = this.ssystem[i].replace(/\s+$/,"")
		this.system[i] = this.ssystem[i].split(/\s+/g);
	}
	this.traits =function() {
var s0 = 'cliquez sur ces flèches '+
'<span style="color:blue; cursor:pointer;" onclick="suivant(-1)">[&nbsp;&lt;--&nbsp;]</span>&nbsp;'+
'<span style="color:blue; cursor:pointer;" onclick="suivant(+1)">[&nbsp;--&gt;&nbsp;]</span>&nbsp;'+
" pour passer d'une solution à l'autre.<br><br />"
 	       var s = "a, x, y=x+a    trait\n\n"
        	for(var i=0; i<this.n; i++) {
                	var s1=this.selts[i];
			for(;s1.length<15;)
				s1 += " ";
	                for(var j=0; j < this.elts[i][1]; j++) 
				s1 += " "
	                s1 += "|"
        	        for(var j=0; j<this.elts[i][0]-1; j++) 
				s1 += "_"
                	s1 += "|\n"
//alert(s1)
	                s += s1
        	}
	
		s = s0+'<pre>'+s+'</pre>'
//alert(s)
       		document.getElementById("traits").innerHTML=s
		return s
	}
	this.affsystem=function() {
var s0 = 'cliquez sur ces flèches '+
'<span style="color:blue; cursor:pointer;" onclick="suivant(-1)">[&nbsp;&lt;--&nbsp;]</span>&nbsp;'+
'<span style="color:blue; cursor:pointer;" onclick="suivant(+1)">[&nbsp;--&gt;&nbsp;]</span>&nbsp;'+
" pour passer d'une solution à l'autre.<br><br />"+
" Un triple système de Skolem est une partition de l'ensemble "+
" <i>{1, 2, 3, 4,...,3n}</i> par <i>n</i> sous-ensembles de 3 éléments, "+
"obtenus à partir des suites de Skolem.<br />"+
"Les systèmes de Skolem permettent de construire des systèmes triples de Steiner cycliques, dordre 6n+1."
               var s = "<pre>"
		var s1=""
		for(var i=0; i<this.n; i++) {
			s1 += "{"+this.system[i][0]+", "+this.system[i][1]+", "+this.system[i][2]+"}"+((i<this.n-1)?", ":"</pre>")
			if(s1.length>100) {
				s += s1+"\n"; 
				s1="";
			}
		}
		document.getElementById("tbl").innerHTML=s0+s+s1+"</pre>"
	}
	this.diffsystem = function() {
var s0 = 'cliquez sur ces flèches '+
'<span style="color:blue; cursor:pointer;" onclick="suivant(-1)">[&nbsp;&lt;--&nbsp;]</span>&nbsp;'+
'<span style="color:blue; cursor:pointer;" onclick="suivant(+1)">[&nbsp;--&gt;&nbsp;]</span>&nbsp;'+
" pour passer d'une solution à l'autre.<br><br />"+
" Les triples suivants forment un système de différences permettant la construction d'un système triple cyclique de Steiner, dordre "+(6*this.n+1)+"<br />"+
"En calculant toutes les différences de deux éléments différents quelconques pris dans un même sous-ensemble," +
" on obtient tous les entiers non nuls de "+(-3*this.n)+" à "+(3*this.n)+"";
               var s = "<pre>"
                var s1=""
		//for(var j=0; j<this.n; j++) {
                for(var i=0; i<this.n; i++) {
                        s1 += "{"+0+", "+this.system[i][0]+", "+this.system[i][2]+"}"+((i<this.n-1)?", ":"</pre>")
                        if(s1.length>90) {
                                s += s1+"\n";
                                s1="";
                        }
                }
		//}
                document.getElementById("diff").innerHTML=s0+s+s1+"</pre>"
	}
	this.blocks = function() {
var s0 = 'cliquez sur ces flèches '+
'<span style="color:blue; cursor:pointer;" onclick="suivant(-1)">[&nbsp;&lt;--&nbsp;]</span>&nbsp;'+
'<span style="color:blue; cursor:pointer;" onclick="suivant(+1)">[&nbsp;--&gt;&nbsp;]</span>&nbsp;'+
" pour passer d'une solution à l'autre.<br><br />"+
"pour obtenir les blocs d'un système triple de Steiner, il suffit d'ajouter aux trois éléments des ensembles du système de différences ci-dessus, un même élément g de Z<sub>"+(6*this.n+1)+"</sub>, et de recommencer l'opération pour tous les éléments de Z<sub>"+(6*this.n+1)+"</sub>"
               var s = "<pre>"
                var s1=""

		var u = 6*this.n+1;
                for(var i=0; i<this.n; i++) {
			for(var j=0; j<u; j++) {
				var e0=(parseInt(this.system[i][0])+j)%u, e1 = (parseInt(this.system[i][2])+j)%u;
				//e0=(e0>u)?e0-u : e0;
				//e1=(e1>u)?e1-u : e1;
                        	s1 += "{"+j+", "+(e0)+", "+(e1)+"}"+" "
                 	       if(s1.length>90) {
                                	s += s1+"\n";
                              	  	s1="";
                        	}
                	}
			if(s1=="")s1 += "\n";
			else {
				s +=s1 + "\n\n";
				s1="";
			}
		}
		
                document.getElementById("blocks").innerHTML=s0+s+s1+"</pre>"
        }
}

function fin() {
	document.frm.ar.value = document.frm.ar.value+"\n---- fin ----";
}

function rem(s) {
	document.frm.ar.value = s+"\n"+document.frm.ar.value;
}

var id;

function suivt(x) {
var u0 = parseInt(document.frm.n.value),u=u0+x;
	if(u<1) u=1;
	document.frm.n.value=u;
	cherche();
}

function cherche() {
     var ns = parseInt(document.frm.n.value);
     if(ns<0) {
        ns =0;
        document.frm.n.value=0;
     } 
	v=ns;
     var s="Calcul en cours n= "+ns+"\n"+
           "Arrêt après "+maxsols+" solutions au plus\n\n"+
          "Merci d'être patient !\n";
     document.frm.ar.value = s;
     //for(var j=0;j<10000;j++) ;
     sols=0;
     pos=0;
     document.R.skolem2(v);
}

var cur=0;

function stop() {
document.R.stop();
document.frm.ar.value="Arrêt"
}

function w() {
  if(sols==0) {
    document.frm.ar.value=tab[cur]+"\n";
    cur = (cur+1)%tab.length;
  } else {
    clearInterval[id];
  }
}

function voir() {
  document.frm.ar.value = results[pos];
}

function suivant(k) {
  if(sols==0) return;
  pos += k;
  if(pos>=sols) pos = sols-1;
  if(pos<0) pos=0;
  voir();
	//traite(pos)
        var sk = new Skolem(results[pos])
	sk.affsystem();
	sk.traits();
	sk.diffsystem();
	sk.blocks();
	//traits(pos)
}

function extr(r) {
  if(sols==0) return;
  if(r==0) pos=0;
  else if(r==1) pos = sols-1;
  voir();
        //traite(pos)
        //traits(pos)
	var sk = new Skolem(results[pos])
	sk.affsystem();
	sk.traits();
	sk.diffsystem();
	sk.blocks();
}


var current = new String();
var max;

function exple(n) {
	document.frm.n.value=n;
	cherche();
}

