Talk About Network



Register and Login
Nick
Password
Register create new account Sign up is FREE and you can post replies, new topics, bookmark posts and more!
Recover lost password


Programming > Forth > Euler problem #...
Latest [ Topics | Posts ] Archive Post A New Topic Post a Reply
<< Topic < Post Post 1 of 12 Topic 4022 of 4053
Post > Topic >>

Euler problem #22

by mhx@[EMAIL PROTECTED] (Marcel Hendrix) Apr 27, 2008 at 02:29 PM

This Euler problem was relatively complicated.
Download names.txt from http://projecteuler.net/index.php?section=problems
.

$PROCESS            "string-process"                                
IFORTH
     ( c-addr u xt -- )
     The counted string described by c-addr and u becomes the temporary
input
     buffer during the execution of xt. The following code is equivalent:

     CREATE foo 4 ,
     S" foo "  ' CREATE  $PROCESS 4 ,

     See also: EVALUATE

$PROCESS is available in Gforth under a name I can never remember.

DLSHIFT             "d-l-shift"                                     
IFORTH
     ( d1 x -- d2 )
     Logically shift d1 over x bits to the left, giving the result d2. A 0
     bit is inserted at the right end of the value.

DRSHIFT             "d-r-shift"                                     
IFORTH
     ( d1 x -- d2 )
     Logically shift d1 over x bits to the right, giving the result d2. A
0
     bit is inserted at the left end of the value. Since this bit is also
the
     sign bit for signed numbers, the sign bit is cleared by this command.

<WORD>              "fast-word"                                     
IFORTH
     ( c -- c-addr u )
     Perform the scanning functions of WORD . However the result is given
as
     a character string. In this way the command executes much faster than
     WORD .

-marcel

--
--------------------------------------------------------------------------------------
: DOUBLE[]  2* CELLS + ;
: []DOUBLE  SWAP 2* CELLS + ;
: CELL[]    CELLS + ;
: []CELL    SWAP CELLS + ;

(*
	Using names.txt, a 46K text file containing over five-thousand first
names, 
	begin by sorting it into alphabetical order. Then working out the
alphabetical
	value for each name, multiply this value by its alphabetical position in
the 
	list to obtain a name score.

	For example, when the list is sorted into alphabetical order, COLIN,
which is 
	worth 3 + 15 + 12 + 9 + 14 = 53, is the 938th name in the list. So, COLIN
would
	obtain a score of 938 * 53 = 49714.
	
	What is the total of all the name scores in the file?

	Example output:

	FORTH> euler22

	The total of all the name scores in the file names.txt is 18,049,839,040
	0.005 seconds elapsed. ok
	FORTH> .colin
	COLIN should be item #938, worth 53, score of 938 * 53 = 49714
	COLIN_______is worth 53, score = 49714  ok
	FORTH> 0 5 .index
	AARON_______    $00000031
	ABBEY_______    $00000023
	ABBIE_______    $00000013
	ABBY________    $0000001E
	ABDUL_______    $00000028 ok
*)

0 VALUE #items 				
CREATE nameindex #6000 2* CELLS ALLOT	
CREATE namevals  #6000    CELLS ALLOT	
CREATE dummy     #12 1+   CHARS ALLOT	

\ names.txt is quoted, comma-delimited, uppercased and contains no line
feeds. 
: fetch-names ( -- addr size )
	S" names.txt" R/O BIN OPEN-FILE THROW LOCALS| handle |
	PAD #100000 handle READ-FILE THROW
	handle CLOSE-FILE THROW
	PAD SWAP ; 

: SKIP-, ( -- ) BEGIN  SOURCE DROP >IN @[EMAIL PROTECTED]
 + C@[EMAIL PROTECTED]
 ','  = WHILE  1 >IN +! 
REPEAT ; 
: EOI?   ( -- bool ) SOURCE NIP >IN @[EMAIL PROTECTED]
 <= ; 

: indexed ( c-addr u1 -- ) 
	0. DLOCAL hash
	dummy #13 '_' FILL  #12 MIN dummy PACK COUNT DROP 
	#12 0 ?DO  C@[EMAIL PROTECTED]
 'A' - $1F AND 0  hash 5 DLSHIFT D+ TO hash  LOOP DROP 
	hash  nameindex #items DOUBLE[] 2! ; 

: PRINT~NAME ( ud -- ) 
	DLOCAL name
	CR #12 0 DO  name #11 I - 5 * DRSHIFT DROP  $1F AND 'A' + EMIT  LOOP ; 

\ Test 1; print the index. This succeeds in printing names that are 12
characters 
\ or shorter. This is however only a side-effect: names are not stored.
: .INDEX ( begin end -- ) 
	2DUP > IF SWAP ENDIF  #items MIN   SWAP 0 MAX 
	 ?DO  	nameindex I DOUBLE[] 2@[EMAIL PROTECTED]
 PRINT~NAME
		4 SPACES  
		namevals I CELL[] @[EMAIL PROTECTED]
 H.
	LOOP ;

