TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: MeasureUp on January 15, 2024, 02:38:38 AM

Title: How to Get First Letter of Words in A Sentence
Post by: MeasureUp on January 15, 2024, 02:38:38 AM
I can't figure it out.

Here is an example:
What you see is what you get.
I want to get something like this:
WYSIWYG

Thanks in advance.
Title: Re: How to Get First Letter of Words in A Sentence
Post by: ribarm on January 15, 2024, 03:12:50 AM
Code - Auto/Visual Lisp: [Select]
  1. (defun c:firstletters ( / txt lett pos )
  2.   (setq txt (getstring t "\nInput sentence : "))
  3.   (setq lett (cons (substr txt 1 1) lett))
  4.   (while (setq pos (vl-string-position 32 txt))
  5.     (setq lett (cons (substr txt (+ 2 pos) 1) lett))
  6.     (setq txt (substr txt (+ 2 pos)))
  7.   )
  8. )
  9.  

Code: [Select]
: FIRSTLETTERS
Input sentence : What you see is what you get.
"WYSIWYG"
Title: Re: How to Get First Letter of Words in A Sentence
Post by: Marc'Antonio Alessi on January 15, 2024, 03:20:13 AM
Code: [Select]
(defun ALE_String_ToList (InpStr CarDlm TrueFl / SttPos EndPos TmpLst TmpStr)
  (setq
    CarDlm (ascii CarDlm)   SttPos 0
    EndPos (vl-string-position CarDlm InpStr)
  )
  (while EndPos
    (setq
      TmpStr (substr InpStr (1+ SttPos) (- EndPos SttPos))
      SttPos (1+ EndPos) EndPos (vl-string-position CarDlm InpStr SttPos)
    )
    (and
      (or (/= TmpStr "") TrueFl)
      (setq TmpLst (cons TmpStr TmpLst))
    )
  )
  (if (or (/= (setq TmpStr (substr InpStr (1+ SttPos))) "") TrueFl)
    (reverse (cons TmpStr TmpLst))
    (reverse TmpLst)
  )
)
(defun Foo (InpStr / OutStr)
  (setq OutStr "")
  (foreach ForElm (ALE_String_ToList InpStr " " nil)
    (setq OutStr (strcat OutStr (strcase (substr ForElm 1 1))))
  )
)
(Foo "What you see is what you get.") => "WYSIWYG"
Title: Re: How to Get First Letter of Words in A Sentence
Post by: Lee Mac on January 15, 2024, 03:53:29 AM
Code - Auto/Visual Lisp: [Select]
  1. (defun acronym ( s )
  2.     (   (lambda ( l )
  3.             (vl-list->string
  4.                 (vl-remove nil
  5.                     (mapcar '(lambda ( a b ) (if (and (= 32 a) (< 64 (setq b (logand (~ 32) b)) 91)) b))
  6.                         (cons 32 l) l
  7.                     )
  8.                 )
  9.             )
  10.         )
  11.         (vl-string->list s)
  12.     )
  13. )
Title: Re: How to Get First Letter of Words in A Sentence
Post by: bruno_vdh on January 15, 2024, 09:34:59 AM
Hello,
Another...
Code - Auto/Visual Lisp: [Select]
  1. (defun acronym (s / foo)
  2.  
  3.   (defun foo (l)
  4.     (cond ((null l) nil)
  5.           ((< 64 (car l) 91) (cons (car l) (foo (cdr (member 32 (cdr l))))))
  6.           (T (foo (cdr l)))
  7.     )
  8.   )
  9.  
  10.   (vl-list->string (foo (vl-string->list (strcase s))))
  11. )

Code: [Select]
_$ (acronym "  _What you see is   what you get.")
"WYSIWYG"   
   
Title: Re: How to Get First Letter of Words in A Sentence
Post by: dexus on January 15, 2024, 10:41:04 AM
And anotherone  :-D
Code - Auto/Visual Lisp: [Select]
  1. (defun acronym (str / char rtn skipNext)
  2.   (foreach char (vl-string->list (strcase str))
  3.     (cond
  4.       ((= 32 char)
  5.         (setq skipNext nil)
  6.       )
  7.       ((and (not skipNext) (< 64 char 91))
  8.         (setq rtn (cons char rtn)
  9.               skipNext t)
  10.       )
  11.     )
  12.   )
  13.   (vl-list->string (reverse rtn))
  14. )
