;;; -*- mode: lisp -*-
;;; $Id: hash.poplisp,v 1.0 2002/05/03 13:28:00 dada Exp $

(declaim (optimize (speed 3) (space 0) (safety 0) (debug 0) (compilation-speed 0)))
(defun command-line-argument ()
  (parse-integer (or (car pop11::poparglist) "1")))

(defconstant +digit+ "0123456789ABCDEF")

(defconstant +digits-needed+
  #(    (10 100 1000 10000 100000 10000000 100000000 536870911)
        (16 256 4096 65536 1048576 16777216 268435456 4294967296 536870911)
    )
)

(defun fixnum-to-string (n base)
  (declare (fixnum n base))
  (let* ((size (position-if (lambda (x) (>; (the fixnum x) n))
                (aref +digits-needed+ (ash base -4))))
     (result (make-string (1+ size))))
    (loop for i fixnum from size downto 0 with q fixnum = n and r fixnum = 0
      do (multiple-value-setq (q r) (floor q base))
         (setf (schar result i) (aref +digit+ r)))
    result)
)

(defun main (&optional (n (command-line-argument)))
  (let ((hash (make-hash-table :test 'equal :size n)))
    (macrolet ((hash (i base) `(gethash (fixnum-to-string ,i ,base) hash)))
      (loop for i fixnum from 1 to n do (setf (hash i 16) i))
      (format t "~a~%" (loop for i fixnum from n downto 1 count (hash i 10))))))

(main)