Re: Goto (Was Re: Open Source)
Juergen Luethje wrote:
> > If I didn't make a mistake, this translates to the following Eu program:
<snip>
> I actually would prefer to write the code this way:
<snip>
> Now this is short and pretty clear. Without using GOTO, the structure of
> the program (2 nested loops) is directly visible. So the "nature" of the
> program can be understood immediately and intuitively.
No arguments here, but you did need two attempts even on such a trivial piece of
code
> Sorry, I do not know anything about COBOL.
Try this then:
-- optimised best-fit algorithm
include sort.e
integer required
required = 2482
-- expected results with first sizes set:
--Exact 2482: 12 505, 10 425, 7 396, 6 391, 5 388, 1 377
-- expected results with second sizes set:
--Lower 2324: 6 798, 5 734, 3 410, 2 382
--Higher 2520: 5 734, 4 650, 3 410, 2 382, 1 344
required = 1659
-- expected results with first sizes set:
--Exact 1659: 11 488, 7 396, 6 391, 3 384
-- expected results with second sizes set:
--Lower 1590: 6 798, 3 410, 2 382
--Higher 1728: 5 734, 4 650, 1 344
sequence sizes
-- sizes = {377,378,384,387,388,391,396,422,424,425,488,505}
sizes = {798,344,650,410,382,734}
sequence incset
integer lowbest, lowlevel, highbest, highlevel, worktot, level, item
sequence lowset, highset
procedure display(integer tot, integer level, sequence incset)
integer item
printf(1,"%d ",tot)
for i = 1 to level do
item = incset[i]
printf(1,"%d %d ",{item,sizes[item]})
end for
puts(1," key <cr>")
if getc(0) then end if
puts(1,"\n")
end procedure
function find_combination(integer jumpToDa200)
--
-- this section tries to find a set of sizes which add up to the
-- required amount exactly.
--
if jumpToDa200 then goto da200 end if
level = 1
lowbest = 0
highbest = 999999999
item = length(sizes)
incset=repeat(0,item)
worktot=0
da100::
incset[level] = item
worktot += sizes[item]
if worktot = required then return 0 end if -- found exact fit
if worktot > required then goto da200 end if -- too big
--
-- this set is smaller than required - save it if it is best so far
--
if worktot > lowbest then
lowbest = worktot
lowlevel = level
lowset = incset
end if
if item > 1 then -- more to be tested
item -= 1
level += 1 -- leave item in table;
goto da100
end if
goto da300
da200::
--
-- this set is larger than required - save it if it is best so far
--
if worktot < highbest then
highbest = worktot
highlevel = level
highset = incset
end if
da300::
--
-- now we need to backtrack; remove item from running total and look
-- at the next instead.
--
worktot -= sizes[item]
if item > 1 then -- more to be tested
item -= 1 -- look at next (overwrite item in table)
goto da100
end if
--
-- we have exhausted all possibilities at this level; backtrack to
-- a previous level.
--
incset[level] = 0
level -= 1
if level = 0 then return 1 end if -- all done
item = incset[level]
goto da300
end function
procedure main()
sizes=sort(sizes)
if not find_combination(0) then
while 1 do
display(worktot,level,incset)
-- if da200() then exit end if
if find_combination(1) then exit end if
end while
end if
puts(1,"lower figure ")
display(lowbest,lowlevel,lowset)
puts(1,"higher figure ")
display(highbest,highlevel,highset)
end procedure
main()
I wasn't really keeping track but I think it just took me a shade under an hour
to hack that into something working, then again I know how it works and I've
managed that trick once before, and that I tried and failed many moons ago when I
was still an Eu novice. While messing about I trigered two fatal crashes in Edita
(in re-indent and CtrlBracket) which I fixed (as part of that hour), so at least
it was not a complete and utter waste of time
One thing I would like to say is that the original of that code was used as part
of the compilation process in a team of ten programmers for many years, so any
restructuring or rewrite would, I felt, carry a strong chance of (re-)introducing
bugs that had been ironed out long ago. OTOH if you translate some code from
language A to language B then a) that is a big enough upheaval anyway, and b) if
you don't test it thoroughly then you know what to expect.
The point that this is the only real nasty I have encountered in 5+ years with
Eu is not a small point either.
Regards,
Pete
|
Not Categorized, Please Help
|
|