Creating a function using DrRacket that takes two lists and outputs it as a fraction - racket

Write a function that takes two lists of numbers, numerators and denominators, and returns a list of fractions produced by dividing numerators by denominators. If one list is shorter than the other, assume that the corresponding numbers are all 1s. Don't worry about zeros in the denominators (it's ok if your function breaks when dividing by zero).
Input: (list 1 2 3) (list 1 3 5)
Output: (list 1/1 2/3 3/5)

You can solve it by recursion:
(define (r-map func l1 l2 (default-l1 1) (default-l2 1) (acc '()))
(cond ((and (null? l1) (null? l2)) (reverse acc))
((null? l1) (r-map func '() (cdr l2) default-l1 default-l2 (cons (func default-l1 (car l2)) acc)))
((null? l2) (r-map func (cdr l1) '() default-l1 default-l2 (cons (func (car l1) default-l2) acc)))
(else (r-map func (cdr l1) (cdr l2) default-l1 default-l2 (cons (func (car l1) (car l2)) acc)))))
The nice thing with this function is that you can change the default value for each list independently from each other.
Test it:
(define a '(1 2 3))
(define b '(4 5 6))
(define c '(10 20))
(define d '(40 50 60 70))
;; run all combinations of the four:
(let ((lists (list a b c d)))
(for*/list [(x lists)
(y lists)]
(list `(r-map ,x ,y ,default-l1 ,default-l2) '=> (r-map / x y))))
It returns:
Welcome to DrRacket, version 6.11 [3m].
Language: racket, with debugging; memory limit: 128 MB.
'(((r-map (1 2 3) (1 2 3) 1 1) => (1 1 1))
((r-map (1 2 3) (4 5 6) 1 1) => (1/4 2/5 1/2))
((r-map (1 2 3) (10 20) 1 1) => (1/10 1/10 3))
((r-map (1 2 3) (40 50 60 70) 1 1) => (1/40 1/25 1/20 1/70))
((r-map (4 5 6) (1 2 3) 1 1) => (4 2 1/2 2))
((r-map (4 5 6) (4 5 6) 1 1) => (1 1 1))
((r-map (4 5 6) (10 20) 1 1) => (2/5 1/4 6))
((r-map (4 5 6) (40 50 60 70) 1 1) => (1/10 1/10 1/10 1/70))
((r-map (10 20) (1 2 3) 1 1) => (10 10 1/3))
((r-map (10 20) (4 5 6) 1 1) => (2 1/2 4 1/6))
((r-map (10 20) (10 20) 1 1) => (1 1))
((r-map (10 20) (40 50 60 70) 1 1) => (1/4 2/5 1/60 1/70))
((r-map (40 50 60 70) (1 2 3) 1 1) => (40 25 20 70))
((r-map (40 50 60 70) (4 5 6) 1 1) => (10 10 10 70))
((r-map (40 50 60 70) (10 20) 1 1) => (4 2 1/2 60 70))
((r-map (40 50 60 70) (40 50 60 70) 1 1) => (1 1 1 1)))

Let's do this a bit more straightforwardly.
There are two simple cases:
Both lists are empty; the result is '()
Neither list is empty; cons the fraction of the cars onto the result of recursing.
Short-circuiting out the tricky cases:
(define (fractions ns ds)
(cond [(and (null? ns) (null? ds)) '()]
[(null? ns) 'only-denominators]
[(null? ds) 'only-numerators]
[else (cons (/ (car ns) (car ds)) (fractions (cdr ns) (cdr ds)))]))
Test:
> (fractions '() '())
'()
> (fractions '(1 2) '(4 5))
'(1/4 2/5)
> (fractions '(1 2 3) '(4 5))
'(1/4 2/5 . only-numerators)
> (fractions '(1 2) '(4 5 6))
'(1/4 2/5 . only-denominators)
If there are only numerators, the results are the same as those numerators, since x/1 is the same as x:
...
[(null? ds) ns]
...
And if there are only denominators, you divide 1 with each element.
This is easy with map:
...
[(null? ns) (map (lambda (d) (/ 1 d)) ds)]
...
In full:
(define (fractions ns ds)
(cond [(and (null? ns) (null? ds)) '()]
[(null? ns) (map (lambda (d) (/ 1 d)) ds)]
[(null? ds) ns]
[else (cons (/ (car ns) (car ds)) (fractions (cdr ns) (cdr ds)))]))
Test:
> (fractions '() '(4 5 6))
'(1/4 1/5 1/6)
> (fractions '(1 2 3) '())
'(1 2 3)
> (fractions '(1 2 3) '(4 5))
'(1/4 2/5 3)
> (fractions '(1 2) '(4 5 6))
'(1/4 2/5 1/6)

Related

Can this type of problem be easily expressed in logic programming paradigm?

For simplicity, this is a toy version of the actual problem: given a set of integers, find the longest sequence of consecutive numbers from that set.
I looked at CLIPS and other expert systems, and they seem ill-suited to express this kind of problem. Specifically, I don't see a list like data structure, which seems to be necessary to implement a solution. I'm looking for an example of implementation using logic programming.
One way:
CLIPS (6.4 2/9/21)
CLIPS>
(deffacts start
(set 1 9 2 10 4 3 11 13 5 14))
CLIPS>
(defrule combine-1
?f <- (set $?b ?n $?e)
=>
(retract ?f)
(assert (combine ?n))
(assert (set ?b ?e)))
CLIPS>
(defrule combine-2
?f1 <- (combine $?b ?j1)
?f2 <- (combine ?j2&=(+ ?j1 1) $?e)
=>
(retract ?f1 ?f2)
(assert (combine ?b ?j1 ?j2 ?e)))
CLIPS>
(defrule longest
(declare (salience -10))
(combine $?c)
(not (combine $?o&:(> (length$ ?o) (length$ ?c))))
=>
(println "Longest is " ?c))
CLIPS> (reset)
CLIPS> (run)
Longest is (1 2 3 4 5)
CLIPS> (facts)
f-21 (set)
f-22 (combine 13 14)
f-26 (combine 1 2 3 4 5)
f-28 (combine 9 10 11)
For a total of 4 facts.
CLIPS>
Another way:
CLIPS> (clear)
CLIPS>
(deffacts start
(set 1 9 2 10 4 3 11 13 5 14))
CLIPS>
(defrule sort
?f <- (set $?s)
(test (neq ?s (sort > ?s)))
=>
(retract ?f)
(assert (set (sort > ?s))))
CLIPS>
(deffunction consecutive ($?s)
(loop-for-count (?i (- (length$ ?s) 1))
(if (<> (+ (nth$ ?i ?s) 1) (nth$ (+ ?i 1) ?s))
then (return FALSE)))
(return TRUE))
CLIPS>
(defrule longest
(set $? $?s&:(consecutive $?s) $?)
(not (set $? $?s2&~$?s&:(consecutive $?s2)&:(> (length$ ?s2) (length$ ?s)) $?))
=>
(println "Longest is " ?s))
CLIPS> (reset)
CLIPS> (run)
Longest is (1 2 3 4 5)
CLIPS> (facts)
f-2 (set 1 2 3 4 5 9 10 11 13 14)
For a total of 1 fact.
CLIPS>

Racket Scalar-Vector Multiplication

I was trying to make a function that does scalar to vector multiplication using map, but doesn't seem to work.
(define (f k m)
(map (lambda (x) (map * k x)) m))
Example usage would be (f 2 '((1 2 3) (4 5 6) (7 8 9))) which would give '((2 4 6) (8 10 12) (14 16 18)).
Thanks.
You are near the solution, which requires two maps, since you have a list of lists:
(define (f k m)
(map (lambda (x)
(map (lambda (y) (* k y))
x))
m))
(f 2 '((1 2 3) (4 5 6) (7 8 9)))
; => '((2 4 6) (8 10 12) (14 16 18))

Maximum and minimum numbers in the list

I am using DrRacket.
How can I write a function for the difference between the maximum and minimum number in the list using accumulators and mutually recursive functions.
For instance, (list 10 2 3 -5 4 1 -6)) 9). The list has at least one element in the list.
Do I need two accumulators?
Version 1: An accumulator based solution that's mutually recursive. Since the input list is assumed to be non-empty, we start of with the first element being max and min. As we go through the list, we pick new max and mins by comparing the current element with the accumulators.
#lang racket
; [NEList-of Number] -> Number
(define (max-min-diff.v1 nelst)
(max-min-diff/t.v1 (rest nelst) (first nelst) (first nelst)))
; [List-of Number] -> Number
(define (max-min-diff/t.v1 l max min)
(cond [(empty? l) (- max min)]
[else (get-new-max-min (rest l) (first l) max min)]))
; [List-of Number] Number Number Number -> Number
(define (get-new-max-min rst fst max min)
(max-min-diff/t.v1 rst
(if (> fst max) fst max)
(if (< fst min) fst min)))
(max-min-diff.v1 '(0 33 2 32 4 8 3 3 5))
; => 33
(max-min-diff.v1'(1 3 9 4 7 2 2 5 11))
; => 10
Version 2: An accumulator based solution that's not mutually recursive. More abstract because we pass the comparators to a generic helper.
; [NEList-of Number] -> Number
(define (max-min-diff.v2 nelst)
(max-min-diff/t.v2 (rest nelst) (first nelst) (first nelst)))
; [List-of Number] -> Number
(define (max-min-diff/t.v2 l max min)
(cond [(empty? l) (- max min)]
[else (max-min-diff/t.v2 (rest l)
(f-if (first l) max >)
(f-if (first l) min <))]))
; X X [X X -> Boolean] -> X
(define (f-if n1 n2 func)
(if (func n1 n2) n1 n2))
(max-min-diff.v2 (list 0 33 2 32 4 8 3 3 5))
; => 33
(max-min-diff.v2 (list 1 3 9 4 7 2 2 5 11))
; => 10
Version 3: Small version. No explicit recursion.
(define (max-min-diff.v3 nelst)
(- (apply max nelst) (apply min nelst)))
(max-min-diff.v3 (list 0 33 2 32 4 8 3 3 5))
; => 33
(max-min-diff.v3 (list 1 3 9 4 7 2 2 5 11))
; => 10

inner and outer reduction, same result?

Does inner and outer reduction always create the same value, if not what would cause different ones?
I am talking about Racket, a functional language.
There are I know possibilities where it is more efficient like in Racket but actually causing a different result. I wasn't able to create a case where that happens, but I feel like it should be possible and may be. dangerous not to know.
Example:
;inner reduction
(sqr (* 3 (+ 1 (sqr 2))))
->(sqr (* 3 (+ 1 (* 2 2))) ;(sqr)
->(sqr (* 3 (+ 1 4)) ;(*)
->(sqr (* 3 5)) ;(+)
->(sqr 15) ;(*)
->(* 15 15) ;(sqr)
->225 ;(*)
;outer reduction
(sqr (* 3 (+ 1 (sqr 2))))
->(* (* 3 (+ 1 (sqr 2))) (* 3 (+ 1 (sqr 2))) ;(sqr)
->(* (* 3 (+ 1 (* 2 2))) (* 3 (+ 1 (sqr 2))) ;(sqr)
->(* (* 3 (+ 1 4)) (* 3 (+ 1 (sqr 2))) ;(*)
->(* (* 3 5) (* 3 (+ 1 (sqr 2))) ;(+)
->(* 15 (* 3 (+ 1 (sqr 2))) ;(*)
->(* 15 (* 3 (+ 1 (* 2 2))) ;(sqr)
->(* 15 (* 3 (+ 1 4))) ;(*)
->(* 15 (* 3 5)) ;(+)
->(* 15 15) ;(*)
->225 ;(*)
I don't know Racket, but in general you can run into trouble if any of your expressions have side effects, such as modifying variables, doing input/output, etc.
Take the following example:
(define x 1)
(sqr (begin (set! x (add1 x)) x))
Inner reduction:
; x = 1
(sqr (begin (set! x (add1 x)) x))
; x = 2
(sqr (begin x))
; x = 2
(sqr (begin 2))
; x = 2
(sqr 2)
; x = 2
(* 2 2)
; x = 2
4
I.e. the result is 4 and the final value of x is 2.
With outer reduction, you get:
; x = 1
(* (begin (set! x (add1 x)) x)
(begin (set! x (add1 x)) x))
; x = 2
(* (begin x)
(begin (set! x (add1 x)) x))
; x = 2
(* 2
(begin (set! x (add1 x)) x))
; x = 3
(* 2
(begin x))
; x = 3
(* 2
(begin x))
; x = 3
(* 2
3)
; x = 3
6
I.e. the result is 6 and the final value of x is 3.
There's another difference. With inner reduction it's possible that you don't get a result at all:
(define (my-if c t e)
(if c t e))
(define (loop)
(loop))
(my-if #t 42 (loop))
With outer reduction:
(my-if #t 42 (loop))
; definition of 'my-if'
(if #t 42 (loop))
; built-in 'if'
42
With inner reduction:
(my-if #t 42 (loop))
; definition of 'loop'
(my-if #t 42 (loop))
; definition of 'loop'
(my-if #t 42 (loop))
; definition of 'loop'
(my-if #t 42 (loop))
; definition of 'loop'
...
This never terminates.

How to print a list as matrix in Common Lisp

I am working in Common Lisp, trying to make Windows game minesweeper.
I have a list (1 1 1 2 2 2 3 3 3) and want to print that like matrix
(1 1 1
2 2 2
3 3 3)
How to do that?
Edit
I am at the beginning of
(format t "Input width:")
(setf width (read))
(format t "Input height:")
(setf height (read))
(format t "How many mines:")
(setf brMina (read))
(defun matrica (i j)
(cond ((= 0 i) '())
(t (append (vrsta j) (matrica (1- i) j) ))))
(setf minefield (matrica width height))
(defun stampaj ()
(format t "~%~a" minefield ))
Another example, using the pretty-printer for fun:
(defun print-list-as-matrix
(list elements-per-row
&optional (cell-width (1+ (truncate (log (apply #'max list) 10)))))
(let ((*print-right-margin* (* elements-per-row (1+ cell-width)))
(*print-miser-width* nil)
(*print-pretty* t)
(format-string (format nil "~~<~~#{~~~ad~~^ ~~}~~#:>~%" cell-width)))
(format t format-string list)))
Works like this:
CL-USER> (print-list-as-matrix (loop for i from 1 to 9 collect i) 3)
1 2 3
4 5 6
7 8 9
NIL
CL-USER> (print-list-as-matrix (loop for i from 1 to 25 collect i) 5)
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25
NIL
CL-USER> (print-list-as-matrix (loop for i from 1 to 16 collect i) 2)
1 2
3 4
5 6
7 8
9 10
11 12
13 14
15 16
Like this:
(defun print-list-as-grid (list rows cols)
(assert (= (length list) (* rows cols))
(loop for row from 0 below rows do
(loop for col from 0 below cols do
(princ (car list))
(princ #\space)
(setf list (cdr list)))
(princ #\newline)))
* (print-list-as-grid '(a b c d e f g h i) 3 3)
A B C
D E F
G H I
NIL