Question

I have to use Smalltalk to return the nth Fibonacci number, I haven't used this language before. This program returns 1 to any input and I don't know why. It didn't even iterate the for loop I think. Could someone help me? Thanks.

'Which fibonacci number do you want? (n>2)' printNl.
n := stdin nextLine asInteger.

(n <= 2)
    ifTrue: ['Type a larger number, F(1) and F(2) equals 1!' displayNl.]
    ifFalse: [  
        result:= 1.
        parent := 1.
        gparent := 1.   
        2 to: n do: [ :i | [
                result := (parent + gparent).
                gparent := parent.
                parent := result.
                'come on, do something' displayNl.
            ]
        ].
        result displayNl.
    ].
Was it helpful?

Solution 2

You have an extra set of brackets in your loop body, which makes it create (but not execute) a block on each loop iteration. Here's what you meant to write:

    2 to: n do: [ :i |
        result := (parent + gparent).
        gparent := parent.
        parent := result.
        'come on, do something' displayNl.
    ].

OTHER TIPS

You can simplify it even more if you want:

a := b := 1.
(n - 1) timesRepeat: [a := b + (b := a)].

The semi symmetric "ratchet" expression inside the block is one of my all time Smalltalk favorites. Not necessarily going to win readability contests, but I think it is cool looking. It drives home the strictly left to right rules of Smalltalk, whereas in other languages we'd want to mentally evaluate the rightmost assignment before placing the (original) value of b in the receiver position.

Notice also how I replaced your 2 to: n do: expression, since you're not using the i argument variable.

Why don't you define a method

fib
  ^ self < 2
    ifTrue: [ 1 ]
    ifFalse: [ (self - 2) fib + (self - 1) fib ]

in the Integer class and use it to calculate the sequence?

  1. Smalltalk is not a procedural language, you shouldn't write just a long script in one method.
  2. Use the beauty of recursion
fib := [:n |
        (n<=1)
            ifTrue: [n]
            ifFalse:
                [
                    (fib value: (n-1)) +
                    (fib value: (n-2))
                ]
    ].
fib value 10

for VisualWorks

(1 to: n)
inject: OrderedCollection new
into: [ :coll :each |
    | p pp n |
    p := coll at: (each - 1) ifAbsent: [ 0 ].
    pp := coll at: (each - 2) ifAbsent: [ 0 ].
    n := p + pp.
    ((n = 0) and: [ each = 1 ])
        ifTrue: [ n := 1 ].
    coll 
        add: n;
        yourself ].

In Pharo.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top