Easy function to commatize a number in string in Racket - scheme

To add commas to a number in string, can there be a simple function for common situation use? I found one method but it seems very complex though comprehensive: https://rosettacode.org/wiki/Commatizing_numbers#Racket
I simply want to have a function which works as follows:
(addcommas 1234567890)
"1,234,567,890"
(It is slightly surprising that Racket, which has many high level functions, does not have a built-in function for this common requirement).

You can try with this:
(define (addcommas n)
(define (split n acc)
(if (< (abs n) 1000)
(cons n acc)
(let-values ([(quot rem) (quotient/remainder n 1000)])
(split quot (cons (abs rem) acc)))))
(apply ~a (split n '()) #:separator ","))
(addcommas -2332342390)
;; -> "-2,332,342,390"
If you want to format real numbers, since they have a binary representation, and the conversion can be imprecise, you have to add a precision parameter which specifies the number of digits after the point:
(define (addcommas-real n precision)
(let* ((int-part (exact-truncate n))
(float-part (exact-truncate (* (- n int-part) (expt 10 precision)))))
(~a (addcommas int-part) "." (abs float-part))))
(addcommas-real -2332342390.34 2)
;; -> "-2,332,342,390.34"
(addcommas-real -2332342390.34 5)
;; -> "-2,332,342,390.34000"

Related

Geometric Series function in Scheme language

Im trying to learn scheme and Im having trouble with the arithmetic in the Scheme syntax.
Would anyone be able to write out a function in Scheme that represents the Geometric Series?
You have expt, which is Scheme power procedure. (expt 2 8) ; ==> 256 and you have * that does multiplication. eg. (* 2 3) ; ==> 6. From that you should be able to make a procedure that takes a n and produce the nth number in a specific geometric series.
You can also produce a list with the n first if you instead of using expt just muliply in a named let, basically doing the expt one step at a time and accumulate the values in a list. Here is an example of a procedure that makes a list of numbers:
(define (range from to)
(let loop ((n to) (acc '())
(if (< n from)
acc
(loop (- 1 n) (cons n acc)))))
(range 3 10) ; ==> (3 4 5 6 7 8 9 10)
Notice I'm doing them in reverse. If I cannot do it in reverse I would in the base case do (reverse acc) to get the right order as lists are always made from end to beginning. Good luck with your series.
range behaves exactly like Python's range.
(define (range from (below '()) (step 1) (acc '()))
(cond ((null? below) (range 0 from step))
((> (+ from step) below) (reverse acc))
(else (range (+ from step) below step (cons from acc)))))
Python's range can take only one argument (the upper limit).
If you take from and below as required arguments, the definition is shorter:
(define (range from below (step 1) (acc '()))
(cond ((> (+ from step) below) (reverse acc))
(else (range (+ from step) below step (cons from acc)))))
Here is an answer, in Racket, that you probably cannot submit as homework.
(define/contract (geometric-series x n)
;; Return a list of x^k for k from 0 to n (inclusive).
;; This will be questionable if x is not exact.
(-> number? natural-number/c (listof number?))
(let gsl ((m n)
(c (expt x n))
(a '()))
(if (zero? m)
(cons 1 a)
(gsl (- m 1)
(/ c x)
(cons c a)))))

Sort faster in racket using hash table

So I have an example list of elements like this
(define A (list 'a 'c 'd 'e 'f 'e 'a))
Now I want to make a ranking from this sample
(define (scan lst)
(foldl (lambda (element a-hash) (hash-update a-hash element add1 0))
(hash)
lst))
The result should be like this:
> #(('a . 2) ('f . 1) ('e . 2) ....)
Because `scan function will make a hash table containing unique keys and the number of repetitions of that key (if it catches an unindexed key it will create a new place for that new key, counting from 0).
Then I'd like to sort that hash-table because it's unsorted:
(define (rank A)
(define ranking (scan A))
(sort ranking > #:key cdr)))
So the result would look like this:
#(('a . 2) ('e . 2) ('f . 1) ...)
Now I'd like to truncate the hash-table and throw away the bottom at the threshold of n = 1 (aka only take the elements with more than 2 repetitions).
(define (truncate lst n)
(define l (length lst))
(define how-many-to-take
(for/list
([i l]
#:when (> (cdr (list-ref lst i))
n))
i))
(take lst (length how-many-to-take)))
So the result might look like this:
(('a . 2) ('e . 2))
However, at the big scale, this procedure is not very efficient, it takes too long. Would you have any suggestion to improve the performance?
Thank you very much,
Part 2:
I have this data structure:
(automaton x
(vector (state y (vector a b c))
(state y (vector a b c)) ...))
Then i generate randomly a population of 1000 of them. Then i scan and rank them using the above functions. If i just scan them as is, it already takes long time. If i try to flatten them into a list like this
(list x y a b c y a b c...)
it'd take even more time. Here is the flatten function:
(define (flatten-au au)
(match-define (automaton x states) au)
(define l (vector-length states))
(define body
(for/list ([i (in-range l)])
(match-define (state y z) (vector-ref states i))
(list y (vector->list z))))
(flatten (list x body)))
The scan function will look a bit different:
(define (scan population)
(foldl (lambda (auto a-hash) (hash-update a-hash (flatten-automaton auto) add1 0))
(hash)
population))
Yep, I believe I see the problem. Your algorithm has O(n^2) ("n-squared") running time. This is because you're counting from one to the length of the list, then for each index, performing a list-ref, which takes time proportional to the size of the index.
This is super-easy to fix.
In fact, there's really no reason to sort it or convert it to a list if this is what you want; just filter the hash table directly. Like this...
#lang racket
(define A (build-list 1000000 (λ (idx) (random 50))))
(define (scan lst)
(foldl (lambda (element a-hash) (hash-update a-hash element add1 0))
(hash)
lst))
(define ht (scan A))
(define only-repeated
(time
(for/hash ([(k v) (in-hash ht)]
#:when (< 1 v))
(values k v))))
I added the call to time to see how long it takes. For a list of size one million, on my computer this takes a measured time of 1 millisecond.
Asymptotic complexity is important!

Elegant Way Of Accounting For "A" When Converting Strings To 26-Ary And Back?

I need to convert strings to 26-ary and then be able to convert them back.
My current code is:
(define (26-ary-word s)
(let ([len (string-length s)])
(let f ([n 0]
[acc (+
(- (char->integer (string-ref s 0)) 97)
1)]) ; adding 1 so that all strings start with 'b'
(if (< n len)
(f (add1 n) (+ (* acc 26) (- (char->integer (string-ref s n)) 97)))
acc))))
(define (word-ary-26 n)
(let f ([n (/ (- n (modulo n 26)) 26)]
[acc (cons (integer->char (+ (modulo n 26) 97)) '())])
(if (> n 0)
(f (/ (- n (modulo n 26)) 26) (cons (integer->char (+ (modulo n 26) 97)) acc))
(list->string (cdr acc))))) ; remove "b" from front of string
I add 1 to acc to start with, and remove the "b" at the end. This is because multiplying "a" - 97 by 26 is still 0.
This is already ugly, but it doesn't even work. "z" is recorded as "701" when it's in the first position (26^2), which is translated back as "az".
I can add another if clause detecting if the first letter is z, but that's really ugly. Is there any way to do this that sidesteps this issue?
(if (and (= n 0) (= acc 26))
(f (add1 n) 51)
(f (add1 n) (+ (* acc 26) (- (char->integer (string-ref s n)) 97))))
This is the ugly edge case handling code I've had to use.
Honestly, I'm not entirely sure what your code is doing, but either way, it's far more complicated than it needs to be. Converting a base-26 string to an integer is quite straightforward just by using some higher-order constructs:
; (char-in #\a #\z) -> (integer-in 0 25)
(define (base-26-char->integer c)
(- (char->integer c) (char->integer #\a)))
; #rx"[a-z]+" -> integer?
(define (base-26-string->integer s)
(let ([digits (map base-26-char->integer (string->list s))])
(for/fold ([sum 0])
([digit (in-list digits)])
(+ (* sum 26) digit))))
By breaking the problem into two functions, one that converts individual characters and one that converts an entire string, we can easily make use of Racket's string->list function to simplify the implementation.
The inverse conversion is actually slightly trickier to make elegant using purely functional constructs, but it becomes extremely trivial with an extra helper function that "explodes" an integer into its digits in any base.
; integer? [integer?] -> (listof integer?)
(define (integer->digits i [base 10])
(reverse
(let loop ([i i])
(if (zero? i) empty
(let-values ([(q r) (quotient/remainder i base)])
(cons r (loop q)))))))
Then the implementation of the string-generating functions becomes obvious.
; (integer-in 0 25) -> (char-in #\a #\z)
(define (integer->base-26-char i)
(integer->char (+ i (char->integer #\a))))
; integer? -> #rx"[a-z]+"
(define (integer->base-26-string i)
(list->string (map integer->base-26-char (integer->digits i 26))))

Why Scheme requires apply in Y-combinator implementation, but Racket doesn't?

Here is the Y-combinator in Racket:
#lang lazy
(define Y (λ(f)((λ(x)(f (x x)))(λ(x)(f (x x))))))
(define Fact
(Y (λ(fact) (λ(n) (if (zero? n) 1 (* n (fact (- n 1))))))))
(define Fib
(Y (λ(fib) (λ(n) (if (<= n 1) n (+ (fib (- n 1)) (fib (- n 2))))))))
Here is the Y-combinator in Scheme:
(define Y
(lambda (f)
((lambda (x) (x x))
(lambda (g)
(f (lambda args (apply (g g) args)))))))
(define fac
(Y
(lambda (f)
(lambda (x)
(if (< x 2)
1
(* x (f (- x 1))))))))
(define fib
(Y
(lambda (f)
(lambda (x)
(if (< x 2)
x
(+ (f (- x 1)) (f (- x 2))))))))
(display (fac 6))
(newline)
(display (fib 6))
(newline)
My question is: Why does Scheme require the apply function but Racket does not?
Racket is very close to plain Scheme for most purposes, and for this example, they're the same. But the real difference between the two versions is the need for a delaying wrapper which is needed in a strict language (Scheme and Racket), but not in a lazy one (Lazy Racket, a different language).
That wrapper is put around the (x x) or (g g) -- what we know about this thing is that evaluating it will get you into an infinite loop, and we also know that it's going to be the resulting (recursive) function. Because it's a function, we can delay its evaluation with a lambda: instead of (x x) use (lambda (a) ((x x) a)). This works fine, but it has another assumption -- that the wrapped function takes a single argument. We could just as well wrap it with a function of two arguments: (lambda (a b) ((x x) a b)) but that won't work in other cases too. The solution is to use a rest argument (args) and use apply, therefore making the wrapper accept any number of arguments and pass them along to the recursive function. Strictly speaking, it's not required always, it's "only" required if you want to be able to produce recursive functions of any arity.
On the other hand, you have the Lazy Racket code, which is, as I said above, a different language -- one with call-by-need semantics. Since this language is lazy, there is no need to wrap the infinitely-looping (x x) expression, it's used as-is. And since no wrapper is required, there is no need to deal with the number of arguments, therefore no need for apply. In fact, the lazy version doesn't even need the assumption that you're generating a function value -- it can generate any value. For example, this:
(Y (lambda (ones) (cons 1 ones)))
works fine and returns an infinite list of 1s. To see this, try
(!! (take 20 (Y (lambda (ones) (cons 1 ones)))))
(Note that the !! is needed to "force" the resulting value recursively, since Lazy Racket doesn't evaluate recursively by default. Also, note the use of take -- without it, Racket will try to create that infinite list, which will not get anywhere.)
Scheme does not require apply function. you use apply to accept more than one argument.
in the factorial case, here is my implementation which does not require apply
;;2013/11/29
(define (Fact-maker f)
(lambda (n)
(cond ((= n 0) 1)
(else (* n (f (- n 1)))))))
(define (fib-maker f)
(lambda (n)
(cond ((or (= n 0) (= n 1)) 1)
(else
(+ (f (- n 1))
(f (- n 2)))))))
(define (Y F)
((lambda (procedure)
(F (lambda (x) ((procedure procedure) x))))
(lambda (procedure)
(F (lambda (x) ((procedure procedure) x))))))

Reversing an integer

I am trying to write a function which takes an input number and outputs the number in reverse order.
Ie:
Input -> 25
Output -> 52
Input -> 125
Output -> 521
I am new to lisp, if its helpful here is the working function in c++
function.cpp
int revs(int rev, int n)
{
if (n <= 0)
return rev;
return revs((rev * 10) + (n % 10), n/10);
}
I have written it in Racket as follows:
(define (revs rev n)
(if (<= n 0)
rev
(revs (+ (* rev 10) (modulo n 10)) (/ n 10))))
But when I run it with (revs 0 125) I get this error:
modulo: contract violation
expected: integer?
given: 25/2
argument position: 1st
other arguments...:
10
Certainly I am doing something incorrect here, but I am unsure of what I am missing.
The division operator / doesn't do integer division, but general division, so when you call, e.g., (/ 25 2), you don't get 12 or 13, but rather the rational 25/2. I think you'd want quotient instead, about which the documentation has:
procedure (quotient n m) → integer?
n : integer?
m : integer?
Returns (truncate (/ n m)). Examples:
> (quotient 10 3)
3
> (quotient -10.0 3)
-3.0
> (quotient +inf.0 3)
quotient: contract violation
expected: integer?
given: +inf.0
argument position: 1st
other arguments...:
3
Treating the operation lexicographically:
#lang racket
(define (lexicographic-reverse x)
(string->number
(list->string
(reverse
(string->list
(number->string x))))))
Works[1] for any of Racket's numerical types.
[edit 1] "Works," I realized, is context dependent and with a bit of testing shows the implicit assumptions of the operation. My naive lexicographic approach makes a mess of negative integers, e.g. (lexicographic-reverse -47) will produce an error.
However, getting an error rather than -74 might be better when if I am reversing numbers for lexicographic reasons rather than numerical ones because it illuminates the fact that the definition of "reversing a number" is arbitrary. The reverse of 47 could just as well be -74 as 74 because reversing is not a mathematical concept - even though it might remind me of XOR permutation.
How the sign is handled is by a particular reversing function is arbitrary.
#lang racket
;; Reversing a number retains the sign
(define (arbitrary1 x)
(define (f n)
(string->number
(list->string
(reverse
(string->list
(number->string n))))))
(if (>= x 0)
(f x)
(- (f (abs x)))))
;; Reversing a number reverses the sign
(define (arbitrary2 x)
(define (f n)
(string->number
(list->string
(reverse
(string->list
(number->string n))))))
(if (>= x 0)
(- (f x))
(f (abs x))))
The same considerations extend to Racket's other numerical type notations; decisions about reversing exact, inexact, complex, are likewise arbitrary - e.g. what is the reverse of IEEE +inf.0 or +nan.0?
Here is my solution for this problem
(define (reverseInt number)
(define (loop number reversedNumber)
(if (= number 0)
reversedNumber
(let ((lastDigit (modulo number 10)))
(loop (/ (- number lastDigit) 10) (+ (* reversedNumber 10) lastDigit)))))
(loop number 0))
Each time we multiply the reversed number by 10 and add the last digit of number.
I hope it makes sense.
A R6RS version (will work with R7RS with a little effort)
#!r6rs
(import (rnrs)
(srfi :8))
(define (numeric-reverse n)
(let loop ((acc 0) (n n))
(if (zero? n)
acc
(receive (q r) (div-and-mod n 10)
(loop (+ (* acc 10) r) q)))))
A Racket implementation:
#!racket
(require srfi/8)
(define (numeric-reverse n)
(let loop ((acc 0) (n n))
(if (zero? n)
acc
(receive (q r) (quotient/remainder n 10)
(loop (+ (* acc 10) r) q)))))
With recursion, you can do something like:
#lang racket
(define (reverse-num n)
(let f ([acc 0]
[n n])
(cond
[(zero? n) acc]
[else (f (+ (* acc 10) (modulo n 10)) (quotient n 10))])))

Resources