stringtranslate.com

tomar (función)

En informática , la función Tak es una función recursiva , que lleva el nombre de Ikuo Takeuchi (ja:竹内郁雄). Se define de la siguiente manera:

def  tak ( x ,  y ,  z ):  si  y  <  x :  devolver  tak (  tak ( x - 1 ,  y ,  z ),  tak ( y - 1 ,  z ,  x ),  tak ( z - 1 ,  x ,  y )  )  más :  devolver  z

Esta función se utiliza a menudo como punto de referencia para lenguajes con optimización para recursividad . [1] [2] [3] [4]

tak() contra tarai()

La definición original de Takeuchi era la siguiente:

def  tarai ( x ,  y ,  z ):  si  y  <  x :  devuelve  tarai (  tarai ( x - 1 ,  y ,  z ),  tarai ( y - 1 ,  z ,  x ),  tarai ( z - 1 ,  x ,  y )  )  más :  devuelve  y  # no z!

tarai es la abreviatura de たらい回しtarai mawashi , "pasar" en japonés.

John McCarthy nombró esta función tak() en honor a Takeuchi. [5]

Sin embargo, en ciertas referencias posteriores, la y de alguna manera se convirtió en z. Esta es una diferencia pequeña, pero significativa, porque la versión original se beneficia significativamente de la evaluación diferida .

Aunque está escrito exactamente de la misma manera que otros, el siguiente código de Haskell se ejecuta mucho más rápido.

tarai :: Int -> Int -> Int -> Int tarai x y z | x <= y = y | de lo contrario = tarai ( tarai ( x - 1 ) y z ) ( tarai ( y - 1 ) z x ) ( tarai ( z - 1 ) x y )                                 

Se puede acelerar fácilmente esta función mediante la memorización , pero la evaluación perezosa sigue ganando.

La forma más conocida de optimizar tarai es utilizar la función auxiliar mutuamente recursiva de la siguiente manera.

def laziest_tarai ( x , y , zx , zy , zz ): si no y < x : devolver y else : devolver laziest_tarai ( tarai ( x - 1 , y , z ), tarai ( y - 1 , z , x ), tarai ( zx , zy , zz ) - 1 , x , y )                          def tarai ( x , y , z ): si no y < x : devolver y sino : devolver laziest_tarai ( tarai ( x - 1 , y , z ), tarai ( y - 1 , z , x ), z - 1 , x , y )                      

Aquí hay una implementación eficiente de tarai() en C:

int tarai ( int x , int y , int z ) { while ( x > y ) { int oldx = x , oldy = y ; x = tarai ( x - 1 , y , z ); y = tarai ( y - 1 , z , viejox ); si ( x <= y ) romper ; z = tarai ( z - 1 , viejox , viejo ); } devolver y ; }                                               

Tenga en cuenta la verificación adicional de (x <= y) antes de que se evalúe z (el tercer argumento), evitando una evaluación recursiva innecesaria.

Referencias

  1. ^ Peter Café (1996). "Tak test resiste la prueba del tiempo". Semana de la PC . 13 (39).
  2. ^ "Métodos recursivos" de Elliotte Rusty Harold
  3. ^ Johnson-Davies, David (junio de 1986). "Seis de los mejores contrarreloj". Usuario de bellota . págs.179, 181-182 . Consultado el 28 de octubre de 2020 .
  4. ^ Johnson-Davies, David (noviembre de 1986). "Probando el Tak". Usuario de bellota . págs.197, 199 . Consultado el 28 de octubre de 2020 .
  5. ^ John McCarthy (diciembre de 1979). "Una función LISP interesante". Boletín ACM Lisp (3): 6–8. doi :10.1145/1411829.1411833. S2CID  31639459.

enlaces externos