Recursion with Logo: Counting up and down - recursion

I am a newbie in the Logo programming language (the turtle's language). I am trying to implement a simple recursion program. I want to write a procedure (or several ones) that will get a natural number as input, type all the numbers from this number down to 1, and then back up to the original number.
I did manage to write a program that will print all the numbers down to 1, but I can't figure out how to go up again. I would like to ask for your assistance. Even those of you who are not familiar with Logo syntax will probably figure it out...
My code so far is:
to down :n
if :n = 0 [stop]
pr :n
make "n (:n - 1)
down (:n)
end
Thanking you in advance.

type all the numbers from this number down to 1, and then back up to
the original number.
This slight change to your program should do the trick:
to down :n
if :n = 0 [stop]
pr :n
down :n - 1
pr :n
end
down 10

Related

Making a cryptaritmetic solver in C++

I am planning out a C++ program that takes 3 strings that represent a cryptarithmetic puzzle. For example, given TWO, TWO, and FOUR, the program would find digit substitutions for each letter such that the mathematical expression
TWO
+ TWO
------
FOUR
is true, with the inputs assumed to be right justified. One way to go about this would of course be to just brute force it, assigning every possible substitution for each letter with nested loops, trying the sum repeatedly, etc., until the answer is finally found.
My thought is that though this is terribly inefficient, the underlying loop-check thing may be a feasible (or even necessary) way to go--after a series of deductions are performed to limit the domains of each variable. I'm finding it kind of hard to visualize, but would it be reasonable to first assume a general/padded structure like this (each X represents a not-necessarily distinct digit, and each C is a carry digit, which in this case, will either be 0 or 1)? :
CCC.....CCC
XXX.....XXXX
+ XXX.....XXXX
----------------
CXXX.....XXXX
With that in mind, some more planning thoughts:
-Though leading zeros will not be given in the problem, I probably ought to add enough of them where appropriate to even things out/match operands up.
-I'm thinking I should start with a set of possible values 0-9 for each letter, perhaps stored as vectors in a 'domains' table, and eliminate values from this as deductions are made. For example, if I see some letters lined up like this
A
C
--
A
, I can tell that C is zero and this eliminate all other values from its domain. I can think of quite a few deductions, but generalizing them to all kinds of little situations and putting it into code seems kind of tricky at first glance.
-Assuming I have a good series of deductions that run through things and boot out lots of values from the domains table, I suppose I'd still just loop over everything and hope that the state space is small enough to generate a solution in a reasonable amount of time. But it feels like there has to be more to it than that! -- maybe some clever equations to set up or something along those lines.
Tips are appreciated!
You could iterate over this problem from right to left, i.e. the way you'd perform the actual operation. Start with the rightmost column. For every digit you encounter, you check whether there already is an assignment for that digit. If there is, you use its value and go on. If there isn't, then you enter a loop over all possible digits (perhaps omitting already used ones if you want a bijective map) and recursively continue with each possible assignment. When you reach the sum row, you again check whether the variable for the digit given there is already assigned. If it is not, you assign the last digit of your current sum, and then continue to the next higher valued column, taking the carry with you. If there already is an assignment, and it agrees with the last digit of your result, you proceed in the same way. If there is an assignment and it disagrees, then you abort the current branch, and return to the closest loop where you had other digits to choose from.
The benefit of this approach should be that many variables are determined by a sum, instead of guessed up front. Particularly for letters which only occur in the sum row, this might be a huge win. Furthermore, you might be able to spot errors early on, thus avoiding choices for letters in some cases where the choices you made so far are already inconsistent. A drawback might be the slightly more complicated recursive structure of your program. But once you got that right, you'll also have learned a good deal about turning thoughts into code.
I solved this problem at my blog using a randomized hill-climbing algorithm. The basic idea is to choose a random assignment of digits to letters, "score" the assignment by computing the difference between the two sides of the equation, then altering the assignment (swap two digits) and recompute the score, keeping those changes that improve the score and discarding those changes that don't. That's hill-climbing, because you only accept changes in one direction. The problem with hill-climbing is that it sometimes gets stuck in a local maximum, so every so often you throw out the current attempt and start over; that's the randomization part of the algorithm. The algorithm is very fast: it solves every cryptarithm I have given it in fractions of a second.
Cryptarithmetic problems are classic constraint satisfaction problems. Basically, what you need to do is have your program generate constraints based on the inputs such that you end up with something like the following, using your given example:
O + O = 2O = R + 10Carry1
W + W + Carry1 = 2W + Carry1 = U + 10Carry2
T + T + Carry2 = 2T + Carry2 = O + 10Carry3 = O + 10F
Generalized pseudocode:
for i in range of shorter input, or either input if they're the same length:
shorterInput[i] + longerInput2[i] + Carry[i] = result[i] + 10*Carry[i+1] // Carry[0] == 0
for the rest of the longer input, if one is longer:
longerInput[i] + Carry[i] = result[i] + 10*Carry[i+1]
Additional constraints based on the definition of the problem:
Range(digits) == {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
Range(auxiliary_carries) == {0, 1}
So for your example:
Range(O, W, T) == {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
Range(Carry1, Carry2, F) == {0, 1}
Once you've generated the constraints to limit your search space, you can use CSP resolution techniques as described in the linked article to walk the search space and determine your solution (if one exists, of course). The concept of (local) consistency is very important here and taking advantage of it allows you to possibly greatly reduce the search space for CSPs.
As a simple example, note that cryptarithmetic generally does not use leading zeroes, meaning if the result is longer than both inputs the final digit, i.e. the last carry digit, must be 1 (so in your example, it means F == 1). This constraint can then be propagated backwards, as it means that 2T + Carry2 == O + 10; in other words, the minimum value for T must be 5, as Carry2 can be at most 1 and 2(4)+1==9. There are other methods of enhancing the search (min-conflicts algorithm, etc.), but I'd rather not turn this answer into a full-fledged CSP class so I'll leave further investigation up to you.
(Note that you can't make assumptions like A+C=A -> C == 0 except for in least significant column due to the possibility of C being 9 and the carry digit into the column being 1. That does mean that C in general will be limited to the domain {0, 9}, however, so you weren't completely off with that.)

Lisp Programming Error (Stack Overflow (deep))

I am to write a lisp program to produce the actual value of a hexadecimal number. I have written a function but seem to be getting a stackoverflow (deep) error. I was wondering if anyone could point out my mistake or guide me in the right direction.
I would appreciate it if no code was posted for this question as this is part of a homework assignment. Hence I would only like an explanation or direction where I might be going wrong.
I feel my problem is that my recursion is not terminating but I don't know how to fix it.
Here's my code:
(defun calc (hex)
(if hex
(if (> (length hex) 1)
( + (first (reverse hex)) (* 16 (calc (reverse hex)))) hex)))
Thanks in advance.
The "base case" (the case/state where recursion actually stops) is that hex has length of one or less. Tell me, each time you call calc again, is the input to calc ever getting smaller? if not, then it's mathematically impossible for the input to ever reach the base case.
Let's say hex starts with length 9. When you call calc again, you have reversed hex. So now hex is reversed, but it still has a length of 9. I suspect that is why the recursion never stops.

Help to understand Google Code Jam 2011 Candy Splitting problem

I'm participating in google code jam. Before anything I want to say that I don't want anyone to solve me a problem "to win", or something like that. I just want some help to understand a problem I couldn't solve in a round that has already FINISHED.
Here is the link of the problem, called Candy Splitting. I won't explain it here because it is nosense, I wont be able to explain it better than google does.
I would like to know some "good" solution to the problem, for example, I've downloaded the first English solution and I've seen the code has only 30 lines!!! Thats amazing! (Anyone can download it so I think there is no problem with saying it: the solution of theycallhimtom from here). I can't understand the solution even watching the code. (My ignorance of Java doesn't help.)
Thanks!
Google themselves provide discussions about the problems and the solution
See this link for the Candy Splitting problem: http://code.google.com/codejam/contest/dashboard?c=975485#s=a&a=2
Basically, the candies can be divided into two equal value piles (from Patrick's point of view) if
C[0] xor C[1] xor C[2] xor ... xor C[N] == 0.
One such split is the sum of all candy values except one. To maximimise the value of one pile, take the lowest value candy and put it in a pile of its own.
Why is it so?
The way I thought about it, is that by definition Patrick's addition is actually equal to xoring values. From the definition of the problem, we want
C[i] xor C[j] xor ... xor C[k] == C[x] xor C[y] xor ... xor C[z]
for some elements on each side.
Adding the RHS to both the LHS and RHS yields
C[i] xor C[j] xor ... xor C[k] xor C[x] xor C[y] xor ... xor C[z] == 0
Since xoring a value with itself gives 0, and the order of xor operations is not important, the RHS becomes 0.
Any of the elements in the LHS can be moved over the to right side and the equality still holds. Picking the lowest value element makes the best split between the piles.

advice needed with prolog cut?

in this task i have a Prolog database filled with e.g.
edge(1,0)
edge(2,0)
edge(1,3)
an edge signifies that two points are joined.
I am asked to write a function called reach(i,j,k) where i is the start point j is the end point and k is the number of steps you may use.
K is needed to stop the recursion looping e.g.
Suppose the only edge I’ve got goes from 1 to3,and I’m trying to get to 6. Then I can’t get from 1to6 in one go. so I’ll look for somewhere I can get to, and see if I can get from there to 6. The first place I can get to in one go is 3, so I’ll try to get from there to 6.
i have done this as so:
%% Can you get there in one step (need two rules because all links are
%% from smaller to greater, but we may need to get from greater to smaller.
reach1(I, J,_K) :-
edge(I, J).
reach1(I, J,_K) :-
edge(J, I).
%% Chhose somewhere you can get to in one step: can you get from there
%% to your target?
reach1(I,J,K) :-
K>1,
edge(I, B),
K1 is K-1,
reach1(B,J,K1).
reach1(I,J,K) :-
K>1,
edge(B, I),
K1 is K-1,
reach1(B,J,K1).
this works, however i am stuck with the second part in which we are asked not to use k but to use a "cut" to do this.
does anyone know how to do this or can give me some pointers?
The cut ensures that once a goal has been resolved in one way, it doesn't look for another way.
example:
reach(I, J,_K) :-
edge(I, J).
no cut - if for some reason Prolog backtracks, it will try to reach from I to J another way.
You might feel there's no point reaching this node another way if the simple edge works, and in that case you can do:
reach(I, J,_K) :-
edge(I, J),
!.
which "cuts" any alternative to this goal, but the one Prolog has found.

Big O Log problem solving

I have question that comes from a algorithms book I'm reading and I am stumped on how to solve it (it's been a long time since I've done log or exponent math). The problem is as follows:
Suppose we are comparing implementations of insertion sort and merge sort on the same
machine. For inputs of size n, insertion sort runs in 8n^2 steps, while merge sort runs in 64n log n steps. For which values of n does insertion sort beat merge sort?
Log is base 2. I've started out trying to solve for equality, but get stuck around n = 8 log n.
I would like the answer to discuss how to solve this mathematically (brute force with excel not admissible sorry ;) ). Any links to the description of log math would be very helpful in my understanding your answer as well.
Thank you in advance!
http://www.wolframalpha.com/input/?i=solve%288+log%282%2Cn%29%3Dn%2Cn%29
(edited since old link stopped working)
Your best bet is to use Newton;s method.
http://en.wikipedia.org/wiki/Newton%27s_method
One technique to solving this would be to simply grab a graphing calculator and graph both functions (see the Wolfram link in another answer). Find the intersection that interests you (in case there are multiple intersections, as there are in your example).
In any case, there isn't a simple expression to solve n = 8 log₂ n (as far as I know). It may be simpler to rephrase the question as: "Find a zero of f(n) = n - 8 log₂ n". First, find a region containing the intersection you're interested in, and keep shrinking that region. For instance, suppose you know your target n is greater than 42, but less than 44. f(42) is less than 0, and f(44) is greater than 0. Try f(43). It's less than 0, so try 43.5. It's still less than 0, so try 43.75. It's greater than 0, so try 43.625. It's greater than 0, so keep going down, and so on. This technique is called binary search.
Sorry, that's just a variation of "brute force with excel" :-)
Edit:
For the fun of it, I made a spreadsheet that solves this problem with binary search: binary‑search.xls . The binary search logic is in the second data column, and I just auto-extended that.

Resources