How would you write a program to reduce an equation? - c++

I may be misinterpreting the exact phrasing on the question about which I've been thinking, but I'm curious as to how one would reduce an equation of multiple variables.
I'm assuming factoring plays a major role, however the only way I can think of doing it is to break the equation into a tree of operations and search the entire tree for duplicate nodes. I'm assuming that there's a better way, since many web applications do this quite quickly.
Any better way of doing this?

I would assume that the kind of reductions that they are looking for is that something like (2 + 3) * x should become (* 5 x) rather than (* (+ 2 3) x). In which case you can just recognize that subtrees are constant, and calculate them.
You can also use the associative and commutative laws to try to move things around first to assist in the process. So that 2 + x + 3 would become (+ 5 x) rather than (+ (+ 2 x) 3).
Take this idea as far as you want. It has been deliberately given in an open-ended fashion. I'm sure that they would be happy to see you automatically recognize that x * x + 2 * x + 1 is (* (+ 1 x) (+ 1 x)) instead of (+ (+ (* x x) (* 2 x)) 1) but you can do a lot of good reductions without going there.

The general solution is to write flex\bison translator and to reduce parsed expressions. When you have created a translation flow you can add rules like expr*expr + 2*expr + 1 -> (*expr expr) as simple as I write it here.

You can do it using a stack. It is much simpler that way. A solution is posted here
http://bluefintuna.wordpress.com/2008/07/15/infix-prefix/

One Problem is here what one considers as reduced: E.g. (I write it for better readeability in infix - but prefix it is similar) x * x + x + 2 + 2 * x, one obvious reduction would be x * x + 3 * x + 2, another one would be (x + 1) * (x + 2). As this are quite untrivial problems and from the wording of the assignment, I would assume you bring your equation in some canonical form (e.g polynomial, sorted with highest power to lowest (when you have more than one variable take to the sum of the powers) and reduce there the coefficients (calculate them when constant)).
Be careful that some optimizations may seem valid, but are not in general. E.g. dont reduce (/ (* x x) x) to x, as there the solution 0 is suddenly valid, which it was not before.

Related

How to make a multiplication function using just addition function and iterate function in SML

