I have the function below which converts an input of numbers into the partially translated word output of those numbers.
Using product and quotient, it adds the word representation of numbers while splitting the number into groups.
For example:
(number-name 87969087) -> '(87 million 969 thousand 87)
(number-name 1000000) -> '(1 million)
Im trying to complete my problem by fully translating those numbers which are less than 1000 as well. Im trying to implement a function less-than-1000 which will display those smaller numbers as the list is being constructed as well. Alongside:
;; for less than 1000
; state words for 1-19
(define baseNumbers '(one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen))
and
; state words for multiples of ten
(define multiples '(twenty thirty forty fifty sixty seventy eighty ninety))
so
(number-name 1110) -> '(one thousand one hundred ten)
Its also been difficult coming up with a way to display an input of 0 to display as zero by do so in a way in which zero does not show up if the input is anything other than 0.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
(define (number n)
(define units '(thousand million billion trillion quadrillion))
(define (nsplit n units acc lst)
(define q (quotient n 1000))
(define r (remainder n 1000))
(if (zero? n) lst
(cond [(zero? acc)
(if (zero? r)
(nsplit q units (add1 acc) lst)
(nsplit q units (add1 acc) (cons r lst)))]
[(zero? r)
(nsplit q (cdr units) acc lst)]
[else
(nsplit q (cdr units) acc (cons r (cons (car units) lst)))])))
(nsplit n units 0 empty))
You can translate an integer into a list of symbols by breaking apart the number into 3-digit groups, attaching units to each group, and then further translating the 3-digit groups to list of symbols. Here is a sample implementation:
(define (num->lst num)
(define bases '(one two three four five six seven eight nine ten eleven twelve
thirteen fourteen fifteen sixteen seventeen eighteen nineteen))
(define multiples '(twenty thirty forty fifty sixty seventy eighty ninety))
(define units '(empty thousand million billion trillion quadrillion quintillion
sextillion septillion octillion nonillion decillion))
(define (below-1000 num bases mults)
(cond [(zero? num) empty]
[(< num 20) (list (list-ref bases (sub1 num)))]
[(< num 100) (list* (list-ref mults (- (quotient num 10) 2))
(below-1000 (remainder num 10) bases mults))]
[else (list* (list-ref bases (sub1 (quotient num 100))) 'hundred
(below-1000 (remainder num 100) bases mults))]))
(define (nsplit num lst units)
(define q (quotient num 1000))
(define r (remainder num 1000))
(if (zero? num) lst
(cond [(zero? r) (nsplit q lst (cdr units))]
[else (nsplit q (append (below-1000 r bases multiples)
(cons (car units) lst)) (cdr units))])))
(if (zero? num) '(zero)
(remove 'empty (nsplit num empty units))))
below-1000 converts numbers below 1000 into list of symbols.
nsplit breaks the number into 3-digit groups and attaches units to each group, while converting the 3-digits using below-1000.
For example,
> (num->lst 0)
'(zero)
> (num->lst 1000000001)
'(one billion one)
> (num->lst 35579005)
'(thirty five million five hundred seventy nine thousand five)
Related
Working on this program that's supposed to take a vector of integers as input and return the one with the longest integer. Example (vector 20 738 5942 125) and would return 4 as its the longest one. I'm pretty sure I have most of this done the only issue I have is in the conditional as I have to call an outside function (count-integers), this is what I have so far:
(require while)
(define (empty-VINT? low high) (> low high))
(define (count-integers n)
(cond [(< n 10) 1]
(else(+ 1 (count-integers [/ n 10])))))
(define (count-digits V)
(local [
(define x (void))
(define accum (void))
(define largest 0)]
(begin
(set! x (vector-length V))
(set! accum 0)
(while (< accum (vector-length V))
(cond [(empty-VINT? x accum) accum]
[(> (count-integers (vector-ref V accum) largest)
(add1 x) accum(vector-ref V accum))]
[else add1 accum])))))
Right now when its run, I get this message: cond: expected a clause with a question and an answer, but found a clause with only one part. Any suggestions would be great, thanks
First of all, it's not clear what do you want to return. 4 isn't the longest integer (that's 5942), 4 is a maximal digit count among integers in given vector.
Secondly, your code isn't idiomatic and without your comment, it's very hard to say what's going on. Programming in functional languages requies functional way of thinking. Forget about while, set!, void, local and nested define and instead spend some time learning about apply, map, filter and foldl.
I would solve this problem like this:
(define (digits number)
(string-length (number->string number)))
(define (max-digit-count vec)
(apply max (map digits (vector->list vec))))
(max-digit-count (vector 20 738 5942 125))
=> 4
From comments:
Design and implement a function to find the number of digits in the longest integer in a (vectorof integer) ...
use ... while loops
So a plan (design) might be:
count-digits: integer -> natural
max-digit-count: (vectorof integer) -> natural
..something while something max count-digits something ???
Implementing count-digits seems straightforward (but
integers can be negative, and in Racket (integer? 123.000) is true).
#lang racket
(define (count-digits int) ;; Integer -> Natural
;; produce count of digits in int
(string-length (number->string (abs (exact-truncate int)))))
As #Gwang-Jin Kim mentions, while could be defined:
(define-syntax-rule (while condition body ...)
;; From: https://stackoverflow.com/questions/10968212/while-loop-macro-in-drracket
(let loop ()
(when condition
body ...
(loop))))
and then one could use it:
(define (max-digit-count vec) ;; VectorOfInteger -> Natural
;; produce maximum of digit counts of vec elements
(define vx 0)
(define acc 0)
(while (< vx (vector-length vec))
(set! acc (max accum (count-digits (vector-ref vec vx))))
(set! vx (add1 vx)))
acc)
(max-digit-count (vector 20 -738.00 5942 125)) ;=> 4
One of the problems with while is that it can't produce a value (where would it come
from if the condition is false on entry?)
If one "enhanced" while a bit:
(define-syntax-rule (while< x-id limit a-id a-init update)
;; "while loop" incrementing x-id from 0 to limit-1, updating a-id
(let loop ([x-id 0] [a-id a-init])
(if (< x-id limit)
(loop (add1 x-id) update)
a-id)))
max-digit-count could be neater:
(define (max-digit-count vec) ;; VectorOfInteger -> Natural
;; produce maximum of digit counts of vec elements
(while< vx (vector-length vec)
acc 0 (max acc (count-digits (vector-ref vec vx)))))
#MartinPuda's answer is quite good.
I would have defined:
(define (digits n (acc 0))
(if (< n 1)
acc
(digits (/ n 10) (+ acc 1))))
(define (max-digits lst)
(digits (car (sort lst >))))
To apply it:
(max-digits (vector->list (vector 20 738 5942 125)))
Why you should not use while
Using while would force you to mutate variable values. It is much more "natural" for lisp languages to follow the functional style (recursive functions instead of while loops or other loops) rather than the imperative style with mutation of variables.
That is why while is not in the lisp languages.
But if you want to use it:
(define-syntax-rule (while condition body ...)
;; From: https://stackoverflow.com/questions/10968212/while-loop-macro-in-drracket
(let loop ()
(when condition
body ...
(loop))))
(define (digits n (acc 0))
(cond ((< n 1) acc)
(else (digits (/ n 10) (+ acc 1)))))
(define (max-digits lst)
(let ((max-digit 0))
(while (not (null? lst))
(let ((digit (digits (car lst))))
(when (< max-digit digit)
(set! max-digit digit))
(set! lst (cdr lst))))
max-digit))
Then you can try:
> (max-digits (vector->list v))
4
> (max-digits '(1111 123456 2345 34))
6
Prefer let over define
Why? Because if you use let, you can control the scope of the to-be-mutated variable very precisely. You can define in your definition, from where on your variable canNOT have any effect on your code (since its scope ended at some point). While with define you don't have this fine-grained control. (Or this control is implicit not explicite like with let). You could delete/unbind the variable explicitely but that is rarely done in real life.
Therefore, in Lisp, for variable declarations use whenever possible let, especially whenever you deal with mutated variables.
All imperative = declarations should be in Lisp languages let expressions!
You can use function arguments instead of let-definitions, because they are anyway implemented using lets
Just you save syntactically some lines - and the fewer lines you occupy the cleaner the code.
#lang racket
(define (digits n)
(string-length (number->string n)))
(define (max-digit a b)
(if (< (digits a) (digits b)) b a))
(define (max-digits lst (res ""))
(while (not (null? lst))
(set! res (max-digit res (car lst)))
(set! lst (cdr lst)))
(digits res))
So im extremely new to Scheme, and i've been trying to do a multiplying table, if you put
(multiplying-table 10 3) should give a list (3 6 9 12 15 18 21 24 27 30)
Here is my code
(define (multiplying-table n value)
(cond ((= n 0) '())
(else (* n value)(Multiplying-table(- n 1)))))
You need to use cons to combine the first number 3 with the list of the rest.
Eg. (3 6 ...) is (cons 3 (cons 6 ...)). You are instead having two expressions where the (* n value) is only for effect since the result is never used. Because of that every call should return the empty list.
Usually there are 2 ways to do it. With recursion inside cons or with an accumulator. Since lists are created from end to beginning you could count n downwards and build the list from end to beginning. The base case would just return the accumulator which by default is the empty list. Here is an example:
(define (sequence from to)
(let loop ((n to) (acc '()))
(if (< n from)
acc
(loop (- n 1) (cons n acc)))))
(sequence 5 10) ; ==> (5 6 7 8 9 10)
I need a subroutine for my program written in scheme that takes an integer, say 34109, and puts it into a list with elements 3, 4, 1, 0, 9. The integer can be any length. Does anyone have a trick for this? I've thought about using modulo for every place, but I don't think it should be that complicated.
The simplest way I can think of, is by using arithmetic operations and a named let for implementing a tail-recursion:
(define (number->list num)
(let loop ((num num)
(acc '()))
(if (< num 10)
(cons num acc)
(loop (quotient num 10)
(cons (remainder num 10) acc)))))
Alternatively, you can solve this problem using string operations:
(define char-zero (char->integer #\0))
(define (char->digit c)
(- (char->integer c) char-zero))
(define (number->list num)
(map char->digit
(string->list (number->string num))))
This can be compressed into a single function, but I believe it's easier to understand if we split the problem in subparts as above.
(define (number->list num)
(map (lambda (c) (- (char->integer c) (char->integer #\0)))
(string->list
(number->string num))))
Anyway, the results are as expected:
(number->list 34109)
> '(3 4 1 0 9)
Something like this:
(define (num2list-helper num lst)
(cond ((< num 10) (cons num lst))
(else (num2list-helper (floor (/ num 10)) (cons (modulo num 10) lst)))))
(define (num2list num)
(num2list-helper num '()))
(num2list 1432)
As itsbruce commented you can hide helper function inside main one:
(define (num2list num)
(define (num2list-helper num lst)
(cond ((< num 10) (cons num lst))
(else (num2list-helper (floor (/ num 10)) (cons (modulo num 10) lst)))))
(num2list-helper num '()))
(num2list 1432)
to be continued...
I'm not a fan of manual looping, so here's a solution based on unfold (load SRFI 1 and SRFI 26 first):
(define (digits n)
(unfold-right zero? (cut modulo <> 10) (cut quotient <> 10) n))
This returns an empty list for 0, though. If you want it to return (0) instead, we add a special case:
(define (digits n)
(case n
((0) '(0))
(else (unfold-right zero? (cut modulo <> 10) (cut quotient <> 10) n))))
Of course, you can generalise this for other bases. Here, I implement this using optional arguments, so if you don't specify the base, it defaults to 10:
(define (digits n (base 10))
(case n
((0) '(0))
(else (unfold-right zero? (cut modulo <> base) (cut quotient <> base) n))))
Different Scheme implementations use different syntaxes for optional arguments; the above uses Racket-style (and/or SRFI 89-style) syntax.
If we had a list A holding (1 2 1 1 2 3 3 4 4 4), how could we get a new list B with ((1 . 30) (2 . 20) (3 . 20) (4 . 30)) in it, such that the number_after_dot is the percentage of the number_before_dot in the list A.
For example 1 is 30% of list A, 2 is 20% of list A, etc..
(1 . 30) is a pair, which could be made by (cons 1 30)
I think what you want to do is calculate the percentage of the list that is equal to each element. You used the word "unique" but that a bit confusing since your list has no unique elements. This is based on your sample input and output, where the list (1 2 1 1 2 3 3 4 4 4) is composed of "30% ones".
You can break this down roughly into a recursive algorithm consisting of these steps:
If the input list is empty, return the empty list.
Otherwise, get the first element. Calculate how many times it occurs in the list.
Calculate the percentage, and cons the element with this percentage.
Remove all the occurrences of the first item from the cdr of the list.
Recurse on this new list, and cons up a list of (element . percentage) pairs.
To do the first part, let's use filter:
> (filter (lambda (x) (eq? (car A) x)) A)
(1 1 1)
With your list A, this will return the list (1 1 1). We can then use length to get the number of times it occurs:
> (length (filter (lambda (x) (eq? (car A) x)) A))
3
To calculate the percentage, divide by the number of elements in the whole list, or (length A) and multiply by 100:
> (* 100 (/ (length (filter (lambda (x) (eq? (car A) x)) A)) (length A)))
30
It's easy to cons this with the element (car A) to get the pair for the final list.
To do the second step, we can use remove which is the inverse of filter: it will return a list of all elements of the original list which do not satisfy the predicate function:
> (remove (lambda (x) (eq? (car A) x)) A)
(2 2 3 3 4 4 4)
This is the list we want to recurse on. Note that at each step, you need to have the original list (or the length of the original list) and this new list. So you would need to somehow make this available to the recursive procedure, either by having an extra argument, or defining an internal definition.
There might be more efficient ways I'm sure, or just other ways, but this was the solution I came up with when I read the question. Hope it helps!
(define (percentages all)
(let ((len (length all))) ; pre-calculate the length
;; this is an internal definition which is called at ***
(define (p rest)
(if (null? rest)
rest
;; equal-to is a list of all the elements equal to the first
;; ie something like (1 1 1)
(let ((equal-to (filter (lambda (x) (eq? (car rest) x))
rest))
;; not-equal-to is the rest of the list
;; ie something like (2 2 3 3 4 4 4)
(not-equal-to (remove (lambda (x) (eq? (car rest) x))
rest)))
(cons (cons (car rest) (* 100 (/ (length equal-to) len)))
;; recurse on the rest of the list
(p not-equal-to)))))
(p all))) ; ***
The question formulation is very close to the idea of run-length encoding. In terms of run-length encoding, you can use a simple strategy:
Sort.
Run-length encode.
Scale the run lengths to get percentages.
You can implement run-length encoding like this:
(define (run-length-encode lst)
(define (rle val-lst cur-val cur-cnt acc)
(if (pair? val-lst)
(let ((new-val (car val-lst)))
(if (eq? new-val cur-val)
(rle (cdr val-lst) cur-val (+ cur-cnt 1) acc)
(rle (cdr val-lst) new-val 1 (cons (cons cur-val cur-cnt) acc))))
(cons (cons cur-val cur-cnt) acc)))
(if (pair? lst)
(reverse (rle (cdr lst) (car lst) 1 '()))
'()))
and scaling looks like:
(define (scale-cdr count-list total-count)
(define (normalize pr)
(cons (car pr) (/ (* 100 (cdr pr)) total-count)))
(map normalize count-list))
Now we need something to sort a list. I'll just use the sort function in racket (adapt as needed). The function to calculate the percentages for each number in the list is then:
(define (elem-percent lst)
(scale-cdr (run-length-encode (sort lst <)) (length lst)))
Some examples of use:
> (elem-percent '())
'()
> (elem-percent (list 1 2 3 4 5))
'((1 . 20) (2 . 20) (3 . 20) (4 . 20) (5 . 20))
> (elem-percent (list 1 2 1 1))
'((1 . 75) (2 . 25))
> (elem-percent (list 1 2 1 1 2 3 3 4 4 4))
'((1 . 30) (2 . 20) (3 . 20) (4 . 30))
I've been trying to learn some programming on my own by working through the textbook How to Design Programs for Scheme. I've gotten through everything until now. Here's the problem:
9.5.5 Develop the function convert. It consumes a list of digits and
produces the corresponding number. The
first digit is the least significant,
and so on.
Following the first few steps, from data analysis to template, I end
up with this, the bare bones of a program:
;; A list-of-numbers is either 1. an empty list, empty, or 2. (cons n
lon) where n is a number and lon is a list of numbers
;; convert : lon -> number
;; to consume a lon and produce the corresponding number. The least
significant digit corresponds to the first number in the list, and so
on.
;; (= (convert (cons 1 (cons 9 (cons 10 (cons 99 empty))))) 991091)
(define (convert lon)
(cond
[(empty? lon)...]
[(cons? lon)...(first lon)...(convert (rest lon))...]))
How do I get past this stage to, as the book has it, "combining values"?
The one way I think could work is if I multiplied the first value by
10 to the power of the value's significance in the total number, e.g.,
(cons 1 (cons 9 empty)) => 1 * 10^(SIGNIFICANCE), where LEAST
SIGNIFICANCE would be 0. Using my limited understanding of
programming, I figure that requires some counter, where n increases by
one every time the function, in a manner of speaking, is called
recursively. But that looks to me to be an attempt to run two
recursions at the same time. Because expressions are evaluated
sequentially (obviously), you can't call the counter function as you
call the convert function.
So, can anyone help me solve this problem? I would prefer if you
solved this using natural recursion and the CONStructor for lists and
not lambda or other ideas the book hasn't addressed yet.
Thanks!
You don't need to do exponentiation - simple multiplication will do just fine.
(define (convert digits)
(cond
((empty? digits) 0)
(else (+ (* 10 (convert (rest digits))) (first digits)))
)
)
(convert '(1 2 3 4 5 6))
Or, another way of thinking about it:
(define (convert digits)
(convert-helper digits 1 0)
)
(define (convert-helper digits multiplier sofar)
(cond
((empty? digits) sofar)
(else
(convert-helper
(rest digits)
(* 10 multiplier)
(+ (* multiplier (first digits)) sofar)
)
)
)
)
(convert '(1 2 3 4 5 6))
Here's a tail recursive version:
(define (convert lon)
(let rec ((i 0)
(n 0)
(lon lon))
(cond ((empty? lon) n)
(else (rec (+ i 1)
(+ n (* (first lon) (expt 10 i)))
(rest lon))))))