Title: Re: How to Get First Letter of Words in A Sentence
Post by: CodeDing on January 15, 2024, 03:05:01 PM
Code - Auto/Visual Lisp: [Select]
  1. ;; First Letter of Word(s)
  2. ;; str - string of word(s)
  3. ;; returns - string, an acronym [capitalized] of all of the first letters of each 'word'
  4. (defun FLOW (str / prevSpace)
  5.   (vl-list->string
  6.     (vl-remove nil
  7.       (mapcar
  8.         '(lambda (x)
  9.           (cond
  10.             ((and (null prevSpace) (= 32 x)) (not (setq prevSpace t)))
  11.             ((and prevSpace (<= 65 x 90))) (setq prevSpace nil) x)
  12.           )
  13.         )
  14.         (cons 32 (vl-string->list (strcase str)))
  15.       )
  16.     )
  17.   )
  18. )

Code: [Select]
Command: (FLOW "  What you $see is !@#$%what you get... .")
"WYSIWYG"
Title: Re: How to Get First Letter of Words in A Sentence
Post by: CodeDing on January 15, 2024, 09:20:41 PM
I also got my GPT (AutoLISP ACE) to get an answer that works (but it does NOT cover all exceptions like the other codes above). Could be useful in the future if you pay for ChatGPT.

AutoLISP Ace:
https://chat.openai.com/g/g-Zt0xFNpOH-autolisp-ace (https://chat.openai.com/g/g-Zt0xFNpOH-autolisp-ace)

Chat return:
Quote
The issue you are encountering is due to the way the function processes spaces and extracts words. Let's modify the function to correctly handle spaces and ensure it generates the full acronym from the phrase:

(defun C:CreateAcronym ( / phrase acronym word startPos endPos)
    (setq phrase (getstring T "\nEnter phrase: ")) ; Enable spaces in input
    (setq phrase (strcat phrase " ")) ; Append a space to handle the last word
    (setq acronym "") ; Initialize acronym as an empty string
    (setq startPos 0) ; Initialize starting position for substring

    (while (setq endPos (vl-string-search " " phrase startPos)) ; Find next space
        (setq word (substr phrase (+ startPos 1) (- endPos startPos))) ; Extract word
        (setq acronym (strcat acronym (strcase (substr word 1 1)))) ; Add the first letter to the acronym
        (setq startPos (+ endPos 1)) ; Update startPos for next word
    )

    (prompt (strcat "\nAcronym: " acronym)) ; Display the acronym
    (princ)
)

In this revised function, the while loop searches for the next space in the phrase starting from the current startPos. Each word is extracted using substr based on the positions of startPos and endPos, and the first character of each word is added to the acronym. The startPos is then updated to the position after the found space for the next iteration.

Load this updated function into AutoCAD and run it by typing CreateAcronym. It should now correctly generate the full acronym for the input phrase "what you see is what you get" as "WYSIWYG".
Title: Re: How to Get First Letter of Words in A Sentence
Post by: Lee Mac on January 16, 2024, 05:01:30 AM
Another -
Code - Auto/Visual Lisp: [Select]
  1. (defun acronym ( s / l r )
  2.     (setq l (cons 32 (vl-string->list (strcase s))))
  3.     (while (setq l (vl-member-if (function (lambda ( x ) (< 64 x 91))) (cdr (member 32 l))))
  4.         (setq r (cons (car l) r))
  5.     )
  6.     (vl-list->string (reverse r))
  7. )
Title: Re: How to Get First Letter of Words in A Sentence
Post by: bruno_vdh on January 16, 2024, 06:06:35 AM
Another -
Code - Auto/Visual Lisp: [Select]
  1. (defun acronym ( s / l r )
  2.     (setq l (cons 32 (vl-string->list (strcase s))))
  3.     (while (setq l (vl-member-if (function (lambda ( x ) (< 64 x 91))) (cdr (member 32 l))))
  4.         (setq r (cons (car l) r))
  5.     )
  6.     (vl-list->string (reverse r))
  7. )


