I've been tasked with writing a function that generates a table given n operators. The truth table must be in a list and each row of the table must be in separate lists (inside the main list).
I know the solution involves recursion but I just can't seem to think it through.
Can someone help me out? This is only a small part of the assignment.
Easiest way I can think of off the top of my head is to simply convert 2^n to binary and count down, then convert the output to a list.
ie for n=3:
Truth table:
a b c
0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1
2^3 = 8, 8 in binary = 1000, start from 1000-1 = 111 and work your way down to 0, record outputs, and voila!
If hkf's interpretation of your question is right, this should work in Racket:
#lang racket
(define (generate-table n)
(if (zero? n)
'(())
(for*/list ((y (in-list (generate-table (sub1 n))))
(x (in-list '(0 1))))
(cons x y))))
Use it like this:
(generate-table 3)
> ((0 0 0) (1 0 0) (0 1 0) (1 1 0) (0 0 1) (1 0 1) (0 1 1) (1 1 1))
Let's assume that all N operators are binary functions, like AND and OR.
;; Common Lisp
(defun truth-tables (ops)
(loop for op in ops
collecting
(loop for args in '((nil nil) (nil t) (t nil) (t t))
collecting (eval `(,op ,#args)))))
(truth-tables '(and or xor)) -> ((NIL NIL NIL T) (NIL T T T) (NIL T T NIL))
This gives you an idea. Well, here I don't have "each row of the truth table" as a sublist; I have the columns for the AND, OR and XOR truth tables, respectively. The input variable combinations are left implicit: you know that the third entry of every one corresponds to (<op> t nil). Your description of the problem is not very clear.
As you can also see, I cheated by using the Lisp operators through generated code which is dynamically evaluated.
Related
I'm still learning Clojure and can't seem to find a simple answer for this. I've seen similar questions answered with complex code specific for the OP's issue so please let me know the most accurate or acceptable version of the following:
int[][] arrayTest = new int[width][height];
...
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
int a = arrayTest[x][y];
if (a < 100) {
arrayTest[x][y] = 0;
}
}
}
The literal translation is straightforward:
(def array-test
(make-array Integer/TYPE width height))
(doseq [x (range width)
y (range height)]
(when (< (aget array-test x y) 100)
(aset-int array-test x y 0)))
Note, however, that arrays are not commonly used in Clojure. Unless you want to do fast computations or work with existing Java code, you shouldn't normally be creating arrays and other mutable data structures. Most likely, what you want to implement can be done with Clojure's persistent collections instead.
Represented as a sequence of sequences...
user=> (doc repeat)
-------------------------
clojure.core/repeat
([x] [n x])
Returns a lazy (infinite!, or length n if supplied) sequence of xs.
nil
user=> (def width 8)
#'user/width
user=> (def height 6)
#'user/height
user=> (repeat width 0)
(0 0 0 0 0 0 0 0)
user=> (pprint (repeat height (repeat width 0)))
((0 0 0 0 0 0 0 0)
(0 0 0 0 0 0 0 0)
(0 0 0 0 0 0 0 0)
(0 0 0 0 0 0 0 0)
(0 0 0 0 0 0 0 0)
(0 0 0 0 0 0 0 0))
nil
I made this function and I want to make it print like this :
(RANGE ‘(0 7 8 2 3 –1))
(-1 8)
;; print 'The range between the smallest number and the second smallest number in the list' and 'The largest number'
So I made code like this :
(defun my-range (list-of-numbers)
(let* ((largest (max list-of-numbers))
(msmallest (min list-of-numbers))
(ssmallest (min (remove (min list-of-numbers) list-of-numbers)))
(range (- msmallest ssmallest)))
(list range largest)))
and I input function and number like the example on debug window :
(my-range '(0 7 8 2 3 -1))
Error: (0 7 8 2 3 -1)' is not of the expected typeREAL'
[condition type: TYPE-ERROR]
The error message was printed in the window...
What is the meaning of 'is not of the expected type 'REAL'?
And how I can fix this problem? And, Could you let me know which problems my code has?
I need your help.
I am wondering if in Racket I could get n number of items from a list I've already created. So lets say I made a list in Racket
(define base(list 1 2 3 4 5 6 7 8 9 10))
Now I want to define a function which will pick n number of items from this list and display them in a new list. So lets say n=4 I would want 4 random items from the base list I've made above. An example of the output im looking for would be
'(9 4 3 10)
Is there a way I can do this in Racket?
There are built-in procedures that literally do what you need: shuffling the list and taking n elements from it. Try this:
(define (take-n-random lst n)
(take (shuffle lst) n))
(define base (list 1 2 3 4 5 6 7 8 9 10))
(take-n-random base 4)
=> '(6 9 1 7)
Does exist a function in LISP for making a sequence of integers like (0 1 2 3)?
I found make-sequence, but I didn't find out how to make a sequence of integers.
I tried make-list and nothing.
I know that in Scheme exists (build-list 5 (lambda (x) x)). I tried to change the build-list with make-list, but it didn't work.
Some ideas? Thanks
Edit: I need something like make-list 5 ==> (0 1 2 3 4)
Simply done with loop:
(loop :for n :below 10 :collect n)
; ==> (0 1 2 3 4 5 6 7 8 9)
The Alexandria library, which is intended to work on any conforming implementation of Common Lisp, defines iota:
(iota 5)
=> (0 1 2 3 4)
You can also customize start and step:
(iota 3 :start 1 :step 1.0)
=> (1.0 2.0 3.0)
But often you do not need to actually produce the list, you just want to iterate over the given range. That's why there is also map-iota:
(map-iota #'print 3 :start 1 :step 1.0)
=> 3
In such cases you can of course use LOOP:
(loop for i from 1.0 below 22 by 1.5 do (print i))
Instead of do, you can also collect and obtain a list; this is a bit more verbose than iota, but easier to customize.
Lets see if can still write mac lisp of the top of my head:
(defun foo (num acc)
(if (eq num 0)
acc
(foo (- num 1) (cons num acc))))
(foo 5 nil)
should be
(1 2 3 4 5)
In lisp, I am appending lists as:
(setq newlist (append (side a b)(this a b) (that a b) ))
This appends all the required list as: (1 0 0 0 2 0 4 0 6 0)
but what I want is something like this: ((1 0)(0 0)(2 0)(4 0)(6 0))
What should I do to get the required format. Please post code examples in lisp.
So in fact you just need to restructure the elements after you have appended it:
(loop :for (e1 e2)
:on '(1 0 0 0 2 0 4 0 6 0)
:by #'cddr
:collect (list e1 e2))
; ==> ((1 0) (0 0) (2 0) (4 0) (6 0))
Suggested reading is LOOP for black belts, the section you should pay attention to which I've used here is "Looping Over Collections and Packages" and "Destructuring Variables". This is probably the chapter from Practical Common Lisp I read the most. The whole book is very good so every lisper should know about it.