szabivan

Ackermann Example

Oct 24th, 2016
359
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Scala 1.94 KB | None | 0 0
  1. // Ackermann function variants, ready to be tested at e.g. scalakata.com
  2. // the purpose is ONLY to play around with the Scala syntax and notions like currying
  3.  
  4. // "usual" imperative variant, no functions
  5. def ack( n : Int , m : Int ) : Int = {
  6.   if ( n == 0 ) m + 1
  7.   else if ( m == 0 ) ack( n - 1 , 1 )
  8.   else ack( n - 1 , ack( n , m - 1 ) )
  9. }
  10.  
  11. // examples
  12. ack(0,4) // 5 -- in general, ack(0,m) = m + 1
  13. ack(1,1) // 3 -- in general, ack(1,m) = m + 2
  14. ack(1,2) // 4
  15. ack(1,3) // 5
  16. ack(2,2) // 7 -- in general, ack(2,m) = 2*m + 3
  17. ack(3,3) // 61 -- in general, ack(3,m) = 2^(m+3) - 3
  18.  
  19. // we will construct a function ackCurried taking an Int, producing an Int=Int function
  20. // such that ackCurried(n)(m) = ack(n,m), e.g. ackCurried(2) is _ => 2*_+3
  21.  
  22. // helper function ver 1: iterate( f, n ) computes f(f(f(...(f(1))..))), the number of f's being n+1
  23. def iterate( f : Int=>Int , n : Int ) : Int = {
  24.   if( n == 0 ) f(1)
  25.   else f( iterate( f, n - 1 ) )
  26. }
  27.  
  28. //examples
  29. iterate( _+1, 6 ) // 8
  30. iterate( _+1, 9 ) // 11
  31.  
  32. // curried version of iterate: iterateCurried( f ) returns the function g s.t. g(n) = f(f(f(...(f(1))...)))
  33. def iterateCurried( f : Int=>Int ) : Int=>Int = {
  34.   n => if( n == 0 ) f(1) else f ( iterateCurried(f)(n-1) )
  35. }
  36.  
  37. // examples
  38. def addTwo = iterateCurried( _+1 )
  39. addTwo( 6 ) //still 8
  40. addTwo( 9 ) //still 11
  41. def nextFunction = iterateCurried( addTwo )
  42. nextFunction( 1 ) //5
  43. nextFunction( 2 ) //7
  44. nextFunction( 3 ) //9
  45. def oneMoreFunction = iterateCurried( nextFunction )
  46. oneMoreFunction( 1 ) //13
  47. oneMoreFunction( 2 ) //29
  48. oneMoreFunction( 3 ) //61
  49. //got the pattern? ack( n ) is iterateCurried( ack(n-1) )
  50.  
  51. // then, ackCurried can be an Int => (Int=>Int) function with a(n)(m) = a(n,m), as
  52. // a(n) is _+1 if n==0, and iterateCurried( a(n-1) ) otherwise
  53. def ackCurried( n : Int ) : Int=>Int = {
  54.   if( n == 0 ) _ + 1
  55.   else iterateCurried( ackCurried( n - 1 ) )
  56. }
  57.  
  58. // example
  59. ackCurried(2)(2) //7
  60. ackCurried(3)(3) //61
Advertisement
Add Comment
Please, Sign In to add comment