Re: Teaching Smalltalk.

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Re: Teaching Smalltalk.

Jerome Peace
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






     
_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners