/**
 * erdosdemo1.java - 15/01/10
 * 
 * Auteur : Jean-Paul QUELEN
 * 
 * Applique le théorème de Erdös à un entier quelconque (sans les "BigInteger")
 * recherche la suite des +/- tels que m^p+(m+1)^p+...+(m+2^p-1)^p soit indépendant de m.
 * A partir de 5 cela devient très long !
 * ajout de main() le 07/01/18 et modification le 28/08/22
 */

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.math.BigInteger;

public class erdosdemo1 extends JPanel implements ActionListener {
	static final long serialVersionUID = 180107L;
	JTextField tp;
	TextArea ta;
	JButton ok, efface;
	BigInteger deux = new BigInteger ("2");

	public erdosdemo1() {
		setFont (new Font ("Arial, Helvetica, sans-serif", Font.PLAIN, 12));
		setBackground (Color.lightGray);
		setLayout (new BorderLayout ());
		JPanel pnl = new JPanel ();
		add (pnl, BorderLayout.NORTH);

// installe p = 2 et le bouton Ok dans le panneau "nord"
		pnl.add (new JLabel ("p ="));
		pnl.add (tp = new JTextField ("2", 10));
		pnl.add (ok = new JButton ("Ok"));
		ok.addActionListener (this);
		pnl.add (efface = new JButton ("Efface"));
		efface.addActionListener (this);

// installe le champ de texte "ta" qui recevra les éléments de la suite dans le panneau central
		pnl = new JPanel ();
		add (pnl);
		pnl.add (ta = new TextArea ("", 10, 40, TextArea.SCROLLBARS_VERTICAL_ONLY), BorderLayout.CENTER);
	}

	public void actionPerformed (ActionEvent evt) {
		if (evt.getSource() == ok ) {
			try {
				int p = Integer.parseInt (tp.getText());
				if (p <= 0)
					ta.setText ("Entrer un nombre entier supérieur ou égal à 1\n");
				else {
					int deuxpp = 1 << p;						// 2^p
					BigInteger bi = deux.pow (deuxpp - 1);		// On démarre à 10...0 (2^p chiffres)
//					bi = deux;									// C'est pour gagner du temps
					int lbi = bi.bitLength ();
					int lbi1 = lbi;
					while (lbi == lbi1) {						// Le nombre de chiffres doit être constant
						long sigma = 0;
						for (int i = 0; i < lbi; i ++)
							if (bi.testBit (i))
								sigma ++;
							else
								sigma --;
							if (sigma != 0) {
								bi = bi.add (BigInteger.ONE);
								lbi = bi.bitLength ();
								ta.append (".");				// pour faire patienter
							} else {
								for (int k = 1; k < p; k ++) {
									sigma = 0;
									for (int i = 1; i < lbi; i ++) {
										long ipk = 1;
										for (int k1 = 0; k1 < k; k1 ++)		// ipk = i^k
											ipk *= i;
										if (bi.testBit (i))
											sigma += ipk;
										else
											sigma -= ipk;
									}
									if (sigma != 0) {
										bi = bi.add (BigInteger.ONE);
										lbi = bi.bitLength ();
										ta.append (".");		// pour faire patienter
										break;
									}
								}
								if (sigma == 0) {					// C'est bon on affiche le résultat
									String sp = ")^" + p;
									String s = "";
									if (! bi.testBit (0))
										s = "-";
									s += "m^" + p;
									for (int i = 1; i < lbi; i ++) {
										long ipp = 1;
										for (int k1 = 0; k1 < p; k1 ++)			// ipk = i^k
											ipp *= i;
										if (bi.testBit (i)) {
											sigma += ipp;
											s += "+";
										} else {
											sigma -= ipp;
											s += "-";
										}
										s += "(m+" + i + sp; 
									}
									ta.append ("\n" + s + " = " + sigma + "\n\n");
									break;
								}
							}
						}
				}
		}
		catch (NumberFormatException nfe) { 
			ta.setText ("Entrer un nombre entier supérieur ou égal à 1\n");
		}
	} else if (evt.getSource() == efface ) {
		ta.setText("");
	}
}

	public static void main (String args []) {
		int w = 400;
		int h = 300;

		erdosdemo1 e = new erdosdemo1 ();
		JFrame f = new JFrame ("Erdosdemo1");
		f.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
		f.add (e);
		f.setSize (w, h);
		f.setVisible (true);
	}

}
