-- Enots Wolley sequence

toBinNoPad = n -> (
    if n==0 then(
	return {0};
	);
    nDiv := floor (n/2);
    {n%2}|(toBinNoPad nDiv)
    );
-- Converts n >= 0 to a list of length P containing binary digits
toBin := (n,P) -> (
    bin := toBinNoPad(n);
    l := length bin;
    bin|toList((P-l):0)
    );
fromBin := n -> (
    placeVal := 1;
    sum for i in n list(
	x := i*placeVal;
	placeVal = placeVal + placeVal;
	x
       	)
    )

strPad = (S, n) -> (
    newS := toString(S);
    if #newS >= n then (
	return S;
	);
    for i from 0 to (n-(#newS))-1 do(
	newS = newS | " "; 
	);
    
    newS
    );

-- gndList: set which S is a subset of
-- S: a subset of gndList
-- k: the number of charachters per cell
-- symTable: hash table mapping gndList to symbols for printing (can be null)
setPrint = (gndList, S, k, symTable) -> (
    
    outStr := "";
    for i in gndList do(
	if(member(i, S)) then(
	    
	    sym := "X";
	    if symTable =!= null and symTable#?i then(
	       sym = toString(symTable#i);
	       );
	    
	    
	    outStr = outStr | strPad(sym, k);
	    )else(
	    outStr = outStr | strPad(" ", k);
	    );
	);
    outStr
    );
getDivHT = n -> (
    divs := factor n;
    new HashTable from for i in divs list(
	i#0 => i#1
	)
    );
getDivs = n -> (
    f := factor n;
    apply(#f,i->apply(#(f#i),j->f#i#j))
    );

getKer = n -> (
    set(apply(pairs n, x-> ((first x)+1)*(last x)))-set({0})
    );
relPrime = (a,b) ->(
    #((getKer a)*(getKer b)) == 0
    );
intersects = (a,b) -> (
    ((getKer a)*(getKer b)) =!= set({})
    );
requirementBits := (a,b) -> (
    (getKer b)-(getKer a)
    )

N = 100
numBits := 16
a = toBin(3, numBits);
b = toBin(6, numBits);
newB = 0;
found = set({a,b})
-- The amount of charachters to pad the label portion to when printing
lblPad = 8;

symHT := new HashTable from apply(toList(0..numBits), x -> x => 1); 

printEnt = (val, ind) -> (
    kerVal := getKer val;
    s1 := strPad("a("|toString(ind)|")",lblPad)|"= ";
    s2 := " = "|toString(fromBin(val));
    print(s1|setPrint(toList(1..numBits), kerVal, 3, symHT)|s2);    
    );
printEnt(a, 1);
printEnt(b, 2);

for i from 0 to N do(
    j := 1;
    while true do( 
	j = j + 1;
	jBin := toBin(j,numBits);
	A := not relPrime(b,jBin);
    	B := relPrime(a,jBin);
	C := not member(jBin, found);
	--C := true;
	D := #((getKer jBin) - (getKer b)) > 0;
	if A and B and C and D then(
	    newB = jBin;
	    found = found + set({jBin});
	    break;
	    );
       	);    
    
    a = b;
    b = newB;

    printEnt(newB, i+2);
    );

error "stop"