// $Id: Reappear.java,v 1.1 1999/05/19 17:52:25 schmidt Exp $ // Integers That Reappear in Their Squares // Copyright (C) 1999 Eric A. Schmidt // // This applet generates any N-digit integer that reappears in its square. // Correctness was my main focus. There is room for optimization. import java.awt.*; import java.awt.event.*; import java.applet.*; import java.math.*; public class Reappear extends Applet implements ActionListener { static BigInteger m_zero = new BigInteger( "0" ); static BigInteger m_one = new BigInteger( "1" ); static BigInteger m_five = new BigInteger( "5" ); static BigInteger m_six = new BigInteger( "6" ); static BigInteger m_ten = new BigInteger( "10" ); String m_n; BigInteger m_max = new BigInteger( "500" ); TextArea m_messageArea = null; TextField m_nTextField = null; TextField m_5TextField = null; TextField m_5SquaredTextField = null; TextField m_6TextField = null; TextField m_6SquaredTextField = null; TextField m_sumTextField = null; public void init() { m_n = System.getProperty( "line.separator" ); GridBagLayout gridBag = new GridBagLayout(); setLayout( gridBag ); GridBagConstraints c = new GridBagConstraints(); c.gridwidth = GridBagConstraints.REMAINDER; c.fill = GridBagConstraints.BOTH; c.weightx = 1.0; c.weighty = 1.0; m_messageArea = new TextArea( "", 10, 50, TextArea.SCROLLBARS_VERTICAL_ONLY ); m_messageArea.setEditable( false ); gridBag.setConstraints( m_messageArea, c ); add( m_messageArea ); c.gridwidth = GridBagConstraints.REMAINDER; c.fill = GridBagConstraints.HORIZONTAL; c.weightx = 1.0; c.weighty = 0.0; m_nTextField = new TextField( "Enter integer N here and press ENTER.", 50 ); m_nTextField.addActionListener( this ); gridBag.setConstraints( m_nTextField, c ); add( m_nTextField ); c.gridwidth = GridBagConstraints.REMAINDER; c.fill = GridBagConstraints.HORIZONTAL; c.weightx = 1.0; c.weighty = 0.0; m_5TextField = new TextField( "The 5-based reapearing integer will appear here.", 50 ); m_5TextField.setEditable( false ); gridBag.setConstraints( m_5TextField, c ); add( m_5TextField ); c.gridwidth = GridBagConstraints.REMAINDER; c.fill = GridBagConstraints.HORIZONTAL; c.weightx = 1.0; c.weighty = 0.0; m_6TextField = new TextField( "The 6-based reapearing integer will appear here.", 50 ); m_6TextField.setEditable( false ); gridBag.setConstraints( m_6TextField, c ); add( m_6TextField ); c.gridwidth = GridBagConstraints.REMAINDER; c.fill = GridBagConstraints.HORIZONTAL; c.weightx = 1.0; c.weighty = 0.0; m_5SquaredTextField = new TextField( "The square of the 5-based integer will appear here.", 50 ); m_5SquaredTextField.setEditable( false ); gridBag.setConstraints( m_5SquaredTextField, c ); add( m_5SquaredTextField ); c.gridwidth = GridBagConstraints.REMAINDER; c.fill = GridBagConstraints.HORIZONTAL; c.weightx = 1.0; c.weighty = 0.0; m_6SquaredTextField = new TextField( "The square of the 6-based integer will appear here.", 50 ); m_6SquaredTextField.setEditable( false ); gridBag.setConstraints( m_6SquaredTextField, c ); add( m_6SquaredTextField ); c.gridwidth = GridBagConstraints.REMAINDER; c.fill = GridBagConstraints.HORIZONTAL; c.weightx = 1.0; c.weighty = 0.0; m_sumTextField = new TextField( "The sum of the 5- and 6-based integers will appear here.", 50 ); m_sumTextField.setEditable( false ); gridBag.setConstraints( m_sumTextField, c ); add( m_sumTextField ); displayMessage( "Enter the number of digits, N, in the first field below " + "and press ENTER to calculate both N-digit integers " + "that reappear in their squares." ); displayMessage( "Their respective squares and their sum will also be calculated." ); displayMessage( "For example, input 3 for N. Press ENTER and you will see " + "625 and 376 appear because they are the two 3-digit integers " + "that reappear in their squares." ); displayMessage( "The larger the input, the longer the calculation time." ); } public void actionPerformed( ActionEvent event ) { TextField field = m_nTextField; String input = field.getText(); BigInteger i = m_zero; if ( input.length() == 0 ) { displayMessage( "Please enter number of digits, N, and press ENTER." ); return; } try { i = new BigInteger( input ); } catch ( NumberFormatException e ) { displayMessage( "Please enter only numerical characters." ); return; } if ( i.compareTo( m_max ) > 0 ) { displayMessage( "For this applet, input must not exceed " + m_max.toString() + "." ); return; } // A way to strip off any leading zeros. input = i.toString(); field.setText( input ); if ( i.compareTo( m_zero ) <= 0 ) { displayMessage( "Input must be positive." ); return; } displayMessage( "Calculating..." ); BigInteger int5 = A( i.intValue() ); BigInteger int6 = B( i.intValue() ); m_5TextField.setText( "A = " + int5.toString() ); m_6TextField.setText( "B = " + int6.toString() ); BigInteger int5Squared = int5.multiply( int5 ); BigInteger int6Squared = int6.multiply( int6 ); m_5SquaredTextField.setText( "A squared = " + int5Squared.toString() ); m_6SquaredTextField.setText( "B squared = " + int6Squared.toString() ); BigInteger sum = int5.add( int6 ); m_sumTextField.setText( "A + B = " + sum.toString() ); displayMessage( "...done." ); } public void displayMessage( String message ) { m_messageArea.append( ":: " + message + m_n ); } // int_pow( x, y ) == (BigInteger)pow( x, y ). private BigInteger int_pow( BigInteger x, int y ) { BigInteger result = m_one; // Don't modify input. int y_ = y; // FIXME - This can be optimized by breaking y down into binary. while ( y_ > 0 ) { --y_; result = result.multiply( x ); } return result; } // Calculate A sub j. public BigInteger A( int j ) { // Recursion end. if ( j == 1 ) return m_five; BigInteger A_ = A( j - 1 ); return ( A_.multiply( A_ ).subtract( A_ ) ). mod( int_pow( m_ten, j ) ). add( A_ ); } // Calculate B sub j. public BigInteger B( int j ) { // Recursion end. if ( j == 1 ) return m_six; BigInteger B_ = B( j - 1 ); return ( B_.subtract( B_.multiply( B_ ) ) ). mod( int_pow( m_ten, j ) ). add( B_ ); } }