Search

vendredi 17 février 2017

Integer square root, round 2

Context

The Newton's method we used to compute integer square root is generally a very efficient algorithm to compute integer square roots.
However, using BrainFuck, the algorithm itself takes time to be processed, a lot of instructions are needed in order to iterate on different approximations.

Another intuitive but generally inefficient way to compute integer square root is to iterate on all integers and compute their squares until we go over our target number.
A bit less naive approach is to compute the difference between 2 squares, and subtract this difference to N while it's positive.
Example: 27

  • 1: remove 1, result is 26
  • 2: remove 3 (2*2 - 1*1), result is 23
  • 3: remove 5 (3*3 - 2*2), result is 18
  • 4: remove 7 (4*4 - 3*3), result is 11
  • 5: remove 9 (5*5 - 4*4), result is 2
  • 6: remove 11 (6*6 - 5*5), result is negative, so integer square root is 5
We'll see that, due to the nature of BrainFuck, this algorithm is actually really more efficient than Newton's method.

Initial state

  • Memory: A 0 0 0 0
  • Cursor: first cell
  • Input: any

Process

  • Store 1 (square difference) on third cell and 1 (actual result) on fourth
  • While A is not null
    • remove 1
    • remove 1 to square difference
    • If square difference is null
      • Copy actual result's double on third cell
      • Increase both actual result and cell square difference by 1
  • Decrease result by 1 (because the current result is over our target)

Code - try it

start from 1
>>>+>+<<<<

while N is not null
[
  decrease N
  -
  set else bit
  >>+
  decrease square difference
  >-
  if current square difference is null
  [<-]<[-
    reinit square difference
    copy current integer double
    >>[-<++>>+<]>[-<+>]<
    increase both integer and square difference by 1
    +<+
    <
  <]
  <
]
decrease result by 1 and print
>>>[-]>-
[>>>>++++++++++<<<<[->+>>+>-[<-]<[->>+<<<<[->>>+<<<]>]<<]>+[-<+>]>>>[-]>[-<<<<+>>>>]<<<<]<[>++++++[<++++++++>-]<-.[-]<]

Final state


  • Memory: 0 0 0 D R with R=isqrt(A) and D the remaining part of the square difference 
  • Cursor: first cell
  • Input: unchanged
  • Output: unchanged
This algorithm takes about 15 times less instructions to be executed...

Aucun commentaire:

Enregistrer un commentaire