Finding the product of each of the (n-1) subsets of a given array - algorithm

I'm sorry for deleting the original question, here it is:
We have a bag or an array of n integers, we need to find the product of each of the (n-1) subsets. e.g:
S = {1, 0, 3, 6}
ps[1] = 0*3*6 = 0;
ps[2] = 1*3*6 = 18; etc.
After discussions, we need to take care of the three cases and they are illustrated in the following:
1. S is a set (contains one zero element)
for i=1 to n
if s[i]=0
sp[i] = s[1] * s[2] * ...* s[i-1] * s[i+1] *.....*s[n]
else
sp[i] = 0;
2. S is a bag (contains more than one zero element)
for i=1 to n
sp[i] = 0;
3. S is a set (contains no zero elements)
product = 1
for i=1 to n
product *= s[i];
for i=1 to n
sp[i] = product / s[i];
Thanks.

If the set is very large, it may be convenient to:
compute the product P of all the elements beforehand, and then
for each element x, obtain a (n-1) product as P/x
If the set contains zero (i.e. P=0, x=0), you must deal with it as a special case.
EDIT. Here is a solution in Scheme, taking into account andand's answer. I'm a complete beginner - can someone help me improve the following code (make it more efficient, more readable, more lisp-ish)? (Feel free to edit my answer.)
#!/usr/bin/env guile !#
(use-modules (ice-9 pretty-print))
(define (count-zeros l)
(cond ((null? l) 0)
((= 0 (car l)) (+ 1 (count-zeros (cdr l))))
(else (count-zeros (cdr l)))))
(define (non-zero-product l)
(define (non-zero-product-loop l product)
(cond ((null? l) product)
((= 0 (car l)) (non-zero-product-loop (cdr l) product))
(else (non-zero-product-loop (cdr l) (* (car l) product)))))
(non-zero-product-loop l 1))
(define (n-1-products l)
(let ((nzeros (count-zeros l)))
(cond ((> nzeros 1)
(map (lambda (x) 0) l))
((= 1 nzeros)
(map (lambda (x) (if (= 0 x) (non-zero-product l) 0)) l))
(else
(map (lambda (x) (/ (non-zero-product l) x)) l)))))
(pretty-print (n-1-products '(1 2 3 4 5)))
(pretty-print (n-1-products '(0 1 2 3 4)))
(pretty-print (n-1-products '(0 1 2 3 0)))

You need to explicitly consider the three cases:
1) No zeros: Precompute the product of all of the elements and divide out the desired set element from that product.
2) One zero: Precompute the product of the non-zero elements. The answer is always 0 except when you remove the single zero element, in which case it's the precomputed product.
3) More than one zero: The answer is always 0.
This assumes that you have a data type that can contain the products... that is, you need to be careful that your product doesn't exceed the maximum value of the type you're using to store it.
For the actual implementation, always precompute the product of the non-zero elements and keep track of how many zeros there are. If the "set" is dynamic (its values change) you'll need to update the product and the zero count. When asked for a particular subset product, consider the various cases and act accordingly.

Set product = 1;
for item in set:
if item index == argument index
ignore
else
product *= item
If I understand your question, this is the trivial solution. It should be easy to implement in any programming language.

You can solve this in O(N), using O(1) additional space (not counting the O(N) output array), without even using division. Here's the algorithm in Java.
static int[] products(int... nums) {
final int N = nums.length;
int[] prods = new int[N];
int pi = 1;
for (int i = 0; i < N; i++) {
prods[i] = pi;
pi *= nums[i];
}
int pj = 1;
for (int j = N-1; j >= 0; j--) {
prods[j] *= pj;
pj *= nums[j];
}
return prods;
}
//...
System.out.println(
Arrays.toString(products(1, 2, 3, 4, 5))
); // prints "[120, 60, 40, 30, 24]"
See also
Interview Q: given an array of numbers, return array of products of all other numbers (no division)

Assuming you can use Python:
You can use the combinations method from the itertools module to lazily generate the various subsets of the set in question. Once you have that, you can use reduce and operator.mul to generate the product of each one.

Related

Knuth-Morris-Pratt algorithm in Scheme

This is the code to calculate the failure function (how many steps we have to go back) in Scheme, when we use the Knuth-Morris-Pratt algorithm:
(define (compute-failure-function p)
(define n-p (string-length p))
(define sigma-table (make-vector n-p 0))
(let loop
((i-p 2)
(k 0))
(cond
((>= i-p n-p)
(vector-set! sigma-table (- n-p 1) k))
((eq? (string-ref p k)
(string-ref p (- i-p 1)))
(vector-set! sigma-table i-p (+ k 1))
(loop (+ i-p 1) (+ k 1)))
((> k 0)
(loop i-p (vector-ref sigma-table k)))
(else ; k=0
(vector-set! sigma-table i-p 0)
(loop (+ i-p 1) k))))
(vector-set! sigma-table 0 -1)
(lambda (q)
(vector-ref sigma-table q)))
But I do not understand the part when k > 0. Can someone explain it please?
I see you're confused with the syntax of a named let. This post does a good job explaining how it works, but perhaps an example with more familiar syntax will make things clearer. Take this code in Python, it adds all integers from 1 to 10:
sum = 0
n = 1
while n <= 10:
sum += n
n += 1
print(sum)
=> 55
Now let's try to write it in a recursive fashion, I'll call my function loop. This is completely equivalent:
def loop(n, sum):
if n > 10:
return sum
else:
return loop(n + 1, n + sum)
loop(1, 0)
=> 55
In the above example, the loop function implements an iteration, the parameter n is used to keep track of the current position, and the parameter sum accumulates the answer. Now let's write the exact same code, but in Scheme:
(let loop ((n 1) (sum 0))
(cond ((> n 10) sum)
(else (loop (+ n 1) (+ n sum)))))
=> 55
Now we've defined a local procedure called loop which is then automatically called with the initial values 1 and 0 for its parameters n and sum. When the base case of the recursion is reached, we return sum, otherwise we keep calling this procedure, passing updated values for the parameters. It's exactly the same as in the Python code! Don't be confused by the syntax.
In your algorithm, i-p and k are the iteration variables, which are initialized to 2 and 0 respectively. Depending on which condition is true, the iteration continues when we call loop again with updated values for i-p and k, or it ends when the case (>= i-p n-p) is reached, at this point the loop exits and the computed value is in the variable sigma-table. The procedure ends by returning a new function, referred to as the "failure function".

How do i check a list has distinct objects(is a set?) or not Scheme

I am trying to write a function in scheme which is checking a list is a set or not.
In C algorithm would be like this:
int count = sizeof(array) / sizeof(array[0]);
for (int i = 0; i < count - 1; i++) {
for (int j = i + 1; j < count; j++) {
if (array[i] == array[j]) {
//return false
}
}
}
(define set? (lambda (lst)
))
You use the [racket] tag, so I'm going to assume that you're using Racket. You can use the library function check-duplicates to check for duplicate elements. You can use remove-duplicates to remove them.
I assume that you want to know how you would do this if, for instance, the language didn't already have a set datatype (which Racket does) and a bunch of tools to deal with sets, including dealing with lists as sets. So lets reinvent things that already exist, starting with a function which tells you if something occurs in a list (in real life this is a bunch of functions with names like member):
(define (occurs? e l (test? eqv?))
;; does e occur in l, testing with test?
(cond [(null? l)
;; empty lists have no members
#f]
[(test? e (first l))
;; if e is the first element of l then it's in l
#t]
[else
;; if e is in the rest of l it's in l
(occurs? e (rest l) test?)]))
And now you can answer the question as to whether a list is a set. A list is a set if:
it is the empty list;
the first element of the list does not occur in the rest of the list, and the rest of the list is a set.
And this specification can be turned directly into code:
(define (list-set? l (test? eqv?))
;; is l a set?
(if (null? l)
;; the empty list is a set
#t
;; otherwise it is a set if ...
(and
;; .. the first element of it does not occur in the rest of it ...
(not (occurs? (first l) (rest l) test?))
;; ... and the rest of it is a set
(list-set? (rest l) test?))))
Basically what you are doing is having two cursors. i that starts at the beginning and goes towards next to last element and for each of those you have j that starts one next to i and goes to the end.
Here is how to make a loop:
(let name ((var 0) (var2 5))
(if (> var var2)
var
(name (+ (* 2 var) 1) (+ var2 1))))
Since we are talking about lists here and lists are chains of cons instead of having indexes you just use the bindings to the individual cons for iteration:
(define test '(1 2 3 4 5 6 7 8))
(let find-half ((hare test) (tortoise test))
(if (or (null? hare)
(null? (cdr hare)))
tortoise
(find-half (cddr hare) (cdr tortoise))))
So what is the named let? It's a recursive function. The above is the same as:
(define test '(1 2 3 4 5 6 7 8))
(define (find-half hare tortoise)
(if (or (null? hare)
(null? (cdr hare)))
tortoise
(find-half (cddr hare) (cdr tortoise))))
(find-half test test)
It might be easier if you could write your C solution with recursion? Eg.
int fori (int i) {
return i >= count - 1 ||
forj(i, i+1) && fori(i+1);
}
int forj (int i, int j) {
return j >= count ||
array[i] == array[j] && forj(i, j+1);
}
int result = fori(0);

Sort prime factors in ascending order Scheme

I am new to Scheme and I want to sort the prime factors of a number into ascending order. I found this code, but it does not sort.
(define (primefact n)
(let loop ([n n] [m 2] [factors (list)])
(cond [(= n 1) factors]
[(= 0 (modulo n m)) (loop (/ n m) 2 (cons m factors))]
[else (loop n (add1 m) factors)])))
Can you please help.
Thank you
I would say it sorts, but descending. If you want to sort the other way, just reverse the result:
(cond [(= n 1) (reverse factors)]
Usually when you need something sorted in the order you get them you can
cons them like this:
(define (primefact-asc n)
(let recur ((n n) (m 2))
(cond ((= n 1) '())
((= 0 (modulo n m)) (cons m (recur (/ n m) m))) ; replaced 2 with m
(else (recur n (+ 1 m))))))
Note that this is not tail recursive since it needs to cons the result, but since the amount of factors in an answer is few (thousands perhaps) it won't matter much.
Also, since it does find the factors in order you don't need to start at 2 every round but the number you found.
Which dialect of Scheme is used?
Three hints:
You need only to test for divisors less equal as the square-root of your Number.
a * b = N ; a < b ---> a <= sqrt( N ).
If you need all Prime-Numbers less some Number, you should use the sieve of eratothenes. See Wikipedia.
Before you start to write a program, look in Wikipedia.
If

Idiomatic Clojure for solving dynamic programming algorithm

I decided to work through the CLRS Introduction to Algorithms text, and picked the printing neatly problem here.
I worked through the problem and came up with an imperative solution which was straightforward to implement in Python, but somewhat less so in Clojure.
I'm completely stumped on translating the compute-matrix function from my solution into idiomatic Clojure. Any suggestions? Here is the pseudocode for the compute-matrix function:
// n is the dimension of the square matrix.
// c is the matrix.
function compute-matrix(c, n):
// Traverse through the left-lower triangular matrix and calculate values.
for i=2 to n:
for j=i to n:
// This is our minimum value sentinal.
// If we encounter a value lower than this, then we store the new
// lowest value.
optimal-cost = INF
// Index in previous column representing the row we want to point to.
// Whenever we update 't' with a new lowest value, we need to change
// 'row' to point to the row we're getting that value from.
row = 0
// This iterates through each entry in the previous column.
// Note: we have a lower triangular matrix, meaning data only
// exists in the left-lower half.
// We are on column 'i', but because we're in a left-lower triangular
// matrix, data doesn't start until row (i-1).
//
// Similarly, we go to (j-1) because we can't choose a configuration
// where the previous column ended on a word who's index is larger
// than the word index this column starts on - the case which occurs
// when we go for k=(i-1) to greater than (j-1)
for k=(i-1) to (j-1):
// When 'j' is equal to 'n', we are at the last cell and we
// don't care how much whitespace we have. Just take the total
// from the previous cell.
// Note: if 'j' < 'n', then compute normally.
if (j < n):
z = cost(k + 1, j) + c[i-1, k]
else:
z = c[i-1, k]
if z < optimal-cost:
row = k
optimal-cost = z
c[i,j] = optimal-cost
c[i,j].row = row
Additionally, I would very much appreciate feedback on the rest of my Clojure source, specifically with regards to how idiomatic it is. Have I managed to think sufficiently outside of the imperative paradigm for the Clojure code I've written thus far? Here it is:
(ns print-neatly)
;-----------------------------------------------------------------------------
; High-order function which returns a function that computes the cost
; for i and j where i is the starting word index and j is the ending word
; index for the word list "word-list."
;
(defn make-cost [word-list max-length]
(fn [i j]
(let [total (reduce + (map #(count %1) (subvec word-list i j)))
result (- max-length (+ (- j i) total))]
(if (< result 0)
nil
(* result result result)))))
;-----------------------------------------------------------------------------
; initialization function for nxn matrix
;
(defn matrix-construct [n cost-func]
(let [; Prepend nil to our collection.
append-empty
(fn [v]
(cons nil v))
; Like append-empty; append cost-func for first column.
append-cost
(fn [v, index]
(cons (cost-func 0 index) v))
; Define an internal helper which calls append-empty N times to create
; a new vector consisting of N nil values.
; ie., [nil[0] nil[1] nil[2] ... nil[N]]
construct-empty-vec
(fn [n]
(loop [cnt n coll ()]
(if (neg? cnt)
(vec coll)
(recur (dec cnt) (append-empty coll)))))
; Construct the base level where each entry is the basic cost function
; calculated for the base level. (ie., starting and ending at the
; same word)
construct-base
(fn [n]
(loop [cnt n coll ()]
(if (neg? cnt)
(vec coll)
(recur (dec cnt) (append-cost coll cnt)))))]
; The main matrix-construct logic, which just creates a new Nx1 vector
; via construct-empty-vec, then prepends that to coll.
; We end up with a vector of N entries where each entry is a Nx1 vector.
(loop [cnt n coll ()]
(cond
(zero? cnt) (vec coll)
(= cnt 1) (recur (dec cnt) (cons (construct-base n) coll))
:else (recur (dec cnt) (cons (construct-empty-vec n) coll))))))
;-----------------------------------------------------------------------------
; Return the value at a given index in a matrix.
;
(defn matrix-lookup [matrix row col]
(nth (nth matrix row) col))
;-----------------------------------------------------------------------------
; Return a new matrix M with M[row,col] = value
; but otherwise M[i,j] = matrix[i,j]
;
(defn matrix-set [matrix row col value]
(let [my-row (nth matrix row)
my-cel (assoc my-row col value)]
(assoc matrix row my-cel)))
;-----------------------------------------------------------------------------
; Print the matrix out in a nicely formatted fashion.
;
(defn matrix-print [matrix]
(doseq [j (range (count matrix))]
(doseq [i (range (count matrix))]
(let [el (nth (nth matrix i) j)]
(print (format "%1$8.8s" el)))) ; 1st item max 8 and min 8 chars
(println)))
;-----------------------------------------------------------------------------
; Main
;-----------------------------------------------------------------------------
;-----------------------------------------------------------------------------
; Grab all arguments from the command line.
;
(let [line-length (Integer. (first *command-line-args*))
words (vec (rest *command-line-args*))
cost (make-cost words line-length)
matrix (matrix-construct (count words) cost)]
(matrix-print matrix))
EDIT: I've updated my matrix-construct function with the feedback given, so now it's actually one line shorter than my Python implementation.
;-----------------------------------------------------------------------------
; Initialization function for nxn matrix
;
(defn matrix-construct [n cost-func]
(letfn [; Build an n-length vector of nil
(construct-empty-vec [n]
(vec (repeat n nil)))
; Short-cut so we can use 'map' to apply the cost-func to each
; element in a range.
(my-cost [j]
(cost-func 0 j))
; Construct the base level where each entry is the basic cost function
; calculated for the base level. (ie., starting and ending at the
; same word)
(construct-base-vec [n]
(vec (map my-cost (range n))))]
; The main matrix-construct logic, which just creates a new Nx1 vector
; via construct-empty-vec, then prepends that to coll.
; We end up with a vector of N entries where each entry is a Nx1 vector.
(let [m (repeat (- n 1) (construct-empty-vec n))]
(vec (cons (construct-base-vec n) m)))))
Instead of using let with fn's in it, try letfn.
doseq doseq -> looks like it would likely be better as a for comprehension
Your cond / zero? / = 1 code would be easier to read (and faster) with case.
My spidey-sense tells me that the loop/recurs here should be some kind of map call instead
I strongly suspect that this would be far faster with primitive arrays (and possibly cleaner in some places)
You might like to use or look at the source for Incanter
I climbed the wall and was able to think in a sufficiently Clojure-like way to translate the core compute-matrix algorithm into a workable program.
It's just one line longer than my Python implementation, although it appears to be more densely written. For sure, concepts like 'map' and 'reduce' are higher-level functions that require you to put your thinking cap on.
I believe this implementation also fixes a bug in my Python one. :)
;-----------------------------------------------------------------------------
; Compute all table entries so we can compute the optimal cost path and
; reconstruct an optimal solution.
;
(defn compute-matrix [m cost]
(letfn [; Return a function that computes 'cost(k+1,j) + c[i-1,k]'
; OR just 'c[i-1,k]' if we're on the last row.
(make-min-func [matrix i j]
(if (< j (- (count matrix) 1))
(fn [k]
(+ (cost (+ k 1) j) (get-in matrix [(- i 1) k])))
(fn [k]
(get-in matrix [(- i 1) k]))))
; Find the minimum cost for the new cost: 'cost(k+1,j)'
; added to the previous entry's cost: 'c[i-1,k]'
(min-cost [matrix i j]
(let [this-cost (make-min-func matrix i j)
rang (range (- i 1) (- j 1))
cnt (if (= rang ()) (list (- i 1)) rang)]
(apply min (map this-cost cnt))))
; Takes a matrix and indices, returns an updated matrix.
(combine [matrix indices]
(let [i (first indices)
j (nth indices 1)
opt (min-cost matrix i j)]
(assoc-in matrix [i j] opt)))]
(reduce combine m
(for [i (range 1 (count m)) j (range i (count m))] [i j]))))
Thank you Alex and Jake for your comments. They were both very helpful and have helped me on my way toward idiomatic Clojure.
My general approach to dynamic programs in Clojure is not to mess with construction of the matrix of values directly, but rather to use memorization in tandem with a fixed point combinator. Here's my example for computing edit distance:
(defn edit-distance-fp
"Computes the edit distance between two collections"
[fp coll1 coll2]
(cond
(and (empty? coll1) (empty? coll2)) 0
(empty? coll2) (count coll1)
(empty? coll1) (count coll2)
:else (let [x1 (first coll1)
xs (rest coll1)
y1 (first coll2)
ys (rest coll2)]
(min
(+ (fp fp xs ys) (if (= x1 y1) 0 1))
(inc (fp fp coll1 ys))
(inc (fp fp xs coll2))))))
The only difference from the naive recursive solution here is simply to replace the recursive calls with calls to fp.
And then I create a memoized fixed point with:
(defn memoize-recursive [f] (let [g (memoize f)] (partial g g)))
(defn mk-edit-distance [] (memoize-recursive edit-distance-fp))
And then call it with:
> (time ((mk-edit-distance)
"the quick brown fox jumped over the tawdry moon"
"quickly brown foxes moonjumped the tawdriness"))
"Elapsed time: 45.758 msecs"
23
I find memoization easier to wrap my brain around than mutating tables.
Your matrix-lookup and matrix-set functions can be simplified. You can use assoc-in and get-in for manipulating nested associative structures.
(defn matrix-lookup [matrix row col]
(get-in matrix [row col]))
(defn matrix-set [matrix row col value]
(assoc-in matrix [row col] value))
Alex Miller mentioned using primitive arrays. If you end up needing to go that direction you can start by looking at int-array, aset-int, and aget. Look at the clojure.core documentation to find out more.

Help understanding Sieve of Eratosthenes implementation

This is boring, I know, but I need a little help understanding an implementation of the Sieve of Eratosthenes. It's the solution to this Programming Praxis problem.
(define (primes n)
(let* ((max-index (quotient (- n 3) 2))
(v (make-vector (+ 1 max-index) #t)))
(let loop ((i 0) (ps '(2)))
(let ((p (+ i i 3)) (startj (+ (* 2 i i) (* 6 i) 3)))
(cond ((>= (* p p) n)
(let loop ((j i) (ps ps))
(cond ((> j max-index) (reverse ps))
((vector-ref v j)
(loop (+ j 1) (cons (+ j j 3) ps)))
(else (loop (+ j 1) ps)))))
((vector-ref v i)
(let loop ((j startj))
(if (<= j max-index)
(begin (vector-set! v j #f)
(loop (+ j p)))))
(loop (+ 1 i) (cons p ps)))
(else (loop (+ 1 i) ps)))))))
The part I'm having trouble with is startj. Now, I can see that p is going to be cycling through odd numbers starting at 3, defined as (+ i i 3). But I don't understand the relationship between p and startj, which is (+ (* 2 i i) (* 6 i) 3).
Edit: I understand that the idea is to skip previously sifted numbers. The puzzle definition states that when sifting a number x, sifting should start at the square of x. So, when sifting 3, start by eliminating 9, etc.
However, what I don't understand is how the author came up with that expression for startj (algebraically speaking).
From the puzzle comments:
In general, when sifting by n, sifting starts at n-squared because all the previous multiples of n have already been sieved.
The rest of the expression has to do with the cross-reference between numbers and sieve indexes. There’s a 2 in the expression because we eliminated all the even numbers before we ever started. There’s a 3 in the expression because Scheme vectors are zero-based, and the numbers 0, 1 and 2 aren’t part of the sieve. I think the 6 is actually a combination of the 2 and the 3, but it’s been a while since I looked at the code, so I’ll leave it to you to figure out.
If anyone could help me with this, that'd be great. Thanks!
I think I've figured it out, with the assistance of programmingpraxis' comments on their website.
To restate the problem, startj is defined in the listing as (+ (* 2 i i) (* 6 i) 3), i.e. 2i^2 + 6i + 3.
I didn't initially understand how this expression related to p - since 'sifting' for a number p should start at p^2, I figured that startj should be something relating to 4i^2 + 12i + 9.
However, startj is an index into the vector v, which contains odd numbers starting from 3. Therefore, the index for p^2 is actually (p^2 - 3) / 2.
Expanding the equation: (p^2 - 3) / 2 = ([4i^2 + 12i + 9] - 3) / 2 = 2i^2 + 6i + 3 - which is the value of startj.
I feel it might've been clearer to define startj as (quotient (- (* p p) 3) 2), but anyway - I think that solves it :)
David Seiler: perhaps not the clearest, but in addition to implementing the basic Sieve it also has to implement the three optimizations described in the exercise.
Harto: that was my second exercise. I was still experimenting with my writing style.
Ephemient: correct.
See a more complete explanation in my comment at Programming Praxis.
EDIT: I've added an additional comment at Programming Praxis. And when I actually looked at the code, I was wrong about the derivation of the number 6 in the formula; sorry I mislead you.

Resources