Page 1 of 2

Combining digits to make a string

Posted: Tue May 26, 2009 7:09 pm
by miningold
Warning: I am completely new to lisp, I started two days ago.

What I want to do is make a 3 digit number, randomly generated and each number can only range from 0 to 3

ex: '301' '123' '000' '333' ...

They way I was trying to do it was use the random funcion (random 3) then append all three of the digits however whenever I get it to work it makes a list not a string (ex: (0 1 2) or (0 0 0))

The code I used to get those results was:

Code: Select all

(concatenate 'list (list (random 3)) (list (random 3))(list (random 3))) 
=> (1 0 3)


Yes I know that 'list makes it a list but everything else I tried did not work.

Thank You for your help,
all comments are welcome!

Re: Combining digits to make a string

Posted: Wed May 27, 2009 12:39 pm
by Paul Donnelly
333 = 3 * 100 + 3 * 10 + 3 * 1

Does that help? ;)

Re: Combining digits to make a string

Posted: Wed May 27, 2009 1:16 pm
by ramarren
There is also quite silly solution which, if this is in fact homework of some sort, is not the answer you are looking for, but I just cannot resist:

Code: Select all

(format nil "~4,3,'0r" (random 64))

Re: Combining digits to make a string

Posted: Wed May 27, 2009 2:10 pm
by gugamilare
Ramarren wrote:There is also quite silly solution which, if this is in fact homework of some sort, is not the answer you are looking for, but I just cannot resist:

Code: Select all

(format nil "~4,3,'0r" (random 63))
Nice thinking! Just use numbers in base 4. His teacher won't accept this answer, but that is a nice one.

I think you should put (random 64) since (random 63) will not include the number 63 itself (and 63 will generate the string "333").

BTW, instead of

Code: Select all

(concatenate 'list (list (random 3)) (list (random 3))(list (random 3)))
it is much simpler and efficient to write

Code: Select all

(list (random 3) (random 3) (random 3))
instead (but, again, this is not the correct answer).

Re: Combining digits to make a string

Posted: Fri May 29, 2009 12:56 am
by smithzv
I believe you were implicitly suggesting, "why doesn't it work to do some thing like...

Code: Select all

(coerce '(1 2 3) 'string)
...which is basically equivalent to your...

Code: Select all

(concatenate 'string '(1 2 3))
?" After all, this works:

Code: Select all

(coerce '(1 2 3) 'vector) ==> #(1 2 3)
(concatenate 'string '(#\1 #\2 #\3)) ==> "123"
While it is true that strings are nothing more than vectors made of characters, in Common Lisp (as in most languages) the number 1 and the character 1 (denoted #\1 in Common Lisp) are very distinct. So, if you want to pick random numbers and produce random character versions of those numbers, you need a map (or way to convert) between numbers and characters. Once you have such a map, you can MAPCAR over your list and feed the result to COERCE.

One thing to look at are the functions CHAR-CODE and CODE-CHAR. Another (IMO, cleaner) method is to look into writing a new random-like function that chooses random characters by some means instead of choosing random numbers.

Best,
Zach

Re: Combining digits to make a string

Posted: Fri May 29, 2009 5:34 am
by xach
Here are a few things that sprang to mind.

Code: Select all

(defun miningold.alphabet (&key (length 3) (alphabet "0123"))
  (let ((output (make-string length)))
    (dotimes (i length output)
      (setf (aref output i)
            (aref alphabet (random (length alphabet)))))))

(defun miningold.numbers (&key (length 3) (limit 3))
  (let ((output (make-string length)))
    (dotimes (i length output)
      (setf (aref output i)
            (digit-char (random limit))))))

Re: Combining digits to make a string

Posted: Fri May 29, 2009 6:29 am
by gugamilare
smithzv wrote:I believe you were implicitly suggesting, "why doesn't it work to do some thing like...

Code: Select all

(coerce '(1 2 3) 'string)
...which is basically equivalent to your...

Code: Select all

(concatenate 'string '(1 2 3))
?" After all, this works:

Code: Select all

(coerce '(1 2 3) 'vector) ==> #(1 2 3)
(concatenate 'string '(#\1 #\2 #\3)) ==> "123"
Wait, does "miningold" want a number or a string? Because I thought he wanted a number:
What I want to do is make a 3 digit number, randomly generated [...]
but you are teaching him how to obtain a string instead.

Re: Combining digits to make a string

Posted: Fri May 29, 2009 8:54 am
by slobodan.blazeski
If you want string representation:
(concatenate 'string (princ-to-string (random 3)) (princ-to-string (random 3)) (princ-to-string (random 3)))
->"112"
Else I don't know how to present for example 012 as number as starting zeros will be removed.
012
->12

bobi
http://www.linkedin.com/pub/dir/slobodan/blazeski

Re: Combining digits to make a string

Posted: Fri May 29, 2009 12:51 pm
by Paul Donnelly
gugamilare wrote:Wait, does "miningold" want a number or a string?
According to the post title, a string, and according to the post body, a number.

Re: Combining digits to make a string

Posted: Fri May 29, 2009 2:27 pm
by smithzv
Paul Donnelly wrote:
gugamilare wrote:Wait, does "miningold" want a number or a string?
According to the post title, a string, and according to the post body, a number.
Yeah, I took his example of '000' in the body to mean he wants to deal with strings. Just because number has a specific meaning in CL doesn't mean I might not refer to a number that is contained in a string. Also, the question of how many digits are in a number is kind of ill formed until you decide on a few details regarding how a number is printed. For instance, whether leading zeros should be printed or what base the number should be printed in.

Zach S