Smalltalk Prime Generator with a connected list not working - linked-list

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?

Actually looks pretty good for a first attempt.
A little more work should get you going.
Your ConnectedList does not have a new method.
Your ConnectedList does not have an initialize method.
Your Node class is missing the same two methods.
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
]

Related

Insertion sort with a linked list, "Segmentation fault - invalid memory reference" - Fortran

I am trying to use a linked list to do selection sort. However, I receive a segmentation fault.
"""
Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
Backtrace for this error:
\#0 0x7f191e86a32a
\#1 0x7f191e869503
\#2 0x7f191e49cf1f
\#3 0x7f191e9e9330
\#4 0x7f191e9ed0b4
\#5 0x7f191e9e423c
\#6 0x7f191e9e46dc
\#7 0x55ed5c77be79
\#8 0x55ed5c77bfa6
\#9 0x7f191e47fb96
\#10 0x55ed5c77b9c9
\#11 0xffffffffffffffff
Segmentation fault (core dumped)
"""
I'm convinced it is caused when I try and write out the data in between my "output" do loop. I find it quite dificult to see how I screw up with the memory.
Any help is very much appreciated! Thank you very much in advance!
program insertion_sort
implicit none
! Derived data type to store integer values in
type int_value
integer :: value
type (int_value), pointer :: next_value
end type
! Data dictionary: declare variable types & definitions
type (int_value), pointer :: head ! Pointer to head of list
character(20) :: filename ! input data file name
integer :: istat ! status: 0 for succes
integer :: nvals = 0 ! Number of data read
type (int_value), pointer :: ptr ! Ptr to new value
type (int_value), pointer :: ptr1 ! Temp ptr for search
type (int_value), pointer :: ptr2 ! Temp ptr for search
type (int_value), pointer :: tail ! Pointer to tail of list
integer :: temp ! Temporary variable
! Get the name of the file containing the input data
write (*,*) 'Enter the file name with the data to be sorted'
read (*,'(A20)') filename
! Open input data file
Open (Unit=9, file=filename, status='OLD', action='read', &
iostat=istat )
! Was the open succesful
fileopen: if ( istat == 0 ) then ! Open succesful
! The file was opened succesfully, so read the data value
! to sort, allocate a variable for it, and locate the proper
! point to insert the new value into the list
input: do
read (9, *, iostat=istat) temp ! Get value
if ( istat /=0 ) exit ! Exit on end of data
nvals = nvals + 1 ! Bump count
allocate (ptr, STAT=istat) ! Get value
ptr%value = temp ! Store number
! Now find out where to put it in the list.
new: if (.not. associated(head)) then ! No values in list
head => ptr ! Place at front
tail => head ! Tail pts to new value
nullify (ptr%next_value) ! nullify next ptr
else
! Values alreadd in list. Check for location.
front: if ( ptr%value < head%value ) then
! Add at front of list
ptr%next_value => head
head => ptr
else if ( ptr%value >= tail%value ) then
! Add at end of list
tail%next_value => ptr
tail => ptr
nullify (tail%next_value)
else
! Find place to add value
ptr1 => head
ptr2 => ptr1%next_value
search: do
if ( (ptr%value >= ptr1%value) .and. &
(ptr%value < ptr2%value) ) then
! Insert value here
ptr%next_value => ptr2
ptr1%next_value = ptr
exit search
end if
ptr1 => ptr2
ptr2 => ptr2%next_value
end do search
end if front
end if new
end do input
! WHERE I BELIEVE THE SEGMENTATION FAULT OCCURS
! Now write out the data.
ptr => head
output: do
if ( .not. associated(ptr) ) exit ! Pointer valid?
write (*, '(I10)') ptr%value ! Yes: Write value
ptr => ptr%next_value ! Get next pointer
deallocate(ptr, StAT=istat)
end do output
else fileopen
! Else file open failed. Tell user.
write (*, '(A,I6)') 'File open failed--status =', istat
end if fileopen
end program insertion_sort
Just to follow up. I have finished the code and it works now. The segmentation fault was avoided by nullifying the head pointer in the beginning. The previous code also had issues in its if statements, as it before did not account for the last or first number being either highest or lowest.
program insertion_sort
implicit none
! Derived data type to store integer values in
type int_value
real :: value
type (int_value), pointer :: p
end type
! Data dictionary: declare variable types & definitions
type (int_value), pointer :: head => null() ! Pointer to head of list
character(20) :: filename ! input data file name
integer :: istat ! status: 0 for succes
integer :: nvals = 0, i = 0 ! Number of data read
type (int_value), pointer :: ptr ! Ptr to new value
type (int_value), pointer :: ptr1 ! Temp ptr for search
type (int_value), pointer :: ptr2 ! Temp ptr for search
type (int_value), pointer :: tail ! Pointer to tail of list
real :: temp ! Temporary variable
character(80) :: msg ! I/O Message
! Get the name of the file containing the input data
write (*,*) 'Enter the file name with the data to be sorted'
read (*,'(A20)') filename
! Open input data file
Open (Unit=9, file=filename, status='OLD', action='read', &
iostat=istat, iomsg=msg )
! Was the open succesful
fileopen: if ( istat == 0 ) then ! Open succesful
! The file was opened succesfully, so read the data value
! to sort, allocate a variable for it, and locate the proper
! point to insert the new value into the list
input: do
read (9, *, iostat=istat) temp ! Get value
if ( istat /=0 ) exit ! Exit on end of data
nvals = nvals + 1 ! Bump count
allocate (ptr, STAT=istat) ! Get value
ptr%value = temp ! Store number
! Now find out where to put it in the list.
new: if (.not. associated(head)) then ! No values in list
head => ptr ! Place at front
tail => head ! Tail pts to new value
nullify (ptr%p) ! nullify next ptr
else
! Values alreadd in list. Check for location.
front: if ( ptr%value <= head%value ) then
! Add at front of list
ptr%p => head
head => ptr
else if ( ptr%value >= tail%value ) then
! Add at end of list
tail%p => ptr
tail => ptr
nullify (tail%p)
else
! Find place to add value
ptr1 => head
ptr2 => ptr1%p
search: do
if ( (ptr%value >= ptr1%value) .and. &
(ptr%value <= ptr2%value) ) then
! Insert value here
ptr%p => ptr2
ptr1%p = ptr
exit search
end if
ptr1 => ptr2
ptr2 => ptr2%p
end do search
end if front
end if new
end do input
!Now write out the data.
ptr => head
output: do
if ( .not. associated(ptr) ) exit ! Pointer valid?
write (*, '(F10.4)') ptr%value ! Yes: Write value
ptr => ptr%p ! Get next pointer
end do output
deallocate(ptr,STAT=istat)
else fileopen
! Else file open failed. Tell user.
write (*, '(A,I6)') 'File open failed--status =', istat
end if fileopen
end program insertion_sort

