Home > Enterprise >  Find the longest integer in a vector using while loops
Find the longest integer in a vector using while loops

Time:04-30

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

CodePudding user response:

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

CodePudding user response:

@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
  • Related