Hello,
I think a simple if is better :grinwink:
Code - Auto/Visual Lisp: [Select]
  1. (defun acronym (s / l r)
  2.   (setq l (cons 32 (vl-string->list (strcase s))))
  3.   (while (setq l (cdr l))
  4.     (if (< 64 (car l) 91)
  5.       (setq r (cons (car l) r) l (member 32 l))
  6.     )
  7.   )
  8.   (vl-list->string (reverse r))
  9. )
  10.  
Title: Re: How to Get First Letter of Words in A Sentence
Post by: Marc'Antonio Alessi on January 16, 2024, 09:35:48 AM


I don't know if it's a coherent version...
Code: [Select]

(defun acronym_ALE (s / l r)
  (setq
    l (vl-string->list (strcase (vl-string-trim " " s)))
    r (list (car l))
  )
  (while (setq l (cdr l))
    (if (= 32 (car l))
      (setq r (cons (cadr l) r) l (member 32 l))
    )
  )
  (vl-list->string (reverse r))
)
Code: [Select]
(setq Astring "@LeeVdh What you see is what you get.")
(acronym_ALE Astring) => "@WYSIWYG"
(acronym_Lee Astring) => "LWYSIWYG"
Title: Re: How to Get First Letter of Words in A Sentence
Post by: bruno_vdh on January 16, 2024, 10:07:51 AM

I don't know if it's a coherent version...
Code: [Select]
(setq Astring "@LeeVdh What you see is what you get.")
(acronym_ALE Astring) => "@WYSIWYG"
(acronym_Lee Astring) => "LWYSIWYG"

I thought the request was about alphabetic characters...
Title: Re: How to Get First Letter of Words in A Sentence
Post by: Marc'Antonio Alessi on January 16, 2024, 11:31:44 AM

I don't know if it's a coherent version...
Code: [Select]
(setq Astring "@LeeVdh What you see is what you get.")
(acronym_ALE Astring) => "@WYSIWYG"
(acronym_Lee Astring) => "LWYSIWYG"

I thought the request was about alphabetic characters...
Yes but... 

Code: [Select]
; for multi spaced strings:


(defun acronym_ALE2 (s / l r)
  (setq
    l (vl-string->list (strcase (vl-string-trim " " s)))
    r (list (car l))
  )
  (while (setq l (cdr l))
    (and
      (= 32 (car l)) (/= 32 (cadr l))
      (setq r (cons (cadr l) r) l (member 32 l))
    )
  )
  (vl-list->string (reverse r))
)
Title: Re: How to Get First Letter of Words in A Sentence
Post by: Lee Mac on January 16, 2024, 11:40:43 AM
Code - Auto/Visual Lisp: [Select]
  1. _$ (acronym_ALE "What  you  see is  what you get.")
  2. "W Y SI WYG"
Title: Re: How to Get First Letter of Words in A Sentence
Post by: Lee Mac on January 16, 2024, 11:45:53 AM
Another -
Code - Auto/Visual Lisp: [Select]
  1. (defun acronym ( s / l r )
  2.     (setq l (vl-string->list (strcase s)))
  3.     (while
  4.         (cond
  5.             (   (< 64 (car l) 91) (setq r (cons (car l) r) l (member 32 l)))
  6.             (   (setq l (cdr l)))
  7.         )
  8.     )
  9.     (vl-list->string (reverse r))
  10. )
Title: Re: How to Get First Letter of Words in A Sentence
Post by: Marc'Antonio Alessi on January 16, 2024, 11:56:15 AM
Code - Auto/Visual Lisp: [Select]
  1. _$ (acronym_ALE "What  you  see is  what you get.")
  2. "W Y SI WYG"
