Home > Blockchain >  How might I rewrite this recursive function so that it does no consume all my CPU cycles?
How might I rewrite this recursive function so that it does no consume all my CPU cycles?

Time:07-22

The goal of this code is to produce list-of-my-tags, a list that is a subset of list-of-qualities. The user has to specify their choice through a number and not by submitting the value of the elements of their choice, e.g. by specifying 0 instead of dark_eyes.

#!/usr/bin/env racket
#lang racket/base

(require racket/list)
 
(define list-of-qualities (list "dark_eyes" "pigmented_a" "bleached_a"
"natural_breasts" "augmented_breasts"))
(displayln "Select with an integer:")
(for ((quality list-of-qualities))
  (display (index-of list-of-qualities quality))(displayln (string-append ". " quality)))

(define (take-list-of-indices (l '()))(let ((list-of-prefs (append l (list (string->number (read-line))))))
  (displayln "Do you wish to select one more tag?[Y/n]")(let ((ch (read-line))) (if (equal? ch "y") (take-list-of-indices list-of-prefs)
                                                                  list-of-prefs))))
(define list-of-is (take-list-of-indices))


(define (indices->values list-of-is list-of-values (l '()))(let ((list-of-selected-values l))
  (for ((i list-of-is))
    (append list-of-selected-values (list-ref list-of-values i))
    (indices->values list-of-is list-of-values list-of-selected-values))
      list-of-selected-values))

(define list-of-my-tags (indices->values list-of-is list-of-qualities))
(for-each displayln list-of-my-tags)

Calling indices->values seems to consume all the CPU cycles on my computer. How might I rewrite indices->values so that does not do so?

CodePudding user response:

You have an infinite recursion (you're calling indices->values with the exact same parameters every time) , that's why the code seems to consume all the CPU cycles. Also you're not using append correctly, you call the procedure but don't do anything with the resulting value: the input list is not modified in-place, a new list is returned with the appended element - and besides, the second parameter should to be a list, not an item. We need to rewrite the code, perhaps like this?

(define (indices->values list-of-is list-of-values)
  (map (curry list-ref list-of-values)
       list-of-is))

Or if you want to use a looping construct, try this instead:

(define (indices->values list-of-is list-of-values)
  (for/list ([i list-of-is])
    (list-ref list-of-values i)))

For example:

(indices->values '(0 2 4) '(a b c d e f))
=> '(a c e)

I suggest you check the documentation to understand how append works and in general, how we should approach a solution when using functional programming: most list functions return a new list, we execute them for their value and not their effect, functional programming forces you to think differently about how to solve a problem.

  • Related