collatz.ssa 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. # a solution for N=1000 to
  2. # https://projecteuler.net/problem=14
  3. # we use a fast local array to
  4. # memoize small collatz numbers
  5. export
  6. function $test() {
  7. @start
  8. %mem =l alloc4 4000
  9. @loop
  10. %n =w phi @start 1, @newm %n9, @oldm %n9
  11. %cmax =w phi @start 0, @newm %c, @oldm %cmax
  12. %fin =w csltw %n, 1000
  13. jnz %fin, @cloop, @end
  14. @cloop
  15. %n0 =w phi @loop %n, @odd %n2, @even %n3
  16. %c0 =w phi @loop 0, @odd %c1, @even %c1
  17. %no1 =w cnew %n0, 1
  18. jnz %no1, @iter0, @endcl
  19. @iter0
  20. %ism =w csltw %n0, %n
  21. jnz %ism, @getmemo, @iter1
  22. @iter1
  23. %c1 =w add %c0, 1
  24. %p =w and %n0, 1
  25. jnz %p, @odd, @even
  26. @odd
  27. %n1 =w mul 3, %n0
  28. %n2 =w add %n1, 1
  29. jmp @cloop
  30. @even
  31. %n3 =w shr %n0, 1
  32. jmp @cloop
  33. @getmemo # get the count for n0 in mem
  34. %n0l =l extsw %n0
  35. %idx0 =l mul %n0l, 4
  36. %loc0 =l add %idx0, %mem
  37. %cn0 =w loadw %loc0
  38. %c2 =w add %c0, %cn0
  39. @endcl # store the count for n in mem
  40. %c =w phi @getmemo %c2, @cloop %c0
  41. %nl =l extsw %n
  42. %idx1 =l mul %nl, 4
  43. %loc1 =l add %idx1, %mem
  44. storew %c, %loc1
  45. %n9 =w add 1, %n
  46. %big =w cslew %cmax, %c
  47. jnz %big, @newm, @oldm
  48. @newm
  49. jmp @loop
  50. @oldm
  51. jmp @loop
  52. @end
  53. storew %cmax, $a
  54. ret
  55. }
  56. # >>> driver
  57. # extern void test(void);
  58. # int a;
  59. # int main() { test(); return !(a == 178); }
  60. # <<<