Yes  :) (acronym_ALE2 "What  you  see is  what you get.") => "WYSIWYG"
Title: Re: How to Get First Letter of Words in A Sentence
Post by: Lee Mac on January 16, 2024, 12:12:43 PM
Another -
Code - Auto/Visual Lisp: [Select]
  1. (defun acronym ( s / e r )
  2.     (if (setq r (vlax-create-object "vbscript.regexp"))
  3.         (progn
  4.             (setq e
  5.                 (vl-catch-all-apply
  6.                     (function
  7.                         (lambda ( )
  8.                             (vlax-put-property  r 'pattern "([^A-Z]|\\s)*([A-Z])\\S*")
  9.                             (vlax-put-property  r 'global :vlax-true)
  10.                             (vlax-invoke-method r 'replace (strcase (vl-string-trim " " s)) "$2")
  11.                         )
  12.                     )
  13.                 )
  14.             )
  15.             (vlax-release-object r)
  16.             (if (not (vl-catch-all-error-p e)) e)
  17.         )
  18.     )
  19. )
Title: Re: How to Get First Letter of Words in A Sentence
Post by: JohnK on January 16, 2024, 01:16:00 PM
I didn't see the "straight forward" method, so I thought I'd add that (I only glanced at a few of the other offerings so if this method has already been offered, I apologize). The following will just search through a string looking for spaces (this simple method will not work in all cases--like: " 1 @ What you see..." or recognize only chars--but for simple strings/situations, will work fine).

This is a simple loop method that uses only the base autolisp functions (should work in other platforms like OSX and in scripting) but as I stated above is not fool proof like others shown.

Code - Auto/Visual Lisp: [Select]
  1. (defun find-acronym (aString / maxlength counter out)
  2.   ;; This function will iterate a string and assemble an acronym of the first
  3.   ;; letter from each word.
  4.   ;;
  5.   ;; This function assumes that each word is separated by spaces.
  6.   ;;
  7.   ;; PARAMS:
  8.   ;;   aString - A String to search.
  9.   ;;
  10.   ;; Returns:
  11.   ;;   a string
  12.   (setq maxlength  (strlen aString)                    ; -establish length of input string
  13.         counter 1                                      ; -start a counter
  14.         out (substr aString counter 1)                 ; -establish a output string (assume the first char
  15.                                                        ;  is correct).
  16.                                                        ;  NOTE: This is a potential problem (here be dragons);
  17.                                                        ;        We are not "searching/finding" the first char.
  18.         ) ; setq
  19.   (while (< counter maxlength)                         ; -process string one chr at a time
  20.          (if (= " " (substr aString counter 1))        ; -look for the spaces
  21.            (setq out                                   ; -if we have a space, concat the output
  22.                                                        ;  with the next char in the string.
  23.                  (strcat out
  24.                          (substr aString (1+ counter) 1)))
  25.            ) ; if
  26.          (setq counter (1+ counter))                   ; -increment the counterer
  27.          ) ; while
  28.   out                                                  ; -return the output string.
  29.   )
Title: Re: How to Get First Letter of Words in A Sentence
Post by: kdub_nz on January 16, 2024, 04:22:01 PM
Code - C#: [Select]
  1. var str = "Will this fail?";
  2.  
  3. String initials = String.Join("", str.Split(' ').Select(x => x[0].ToString()).ToArray()).ToUpper();
  4.  
  5. Console.WriteLine(initials);
  6.  

added: synchronised code and image  :embarrassed:
Title: Re: How to Get First Letter of Words in A Sentence
Post by: JohnK on January 16, 2024, 05:20:50 PM
I think I have a string split in some of my C stuff already but not an acronym one. And I guess to do it right in C you should create an array to store the items instead of just printing them out as we fly through the string.

Not as concise as C# but still fun.
Code - C++: [Select]
  1. #include <stdio.h>
  2. #include <string.h>
  3.  
  4. #define LINE_SIZE 500
  5. #define MAX_WORDS 50
  6. #define WORD_SIZE 2
  7.  
  8. int main(int argc, const char * argv[]) {
  9.  
  10.     // Read a line of input from the user (ie stdin)
  11.     char line[LINE_SIZE];
  12.     printf("Please type in a list of words delimted with spaces then hit ENTER:\n");
  13.     while ( fgets(line, LINE_SIZE, stdin) == NULL )
  14.         fprintf(stderr, "You did not enter anything.");
  15.  
  16.     // The list of words -i.e. the array to store the letters.
  17.     char words[MAX_WORDS][WORD_SIZE];                   // -an array of upto 50 words
  18.                                                         //  upto 2 characters each
  19.     int wordCount = 0;                                  // -the number of words in the array.
  20.  
  21.     strncpy(words[wordCount++], line, 1);               // -Pull the first char into the array.
  22.  
  23.     // Loop through the string
  24.     for ( char *c=line; *c; ++c ) {                     // -foreach char in line.
  25.         char ch = *c;                                   // -"ch" is the character
  26.                                                         //  value-at the-char-pointer "c".
  27.         if ( ch==' '                                    // -if this char is a space,
  28.           || ch=='\n'                                   //  or we've reached the EOL char
  29.           ) {
  30.           strncpy(words[wordCount++], (c + 1), 1);      // -Copy the char (+1) to the array.
  31.         }
  32.     }
  33.  
  34.     // Print out the words
  35.     for ( int w=0; w<(wordCount - 1); ++w ) {
  36.         printf("%s", words[w]);
  37.     }
  38.     printf("\n");
  39.     return 0;
  40. }
  41.  
Title: Re: How to Get First Letter of Words in A Sentence
Post by: gile on January 16, 2024, 05:31:30 PM
F#
Code - F#: [Select]
  1. let acronym (str: string) =
  2.     Regex.Matches(str.ToUpper(), @"^[A-Z]|\W[A-Z]")
  3.     |> Seq.cast<Match>
  4.     |> Seq.fold (fun s m -> s + m.Value.Trim()) ""

Code: [Select]
> acronym "What you see is what you get";;
val it: string = "WYSIWYG"

Edit: use Seq.fold instead of Seq.map Seq.reduce
Title: Re: How to Get First Letter of Words in A Sentence
Post by: Lee Mac on January 16, 2024, 05:51:37 PM
F#
Code - F#: [Select]
  1. let acronym (str: string) =
  2.     Regex.Matches(str.ToUpper(), @"^[A-Z]|\W[A-Z]")
  3.     |> Seq.cast<Match>
  4.     |> Seq.map (fun m -> m.Value.Trim())
  5.     |> Seq.reduce (+)

Code: [Select]
> acronym "What you see is what you get";;
val it: string = "WYSIWYG"

I considered a similar regex, but abandoned the use of \W as an underscore is considered a word and so bruno's earlier example fails.
Title: Re: How to Get First Letter of Words in A Sentence
Post by: gile on January 16, 2024, 06:20:06 PM
F#
Code - F#: [Select]
  1. let acronym (str: string) =
  2.     Regex.Matches(str.ToUpper(), @"^[A-Z]|\W[A-Z]")
  3.     |> Seq.cast<Match>
  4.     |> Seq.map (fun m -> m.Value.Trim())
  5.     |> Seq.reduce (+)

Code: [Select]
> acronym "What you see is what you get";;
val it: string = "WYSIWYG"

I considered a similar regex, but abandoned the use of \W as an underscore is considered a word and so bruno's earlier example fails.

Using the same pattern as you:
Code - F#: [Select]
  1. let acronym (str: string) =
  2.     Regex.Replace(str.ToUpper(), @"([^A-Z]|\s)*([A-Z])\S*", "$2")

Code: [Select]
> acronym "_What you see is what you get";;                         
val it: string = "WYSIWYG"
Title: Re: How to Get First Letter of Words in A Sentence
Post by: gile on January 16, 2024, 06:23:55 PM
C#
Code - C#: [Select]
  1. public static string Acronym(string str) =>
  2.     Regex.Replace(str.ToUpper(), @"([^A-Z]|\s)*([A-Z])\S*", "$2");
Title: Re: How to Get First Letter of Words in A Sentence
Post by: MeasureUp on January 17, 2024, 01:48:29 AM
Wow...
Appreciated for all your big guys' inputs.
Your codes definitely help.
I will take some time to learn from the codes.
Thanks again.
:-)
Title: Re: How to Get First Letter of Words in A Sentence
Post by: JohnK on January 17, 2024, 09:14:03 AM
So last night I got to thinking about how I would actually do this task in a C program (you don't normally just create arrays 50 big this way and 50 big that way; you have to manage memory). And I thought the most efficient method I would employ would be to do is to just bust up the string by the delimiter--create a list of strings--and then loop over the list and grab the specific character. This would allow me to build the acronym from the second, or last, or first character with almost no overhead (other than the initial parsing).

So, here is another method (in lisp).
Code - Auto/Visual Lisp: [Select]
  1. (defun strparse (aStr delim / strList pos)
  2.  ;; This function will take a string and parse it out into a list of
  3.  ;; of strings.
  4.  ;;
  5.  ;; PARAMS:    aStr - A string to parse
  6.  ;;            delim - A string of the delimiter
  7.  ;;
  8.  ;; Ex: (StrParse "This is a test string" " ")
  9.  ;;   > ("This" "is" "a" "test" "string")
  10.  ;;
  11.  ;; History: Unknown
  12.  ;;
  13.   (while
  14.     (setq pos (vl-string-search delim aStr 0))
  15.     (setq strList (cons (substr aStr 1 POS) strList)
  16.           aStr (substr aStr (+ pos 2))))
  17.   (reverse (cons aStr strList)) )
  18.  
  19. ;; Second-letter cypher.
  20.   'strcat
  21.   (mapcar
  22.     '(lambda (x) (strcase (substr x 2 1)))
  23.     (strparse "What you are is see is what you get" " ")
  24.     )
  25.   )
  26.  
Title: Re: How to Get First Letter of Words in A Sentence
Post by: Marc'Antonio Alessi on January 18, 2024, 04:01:48 AM
So, here is another method (in lisp).
(defun strparse (aStr delim / strList pos) ... )

If you do not setq aStr every delim but use a position, this function is faster in long strings with many delimiters
Code: [Select]
; Version 1.20 - 2001 11 08
; Description:  convert a string into a list

; Arguments:
;   InpStr = string [STR]
;   CarDlm = delimiter > 1 or more characters [STR]
;
; Examples:
;   (ALE_String_ToListStrDlm "\"Abc\"][1.0][1][Xyz" "][")
;   => ("\"Abc\"" "1.0" "1" "Xyz")
;   (ALE_String_ToListStrDlm "\"Abc\"][1.0][1][Xyz][(][99" "][")
;   => ("\"Abc\"" "1.0" "1" "Xyz" "(" "99")
;   (ALE_String_ToListStrDlm "\"Abc\"][1.0][1][Xyz][)][99" "][")
;   => ("\"Abc\"" "1.0" "1" "Xyz" ")" "99")
;   (ALE_String_ToListStrDlm "\"Abc\"][1.0][1][Xyz][\"][99" "][")
;   => ("\"Abc\"" "1.0" "1" "Xyz" "\"" "99")
;   (ALE_String_ToListStrDlm "\"Abc\"][1.0][1][Xyz][,][99" "][")
;   => ("\"Abc\"" "1.0" "1" "Xyz" "," "99")
;   (ALE_String_ToListStrDlm "\"Abc\"][1.0][1][Xyz][.][99" "][")
;   => ("\"Abc\"" "1.0" "1" "Xyz" "." "99")
;   (ALE_String_ToListStrDlm "\"Abc\"][1.0][1][Xyz][.99" "][")
;   => ("\"Abc\"" "1.0" "1" "Xyz" ".99")
; Return Values: [LIST]
;
(defun ALE_String_ToListStrDlm (InpStr StrDlm / SttPos TmpPos DlmLng TmpLst)
  (cond
    ( (/= (type InpStr) (type StrDlm) 'STR) )
    ( (= InpStr StrDlm) '("") )
    ( (setq
        DlmLng (strlen StrDlm)   SttPos 0
        TmpPos (vl-string-search StrDlm InpStr SttPos)
      )
      (while TmpPos
        (setq
          TmpLst (cons (substr InpStr (1+ SttPos) (- TmpPos SttPos)) TmpLst)
          SttPos (+ TmpPos DlmLng)
          TmpPos (vl-string-search StrDlm InpStr SttPos)
        )
      )
      (reverse (cons (substr InpStr (1+ SttPos)) TmpLst))
    )
  )
)