Posted by free-zombie on Wed 22 Oct 22:07
report abuse | download | new post
- ;; Solution to the TeenLinux programming challenge 2 (Common Lisp)
- ;; Copyright (c) 2008 Thomas Jollans
- ;;; You may use this code under the terms of the WTF Public License version 2
- ;;; if you recognize that it's not my fault if it harms you in any way.
- (defun digitsof (numb)
- (if (> numb 0)
- (cons (mod numb 10) (digitsof (floor (/ numb 10))))
- ()))
- (defun unique-p (lst &optional (bad ()))
- (cond ((eq lst ()) t)
- ((member (car lst) bad) nil)
- (t (unique-p (cdr lst) (cons (car lst) bad)))))
- ;;; this version is nice and short, but fails at large numbers
- ;;; due to recursion (stack overflows), and lacks some features
- ;(defun with-unique-digits (from to)
- ; (cond ((> from to) ())
- ; ((unique-p (digitsof from))
- ; (cons from (with-unique-digits (1+ from) to)))
- ; (t
- ; (with-unique-digits (1+ from) to))))
- ;;; This version works with large numbers, and provides additional
- ;;; information. It doesn't work on all common lisp implementations
- ;;; due to non-standard syntax.
- (defun with-unique-digits (start end)
- (loop
- for i from start to end
- with lastval = (1- start)
- with use = nil
- maximizing (- i lastval) into maxjump
- do (if (setf use (unique-p (digitsof i)))
- (setf lastval i))
- append (and use (list i)) into lnums
- count use into nnums
- ; The line below is non-standard code, specified in
- ; Common Lisp the Language, 2nd Edition
- finally return (values lnums nnums maxjump)))
- (defun unique-digits-info (start end)
- (multiple-value-bind (lnums nnums maxjump) (with-unique-digits start end)
- (format t "Numbers without repeating digits between ~d and ~d incl.:~%"
- start end)
- (format t "Total number of values: ~d~%" nnums)
- (format t "Largest jump: ~d~%" maxjump)
- (values nil lnums)))
- ; tips for testers:
- ; * compile. (with CLISP: clisp -c foo.lisp), then just load with (load "foo")
- ; * Avoid seeing the whole value list returned, do
- ; (progn (unique-digits-info n m) nil)
- ; * Time (if you must) with
- ; (time (progn (unique-digits-info 1 1000000) nil))
Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.