NetLogo: histogram

I have a problem with
[histogram]
In particular, I have a global variable (prova) that records the age of the turtles when they get sick.
In the beginning of the code I define prova as follows
set prova (list)
Then in the go procedure turtles can get sick, if they do then I want to record their age
ask turtles [
if ... [
set prova lput y prova ]]
When I try to plot this variable
[histogram] prova
I get the following error "expected a constant"
I don't understand why...since "prova" is a list I thought it worked!
#JenB It should be a list...

Duplicated output in Maxima

I implemented the bubble sort method in Maxima as:
burbuja(l) := block(
for i : 1 step 1 thru length(l) do (
for j : length(l) - 1 step -1 while j >= i do (
if l[j] > l[j + 1] then (
elemento : l[j],
l[j] : l[j + 1],
l[j + 1] : elemento
)
)
), print(l)
);
The problem is that the output is something like this:
(%i1) burbuja([3,2,1]);
[1, 2, 3]
(%o1) [1, 2, 3]
If I remove print(l) from the penultimate line, this is the output:
(%i1) burbuja([3,2,1]);
(%o1) done
The question is how can I print the result without duplicating it?
Thanks.
Instead of print(l) just put l to return the value of l from the function. (Do not put return(l) as the effect of return is actually somewhat different from other languages.)
I also recommend copying the list before sorting it, so that you don't modify the original list. Try l : copy(l) before anything else.
As a complement of Robert Dodier's answer, some more words for explaining what is happening. Maxima has a functional language with following features:
last term in a block is also the value "returned" by this block;
print has to be taken as a function rather than a mere statement.
These two ideas explain what happend in your case:
the print(l) in your code performs something on your screen but also is an expression evaluating to l (try for instance something like a:print(5)$ which will print the number 5 but also assign the value 5 to the variable a;
since print(l) is also the last term in your block, your block will evaluate to l.
Thus your code prints l and also "return" it.
I found the problem. Instead of print(l) I should use append(l).

update all line of table in erlang

I have this table :
-record(person, {id, firstname, lastname, address}).
for example this table contains this values :
2 alen dumas paris
5 franco mocci parma
3 ali othmani london
Now I have the variable Key which contains this value 10
I want to develop a function in erlang which will modify all id of the table person
the new value of this id will be the previous value + the value of Key
mean the table person will became like this
12 alen dumas paris
15 franco mocci parma
13 ali othmani london
meaning each id will be added by 10 (is the value of Key) :(2+10) (5+10) (3+10)
I try with your code :
testmodify()->
Key=22,
[ P#person{id=P#person.id+Key} || P <- Persons ].
but I have this error in the sysntax : variable Persons is unbound
I try to resolve this problem with this code :
testmodify()->
Key=22,
[ P#person{id=P#person.id+Key} || P <- mnesia:table(person) ].
but I have this error :
1> model:testmodify().
** exception error: no function clause matching
model:'-testmodify/0-lc$^0/1-0-'({qlc_handle,
{qlc_table,
#Fun<mnesia.20.112329951>,
true,
#Fun<mnesia.21.62211129>,
#Fun<mnesia.22.75429001>,
#Fun<mnesia.23.26336897>,
#Fun<mnesia.26.62819299>,
#Fun<mnesia.25.51075493>,
#Fun<mnesia.24.47804912>,
'=:=',undefined,
no_match_spec}})
Assuming your table is stored as a list:
[ P#person{id=P#person.id+Key} || P <- Persons ].
UPDATE: For an Mnesia table, you can retrieve similar results with QLC:
-include_lib("stdlib/include/qlc.hrl").
⋮
[ P#person{id=P#person.id+Key} || P <- mnesia:table(person) ].
Note that this only gives you a list of transformed person records. To update the records, you'll probably have to remove the existing records and write the new records in a transaction, since a record with a modified key (assuming that's what id is) is treated as a different record — something like this:
mnesia:transaction(fun() ->
Old = [ P || P <- mnesia:table(person) ],
New = [ P#person{id=P#person.id+Key} || P <- Old ],
[ mnesia:delete({person, P#Person.id}) || P <- Old ],
[ mnesia:write(P) || P <- New ]
end)
You might be able to do this in a single pass with mnesia:foldr, but I don't know what happens if you issue mnesia:delete and mnesia:write inside mnesia:foldr. You might get stuck in an infinite loop (but don't quote me on that).

applying non procedure and non object error

declare
fun {Factorial N}
local FactorialAux in
fun {FactorialAux N Product}
if N == 0 then Product
else {FactorialAux N-1 {fibo N}|Product}
end
end
{FactorialAux N nil}
end
end
fun {fibo N}
if N==1 then 1
else if N==2 then 1
else {fibo N-1}+{fibo N-2}
end
end
end
{Browse {Factorial 3}}
My code prints the list of fibonacci number.If N =4 then it prints first four fibonacci number list
This is my code in which i am getting the error stated in the heading of question.
Thanks for any help in advance
Variables must start with an uppercase letter in Oz. Procedure and function names are always variables, so they must also start with an uppercase letter.
Your function fibo should be called Fibo. And of course, all calls to fibo must be fixed, too.

Resources