\ 'A' is worth 1 etc.
: alphabeticized ( c-addr u1 -- ) 
	0 -ROT 0 ?DO  C@[EMAIL PROTECTED]
 'A' - 1+ ROT + SWAP  LOOP DROP  
	namevals  #items CELL[] ! ; 

\ Test 2. It is defined where COLIN should be.
: .COLIN ( -- )
	CR ." COLIN should be item #938, worth 53, score of 938 * 53 = 49714"
	nameindex #938 1- DOUBLE[] 2@[EMAIL PROTECTED]
 PRINT~NAME 
	." is worth " namevals #938 1- CELL[] @[EMAIL PROTECTED]
 DUP 0 .R  ." , score = " #938 * .
;


\ C.A.R Hoare's famous QUICKSORT

: $>=  ( ix1 ix2 -- bool )  SWAP nameindex []DOUBLE 2@[EMAIL PROTECTED]
  ROT nameindex
[]DOUBLE 2@[EMAIL PROTECTED]
 D>= ;
: $>   ( ix1 ix2 -- bool )  SWAP nameindex []DOUBLE 2@[EMAIL PROTECTED]
  ROT nameindex
[]DOUBLE 2@[EMAIL PROTECTED]
 D>  ;

: XCHG ( ix1 ix2 -- ) 
	0 0 LOCALS| a2 a1 ix2 ix1 |
	nameindex ix1 DOUBLE[] TO a1 
	nameindex ix2 DOUBLE[] TO a2
	a1 2@[EMAIL PROTECTED]
 a2 2@[EMAIL PROTECTED]
 a1 2! a2 2! 
	namevals ix1 CELL[] TO a1 
	namevals ix2 CELL[] TO a2
	a1 @[EMAIL PROTECTED]
 a2 @[EMAIL PROTECTED]
 a1 ! a2 ! ; 

\ The newest qsort algorithm (Bentley) integrates 3-way partioning.
: QUICKSORT ( l r -- ) RECURSIVE
	2DUP >= IF  2DROP EXIT  ENDIF
	0 0 0 0 LOCALS| m I J pivot r l |
	l 1- TO I   r TO J 
	r l - 3 > IF	r l + 2/ TO m  ( median-of-three pivot selection )
			l m $> IF  l m XCHG  ENDIF
			l r $> IF  l r XCHG  ELSE  
			r m $> IF  r m XCHG  ENDIF ENDIF
	       ENDIF
	r TO pivot  ( note that we need a check on J becoming out of bounds )
	BEGIN	BEGIN  1 +TO I  I pivot $>=  UNTIL
		BEGIN  1 -TO J  J pivot $>   WHILE  J l = UNTIL THEN
		I J < 
	WHILE	I J XCHG 
	REPEAT	I r XCHG
	l I 1- QUICKSORT
	I 1+ r QUICKSORT ;

: INDEXED-SORT ( -- ) 0 #items 1- QUICKSORT ;

: store ( -- ) 
	CLEAR #items
	BEGIN  
	  &" <WORD> 
	  2DUP indexed
	       alphabeticized
	  1 +TO #items
	  SKIP-,
	  EOI?
	UNTIL ;

\ index should go from 1 to #items for the purpose of counting.
: NAME-SCORES ( -- ud )
	0. #items 0 DO  namevals I CELL[] @[EMAIL PROTECTED]
  I 1+ *  0 D+  LOOP ;

: Euler22 ( -- ) 
	fetch-names 
	['] store $PROCESS
	INDEXED-SORT 
	CR ." The total of all the name scores in the file names.txt is "
NAME-SCORES D. ; 

: .ABOUT CR ." Euler22 -- What is the total of all the name scores in the
file names.txt?" ;

	.ABOUT




 12 Posts in Topic:
Euler problem #22
mhx@[EMAIL PROTECTED] (M  2008-04-27 14:29:26 
Re: Euler problem #22
William James <w_a_x_m  2008-04-27 13:51:04 
Re: Euler problem #22
William James <w_a_x_m  2008-04-29 08:31:00 
Re: Euler problem #22
Andrew Haley <andrew29  2008-04-29 12:34:13 
Re: Euler problem #22
mhx@[EMAIL PROTECTED] (M  2008-04-29 20:44:53 
Re: Euler problem #22
Bruce McFarling <agila  2008-04-29 11:35:03 
Re: Euler problem #22
Slava Pestov <slava@[E  2008-04-29 20:57:36 
Re: Euler problem #22
mhx@[EMAIL PROTECTED] (M  2008-04-30 09:34:59 
Re: Euler problem #22
Zev Weiss <i_dance_on_  2008-04-30 08:05:58 
Re: Euler problem #22
mhx@[EMAIL PROTECTED] (M  2008-04-30 10:59:09 
Re: Euler problem #22
Albert van der Horst <  2008-04-30 08:19:44 
Re: Euler problem #22
Jonah Thomas <jethomas  2008-04-29 17:30:15 

Post A Reply:
  Go here to Signup

AddThis Feed Button


About - Advertising - Contact - Frequently Asked Questions - Privacy Policy - Terms of Use - Signup

Contact
tan12V112 Wed May 14 21:28:39 CDT 2008.