[Newbies] Re: Teaching Smalltalk.

Jerome Peace peace_the_dreamer at yahoo.com
Wed May 5 22:18:29 UTC 2010


Hi all,

Okay, I wanted to take a shot too.

I looked at the Gnu smalltalk version of the code and saw it was pretty good. I gave up trying to compete with it directly.

Then I thought about how I would do the optimized version. I wanted brevity. Plus I wanted to show why I like squeak, the ability to make clear readable code.

I usually practice code in a workspace before committing it to methods and such. So I ended up writing this as workspace code with the exception of adding a method to Integer which I would want it to have anyway.

So the optimized version where you recognize that only the square doors are left open:

| count doorEndsUp |
count := 100 .
doorEndsUp :=
[ :door | door isSquare
	ifTrue: [ ' Door  ' , door  , ' is open '  ] 
	ifFalse: [ ' Door  ' , door  , ' is closed '  ]  ] .

1 to: count do: [ :each |
	Transcript show: ( doorEndsUp value: each ) ; cr ] .

"plus Integers now know how to tell if they are square ."

Integer>>isSquare
"True if our square root has no fraction"
^ self sqrt \\ 1 = 0

I needed to define #isSquare because it was not there already. Also it would go against my style to put the low level test directly in doorEndsUp


doorEndsUp takes responsibility for producing the output string as the value of the door number.

Then the main loop takes responsibility for knowing where the output line is to be put and providing a door number to each door. It is actually just a message to all the door numbers.

The simulation version of the solution followed from the optimized version:

| count doorEndsUp swing doors |

count := 100 .
 
doors := Array new: count withAll: false .

doorEndsUp :=
[ :door | ( doors at: door )
	ifTrue: [ ' Door  ' , door  , ' is open '  ] 
	ifFalse: [ ' Door  ' , door  , ' is closed '  ]  ] .

swing :=
 [ :each  | doors at: each 
		put: ( doors at: each ) not ] .
 
1 to: count do: [ :eachPass |
 ( eachPass to: count by: eachPass ) do: swing .
  Transcript show: ( doorEndsUp value: eachPass ) ; cr ] .


Note we just had to change the predicate for doorEndsUp. Also to go along with the style we define swing to hide the details in the main routine. This makes it more readable.

To one up the other examples we note that when a doors pass comes up, by the end of the pass the doors final fate is known. So we simply combine the output with the the pass. This makes for a very simple, compact way to represent the problem.

Alright, now the itch is scratched. I await the restless coder who one ups me. 

Yours in curiosity and service, --Jerome Peace






      


More information about the Beginners mailing list