Re: String Manipulation Challenge



The solution below works. I haven't profiled it, but I convert the
string to a list, generate all possible combinations resulting in a
multi-dimensional list and finally compress that multi-dimensional
list back to a list of strings. Obviously, this is not the most
efficient approach. I thought about working from a hash table as
suggested by Chris Russell, but didn't think that that was in the
spirit of the question.

Converting the string to a list back to a list of strings aside, the
code below is indicative of what my first cuts at a program are like
and why programming in a lisp environment is productive and enjoyable.
I broke the problem down into manageable units and interactively
tested as I went. Now that I have something working, areas of
improvement will become obvious, both through using the code and
profiling. Maybe this kludge is sufficient for my problem and I don't
need to waste time on improving performance.

Lisp environments support this approach better than anything else to
which I have been exposed.

Cheers,

Tom H.

;;; Courtesy of D. Herring
(defun letters (entry)
"International Standard as per http://dialabc.com/motion/keypads.html";
(case entry
(#\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))
(#\1 (signal :no-letter-assigned))
(t (signal :not-a-number))))

(defun replace-asterisk (entry-list &optional result-list)
"Replace the asterisk and next numeric character with the list
of corresponding alpha characters."
(let ((entry (car entry-list)))
(if (null entry)
(reverse result-list)
(case entry
(#\* (replace-asterisk (cddr entry-list)
(push (letters (second entry-list))
result-list)))
(t (replace-asterisk (cdr entry-list)
(push entry result-list)))))))

(defun expand-list (entry-list &optional result-list)
"Generate all possible accounts."
(let ((entry (car entry-list)))
(if (null entry)
(reverse result-list)
(typecase entry
(list (mapcar
(lambda (sub-entry)
(expand-list (cdr entry-list)
(cons sub-entry result-list)))
entry))
(atom (expand-list (cdr entry-list)
(push entry result-list)))
(t (signal :got-nil))))))

(defun compress-accounts (account-list)
"Compress multi-dimensional list of accounts to a list of strings."
(let ((account (car account-list)))
(unless (null account)
(typecase account
(list (concatenate 'list
(compress-accounts account)
(compress-accounts (cdr account-list))))
(standard-char (cons (concatenate 'string account-list) nil))
(t (signal :no-account))))))

(defun get-accounts (keypad-entry)
"Top level function."
(compress-accounts ; Compress to list of strings.
(expand-list ; Permutation
(replace-asterisk ; *number -> characters
(concatenate 'list keypad-entry))))) ; String -> list

.



Relevant Pages

  • Win a holiday in Portugal
    ... Correctly answer our question for a chance to win: ... click&buy to pay for online entry to the competition. ... Your click&buy account can be ...
    (uk.rec.competitions)
  • Re: Minimise process of small business cash receipts?
    ... >>> As it's a home written accounts package it's not double entry as I'm ... >> little point in using double entry because each income entry (a credit) ... account as your "bank" account. ... > pocket that's entered as a debit to Petty Cash. ...
    (uk.finance)
  • Re: [opensuse] Difference between Yast->Group Mgmt. and groupadd
    ... groupadd creates a new group entry using the values specified on the command line. ... Encrypted password as returned by cryptfor the new account. ... A system group is an entry with an GID between SYSTEM_GID_MIN and SYS- ...
    (SuSE)
  • Re: Set default user at logon - XP SP2
    ... I said, there is only _one_ account on each machine, and that is the only ... the screen appears, ready for entry, while on the desktop it requires either ... password entry textbox and place the text cursor in it. ... (which only switches between Classic and Welcome screens), ...
    (microsoft.public.windowsxp.security_admin)
  • Re: Looking for a good idea (in D3)
    ... should be able to paste into the editor and run as-is in any account. ... ENTRY = "" ... COL = BASECOL ... CRT @:@: ...
    (comp.databases.pick)