Recursion in Towers of hanoi - recursion

I have read the Towers of Hanoi problem statement and the solution as well. The solution states that when you have to move a set of N disks from A to B, use C as temp and transfer N-1 disks from A to C. Then transfer Nth disk from A to B and then transfer the N-1 disks from C to B. I know that the problem has reduced in size and therefore a contender for implementation recursively. However, we cannot transfer more than 1 disk at a time. How can we transfer N-1 disks in the first place.

By using the recursion. See also Tower of Hanoi: Recursive Algorithm and the wikipedia page
The recursion is as follow: You know how to move 1 disc, suppose you know how to move n-1 discs, how do you move n discs?
The "suppose" part is your recursion: You move 10 discs by moving 9, then 1 then 9.
To move the 9 discs, you move 8, then 1, then 8.
To move the 8 discs...
...
To move the 2 discs, you move 1, then 1, then 1.

That's the recursive step. Transfer N-1 disks from A to C using the same algorithm that transfers N disks from A to B. If N is one, then simply move the single disk. (Or, equivalnently, if N is zero, do nothing).
In pseudocode:
move(N, A, B):
if (N > 0)
move(N-1, A, C)
move_single_disk(A, B)
move(N-1, C, B)

Related

Find paths of length = 4, starting by an adjacency matrix of a directed graph, considering only distinct edges?

Given an EREW-PRAM model, that allows me to use an arbitrary number of processors in parallel without them conflicting nor in read, nor in write access, I need to find the number of paths of length 4, considering that I have an input node-node adjacency matrix A representing a directed graph and that I need to exclude paths that don't use distinct edges (e.g.: (a,b),(b,a),(a,b),(b,a) is not a valid path).
I have a function that uses n^3 processors and calculates the matrix multiplication of two given matrices in time O(logn):
mult-matrix(A, A, n) => B --> gives me the paths of length 2.
mult-matrix(B, B, n) => C --> gives me the paths of length 4, but I think it considers paths that run across the same edges.
I tried subtracting 1 from elements of C that have a node u communicating with a node v in both directions, but I'm not sure it works.
How could I solve the problem considering that I just need to exclude some paths from the resulting matrix C?
Any working solution is appreciated, considering that the number of processors is constrained to n^3 and time must be O(logn) in the worst case. The exercises must be solved using a pseudo-pascal language, but given a working solution, I should be able to write the pseudocode by myself.
I think I found a solution in https://www.perlmonks.org/?node_id=522270
Given an input matrix A, I am able to calculate the adjacency matrix for paths of length 2, 3 and 4 with the provided function.
A2 is the adjacency matrix obtained by multiplying A*A and contains paths of length 2
A3 is obtained by multiplying A2*A and contains paths of length 3
A4 is obtained by multiplying A3*A and contains paths of length 4
In order to exclude the repeated edges, I have to compute the matrix C, obtained by doing an element-wise subtraction among the calculated matrices.
C[i,j] = A4[i,j] - A3[i,j] - A2[i,j] - A[i,j]
C contains the final result.
The following pseudocode solves the problem with an EREW-PRAM using O(n^3) processors and in time O(logn).
procedure paths_length_4(A, n) // Work = O(n^3 logn)
begin
A2 := mult_matrix(A, A, n) // T=O(logn), P=O(n^3)
A3 := mult_matrix(A2, A, n) // T=O(logn), P=O(n^3)
A4 := mult_matrix(A3, A, n) // T=O(logn), P=O(n^3)
for all i,j where 1 ≤ i ≤ n, 1 ≤ j ≤ n pardo // P=O(n^2)
C[i,j] := A4[i,j] - A3[i,j] - A2[i,j] - A[i,j]
end

Z80 register pairs

