Smalltalk Prime Generator with a connected list not working

120 Views Asked by At

Been trying to debug this code for a while but I can't seem to understand the problem at hand. The program that I'm making is a Smalltalk program that has to use a connected list with nodes to generate prime numbers.

The problem at hand apparently is this line: But I can't seem to figure out what would need to be changed in it. As it seems correct to me. And the Smalltalk error codes are certainly not helping much: I Should note that I am using an online IDE (jdoodle.com) for coding this. This one in particular: https://www.jdoodle.com/execute-smalltalk-online/

If you drop the given code in https://www.jdoodle.com/execute-smalltalk-online/ You should get the same error. The full code:

Object subclass: #Node
    instanceVariableNames: 'value next'
    classVariableNames: ''
    poolDictionaries: ''
    category: 'MyApplication'

!Node methodsFor: 'initialization'!
init
    "Initialize a new node"
    
    super init.
    value := nil.
    next := nil.
    ^self
    
! !

!Node methodsFor: 'accessing'!
value
    "Return the node's value"
    
    ^value
    
! !

!Node methodsFor: 'accessing'!
next
    "Return the next node in the list"
    
    ^next
    
! !

!Node methodsFor: 'accessing'!
setValue: anObject
    "Set the node's value"
    
    value := anObject
    
! !

!Node methodsFor: 'accessing'!
setNext: aNode
    "Set the next node in the list"
    
    next := aNode
    
! !

Object subclass: #ConnectedList
    instanceVariableNames: 'head tail'
    classVariableNames: ''
    poolDictionaries: ''
    category: 'MyApplication'

!ConnectedList methodsFor: 'initialization'!
init
    "Initialize a new connected list"
    
    super init.
    head := nil.
    tail := nil.
    ^self
    
! !

!ConnectedList methodsFor: 'accessing'!
head
    "Return the head of the list"
    
    ^head
    
! !

!ConnectedList methodsFor: 'accessing'!
tail
    "Return the tail of the list"
    
    ^tail
    
! !

!ConnectedList methodsFor: 'accessing'!
isEmpty
    "Return true if the list is empty, false otherwise"
    
    ^head isNil
    
! !

!ConnectedList methodsFor: 'adding'!
add: anObject
    "Add an object to the list"
    
    | newNode |
    newNode := Node new.
    newNode setValue: anObject.
    newNode setNext: nil.
    
    "newNode := Node value: anObject next: nil." "Maybe we need to initialize a node first and then add values?"
    
    "If the list is empty, set the head and tail to the new node"
    head isNil
        ifTrue: [
            head := newNode.
            tail := newNode.
        ]
        
        "Otherwise, add the new node to the end of the list"
        ifFalse: [
            tail setNext: newNode. "maybe?: tail setNext: newNode | tail next: newNode"
            tail := newNode.
        ].
    
    ^self
    
! !

Object subclass: #PrimesGenerator
    instanceVariableNames: 'primes'
    classVariableNames: ''
    poolDictionaries: ''
    category: 'MyApp-PrimesGenerator'

!PrimesGenerator class methodsFor: 'instance creation'!
"Create a new PrimesGenerator object"
new
    "Initialize the object and return it"
    ^self basicNew initialize

! !

!PrimesGenerator methodsFor: 'initialization'!
initialize
    "Create a new ConnectedList to hold the prime numbers"
    primes := ConnectedList new.
    "Seed the list with the first prime number, 2"
    primes add: 2.
    ^self

! !

!PrimesGenerator methodsFor: 'generating primes'!
next
    "Return the next prime number in the sequence"
    | value |
    value := 3.
    
    "Continuously generate new values and check if they are prime. If not,
    generate the next value until a prime number is found"
    [ primes do: [ :each | value \\ each = 0 ifTrue: [ ^self next ] ] ] whileTrue.
    
    "Add the new prime number to the list"
    primes add: value.
    ^value

! !

"Create a new PrimesGenerator object"
generator := PrimesGenerator new.

"Generate the first 5 prime numbers"
1 to: 5 do: [ :i |
    Transcript show: generator next; cr.
].

The expected result of this code would be that it writes out the prime numbers as follows

2
3
5
7
11

Does anyone have an idea how to fix this?

1

There are 1 best solutions below

0
On

Actually looks pretty good for a first attempt. A little more work should get you going.

  1. Your ConnectedList does not have a new method.
  2. Your ConnectedList does not have an initialize method.
  3. Your Node class is missing the same two methods.
  4. The #whileTrue loop in your #next method is messed up.
   It should look something like this:

    [ aBooleanExpression
    ] whileTrue.

    Yours looks more like this:

    [ [someCode which does not result in a boolean].
    ] whileTrue.

5. Your ConnectedList does not have a #do: method.

    You'll need it to evaluate a1block parameter
    with each of the nodes in the ConnectedList,
    It should be something similar to this: 
    
    >>do: a1block
            node := head.
            [ node isNil
            ] whileFalse:
                [ a1block value: node.
                  node := node next
                ]