2010-04-21 10 views
1

J'essaie de calculer la fonction Ackermann. Une description de ce que j'essaie d'atteindre est au http://rosettacode.org/wiki/Ackermann_function.Quel est le problème avec ce script Windows CMD récursif? Je ne vais pas faire correctement Ackermann

En utilisant le script de test, Test 0 4 me donne 5 qui est correct. Cependant, le test 1 4 donne 5 non 6, et le test 2 4 donne 5 au lieu de 11.

Où est-ce que je me trompe?

::echo off 
set depth=0 
:ack 
if %1==0 goto m0 
if %2==0 goto n0 

:else 
set /a n=%2-1 
set /a depth+=1 
call :ack %1 %n% 
set t=%errorlevel% 
set /a depth-=1 
set /a m=%1-1 
set /a depth+=1 
call :ack %m% %t% 
set t=%errorlevel% 
set /a depth-=1 
if %depth%==0 (exit %t%) else (exit /b %t%) 

:m0 
set/a n=%2+1 
if %depth%==0 (exit %n%) else (exit /b %n%) 

:n0 
set /a m=%1-1 
set /a depth+=1 
call :ack %m% %2 
set t=%errorlevel% 
set /a depth-=1 
if %depth%==0 (exit %t%) else (exit /b %t%) 

-je utiliser ce script pour tester

@echo off 
cmd/c ackermann.cmd %1 %2 
echo Ackermann of %1 %2 is %errorlevel% 

Un exemple de sortie, pour le test 1 1, donne:

>test 1 1 
>set depth=0 
>if 1 == 0 goto m0 
>if 1 == 0 goto n0 
>set /a n=1-1 
>set /a depth+=1 
>call :ack 1 0 
>if 1 == 0 goto m0 
>if 0 == 0 goto n0 
>set /a m=1-1 
>set /a depth+=1 
>call :ack 0 0 
>if 0 == 0 goto m0 
>set/a n=0+1 
>if 2 == 0 (exit 1 ) else (exit /b 1 ) 
>set t=1 
>set /a depth-=1 
>if 1 == 0 (exit 1 ) else (exit /b 1 ) 
>set t=1 
>set /a depth-=1 
>set /a m=1-1 
>set /a depth+=1 
>call :ack 0 1 
>if 0 == 0 goto m0 
>set/a n=1+1 
>if 1 == 0 (exit 2 ) else (exit /b 2 ) 
>set t=2 
>set /a depth-=1 
>if 0 == 0 (exit 2 ) else (exit /b 2 ) 
Ackermann of 1 1 is 2 
+2

Certains d'entre nous ne savent pas ce qu'est un "Ackerman" est. Vous dites que "presque" fonctionne. Alors qu'est-ce qui ne va pas? Vous avez la trace là, à quel point dans le chemin d'exécution les choses divergent-elles de ce que vous attendez? – djna

Répondre

2

ligne de changement 27 ci-dessus de

call :ack %m% %2 

à

call :ack %m% 1 
+0

(rougir) une chose aussi simple. Eh bien, c'est la solution gagnante. Merci beaucoup, Patrick. – bugmagnet

0

Quelle est la portée de vos variables m et n?

Vous définissez les valeurs dans un appel à: ack, puis appel récursivement à nouveau, définissant des valeurs. Les écrasez-vous? Dans les langages basés sur Stack tels que C et Java, les variables locales sont correctes, chaque niveau de récursivité obtient de nouvelles variables. Que se passe-t-il dans cmd?

+0

Aucun problème de portée ici. Il utilise toujours les arguments du sous-programme ou du code de retour, donc il n'y a pas d'endroit où les variables sont définies avant un appel récursif et réutilisées ensuite (sauf pour 'depth' mais c'est intentionnel). – Joey

+0

@Johannes: oui, vous avez raison. Je regardais les variables m et n mais elles sont transitoires. – djna