Home > OS >  Replacing token RANDOM with a random number between 0 and 100 in a list scheme
Replacing token RANDOM with a random number between 0 and 100 in a list scheme

Time:10-01

Background

I have this current program in scheme

(define (tsar subj srch repl)
   (cond
         ((list? subj)
          (map
              (lambda (lst) (tsar lst srch repl))
              subj))
         (else
              (if (equal? subj repl)
                   srch
                   subj))))

This function takes a subject subj as a parameter (generally speaking this is should be a list), a value to search for in the list srch and a value to replace the value with repl

Now generally, this function works:

for instance:

(display(tsar '(1 2 () 4 (7 (7 (3 7)))) '() 3))

yields

(1 2 () 4 (7 (7 (() 7))))

the atom 3 in the list is replaced with () as expected.

The problem

There's another twist to this program that I need to resolve, in situations where the atom RANDOM is contained in the list we need to replace that atom with a random number between 0-100 by using (random 100).

What I know (or think I know)

I know I should probably use eq? or something similar to determine whether an atom is RANDOM or not. I also know (perhaps) that I can probably recursively use the tsar function to achieve this by passing in the list as subj, RANDOM as srch and (random 100) as repl.

I'm having an absolute doozy trying to wrap my head around how to make this happen (I am almost completely new to scheme and functional programming in general)

For clarification purposes RANDOM is not a string it is a symbol

CodePudding user response:

In general, you could test for that specific symbol by quoting, then return either the result of (random 100) -- assuming (random 100) returns a result between 0 and 100 in your scheme, this is apparantly not standard -- or else the subject again:

(if (eq? subj 'random)
    (random 100)
    subj))

And you would put this (eq? subj 'RANDOM) as a clause in your function's COND statement:

(define (tsar subj srch repl)
   (cond
         ((list? subj)
          (map
              (lambda (lst) (tsar lst srch repl))
               subj))
         ((eq? subj 'random)
               (random 100))
         (else
              (if (equal? subj repl)
                   srch
                   subj))))

(edited out an extraneous 'if' condition.)

As an aside: at least the Scheme I tested on, BiwaScheme, has caps-specific symbols, so 'random, 'Random, 'RANDOM, etc. all test false with each other, and you would need a COND clause for each symbol. I'm not sure how to combine them to the general case.

CodePudding user response:

My suspicion is you have srch and repl backwards: do you really want to replace repl by srch? You are also using cond in a non-idiomatic way: you don't need to write

(cond
  ...
  (else (if x y z)))

Because the body of cond itself is a bunch of conditionals and results, so you can just turn that into

(cond
  ...
  (x y)
  (else z))

So here is your function with those things changed (this is Racket you may need to change [...] to (...) and λ to lambda):

(define (tsar subj srch repl)
   (cond
     [(list? subj)
      (map (λ (lst) (tsar lst srch repl)) subj)]
     [(equal? subj srch)
      repl]
     [else subj]))

Now, OK to fix this to check for RANDOM we need another clause in the cond which checks for RANDOM. I'm not going to write it but its test will be (eqv? subj 'RANDOM) and the result will be, probably (random 100).

CodePudding user response:

Tested it using mit-scheme:

1 ]=> (fold-right (lambda (x a) (if (eq? x 'random) (cons (random 100) a) (cons x a))) '() '(1 2 3))

;Value: (1 2 3)

1 ]=> (fold-right (lambda (x a) (if (eq? x 'random) (cons (random 100) a) (cons x a))) '() '(1 random 3))

;Value: (1 38 3)

1 ]=> (fold-right (lambda (x a) (if (eq? x 'random) (cons (random 100) a) (cons x a))) '() '(1 random random))

;Value: (1 97 50)

So you can do something like:

(define (doit input)
  (fold-right
    (lambda (x a)
      (if (eq? x 'random)
          (cons (random 100) a)
          (cons x a)))
    '()
    input)
  • Related