PageRenderTime 25ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/samples/Forth/KataDiversion.fth

https://gitlab.com/Aaeinstein54/linguist
Forth | 79 lines | 68 code | 10 blank | 1 comment | 5 complexity | f2e635b09352a568edbd9194882fdf0f MD5 | raw file
  1. \ KataDiversion in Forth
  2. \ -- utils
  3. \ empty the stack
  4. : EMPTY
  5. DEPTH 0 <> IF BEGIN
  6. DROP DEPTH 0 =
  7. UNTIL
  8. THEN ;
  9. \ power
  10. : ** ( n1 n2 -- n1_pow_n2 ) 1 SWAP ?DUP IF 0 DO OVER * LOOP THEN NIP ;
  11. \ compute the highest power of 2 below N.
  12. \ e.g. : 31 -> 16, 4 -> 4
  13. : MAXPOW2 ( n -- log2_n ) DUP 1 < IF 1 ABORT" Maxpow2 need a positive value."
  14. ELSE DUP 1 = IF 1
  15. ELSE
  16. 1 >R
  17. BEGIN ( n |R: i=1)
  18. DUP DUP I - 2 *
  19. ( n n 2*[n-i])
  20. R> 2 * >R ( |R: i*2)
  21. > ( n n>2*[n-i] )
  22. UNTIL
  23. R> 2 /
  24. THEN
  25. THEN NIP ;
  26. \ -- kata
  27. \ test if the given N has two adjacent 1 bits
  28. \ e.g. : 11 -> 1011 -> -1
  29. \ 9 -> 1001 -> 0
  30. : ?NOT-TWO-ADJACENT-1-BITS ( n -- bool )
  31. \ the word uses the following algorithm :
  32. \ (stack|return stack)
  33. \ ( A N | X ) A: 0, X: N LOG2
  34. \ loop: if N-X > 0 then A++ else A=0 ; X /= 2
  35. \ return 0 if A=2
  36. \ if X=1 end loop and return -1
  37. 0 SWAP DUP DUP 0 <> IF
  38. MAXPOW2 >R
  39. BEGIN
  40. DUP I - 0 >= IF
  41. SWAP DUP 1 = IF 1+ SWAP
  42. ELSE DROP 1 SWAP I -
  43. THEN
  44. ELSE NIP 0 SWAP
  45. THEN
  46. OVER
  47. 2 =
  48. I 1 = OR
  49. R> 2 / >R
  50. UNTIL
  51. R> 2DROP
  52. 2 <>
  53. ELSE 2DROP INVERT
  54. THEN ;
  55. \ return the maximum number which can be made with N (given number) bits
  56. : MAX-NB ( n -- m ) DUP 1 < IF DROP 0 ( 0 )
  57. ELSE
  58. DUP IF DUP 2 SWAP ** NIP 1 - ( 2**n - 1 )
  59. THEN
  60. THEN ;
  61. \ return the number of numbers which can be made with N (given number) bits
  62. \ or less, and which have not two adjacent 1 bits.
  63. \ see http://www.codekata.com/2007/01/code_kata_fifte.html
  64. : HOW-MANY-NB-NOT-TWO-ADJACENT-1-BITS ( n -- m )
  65. DUP 1 < IF DUP 0
  66. ELSE
  67. 0 SWAP
  68. MAX-NB 1 + 0 DO I ?NOT-TWO-ADJACENT-1-BITS - LOOP
  69. THEN ;