두 개의 재귀 호출이 완료되지 않았습니다. 이 기능은 소스 스틱에서 하나의 대체 스틱으로 목적지 스틱까지의 단계 수를 제공합니다.하노이 타워 문제의 <strong>haskell</strong>에이 기능을 프로그래밍했습니다. (베트남 하노이 타워)
numStepsHanoi :: Integer -> Integer
numStepsHanoi 0 = 0
numStepsHanoi n = numStepsHanoi (n-1) + numStepsHanoi (n-1) + 1
이 기능은 잘 작동 ... N 때까지, 디스크의 숫자가 너무 높게 가져옵니다. GHCi가 끝나지 않습니다. 나는이 문제의 복잡성을 알고 있으며 더 빨리 달릴 수 없다는 것을 알고있다.
예를 들어 n = 64
으로 전화를 걸면 20 분 정도 기다려도 결과가 출력되지 않습니다 (완료되지 않음). n = 20
이라도 약 2 초가 걸립니다.
다른 구현 (아래)을 사용하면 시간이 상당히 줄어 듭니다.
numStepsHanoi :: Integer -> Integer
numStepsHanoi 0 = 0
numStepsHanoi n = 2 * numStepsHanoi (n-1) - 1
이제 n = 64
으로 결과가 즉시 나타납니다. 분명히 이것은 단 하나의 순환 호출을 가지지 만 그렇게 큰 영향을 미칩니 까?
GHCi 최적화의 문제 일 수 있습니까?
GHCi에서 최적화가 수행되지 않으며 그 외에 GHC 컴파일러는'x + x'에서'2 * x'와 같은 것을 최적화하지 않습니다. 후자가 전자보다 훨씬 빠른 이유는 첫 번째 솔루션 (지수)과 두 번째 (선형)의 복잡성에 대해 잘못 되었기 때문입니다. – user2407038
@ user2407038 나는 지수 적 복잡성을 알고 있었지만 GHCi가 x * x를 2 * x로 변환한다고 생각했습니다. 고마워요! –
[공통 하위 표현식 제거] (https://wiki.haskell.org/GHC_optimisations#Common_subexpression_elimination) – chepner