Deutsch   English   Français   Italiano  
<v9ubmn$2nink$1@dont-email.me>

View for Bookmarking (what is this?)
Look up another Usenet article

Path: ...!news.misty.com!2.eu.feeder.erje.net!feeder.erje.net!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: "B. Pym" <Nobody447095@here-nor-there.org>
Newsgroups: comp.lang.lisp
Subject: re: Interleaving strings
Date: Mon, 19 Aug 2024 02:46:53 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 105
Message-ID: <v9ubmn$2nink$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=iso-8859-1
Injection-Date: Mon, 19 Aug 2024 04:46:54 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="73cb5f305d7564436335108f5e5d2005";
	logging-data="2870004"; mail-complaints-to="abuse@eternal-september.org";	posting-account="U2FsdGVkX18Ub1XGEEfLD590jXl+Jc/G"
User-Agent: XanaNews/1.18.1.6
Cancel-Lock: sha1:2v1lGQewG1imXujK+c33Hvvfm78=
Bytes: 4917

Pascal J. Bourguignon wrote:

> Eric Wolf <e...@boese-wolf.eu> writes: 
> > Hi there! 
> 
> > I want to have a function, which interleaves strings. So if the input is 
> > "aaa" "bbb" the result should be "ababab". If the input is "aaaa" "bbb" 
> > "cc" the result shall be "abcabcaba". So you just put a character from 
> > the first string into the result string then you put a character from 
> > the second string into the result strings and so, until all input 
> > strings are exhausted. 
> 
> > This is what I came up with, but I'm wondering, if there aren't better 
> > ways in *Common Lisp*, which I'm not able to see. (Comings from C++ and 
> > the likes): 
> 
> > (defun interleave-strings (&rest args) 
> >   (if args 
> >       (let* ((result-length (apply #'+ (mapcar #'length args))) 
> >              (erg (make-array `(,result-length) 
> >                               :element-type 'character 
> >                               :fill-pointer 0))) 
> >         ;;prepare the input, so we can count the used characters in a string 
> >         ;;and know, when it is exhausted. 
> >         (setf args (mapcar #'(lambda (arg) 
> >                                (list 0 (length arg) arg)) 
> >                            args)) 
> >         ;;keep the last cons cell in mind         
> >         (let  ((last (last args))) 
> >           ;;create a circular list, so we can wrap around 
> >           (setf (cdr last) args) 
> >           ;;loop over the circular list, keeping the actual position and the 
> >           ;;position before 
> >           (do* ((oldpos last pos) 
> >                (pos args (cdr pos)) 
> >                (elem (car args) (car pos))) 
> >               ((null elem) erg) 
> >             (vector-push (char (third elem) (first elem)) erg) 
> >             (incf (first elem)) 
> >             (if (not (< (first elem) (second elem))) 
> >                 (if (eql pos oldpos) 
> >                     ;;if its the last remaining item, clear the circular list 
> >                     (setf oldpos nil 
> >                           pos nil) 
> >                     ;;if there are more then one item, delete one entry 
> >                     (setf (cdr oldpos) (cdr pos) 
> >                           pos oldpos)))))) 
> >       ""))   
> 
> > Please comment and suggest better ways. 
> 
> > Yours sincerely, 
> 
> > Eric 
> 
> (defun interleave-strings (&rest strings) 
>   (with-output-to-string (*standard-output*) 
>     (loop 
>        :with indexes = (make-array (length strings) :initial-element 0) 
>        :with len     = (reduce (function max) strings :key (function length)) 


Note his error.  He assigns a value to len and then
never uses it.


>        :for done     = t 
>        :do (map-into indexes (lambda (string index) 
>                                (when (< index (length string)) 
>                                  (princ (aref string index)) 
>                                  (incf index) 
>                                  (setf done nil)) 
>                                index) 
>                      strings indexes) 
>        :until done))) 


A good example of the wrong way to program.

There are two ways of constructing a software design: One way is
to make it so simple that there are obviously no deficiencies,
and the other way is to make it so complicated that there are no
obvious deficiencies.
  --- Charles Antony Richard Hoare


> 
> (defun test/interleave-strings () 
>   (assert (string= (interleave-strings  "aaa" "bbb") "ababab")) 
>   (assert (string= (interleave-strings  "aaaa" "bbb" "cc") "abcabcaba")) 
>   :success)

newLISP

(define (interleave-strings)
  (let (result ""   strings (copy $args))
    (until (for-all empty? strings)
      (dotimes (i (length strings))
        (unless (empty? (nth i strings))
          (push (pop (nth i strings)) result -1))))
    result))

(interleave-strings "aa" "bbbbb" "c")

"abcabbbb"