Re: Given string 'a.bc.' -- replace each dot(.) with 0 or 1

Liste des GroupesRevenir à cl lisp 
Sujet : Re: Given string 'a.bc.' -- replace each dot(.) with 0 or 1
De : 643-408-1753 (at) *nospam* kylheku.com (Kaz Kylheku)
Groupes : comp.lang.lisp
Date : 19. May 2024, 21:56:35
Autres entêtes
Organisation : A noiseless patient Spider
Message-ID : <20240519121441.337@kylheku.com>
References : 1 2
User-Agent : slrn/pre1.0.4-9 (Linux)
On 2024-05-18, Kaz Kylheku <643-408-1753@kylheku.com> wrote:
On 2024-05-18, HenHanna <HenHanna@devnull.tb> wrote:
>
How can i write this function simply?   (in Common Lisp)
>
-- Given a string  'a.bc.'   -- replace each dot(.)  with 0 or 1.
>
        -- So the value is a list of 4 strings:
                                  ('a0bc0'  'a0bc1'  'a1bc0'  'a1bc1')
>
-- The order is not important.
             If the string has 3 dots, the value is a list of length 8.
>
If the program is going to be simpler,
                       pls use, e.g.   (a $ b c $)  rather than  'a.bc.'
>
TXR Lisp:
>
(defun bindots (str)
  (let* ((s (copy str))
         (ixs (where (op eql #\.) s))
         (n (len ixs)))
    (collect-each ((digs (rperm '(#\0 #\1) n)))
      (set [s ixs] digs)
      (copy s))))

Using format. I.e. transform an input string like "a.b~c.d.e" into
the format string "a~ab~~c~ad~ae", and then feed it the digit
permutations as arguments, which can now be integers:

(defun bindots (str)
  (let* ((n (countql #\. str))
         (fs (flow str
               (regsub "~" "~~")
               (regsub "." "~a"))))
    (collect-each ((digs (rperm '(0 1) n)))
      (fmt fs . digs))))

Doh, why stick to the collect-each copy paste; it's a mapcar job:

(defun bindots (str)
  (let* ((n (countql #\. str))
         (fs (flow str
               (regsub "~" "~~")
               (regsub "." "~a"))))
    (mapcar (ap fmt fs) (rperm '(0 1) n))))

Use flow syntax for the whole body:

(defun bindots (str)
  (flow str
    (regsub "~" "~~")
    (regsub "." "~a")
    (mapcar (ap fmt @@1) (rperm '(0 1) (countql #\. str)))))

Why @@1?  (ap fmt @1) would refer to the ap expression's own parameter 1.  @@1
escapes one level out to access the (mapcar ...) expression's implicit
parameter 1, which is the prepared format string coming out of the previous
regsub.

The op syntax, inspired the op operator in MIT Goo, has a fully
developed argument referencing system that supports nesting,
reminiscent of nested commas in backquotes.

Whenver an op expression explicitly refers to parameter material
using @1, @2, ... or @rest, this has the effect of suppressing
the insertion of the implicit rightmost parameter @1, the idea
being that the expression is taking full control over what arguments are
inserted where.

Thus because @@1 mentions an implicit parameter of the mapcar
expression, that expression no longer receives an implicit rightmost
argument. We want this, because otherwise the format string object
from the previous regsub pipeline element would appear as an extra
sequence for mapcar to traverse.

Instead of rperm, we could also count up to below (expt 2 n),
and then use digits to explode digits, like this.
Ah, right but no, because we don't get leading zeros. I will
still mention this:

1> (mapcar (lop digits 2) 0..16)
((0) (1) (1 0) (1 1) (1 0 0) (1 0 1) (1 1 0) (1 1 1) (1 0 0 0)
 (1 0 0 1) (1 0 1 0) (1 0 1 1) (1 1 0 0) (1 1 0 1) (1 1 1 0) (1 1 1 1))

In TXR, I have moved toward generic iteration. Most of the library
is converted.

Actually since now ancient history, sequences other than list have been
traversable with car and cdr, and still are.  But that convenience is
inefficient due to copying.

There is an iteration system which works like this:

1> (iter-begin '(a b c))
(a b c)
2> (iter-more *1)
t
3> (iter-item *1)
a
4> (iter-step *1)
(b c)
5> (iter-begin "abc")
#<seq-iter: 85d75f0>
6> (iter-more *5)
t
7> (iter-item *5)
#\a
8> (iter-step *5)
#<seq-iter: 85d75f0>
9> (iter-item *5)
#\b

Iterators can be functional or stateful, so the return value of iter-step must
be captured.

Above, (iter-begin "abc") produces a heap object, whereas (iter-begin '(a b c))
just returns (a b c).

mapcar efficiently allocates the iterator objects on the stack.  In that case,
list iteration uses an iterator object also; it's not just using the list
as an iterator.

The public function iter-begin performs this optimization whereby for certain
objects, an iteration object need not be constructed, because iter-more,
iter-item and iter-step can handle the original representation.

E.g. infinitely iterate from 3:

1> (iter-begin 3) ;; identity
3
2> (iter-more *1) ;; unconditional true
t
3> (iter-item *1) ;; identity
3
4> (iter-step *1) ;; successor function
4

Since numbers are iterable, we can easily add numbering in
a mapcar, just by mentioning a number as one of the sequence
arguments.

1> (mapcar (do pic `>>:0#` @1 @2) "AA".."DD" 0)
("AA:00" "AB:01" "AC:02" "AD:03" "BA:04" "BB:05" "BC:06" "BD:07"
 "CA:08" "CB:09" "CC:10" "CD:11" "DA:12" "DB:13" "DC:14" "DD:15")

do is the variant of op which handles macros rather than functions.

The pipelining opip (basis of flow macro) automatically applies do or
op to the pipeline elements based on whether they have an operator
or function binding. Thus we can do

  (flow whatever (mapcar ...) (if ...) (progn ..))

The mapcar will be treated as an (op mapcar ...) the if and progn
as (do if ...) and (do progn ...).

--
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
Mastodon: @Kazinator@mstdn.ca

Date Sujet#  Auteur
18 May 24 * Given string 'a.bc.' -- replace each dot(.) with 0 or 122HenHanna
18 May 24 +- Re: Given string 'a.bc.' -- replace each dot(.) with 0 or 11Kaz Kylheku
18 May 24 +* Re: Given string 'a.bc.' -- replace each dot(.) with 0 or 13Kaz Kylheku
19 May 24 i+- Re: Given string 'a.bc.' -- replace each dot(.) with 0 or 11steve
19 May 24 i`- Re: Given string 'a.bc.' -- replace each dot(.) with 0 or 11Kaz Kylheku
19 May 24 +* Re: Given string 'a.bc.' -- replace each dot(.) with 0 or 14Madhu
19 May 24 i`* Re: Given string 'a.bc.' -- replace each dot(.) with 0 or 13steve
19 May 24 i `* Re: Given string 'a.bc.' -- replace each dot(.) with 0 or 12Madhu
29 May 24 i  `- Re: Given string 'a.bc.' -- replace each dot(.) with 0 or 11steve
19 May 24 +- Re: Given string 'a.bc.' -- replace each dot(.) with 0 or 11steve
19 May 24 +* Re: Given string 'a.bc.' -- replace each dot(.) with 0 or 17Joerg Mertens
21 May 24 i`* Re: Given string 'a.bc.' -- replace each dot(.) with 0 or 16HenHanna
22 May 24 i `* Re: Given string 'a.bc.' -- replace each dot(.) with 0 or 15Madhu
29 May 24 i  `* Re: Given string 'a.bc.' -- replace each dot(.) with 0 or 14steve
29 May 24 i   `* Re: Given string 'a.bc.' -- replace each dot(.) with 0 or 13Lawrence D'Oliveiro
29 May 24 i    `* Re: Given string 'a.bc.' -- replace each dot(.) with 0 or 12Madhu
30 May 24 i     `- Re: Given string 'a.bc.' -- replace each dot(.) with 0 or 11steve
24 May 24 +* Re: Given string 'a.bc.' -- replace each dot(.) with 0 or 13WJ
25 May 24 i+- Re: Given string 'a.bc.' -- replace each dot(.) with 0 or 11HenHanna
26 May 24 i`- Re: Given string 'a.bc.' -- replace each dot(.) with 0 or 11Madhu
24 May 24 +- Re: Given string 'a.bc.' -- replace each dot(.) with 0 or 11Mark Wooding
26 May 24 `- Re: Given string 'a.bc.' -- replace each dot(.) with 0 or 11B. Pym

Haut de la page

Les messages affichés proviennent d'usenet.

NewsPortal