/* || ProthWeight.java || || Copyright 1998, 2002 John F. Brennen || Any noncommercial use of this code is permitted with only one || restriction: you must include the copyright line above and || this clause. || || || If you make improvements to this code or port it in any way, || please consider sending me a copy of your work. */ import java . awt . * ; import java . awt . event . * ; import java . applet . * ; import java . math . * ; import java . util . * ; public class ProthWeight extends Applet implements ActionListener , Runnable { private TextArea process_log_text ; private TextArea worst_k_text ; private TextArea best_k_text ; private TextField enumber_field ; private TextField number_field ; private TextField step_field ; private Button compute_button ; private Button stop_button ; private Button clog_button ; private Button cbest_button ; private Button cworst_button ; private Vector work_queue ; private BigInteger BigOne ; private Thread worker ; private BigInteger bestk [ ] ; private BigInteger worstk [ ] ; private double bestk_weight [ ] ; private double worstk_weight [ ] ; private int bestk_len ; private int worstk_len ; private boolean stop_it ; private void add ( Component c , int wx , int wy , int x , int y , int w , int h ) { GridBagConstraints gbc ; gbc = new GridBagConstraints ( ) ; gbc . weightx = wx ; gbc . weighty = wy ; gbc . gridx = x ; gbc . gridy = y ; gbc . gridwidth = w ; gbc . gridheight = h ; add ( c , gbc ) ; } public void init ( ) { setLayout ( new GridBagLayout ( ) ) ; add ( new Label ( "For k =" ) , 100 , 100 , 0 , 0 , 1 , 1 ) ; number_field = new TextField ( 9 ) ; add ( number_field , 100 , 100 , 1 , 0 , 2 , 1 ) ; add ( new Label ( "to" ) , 100 , 100 , 3 , 0 , 1 , 1 ) ; enumber_field = new TextField ( 9 ) ; add ( enumber_field , 100 , 100 , 4 , 0 , 2 , 1 ) ; add ( new Label ( "step" ) , 100 , 100 , 6 , 0 , 1 , 1 ) ; step_field = new TextField ( 9 ) ; add ( step_field , 100 , 100 , 7 , 0 , 2 , 1 ) ; compute_button = new Button ( "Compute Weight" ) ; compute_button . addActionListener ( this ) ; add ( compute_button , 100 , 100 , 7 , 1 , 2 , 1 ) ; stop_button = new Button ( "Stop" ) ; stop_button . addActionListener ( this ) ; add ( stop_button , 100 , 100 , 7 , 16 , 2 , 1 ) ; clog_button = new Button ( "Clear Log" ) ; clog_button . addActionListener ( this ) ; add ( clog_button , 100 , 100 , 5 , 15 , 2 , 1 ) ; cbest_button = new Button ( "Clear Best" ) ; cbest_button . addActionListener ( this ) ; add ( cbest_button , 100 , 100 , 2 , 2 , 2 , 1 ) ; cworst_button = new Button ( "Clear Worst" ) ; cworst_button . addActionListener ( this ) ; add ( cworst_button , 100 , 100 , 7 , 2 , 2 , 1 ) ; add ( new Label ( "Process Log:" ) , 100 , 100 , 2 , 15 , 3 , 1 ) ; process_log_text = new TextArea ( 5 , 30 ) ; process_log_text . setEditable ( false ) ; add ( process_log_text , 100 , 100 , 2 , 16 , 5 , 5 ) ; add ( new Label ( "Best k" ) , 100 , 100 , 0 , 2 , 2 , 1 ) ; best_k_text = new TextArea ( 12 , 30 ) ; best_k_text . setEditable ( false ) ; add ( best_k_text , 100 , 100 , 0 , 3 , 4 , 12 ) ; add ( new Label ( "Worst k" ) , 100 , 100 , 5 , 2 , 2 , 1 ) ; worst_k_text = new TextArea ( 12 , 30 ) ; worst_k_text . setEditable ( false ) ; add ( worst_k_text , 100 , 100 , 5 , 3 , 4 , 12 ) ; work_queue = new Vector ( ) ; BigOne = BigInteger . valueOf ( 1 ) ; bestk = new BigInteger [ 10 ] ; worstk = new BigInteger [ 10 ] ; bestk_weight = new double [ 10 ] ; worstk_weight = new double [ 10 ] ; bestk_len = 0 ; worstk_len = 0 ; } void new_best_weight ( BigInteger k , double w ) { BigInteger tk ; String mystr ; double tw ; int j ; for ( j = 0 ; j < bestk_len ; j ++ ) { if ( bestk [ j ] . compareTo ( k ) == 0 ) return ; } if ( bestk_len < bestk . length ) { bestk [ bestk_len ] = k ; bestk_weight [ bestk_len ] = w ; ++ bestk_len ; } else if ( w > bestk_weight [ bestk_len - 1 ] ) { bestk [ bestk_len - 1 ] = k ; bestk_weight [ bestk_len - 1 ] = w ; } else { return ; } j = bestk_len - 1 ; while ( j > 0 && bestk_weight [ j ] > bestk_weight [ j - 1 ] ) { tk = bestk [ j ] ; tw = bestk_weight [ j ] ; bestk [ j ] = bestk [ j - 1 ] ; bestk_weight [ j ] = bestk_weight [ j - 1 ] ; bestk [ j - 1 ] = tk ; bestk_weight [ j - 1 ] = tw ; -- j ; } mystr = new String ( ) ; for ( j = 0 ; j < bestk_len ; j ++ ) { mystr = mystr + "k : " + bestk [ j ] + ", w : " + bestk_weight [ j ] + "\n" ; } best_k_text . setText ( mystr ) ; } void new_worst_weight ( BigInteger k , double w ) { BigInteger tk ; String mystr ; double tw ; int j ; if ( w == 0 ) return ; for ( j = 0 ; j < worstk_len ; j ++ ) { if ( worstk [ j ] . compareTo ( k ) == 0 ) return ; } if ( worstk_len < worstk . length ) { worstk [ worstk_len ] = k ; worstk_weight [ worstk_len ] = w ; ++ worstk_len ; } else if ( w < worstk_weight [ worstk_len - 1 ] ) { worstk [ worstk_len - 1 ] = k ; worstk_weight [ worstk_len - 1 ] = w ; } else { return ; } j = worstk_len - 1 ; while ( j > 0 && worstk_weight [ j ] < worstk_weight [ j - 1 ] ) { tk = worstk [ j ] ; tw = worstk_weight [ j ] ; worstk [ j ] = worstk [ j - 1 ] ; worstk_weight [ j ] = worstk_weight [ j - 1 ] ; worstk [ j - 1 ] = tk ; worstk_weight [ j - 1 ] = tw ; -- j ; } mystr = new String ( ) ; for ( j = 0 ; j < worstk_len ; j ++ ) { mystr = mystr + "k : " + worstk [ j ] + ", w : " + worstk_weight [ j ] + "\n" ; } worst_k_text . setText ( mystr ) ; } void compute_weight ( BigInteger k ) { BigInteger ptab [ ] ; BigInteger r ; int evalue [ ] ; int dvalue [ ] ; byte sva [ ] ; int ecnt ; int n ; int i ; int d ; /* process_log_text . append ( "Working on " + k + "\n" ) ; */ ptab = new BigInteger [ 512 ] ; /* process_log_text . append ( "Computing powers ..." ) ; */ for ( n = 0 ; n <= 511 ; n ++ ) { ptab [ n ] = k . shiftLeft ( n ) . add ( BigOne ) ; } /* process_log_text . append ( " done\n" ) ; */ evalue = new int [ 500 ] ; dvalue = new int [ 500 ] ; ecnt = 0 ; for ( d = 1 ; d <= 256 ; d ++ ) { for ( i = 0 ; i < d ; i ++ ) { for ( n = 0 ; n < ecnt ; n ++ ) { if ( d % dvalue [ n ] == 0 && i % dvalue [ n ] == evalue [ n ] ) { break ; } } if ( n >= ecnt ) { r = ptab [ i ] . gcd ( ptab [ i + d ] ) ; if ( r . compareTo ( BigOne ) > 0 ) { /* process_log_text . append ( "Eliminate " + i + ", step " + d + "\n" ) ; */ evalue [ ecnt ] = i ; dvalue [ ecnt ] = d ; ecnt ++ ; } } } } sva = new byte [ 10000 ] ; for ( i = 0 ; i < 10000 ; i ++ ) sva [ i ] = 1 ; for ( n = 0 ; n < ecnt ; n ++ ) { i = evalue [ n ] ; d = dvalue [ n ] ; while ( i < 10000 ) { sva [ i ] = 0 ; i += d ; } } n = 0 ; for ( i = 0 ; i < 10000 ; i ++ ) n += sva [ i ] ; process_log_text . append ( "Weight of " + k + " is " + ( n / 1751.542 ) + "\n" ) ; new_best_weight ( k , n / 1751.542 ) ; new_worst_weight ( k , n / 1751.542 ) ; } void do_job ( String w , String x , String y ) { BigInteger k ; BigInteger z ; BigInteger d ; try { k = new BigInteger ( w ) ; } catch ( NumberFormatException e ) { process_log_text . append ( "Not a number: " + w + "\n" ) ; return ; } try { z = new BigInteger ( x ) ; } catch ( NumberFormatException e ) { process_log_text . append ( "Not a number: " + x + "\n" ) ; return ; } try { d = new BigInteger ( y ) ; } catch ( NumberFormatException e ) { process_log_text . append ( "Not a number: " + y + "\n" ) ; return ; } if ( d . signum ( ) == 0 ) { process_log_text . append ( "Can't step by 0!\n" ) ; return ; } stop_it = false ; for ( ; ; ) { if ( stop_it ) { process_log_text . append ( "Cancelled by user\n" ) ; break ; } if ( k . compareTo ( z ) == d . signum ( ) ) break ; compute_weight ( k ) ; k = k . add ( d ) ; } } public void run ( ) { String z ; String w ; String x ; String y ; w = null ; x = null ; y = null ; while ( isActive ( ) ) { synchronized ( work_queue ) { while ( work_queue . isEmpty ( ) ) { try { work_queue . wait ( ) ; } catch ( InterruptedException e ) { } } z = ( String ) work_queue . firstElement ( ) ; work_queue . removeElementAt ( 0 ) ; if ( z . equals ( "C" ) ) { w = ( String ) work_queue . firstElement ( ) ; work_queue . removeElementAt ( 0 ) ; x = ( String ) work_queue . firstElement ( ) ; work_queue . removeElementAt ( 0 ) ; y = ( String ) work_queue . firstElement ( ) ; work_queue . removeElementAt ( 0 ) ; } } if ( z . equals ( "C" ) ) { do_job ( w , x , y ) ; } if ( z . equals ( "L" ) ) { process_log_text . setText ( "" ) ; } if ( z . equals ( "B" ) ) { best_k_text . setText ( "" ) ; bestk_len = 0 ; } if ( z . equals ( "W" ) ) { worst_k_text . setText ( "" ) ; worstk_len = 0 ; } } worker = null ; } public void start ( ) { if ( worker == null ) { worker = new Thread ( this ) ; worker . start ( ) ; } } public void actionPerformed ( ActionEvent evt ) { if ( evt . getActionCommand ( ) . equals ( "Compute Weight" ) ) { synchronized ( work_queue ) { work_queue . addElement ( "C" ) ; work_queue . addElement ( number_field . getText ( ) . trim ( ) ) ; work_queue . addElement ( enumber_field . getText ( ) . trim ( ) ) ; work_queue . addElement ( step_field . getText ( ) . trim ( ) ) ; work_queue . notify ( ) ; } } if ( evt . getActionCommand ( ) . equals ( "Stop" ) ) { stop_it = true ; } if ( evt . getActionCommand ( ) . equals ( "Clear Log" ) ) { synchronized ( work_queue ) { work_queue . addElement ( "L" ) ; work_queue . notify ( ) ; } } if ( evt . getActionCommand ( ) . equals ( "Clear Best" ) ) { synchronized ( work_queue ) { work_queue . addElement ( "B" ) ; work_queue . notify ( ) ; } } if ( evt . getActionCommand ( ) . equals ( "Clear Worst" ) ) { synchronized ( work_queue ) { work_queue . addElement ( "W" ) ; work_queue . notify ( ) ; } } } }