Racket dice function - racket

I code a function to roll dnd's dice :
(define (rnd [n 0] [d 0] [li '()] [count 0])
(cond [(= n 0) '()]
[(= count n) (values li (foldl + 0 li))]
[(< count n) (rnd n d (cons (random 1 (+ d 1)) li) (+ count 1))]))
But I always feel this code was ugly.
Have idea to improve this?

Here is a simplified version:
(define (rnd [n 0] [d 1] [li '()])
(if (<= n 0)
(values li (foldl + 0 li))
(rnd (- n 1) d (cons (random 1 (+ d 1)) li))))
Note that the default value of d is 1 instead of zero, otherwise the function does not work with just one argument.

Related

Racket Programming ;Write a recursive function to compute the summation sum( x^2, x=1..n

;Write a recursive function to compute the summation sum( x^2, x=1..n)
;You must write a recursive function.
;If you use any iterative commands (for/loop/sum/etc you will receive a 0)
I'm stuck on this
(define (expo base x)
(cond ((or (= base 1) (= x 0)) 1)
(else (* base (expo base (- x 1)))))
I wrote this but its not right
Your code is working but is only missing a bracket at the end. You will see an error expected a ) to close ( possible cause: indentation suggests a missing ) when you are missing a bracket.
If n equal 5. You want see this: 1^2 + 2^2 + 3^2 + 4^2 + 5^2 = 55
#lang racket
(define (summation from-n to-n fn)
(local [(define (aux n)
(if (< n from-n)
0
(+ (fn n) (aux (- n 1)))))]
(aux to-n)))
(define (1^2+2^2+3^2+...+n^2 n)
(summation 1 n sqr))
(define (1+2+3+...+n n)
(summation 1 n identity))
;;; TEST
(1+2+3+...+n 100) ; 5050
(1^2+2^2+3^2+...+n^2 5) ; 55

Make a program that determines the average of its digits from a number

I must make a program that averages the digits of a number, but it is impossible for me, especially the module of a division (remainder).
What I can do?
(define (digitos number)
(cond
[(and (>= number 1) (< number 11)) 1]
[else (+ 1 (digitos (/ number 10)))]))
(define (modulo_ n m)
(cond
[(real? n) (- n (* (floor (/ n m)) m))]
[else (remainder n m)]))
(define (sumatoria number)
(cond
[(equal? number 0) 0]
[else (+ (modulo_ number 10) (sumatoria (/ number 10)))]))
(define (promedio number)
(/ (sumatoria number) (digitos number)))
;(promedio 40) ;3
update:
your question is repeated
How to count number of digits?
Count digits in list Racket
Return the sum of odd digits of a number
Convert number to list of digits
; only consider nature number 0,1,2,3,...
; if you want input Decimal use number->string
(define (cut-right-digit n)
(/ (- n (remainder n 10)) 10))
(define (sum-each-digit n result)
(cond
[(<= 0 n 9)
(+ result n)]
[else
(sum-each-digit (cut-right-digit n) (+ result (remainder n 10)))]))
(define (digits n result)
(cond
[(<= 0 n 9)
result]
[else
(digits (cut-right-digit n) (+ 1 result))]))
(define (avg-digits n)
(/ (sum-each-digit n 0) (digits n 1)))
;;; TEST
(avg-digits 0) ; 0
(avg-digits 1) ; 1
(avg-digits 11111) ; 1
(avg-digits 10203040506789) ; (/ 55 14)
(avg-digits 101001) ; 1/2

How to make fibonacci sequence in racket using abstract list functions

I am trying to write a racket program that computes the sum of the first n terms in a fibonacci sequence without using recursion, and only using abstract list functions (so map, builld-list, foldr, foldl). I can use helper functions.
I'm stuck on how to make a list of the fibonacci numbers without using recursion. I thought I could use a lambda function:
(lambda (lst) (+ (list-ref lst (- (length lst) 1)) (list-ref lst (- (length lst 2)))))
But I am not sure how to generate the input list/how to add this to a function.
Once I have a fibonacci sequence I know I can just use (foldl + (car lst) (cdr lst)) to find the sum.
Could anyone explain to me how to make the fibonacci sequence/give me a hint?
; This is how I figure out
#|
(1 2 3 4 (0 1))
-> (1 2 3 (1 1))
-> (1 2 (1 2))
-> (1 (2 3))
-> (3 5)
|#
(define (fib n)
(cond
[(= n 0) 0]
[(= n 1) 1]
[(> n 1)
(second
(foldr (λ (no-use ls) (list (second ls) (+ (first ls) (second ls))))
'(0 1)
(build-list (- n 1) (λ (x) x))))]))
(fib 10)
(build-list 10 fib)
Upgrade version 2
(define (fib-v2 n)
(first
(foldr (λ (no-use ls) (list (second ls) (+ (first ls) (second ls))))
'(0 1)
(build-list n (λ (x) x)))))
(build-list 10 fib-v2)
fib-seq produces a list of first n fibonacci numbers and fib-sum produces the sum of first n fibonacci numbers.
; Number -> [List-of Number]
(define (fib-seq n)
(cond [(= n 0) '()]
[(= n 1) '(0)]
[else (reverse
(for/fold ([lon '(1 0)]) ([_ (in-range (- n 2))])
(cons (apply + (take lon 2)) lon)))]))
; Number -> Number
(define (fib-sum n)
(if (= n 0) 0 (add1 (apply + (take (fib-seq n) (sub1 n))))))
Note: fib-sum is equivalent to the following recursive versions:
(define (fib0 n)
(if (< n 2) n (+ (fib0 (- n 1)) (fib0 (- n 2)))))
(define (fib1 n)
(let loop ((cnt 0) (a 0) (b 1))
(if (= n cnt) a (loop (+ cnt 1) b (+ a b)))))
(define (fib2 n (a 0) (b 1))
(if (= n 0) 0 (if (< n 2) 1 (+ a (fib2 (- n 1) b (+ a b))))))
Once I have a fibonacci sequence I know I can just use (foldl + (car lst) (cdr lst)) to find the sum.
Note that you don't have to generate an intermediate sequence to find the sum. Consider the (fast) matrix exponentiation solution:
(require math/matrix)
(define (fib3 n)
(matrix-ref (matrix-expt (matrix ([1 1] [1 0])) n) 1 0))
Testing:
(require rackunit)
(check-true
(let* ([l (build-list 20 identity)]
[fl (list fib0 fib1 fib2 fib3 fib-sum)]
[ll (make-list (length fl) l)])
(andmap (λ (x) (equal? (map fib0 l) x))
(map (λ (x y) (map x y)) fl ll))))

Return the sum of odd digits of a number

For class, I have to write a function that takes positive integer n and returns the sum of n’s odd digits in scheme. So far, I have my base case such that if n equals 0 then 0. But I am not sure on how to continue.
(define sumOddDigits
(lambda (n)
(if (= n 0)
0
Test cases:
(sumOddDigits 0) → 0
(sumOddDigits 4) → 0
(sumOddDigits 3) → 3
(sumOddDigits 1984) → 10
You could do it efficiently using one functional loop:
(define (sumOddDigits n)
(let loop ([n n])
(cond [(zero? n) 0]
[else
(let-values ([(q r) (quotient/remainder n 10)])
(+ (if (odd? r) r 0)
(loop q)))])))
One can get list of digits using following function which uses 'named let':
(define (getDigits n)
(let loop ((ol '()) ; start with an empty outlist
(n n))
(let-values (((q r) (quotient/remainder n 10)))
(if (= q 0) (cons r ol)
(loop (cons r ol) q)))))
Then one can apply a filter using odd? function to get all odd elements of list- and then apply 'apply' function with '+' to add all those elements:
(apply + (filter
(lambda(x)
(odd? x))
digitList))
Together following can be the full function:
(define (addOddDigits N)
(define (getDigits n)
(let loop ((ol '())
(n n))
(let-values (((q r) (quotient/remainder n 10)))
(if (= q 0) (cons r ol)
(loop (cons r ol) q)))))
(define digitList (getDigits N))
(println digitList)
(apply + (filter
(lambda(x)
(odd? x))
digitList)))
Testing:
(addOddDigits 156)
Output:
'(1 5 6)
6
Your basecase is if n < 10. Because you are then on the last digit.
You then need to check if it's odd, and if so return it. Else, return the addition qualifier(0).
If n > 10, you remainder off the first digit, then test it for odd.
If odd, then add it to a recursive call, sending in the quotient of 10(shaves off the digit you just added).
Else, you recursively call add-odds with the quotient of 10, without adding the current digit.
Here it is in a recursive form(Scheme LOVES recursion) :
(define add-odds
(lambda (n)
(if(< n 10)
(if(= (remainder n 2) 1)
n
0)
(if(= (remainder (remainder n 10) 2) 1)
(+ (remainder n 10) (add-odds (quotient n 10)))
(add-odds(quotient n 10))))))
First get a (reversed) list of digits with simple recursive implementation:
(define (list-digits n)
(if (zero? n) '()
(let-values ([(q r) (quotient/remainder n 10)])
(cons r (list-digits q)))))
then filter the odd ones and sum them:
(define (sum-of-odd-digits n)
(apply + (filter odd? (list-digits n))))
Note: (list-digits 0) returns '() but it is ok for later usage.
More accurate list-digits iterative implementation (produce list of digits in right order):
(define (list-digits n)
(define (iter n acc)
(if (zero? n) acc
(let-values ([(q r) (quotient/remainder n 10)])
(iter q (cons r acc)))))
(iter n '()))

Issue in implementing 64-bit binary number multiplication in LISP

I am trying to write a code in LISP to multiply two 64-bit numbers.
Using SBCL on ubuntu platform to compile program.
My algorithm is as follows.
1) Convert first number into 64-bit binary representation.
2) Perform binary addition of first number with itself second number of times.
I wrote following function to convert decimal number into binary (takes decimal number & empty list as parameter)
(defun bin (N B)
(cond
((= N 0) B)
((evenp N)(bin (round (/ N 2)) (cons 0 B)))
((oddp N) (bin (floor (/ N 2)) (cons 1 B)))
))
Following function to to perform binary addition.( takes nos of bits, initial carry, first binary no, second binary no, empty list)
(defun addbin (n carry L1 L2 L3)
(cond
((< n 0) (cons carry L3))
((and (= (lastE L1 n) 0) (= (lastE L2 n) 0) (= carry 0)) (addbin (- n 1) 0 L1 L2 (cons 0 L3)))
((and (= (lastE L1 n) 0) (= (lastE L2 n) 0) (= carry 1)) (addbin (- n 1) 0 L1 L2 (cons 1 L3)))
((and (= (lastE L1 n) 0) (= (lastE L2 n) 1) (= carry 0)) (addbin (- n 1) 0 L1 L2 (cons 1 L3)))
((and (= (lastE L1 n) 0) (= (lastE L2 n) 1) (= carry 1)) (addbin (- n 1) 1 L1 L2 (cons 0 L3)))
((and (= (lastE L1 n) 1) (= (lastE L2 n) 0) (= carry 0)) (addbin (- n 1) 0 L1 L2 (cons 1 L3)))
((and (= (lastE L1 n) 1) (= (lastE L2 n) 0) (= carry 1)) (addbin (- n 1) 1 L1 L2 (cons 0 L3)))
((and (= (lastE L1 n) 1) (= (lastE L2 n) 1) (= carry 0)) (addbin (- n 1) 1 L1 L2 (cons 0 L3)))
((and (= (lastE L1 n) 1) (= (lastE L2 n) 1) (= carry 1)) (addbin (- n 1) 1 L1 L2 (cons 1 L3)))
))
supplementary function to return nth bit in binary number is (takes list & n)
(defun lastE (L n)
(cond
((= n 0) (first L))
(t (lastE (rest L) (- n 1)))
))
and multiplication function as
(defun bin_mult(nA A B)
(cond
((= B 1) A)
(t (bin_mult (addbin (- (length A) 1) 0 A nA ()) A (- B 1)))
))
and I am executing following piece of code to perform multiplication
(print "Enter two numbers to be multiplied")
(finish-output nil)
(defvar num1)
(defvar num2)
(defvar a)
(setq num1 (read))
(setq num2 (read))
(setq a (bin num1 ()))
(defvar cnt)
(setq cnt (integer-length num1))
(print cnt)
(dotimes (i (- 63 cnt))
(push 0 a)
)
(print "First number in binary format is" )
(print a)
(print "Multiplication two numbers with concurrency is")
(print (bin_mult a a num2))
I am getting following output (for 10*4)
(1 0 1 0)
I tried tracing the execution of bin_mult function on command prompt.
I am getting following output for (trace bin_mult x x 4) where x is (1 0 1 0)
(bin_mult x x 4)
0: (BIN_MULT (1 0 1 0) (1 0 1 0) 4)
1: (BIN_MULT (1 0 1 0 0) (1 0 1 0) 3)
2: (BIN_MULT (1 0 1 0 0) (1 0 1 0) 2)
3: (BIN_MULT (1 0 1 0 0) (1 0 1 0) 1)
3: BIN_MULT returned (1 0 1 0)
2: BIN_MULT returned (1 0 1 0)
1: BIN_MULT returned (1 0 1 0)
0: BIN_MULT returned (1 0 1 0)
(1 0 1 0)
Somehow intermediate results are not getting added.
Kindly help in resolving bug in this piece of code..
Thank you..
I'm not sure what you are trying to do, but you can just do the multiplication and simulate overflow later.
(defun multiply-overflow (bits &rest xs)
(let ((result (reduce #'* xs :initial-value 1)))
(multiple-value-bind (_ remainder) (floor result (1- (ash 1 bits)))
remainder)))
(multiply-overflow 64 1000000000000 1000000000000)
; ==> 2003764205206950850