This version uses the iterate macro and generate.
Also note that all the processing is done on lists with a coerce
translating back and fourth.
(defpackage :my-user (:use :cl :iterate)
(in-package :my-user)
(defun parse (key-list)
(iter
(generate char in key-list)
(next char)
(if* (char= char #\*)
:then
(next char)
(collect (ecase char
(#\2 '(#\A #\B #\C))
(#\3 '(#\D #\E #\F))
(#\4 '(#\G #\H #\I))
(#\5 '(#\J #\K #\L))
(#\6 '(#\M #\N #\O))
(#\7 '(#\P #\Q #\R #\S))
(#\8 '(#\T #\U #\V))
(#\9 '(#\W #\X #\Y #\Z))))
:else
(collect char))))
;; Note that for efficency I use push in cross with makes every sublist
come out in reverse order
;; Four cases to consider (Form: accumulated element -> result)
;; A. element is a cons (do a set cross product)
;; 1. nil (A B C) --> ((A) (B) (C))
;; 2. ((A 1) (B 1)) (C D) -> ((C A 1) (C B 1) (D A 1) (D B 1))
;; B. element is a atom
;; 1. nil 1 -> ((1))
;; 2. ((A 1) (B 1)) 2 -> ((2 A 1) (2 B 1))
(defun cross (accumulated element)
(if (consp element)
(if (null accumulated)
(mapcar (lambda (e) (list e)) element)
(mapcan (lambda (e)
(mapcar (lambda (a)
(push e a))
accumulated))
element))
(if (null accumulated)
(list (list element))
(mapcar (lambda (sublis)
(push element sublis))
accumulated))))
(defun expand (list)
(mapcar (lambda (e) (reverse e))
(reduce #'cross list :initial-value nil)))
(defun string-possibilities (key-string)
(mapcar (lambda (a) (coerce a 'string))
(expand (parse (coerce key-string 'list)))))
--
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
In article <·················@pandora.upc.no>,
"John Thingstad" <··············@chello.no> wrote:
> This version uses the iterate macro and generate.
Version of what? This is the start of a thread, what's the problem
you're trying to solve?
--
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***