I have two functions, add and iterate, in SML.
fun add(x,y) = x + y
fun iterate n f x = if n > 0 then iterate (n-1) f(f x) else x;
Using those two functions only, how do I write a multiply function that for example if typed:
multiply 5 6
returns 30.
Then building off of that I need a function called power that only uses iterate and multiply to raise the first argument to the power of the second. An example:
power 5 4
It should return 625.
Any help would be greatly appreciated!
So the trick is to use iterate to help you with applying add recursively. Since iterate is a list-combinator that takes a function as argument, perhaps it is simpler if you go about this in a very rudimentary way: For example, you could define add by recursively incrementing/decrementing by one:
(* Written using if-then-else *)
fun add x y =
if y = 0 then x else
if y > 0 then add (x+1) (y-1) else add (x-1) (y+1)
(* Written using mixture of pattern-matching and if-then-else *)
fun add x 0 = x
| add x y = if y > 0
then add (x+1) (y-1)
else add (x-1) (y+1)
Now, that's of course grossly inefficient and completely unnecessary because we already have +, but for the sake of demonstrating recursion on numbers, this is an example of how to progress with multiply and power (still under the assumption that we don't have iterate yet).
The general method here is recursion: Since the function takes two operands, use one as the "accumulating result" and the other as "counting variable". Because this is a simple problem, you can just use x and y as the complete environment for the function's task. In slightly larger problems you might introduce more arguments that work as temporary/intermediate results.
You can write multiply in a very similar way:
fun multiply x 0 = 0
| multiply x y = if y > 0
then x + multiply x (y-1)
else ~x + multiply x (y+1)
This function solves the task (although still without iterate).
(This multiply isn't tail-recursive because the outermost expression (x + ... or ~x + ...) aren't calls to multiply (since the call happens inside the operand of +). That may not be a problem to you, but if it were, you can't easily write ... then multiply (x + ...) (y - 1), since when we use x for the purpose of accumulating the result, any subsequent recursive call has increased x, which means we can no longer add x to... itself... because x means two things now: the accumulating result, and what needs to be added once per recursive call.)
Any way, to get the last step, you have to identify what iterate has in common with the add and multiply I made. When you can spot the common denominator, you can isolate it and call iterate instead. I would like to fix one whitespace "bug" that may confuse your interpretation of iterate:
fun iterate n f x = if n > 0
then iterate (n-1) f (f x)
else x; (* ^- this space! *)
Adding this space does not change the behavior of the function, but when reading f(f x) one is tempted to believe that it says "apply f to f x", which is the wrong interpretation. What this function actually says under then is "call iterate with three arguments: n-1, f and f x; because n-1 binds less tight than function application, and f x is function application (which is left-associative), we add parentheses around them; this is not necessary for f."
In add and multiply, y is being used as the counting variable, whereas in iterate it is n. So the names and positions have changed, which means that a multiply based on iterate has to place the x and y in the right place. As for determining a value for f: How about the function that adds x to its result? You can express this function either using a lambda, (fn z => ...), or using partial application of the function add.
Lastly, with power it is much the same problem:
fun power x 0 = 1
| power x n = if n > 0
then x * power x (n-1)
else raise Fail "Cannot express 1/x^n as integer"
Since there isn't a good solution for integers, you either have to switch to the real type to express 1/x^n, you can also flip the condition and get the case of n < 0 out of the picture before beginning recursion:
fun power x n =
if n < 0 then raise Fail "Cannot express 1/x^n as integer"
else let fun go result 0 = result
| go result i = go (result * x) (i-1)
in go 1 n
end
The inner function go looks terribly much like add above, except x has become result and 1 has become add, and + has become *, and there is no negative case (if y > 0 ... else ...).
So that means you can actually use iterate instead of go as long as you for iterate n f x find good values:
What should n be? (Something to count down.)
What should f be? (Something that performs the stepwise calculation.)
What should x be? (The thing that gets applied in the stepwise calculation.)
(...all in terms of iterate; they may be called something else in the context of the power function and the arguments it has in scope.)

How can I define x as a list of integers to evaluate a polynomial for all elements in x?

The polynomial:
(modulo (+ (expt x 2) 2) 5)
I want to do something like
(define x <list of integers like 0, ..., 10>)
It should then output the result(s) like:
3
1
1
3
...
Do I have to write a separate method to get this working or does Scheme have something built-in?
The way you have it written won't work. In you're polynoimial your taking expt of x directly, which if you define it to be a list, will result in a run-time error.
(map (lambda (x) (modulo (+ (expt x 2) 2) 5)) (iota 11 1 1))
;Value 2: (3 1 1 3 2 3 1 1 3 2 3)
What I did was wrap up your polynomial as an anonymous function, and used it as an argument to map. The second argument (iota count start step) generates a list of length count starting at start and proceeding by and addition of step. start and step are optional argument defaulting to 0 and 1 respectively.
Map is a higher order function which accepts a function as it's first argument and one or more lists afterwards. To simplify thing's I'll ignore cases where more than one list is use. The new list meets the condition that any given element is the result of applying the function to the corresponting element of the original list.
(map f (x y z ...)) -> ((f x) (f y) (f z) ...)
I am not sure what you are asking, but if you want to construct a list of incrementing integers, to each element of which you can apply your polynomial function, SRFI-1 has the iota procedure. So
(iota 10)
will construct a list of 10 integers in the range 0 to 9. iota optionally takes additional start and step arguments. To apply the polynomial function to each integer and construct a new list of the results, you can use map.

How to parse a list and form a number in Prolog?

I would like to know if someone could help me with a problem in prolog. I have to define two predicates but before that, I need to find out a way how to parse a list and form a number. For example [1,2,3] => 123. I tried different ways to do this but nothing works good. My code looks like this, I know it is not good but I can't find another way.
num([H|T],I,RI,RES):-
H2 is H * I,
R1 is RI + H2,
I2 is I/10,
RES2 is RES + R1,
num(T,I2,R1,RES2).
Your hunch is correct that this can be much simpler. Recursively, you want to think of the digits [A, B, C] representing number as, (((A * 10) + B) * 10) + C.
To start, you want to think about what kind of predicate you desire. That would simply be, num(Digits, Number). which yields Number given Digits. You'll need an accumulator for intermediate results using the above formula concept, so your num/2 needs to call a num/3 that will include an accumulator argument that you carry along:
num(Digits, Num) :-
num(Digits, 0, Num). % Accumulator initially 0
If the input list is empty, the result is the accumulator:
num([], A, A). % Result is accumulator when there are no digits
Then your recursive case:
num([D|T], A, R) :-
NewA is (D * 10) + A, % New accumulator is (current digit * 10) + old accumlator
... % Need recursive call
I'll leave the ... for you to fill in as an exercise. :)

reduce-while function in clojure?

I am new to Clojure programming, and would like to know what is the idiomatic way to do the following thing:
I would like to sum a collection of numbers nums, which may contains a large number of numbers, let's assume there are only positive numbers.
I don't care the exact sum if the sum is very large. For example, if the sum of the numbers is larger than 9999, I would simply return 10000 without summing the remaining numbers at all.
If I implement it with some OO language such as Java, I may do it like below:
private int sum(int[] nums) {
int sum = 0;
for(int n : nums) {
if(sum > 9999) {
sum = 10000;
break;
} else {
sum += n;
}
}
return sum;
}
A naive implementation in Clojure may look like:
(let [sum (reduce + nums)]
(if (> sum 9999) 10000 sum))
However, this seems to waste some CPU resource to sum the entire collection of numbers, which is not desired. I am looking for something like take-while function but for reduce, but cannot find it. Is there something like:
(reduce-while pred f val coll)
Or is there any other Clojure idiomatic way to solve this problem? I think the solution can be applied to a set of problems requiring similar logic.
Any comment is appreciated. Thanks.
If you're using Clojure 1.5.x then you may take advantage of new reduced function:
(reduce #(if (> %1 9999) (reduced 10000) (+ %1 %2)) nums)
One of the lesser known Clojure functions seems to be reductions. It will give you all the intermediate results of your computation:
(reductions + (range 4)) ;; => (0 1 3 6)
(reduce + (range 4)) ;; => 6
The last element of reductions' result seq will be the reduced value. There are multiple ways to enforce your predicate, e.g. using some:
(let [sums (reductions + nums)]
(if (some #(> % 9999) sums)
10000
(last sums)))
The reduce/reduced version given by #leonid-beschastny is probably faster (no lazy sequence overhead, reducers, ...) but this one will work in earlier Clojure versions, too.

Prolog Finding Kth element in a list

I am trying write a predicate in prolog to find Kth element in a list.
Example:
?- element_at(X,[a,b,c,d,e],3).
X = c
my code as follows
k_ele(X,[X|_],1).
k_ele(X,[_|T],Y) :- Y > 1,Y is Y - 1, k_ele(X,T,Y).
But no use, I found solution on Internet as
element_at(X,[X|_],1).
element_at(X,[_|L],K) :- K > 1, K1 is K - 1, element_at(X,L,K1).
Which is same as my logic except they used one extra variable K1.
What is wrong with my code, why I need another variable ?
The reason your code does not work is that unification is not an assignment. When you say
Y is Y - 1
you are trying to unify a value of Y with the value of Y-1, which is mathematically impossible. This is roughly the same as saying 4 is 3 or 1001 is 1000. The entire condition fails, leading to the failure to find the element in the list.
The fixed solution that you have found on the internet introduces a separate variable K1, which is unified with K - 1. This is very much doable: K1 gets the value to which K-1 evaluates, the condition succeeds, and the clause moves on to the recursive invocation part.
Because variables in prolog are write-once critters. Having been [assigned|unified with|bound to] a non-variable value, it ceases to be variable. It is henceforth that value. Unlike more...conventional...programming languages, once bound, the only way to reassign a prolog variable is to backtrack through the assignment and undo it.
It should be noted, though, that a variable can be unified with another variable: Given a predicate something like
foo(X,Y) :- X = Y .
and something like
shazam(X,Y) :- bar(X,Y) , X = 3.
will result in both X and Y being 3. Having been unified, X and Y are both the same variable, albeit with different names.
I imagine you're working with the exercises from this link:
http://www.ic.unicamp.br/~meidanis/courses/problemas-prolog/
Note, in my opinion the original solution is not the best either.
For example, a query:
element_at(X,[a,b,c],Y).
would crash, even if there are 3 solutions:
X = a, Y = 1;
X = b, Y = 2;
X = c, Y = 3;
I believe writing in an alternative way:
element_at(H, [H | _], 1).
element_at(H, [_ | T], N) :- element_at(H, T, NMinus1), N is NMinus1 + 1.
would give better results. It's less efficient as one can not apply the last call optimization, but the logic becomes more general.