コルーチンの練習

コルーチンの練習です。

function main()
   co = coroutine.create(function()
                            coroutine.yield(1)
                            coroutine.yield(2)
                         end)
   print(co)
   print(coroutine.status(co))
   print(coroutine.resume(co))
   print(coroutine.status(co))
   print(coroutine.resume(co))
   print(coroutine.status(co))
   print(coroutine.resume(co))
   print(coroutine.status(co))
   
   print(coroutine.resume(co))
   print(coroutine.status(co))
end

main()

実行結果です。coroutine.yield()で中断。coroutine.esume()で復帰。coroutine.status()でコルーチンの状態を取得できます。

thread: 0x7fab90c054a0
suspended
true	1
suspended
true	2
suspended
true
dead
false	cannot resume dead coroutine
dead

coroutine.status()呼び出しでdeadが返されるコルーチンに対して、coroutine.resume()を呼び出してもエラーにはなりません。

素因数分解するコルーチン

素因数分解するコルーチンです。

function fac(n)
   assert(n > 0)
   if n == 1 then coroutine.yield(1) end
   
   while n % 2 == 0 do
      coroutine.yield(2)
      n = n / 2
   end

   local p = 3
   while p*p <= n do
      while n % p == 0 do
         coroutine.yield(p)
         n = n / p
      end
      p = p + 2
   end

   if n > 1 then
      coroutine.yield(n)
   end
end

function facgen(n)
   local co = coroutine.create(function() fac(n) end)
   return function()
             local code, ret = coroutine.resume(co)
             return ret
          end
end

function main()
   for p in facgen(123456789) do
      print(p)
   end
end

main()

実行結果です。

3
3
3607
3803