Boolean expression with four operands - boolean

How can I write a boolean expression which will be true if and only if there is one out of four operands is true? I need the most succinct possible way to write it.

Here's how I'd do it:
((A XOR B) XOR (C XOR D)) AND (NOT (A AND B)) AND (NOT (C AND D))
The first part
((A XOR B) XOR (C XOR D))
Works for all cases except three inputs being true, hence the second part.

Related

GCD ( greatest common divisor ) of a list/array of numbers in LISP

How can I make the GCD of a list of numbers in LISP? I want to calculate the Greatest Common Divisor of a given input list.
Common Lisp has a gcd function which takes any number of arguments. So one way is to use that function and apply in an obvious way.
That's a fairly bad way though. A better way is to rely on the fact that GCD is an associative function. This means that gcd(a, gcd(b, c)) = gcd(gcd(a, b), c). That leads you to a very neat approach for computing the gcd of arbitrary length lists:
Given a list l, and a current gcd g, then
if l is empty the result is g;
if l is not empty then it is of the form (a . r), and the result is now the gcd of r using a current value of gcd(g, a).
As an additional trick: once you've got 1 as the current value, you can stop.
If you are required to write the two argument function, here are two implementations which work for non-zero natural numbers:
(defun gcd/euclidean (a b)
(declare (type (integer 0) a b))
(cond
((= a 0) b)
((= a b) a)
((> a b) (gcd/euclidean (mod a b) b))
(t (gcd/euclidean b a))))
(defun gcd/euclid (a b)
(declare (type (integer 1) a b))
(cond
((= a b) a)
((> a b) (gcd/euclid (- a b) b))
(t (gcd/euclid b a))))
One of these is much better than the other!

Why is (a and (not b)) or (a and b) = a?

I reached the end of a pretty long Boolean simplification, where I was supposed to prove that something = a. I reached a point (a and (not b)) or (a and b). Any further reorganization of the equation did not bring me further. But using a Truth tabel I checked to see that (a and (not b)) or (a and b) indeed does equal a. And it does make sense intuitively too, but can you actually use the Laws of Boolean Algebra to turn (a and (not b)) or (a and b) into a?
It makes more sense when you use the simplified notation, * for and, + for or, ~ for not.
(a and b) or (a and (not b)) =
(a*b)+(a*(~b)) =
a*(b+(~b)) =
a*(1) =
a
((a and (not b)) or (a and b)) ... distributive law
<=> (a and (b or not b) ... (b or not b) is alway true
<=> a
Feel free to distribute:
c = (a and ¬b)
(a and b) or c
(a or c) and (b or c)
(a or (a and ¬b)) and (b or (a and ¬b))
distribute again for both the left and right sides:
((a or a) and (a or ¬b)) and ((b or a) and (b or ¬b))
simplify:
(a and (a or ¬b)) and ((b or a) and T)
(a and (a or ¬b)) and (b or a)
simplify again (using the absorption property = x and (x or y) == x):
(a) and (b or a)
and again:
a and (a or b)
== a
(I know this is a bit of the long way around...)

Boolean: How to convert a NAND4 to a NAND2

I have the following problem. My equation is:
NAND2(NAND4(d,c,-b,a),NAND2(c,-a))
the "-" represents "NOT". I am not allowed to use NAND4, I am only allowed to use NAND2.
How do I convert this?
Thanks
NAND in general is equivalent to NOT(AND(…))
AND4(a, b, c, d) is equivalent to AND2(AND2(a, b), AND2(c, d))
NAND4(a, b, c, d) is thus equivalent to NOT(AND4(a, b, c, d)) and that’s equivalent to NOT(AND2(AND2(a, b), AND2(c, d)))
This is equivalent to NAND2(AND2(a, b), AND2(c, d))
If you were only allowed to use NANDs but not ANDs, you could invert the ANDs there: NAND2(NOT(NAND2(a, b)), NOT(NAND2(c, d)))

Common Lisp function that unwraps a list to reveal the sequence of elements inside the list?

I want to apply the union function to the lists within a list. For example:
apply union to the lists inside this list: '((a b c) (a d))
Is there a function that "unwraps" a list, to reveal the sequence of elements inside the list? For example:
unwrapping this list '((a b c) (a d)) produces this sequence '(a b c) '(a d)
If I could do that, then I could apply the union function to the sequence.
What is the recommended idiom for taking the union of a sequence of lists contained within a list?
CL-USER 15 > (reduce #'union '((a b c) (a d)))
(D A B C)

Sublist in common lisp

I have list of lists in my program
for example
(( a b) (c d) (x y) (d u) ........)
Actually I want to add 1 new element in the list but new element would be a parent of all existing sublists.
for example if a new element is z, so my list should become like this
( (z( a b) (c d) (x y) (d u) ........))
I have tried with push new element but it list comes like this
( z( a b) (c d) (x y) (d u) ........)
that I dont want as I have lot of new elements coming in and each element represents some block of sublists in the list
Your help would highly be appreciated.
It sounds like you just need to wrap the result of push, cons, or list* in another list:
(defun add-parent (children parent)
(list (list* parent children)))
(add-parent '((a b) (c d) (x y) (d u)) 'z)
;;=> ((Z (A B) (C D) (X Y) (D U)))
This is the approach that I'd probably take with this. It's just important that you save the return value. In this regard, it's sort of like the sort function.
However, if you want to make a destructive macro out of that, you can do that too using define-modify-macro. In the following, we use define-modify-macro to define a macro add-parentf that updates its first argument to be the result of calling add-parent (defined above) with the first argument and the parent.
(define-modify-macro add-parentf (parent) add-parent)
(let ((kids (copy-tree '((a b) (c d) (x y) (d u)))))
(add-parentf kids 'z)
kids)
;;=> ((Z (A B) (C D) (X Y) (D U)))
For such a simple case you can also use a shorter backquote approach, for example:
(let ((parent 'z) (children '((a b) (c d) (e f))))
`((,parent ,#children)))
If you aren't familiar with backquote, I'd recommend reading the nice and concise description in Appendix D: Read Macros of Paul Graham's ANSI Common Lisp.