blob: 6f58feb9dadd70ffdbaf6c88c63cd3e4e5489ff8 [file] [log] [blame]
-- The Great Computer Language Shootout
-- http://shootout.alioth.debian.org/
-- contributed by Mike Pall
local co = coroutine
local create, resume, yield = co.create, co.resume, co.yield
local N = tonumber(arg and arg[1]) or 10
local first, second
-- Meet another creature.
local function meet(me)
while second do yield() end -- Wait until meeting place clears.
local other = first
if other then -- Hey, I found a new friend!
first = nil
second = me
else -- Sniff, nobody here (yet).
local n = N - 1
if n < 0 then return end -- Uh oh, the mall is closed.
N = n
first = me
repeat yield(); other = second until other -- Wait for another creature.
second = nil
yield() -- Be nice and let others meet up.
end
return other
end
-- Create a very social creature.
local function creature(color)
return create(function()
local me = color
for met=0,1e9 do
local other = meet(me)
if not other then return met end
if me ~= other then
if me == "blue" then me = other == "red" and "yellow" or "red"
elseif me == "red" then me = other == "blue" and "yellow" or "blue"
else me = other == "blue" and "red" or "blue" end
end
end
end)
end
-- Trivial round-robin scheduler.
local function schedule(threads)
local resume = resume
local nthreads, meetings = table.getn(threads), 0
repeat
for i=1,nthreads do
local thr = threads[i]
if not thr then return meetings end
local ok, met = resume(thr)
if met then
meetings = meetings + met
threads[i] = nil
end
end
until false
end
-- A bunch of colorful creatures.
local threads = {
creature("blue"),
creature("red"),
creature("yellow"),
creature("blue"),
}
io.write(schedule(threads), "\n")