1

I have a sentence with me, for example, The game is played on a level playing field.

Now, I have with me a list of words (played is the). These are random words given to me.

Now, I have to order them according to the order they occur in the sentence. How do I do this in Scheme? Is there any function in the SRFI libraries to help me out here? I can't grasp on how to do this recursively.

Rohit Shinde
  • 1,575
  • 5
  • 21
  • 47

2 Answers2

1

This is quite simple. If you use filter with the whole sentence, thus list of all symbols in order, as the list and a predicate that uses memq to find the one symbol amoungst your list of symbols given as argument.

You'll find filter in SRFI-1 if you don't have it already defined in guile.

I've tested it and it works like a charm, but I won't post it here since you didn't post code in your question.

Sylwester
  • 47,942
  • 4
  • 47
  • 79
1

I'd write an implementation based on filter from SRFI-1 (as suggested by @Sylwester) and SRFI-26, because I happen to like the cut macro for currying functions. It'll yield a shorter and IMHO clearer answer, just make sure that all the words are in lower (or upper) case:

(use-modules (srfi srfi-1) (srfi srfi-26))

(define (arrange-by-occurrence sentence random-words)
  (filter (cut memq <> random-words) sentence))

For example:

(arrange-by-occurrence '(the game is played on a level playing field)
                       '(played is the))
=> (the is played)

How does it work? Simple, filter will traverse the original sentence in order and for each word it tests whether it's present in the random list of words - using memq for that. Only those words present in the random list will be selected, and they'll be returned in the output list in the same order that they were found in the original sentence.

Óscar López
  • 232,561
  • 37
  • 312
  • 386
  • 1
    In this case, there is no need to use `cute`, you can just use `cut` (which expands to a simpler lambda expression). `cute` is mainly used when there are expressions in the form that must only be evaluated once, so it generates some `let`s around the `lambda`. – C. K. Young Mar 16 '15 at 01:37
  • So `(cut memq <> random-words)` is the same as `(lambda (x) (memq x random-words))`, and `(cute memq <> random-words)` is the same as `(let ((g1 memq) (g2 random-words)) (lambda (x) (g1 x g2)))`, where `g1` and `g2` are effectively gensyms. – C. K. Young Mar 16 '15 at 01:39
  • @ChrisJester-Young I thought using `cute` would prevent re-evaluating the `random-words` list every time `memq` is invoked. Am I mistaken? – Óscar López Mar 16 '15 at 02:27
  • But `random-words` is just a parameter. There's no effort involved in evaluating that. – C. K. Young Mar 16 '15 at 02:43
  • 1
    Also, you can merge the two `use-modules` forms into a single one: `(use-modules (srfi srfi-1) (srfi srfi-26))`. – C. K. Young Mar 16 '15 at 02:55
  • How would I edit this to do the following? I have a list with me like this: `((played.MC) (is.MA) (the.MZ))`, so how would I arrange it like this `((the.MZ) (is.MA) (played.MC) )`? How would I edit the code above?×Comments may only be edited for 5 minutes×Comments may only be edited for 5 minutes×Comments may only be edited for 5 minutes – Rohit Shinde Mar 19 '15 at 07:53
  • @RohitShinde pass a sentence list where the words appear in the order you expect them. – Óscar López Mar 19 '15 at 13:21
  • So I would pass a list like this: `((The) (game) (is) (played) (on) (a) (level) (palying) (field))`? – Rohit Shinde Mar 19 '15 at 14:59
  • Read the documentation. You'd need to use `member` for comparing sublists, and create a list with exactly the same elements as needed. – Óscar López Mar 19 '15 at 15:28