I am fairly new to the Z80 and machine code, so please don't assume I know anything.
Basically, what I want to know is this: If you load register H with a value (I'll call it y), will HL then be 0xy0? e.g. if H was loaded with 0xAF would HL be 0xAF00?
And would the same be true for loading L with y?
Thanks in advance.
The H and L 8-bit registers can be treated independently. Loading a value in H, will not affect the value in L, and vice versa. The two registers H and L can also be treated as a 16-bit register pair. The following source FIRST STEPS IN MACHINE CODE describes this.
two single register transfers, e.g.
LD H, B
LD L, C
to copy BC into
HL.
and
You can, if you wish, load a register pair directly with a single
instruction, rather than use two instructions. From last time, you
will recall that the H and L, B and C, and D and E registers can be
paired such that they effectively can hold any number between 0 and
65535 (00 to FFFF hex). C, E, and L form the low byte of the pair,
while B, D, and H are the high bytes.

Prolog - writing successive numbers_ [duplicate]

This question already has an answer here:
Hanoi Tower(Towers of Hanoi)
(1 answer)
Closed 8 years ago.
My task is this: Make this hanoi program write a successive number before it writes each sentence.
The hanoi program is this:
hanoi(N):-move(N,left,middle,right).
move(0,_,_,_):- !.
move(N,A,B,C):- M is N-1, move(M,A,C,B), inform(A,B), move(M,C,B,A).
inform(A,B):- write('MOVING DISK FROM '), write(A),write(' TO '),write(B),nl.
And I want the output to look like this:
1: MOVING DISK FROM left TO middle
2: MOVING DISK FROM left TO right
3: MOVING DISK FROM middle TO right
4: MOVING DISK FROM left TO middle
5: MOVING DISK FROM right TO left
6: MOVING DISK FROM right TO middle
7: MOVING DISK FROM left TO middle
First consider using a DCG to describe the list of moves:
hanoi(N, Moves) :- phrase(moves(N,left,middle,right), Moves).
moves(0,_,_,_) --> [].
moves(N,A,B,C) --> { N #> 0, M #= N-1 }, moves(M,A,C,B), [A->B], moves(M,C,B,A).
This lets you separate the program logic from side-effects like printing results. Once you have a list of moves, it is easy to write them, for example with:
write_moves([], _).
write_moves([From->To|Ms], N) :-
format("~w: move disk from ~w to ~w\n", [N,From,To]),
N1 #= N + 1,
write_moves(Ms, N1).
Example query and its result:
?- hanoi(3, Moves), write_moves(Moves, 1).
1: move disk from left to middle
2: move disk from left to right
3: move disk from middle to right
4: move disk from left to middle
5: move disk from right to left
6: move disk from right to middle
7: move disk from left to middle
Moves = [ (left->middle), (left->right), (middle->right), ...].
A straight-forward approach would be to use a dynamic predicate representing the line number. Using assert/retract isn't real-time friendly, but it works fine for an application like this. I reformatted your working Hanoi code for readability, and I added the lines noted with comments:
% hanoi
%
:- dynamic(line/1). % Define a dynamic predicate "line"
hanoi(N) :-
assertz(line(1)), % Assert the first line as 1
move(N, left, middle, right).
move(0, _, _, _) :- !.
move(N, A, B, C) :-
M is N-1,
move(M, A, C, B),
inform(A, B),
move(M, C, B, A).
inform(A, B) :-
line(N), % get the current line number
NextN is N + 1, % next line number will be current one plus 1
retract(line(_)), % retract the old line number
assertz(line(NextN)), % assert the next line number for next time
write(N), % write the line number
write(': '), % and a delimiter
write('MOVING DISK FROM '),
write(A),
write(' TO '),
write(B),
nl.
There are other ways to generate successive numbers, such as the following simplest case.
sequence(1).
sequence(X) :- sequence(Y), X is Y + 1.
| ?- sequence(X).
X = 1 ? ;
X = 2 ? ;
X = 3 ? ;
X = 4 ?
In some cases, something like this can be integrated in with a predicate to give you sequence numbers. Since the hanoi predicate has a tree-like recursion, I found it easier to use an assertz mechanism.

How to shuffle list in O(n) in OCaml?

It is not hard to shuffle an array in O(n), with in place swapping,
How to do it for list in OCaml, with O(n)?
Requirement:
No array or in place usage
Consider this as an interview question
Lists are immutable, and there's often a log n price to pay for working with immutable data. If you're willing to pay this cost, there's an obvious n log n approach: tag each list element with a random value, sort based on random value, remove random values. This is the way I shuffle lists in my production code.
Here is the shuffle code from the iOS apps that I sell:
let shuffle d =
let nd = List.map (fun c -> (Random.bits (), c)) d in
let sond = List.sort compare nd in
List.map snd sond
You could mimick the riffle shuffle for cards.
A riffle shuffle of a deck of cards means to:
cut the deck in two parts
interleave the two parts
It is actually easier to do the reverse permutation:
have two auxiliary lists A and B, iter through your original list L and push each element randomly (with probability 1/2) in front of A or B.
L := List.rev A # List.rev B (this can be tail recursive with a custom List.rev).
repeat k times.
According to "Mathematical developments from the analysis of riffle shuffling, by Persi Diaconis, 2002", choose k = 3/2 log_2(n) + c. Indeed, the total variation distance between uniformity and the result falls exponentially fast to 0: it is approximately halved each time you increment c. You could choose c=10.
Space O(1) (if you destroy L), time O(n log n). But there are O(n log n) calls to the random generator, while Jeffrey Scofield's solution only needs O(n) random bits, but Θ(n) space.

Project Euler #211 - efficiency issue

I've been slowly working my way through the list of Project Euler problems, and I've come to one that I know how to solve, but it seems like I can't (given the way my solution was written).
I am using Common Lisp to do this with and my script has been running for over 24 hours (well over their one minute goal).
For the sake of conciseness, here's my solution (it's a spoiler, but only if you have one hell of a fast processor):
(defun square? (num)
(if (integerp (sqrt num)) T))
(defun factors (num)
(let ((l '()))
(do ((current 1 (1+ current)))
((> current (/ num current)))
(if (= 0 (mod num current))
(if (= current (/ num current))
(setf l (append l (list current)))
(setf l (append l (list current (/ num current)))))))
(sort l #'< )))
(defun o_2 (n)
(reduce #'+ (mapcar (lambda (x) (* x x)) (factors n))))
(defun sum-divisor-squares (limit)
(loop for i from 1 to limit when (square? (o_2 i)) summing i))
(defun euler-211 ()
(sum-divisor-squares 64000000))
The time required to solve the problem using smaller, more friendly, test arguments seems to grow larger than exponentialy... which is a real problem.
It took:
0.007 seconds to solve for 100
0.107 seconds to solve for 1000
2.020 seconds to solve for 10000
56.61 seconds to solve for 100000
1835.385 seconds to solve for 1000000
24+ hours to solve for 64000000
I'm really trying to figure out which part(s) of the script is causing it to take so long. I've put some thought into memoizing the factors function, but I'm at a loss as to how to actually implement that.
For those that want to take a look at the problem itself, here it be.
Any ideas on how to make this thing go faster would be greatly appreciated.
**sorry if this is a spoiler to anyone, it's not meant to be.... but if you have the computing power to run this in a decent amount of time, more power to you.
Here's a solution, keeping in mind the spirit of [Project] Euler. [Warning: spoiler. I've tried to keep the hints slow, so that you can read only part of the answer and think on your own if you want. :)]
When you are confronted with a problem having to do with numbers, one good strategy (as you probably already know from solving 210 Project Euler problems) is to look at small examples, find a pattern, and prove it. [The last part may be optional depending on your attitude to mathematics ;-)]
In this problem, though, looking at small examples -- for n=1,2,3,4,... will probably not give you any hint. But there is another sense of "small examples" when dealing with number-theoretic problems, which you also probably know by now -- primes are the building blocks of the natural numbers, so start with the primes.
For a prime number p, its only divisors are 1 and p, so the sum of the squares of its divisors is 1+p2.
For a prime power pk, its only divisors are 1, p, p2, … pk, so the sum of the squares of its divisors is 1+p+p2+…+pk=(pk+1-1)/(p-1).
That was the simplest case: you've solved the problem for all numbers with only one prime factor.
So far nothing special. Now suppose you have a number n that has two prime factors, say n=pq. Then its factors are 1, p, q, and pq, so the sum of the squares of its divisors is 1+p2+q2+p2q2=(1+p2)(1+q2).
What about n=paqb? What is the sum of the squares of its factors?
[............................Dangerous to read below this line...................]
It is ∑0≤c≤a, 0≤d≤b(pcqd)2 = ((pa+1-1)/(p-1))((qb+1-1)/(q-1)).
That should give you the hint, both on what the answer is and how to prove it: the sum of the divisors of n is simply the product of the (answer) for each of the prime powers in its factorization, so all you need to do is to factorize 64000000 (which is very easy to do even in one's head :-)) and multiply the answer for each (=both, because the only primes are 2 and 5) of its prime powers.
That solves the Project Euler problem; now the moral to take away from it.
The more general fact here is about multiplicative functions -- functions on the natural numbers such that f(mn) = f(m)f(n) whenever gcd(m,n)=1, i.e. m and n have no prime factors in common. If you have such a function, the value of the function at a particular number is completely determined by its values at prime powers (can you prove this?)
The slightly harder fact, which you can try to prove[it's not that hard], is this: if you have a multiplicative function f [here, f(n)=n2] and you define the function F as F(n) = ∑d divides nf(d), (as the problem did here) then F(n) is also a multiplicative function.
[In fact something very beautiful is true, but don't look at it just yet, and you'll probably never need it. :-)]
I think that your algorithm is not the most efficient possible. Hint: you may be starting from the wrong side.
edit: I'd like to add that choosing 64000000 as the upper limit is likely the problem poster's way of telling you to think of something better.
edit: A few efficiency hints:
instead of
(setf l (append l (...)))
you can use
(push (...) l)
which destructively modifies your list by consing a new cell with your value as car and the former l as cdr, then points l to this cell. This is much faster than appending which has to traverse the list once each. If you need the list in the other order, you can nreverse it after it is complete (but that is not needed here).
why do you sort l?
you can make (> current (/ num current)) more efficient by comparing with the square root of num instead (which only needs to be computed once per num).
is it perhaps possible to find the factors of a number more efficiently?
And a style hint: You can put the scope of l into the do declaration:
(do ((l ())
(current 1 (+ current 1)))
((> current (/ num current))
l)
...)
I would attack this by doing the prime factorization of the number (for example: 300 = 2^2 * 3^1 * 5^2), which is relatively fast, especially if you generate this by sieve. From this, it's relatively simple to generate the factors by iterating i=0..2; j=0..1; k=0..2, and doing 2^i * 3^j * 5^k.
5 3 2
-----
0 0 0 = 1
0 0 1 = 2
0 0 2 = 4
0 1 0 = 3
0 1 1 = 6
0 1 2 = 12
1 0 0 = 5
1 0 1 = 10
1 0 2 = 20
1 1 0 = 15
1 1 1 = 30
1 1 2 = 60
2 0 0 = 25
2 0 1 = 50
2 0 2 = 100
2 1 0 = 75
2 1 1 = 150
2 1 2 = 300
This might not be fast enough
The clever trick you are missing is that you don't need to factor the numbers at all
How many numbers from 1..N are multiples of 1? N
How many numbers from 1..N are multiples of 2? N/2
The trick is to sum each number's factors in a list.
For 1, add 1^2 to every number in the list. For 2, add 2^2 to every other number.
For 3, add 3^2 to every 3rd number.
Don't check for divisibility at all.
At the end, you do have to check whether the sum is a perfect square, and that's it.
In C++, this worked in 58 seconds for me.
Sorry, I don't understand LISP well enough to read your answer. But my first impression is that the time cost of the brute force solution should be:
open bracket
sqrt(k) to find the divisors of k (by trial division), square each one (constant time per factor), and sum them (constant time per factor). This is σ2(k), which I will call x.
plus
not sure what the complexity of a good integer square root algorithm is, but certainly no worse than sqrt(x) (dumb trial multiplication). x might well be big-O larger than k, so I reserve judgement here, but x is obviously bounded above by k^3, because k has at most k divisors, each itself no bigger than k and hence its square no bigger than k^2. It's been so long since my maths degree that I have no idea how fast Newton-Raphson converges, but I suspect it's faster than sqrt(x), and if all else fails a binary chop is log(x).
close bracket
multiplied by n (as k ranges 1 .. n).
So if your algorithm is worse than O(n * sqrt(n^3)) = O(n ^ (5/2)), in the dumb-sqrt case, or O(n * (sqrt(n) + log(n^3)) = O(n ^ 3/2) in the clever-sqrt case, I think something has gone wrong which should be identifiable in the algorithm. At this point I'm stuck because I can't debug your LISP.
Oh, I've assumed that arithmetic is constant-time for the numbers in use. It darn well should be for numbers as small as 64 million, and the cube of that fits in a 64bit unsigned integer, barely. But even if your LISP implementation is making arithmetic worse than O(1), it shouldn't be worse than O(log n), so it won't have much affect on the complexity. Certainly won't make it super-polynomial.
This is where someone comes along and tells me just how wrong I am.
Oops, I just looked at your actual timing figures. They aren't worse than exponential. Ignoring the first and last values (because small times aren't accurately measurable and you haven't finished, respectively), multiplying n by 10 multiplies time by no more than 30-ish. 30 is about 10^1.5, which is about right for brute force as described above.
I think you can attack this problem with something like a prime sieve. That's only my first impression though.
I've reworked the program with some notes taken from the comments here. The 'factors' function is now ever so slightly more efficient and I also had to modify the σ_(2)(n) function to accept the new output.
'factors' went from having an output like:
$ (factors 10) => (1 2 5 10)
to having one like
$ (factors 10) => ((2 5) (1 10))
Revised function looks like this:
(defun o_2 (n)
"sum of squares of divisors"
(reduce #'+ (mapcar (lambda (x) (* x x)) (reduce #'append (factors n)))))
After the modest re-writes I did, I only saved about 7 seconds in the calculation for 100,000.
Looks like I'm going to have to get off of my ass and write a more direct approach.

Resources