help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: List not getting filled up


From: uzibalqa
Subject: Re: List not getting filled up
Date: Mon, 31 Jul 2023 00:06:41 +0000

------- Original Message -------
On Monday, July 31st, 2023 at 5:42 AM, Yuri Khan <yuri.v.khan@gmail.com> wrote:


> On Sun, 30 Jul 2023 at 22:11, uzibalqa uzibalqa@proton.me wrote:
> 
> > Use this as a test
> > 
> > (setq collection '())
> > (permute "abc" 0 3 collection)
> > (message "%s" collection)
> > 
> > I should get
> > 
> > collection (abc acb bac bca cba cab)
> > 
> > But I get
> > 
> > Collection (abc abc abc abc abc abc)
> 
> 
> You have a function that builds a list of strings.
> 
> Initially, you have an initial string value, "abc". Along the way, you
> modify its contents, but ultimately there is only one string instance
> in your program.
> 
> Each time you ‘push’ that string into your ‘result’ list, you are
> storing one more reference to the same string object. In
> box-and-pointer diagrams:
> 
> ┌───┬───┐ ┌───┬───┐ ┌───┬───┐ ┌───┬───┐ ┌───┬───┐ ┌───┬───┐
> │ * │ *─┼──→│ * │ *─┼──→│ * │ *─┼──→│ * │ *─┼──→│ * │ *─┼──→│ * │nil│
> └─┼─┴───┘ └─┼─┴───┘ └─┼─┴───┘ └─┼─┴───┘ └─┼─┴───┘ └─┼─┴───┘
> │┌──────────┘ │ │ │ │
> ││┌─────────────────────┘ │ │ │
> │││┌────────────────────────────────┘ │ │
> ││││┌───────────────────────────────────────────┘ │
> │││││┌──────────────────────────────────────────────────────┘
> ↓↓↓↓↓↓
> ┌──────────────────┐
> │ (mutable string) │
> └──────────────────┘
> 
> This explains why you get a list that looks like it contains 6
> identical strings — they are the same string.
> 
> Instead, you should be avoiding in-place string mutation and building
> new string instances as you go, perhaps by redefining ‘swap-chars’ to
> be non-destructive:
> 
> (defun swap-chars (string p q)
> "Swap chars in STRING at positions P and Q."
> (cond
> ((= p q) string)
> ((> p q) (swap-chars string q p))
> 
> (t (concat
> (substring string 0 p)
> (substring string q (1+ q))
> (substring string (1+ p) q)
> (substring string p (1+ p))
> (substring string (1+ q))))))
> 
> (This is likely not the fastest way to build a string with two
> characters swapped. Do not let that distract you from the goal. Your
> first goal is to get your program working correctly. When and if that
> happens, and when and if your working solution is deemed too slow,
> only then you start optimizing.)
> 
> (Adjusting the ‘permute’ function to non-destructive behavior of
> ‘swap-chars’ is left as an exercise. Hint 1: in your first
> ‘swap-chars’ call, you need to arrange for the return value to be
> passed to the recursive invocation of ‘permute’. 

Have done a non-destructive swap-chars which I use directly as follows

(setq result
          (permute (swap-chars string i j) (1+ i) length result))

>  Hint 2: your second
> ‘swap-chars’ call is only there to undo the modification made by the
> first call, so it could be avoided by introducing a local variable to
> hold the result of the modification.)

For your second hint, I am unsure what to store.  Would I store the original 
string passed as an argument to the function as follows.  Then what would I 
do with copy of the string that war not swapped ?


    (let ( (j i)
           (str string) )

      (while (< j length)
        (setq result
          (permute (swap-chars string i j) (1+ i) length result))
        (setq j (1+ j))) ))






reply via email to

[Prev in Thread] Current Thread [Next in Thread]