Programming Challenge

Programming Challenge

john.uhden
Mentor Mentor
8,284 Views
91 Replies
Message 1 of 92

Programming Challenge

john.uhden
Mentor
Mentor

It is claimed that the sentence "The quick brown fox jumped over the lazy dog." contains at least one of all the letters in the English alphabet.  Case doesn't matter.

Your challenge is to post a function that proves or disproves that claim.  It should take the sentence as a string and return T or nil, e.g.

(defun true? (str)

  (and

    (= (type str) 'STR)

    (vl-yes-they-are-all-there str)

  )

)

Have fun, OR ELSE!

John F. Uhden

Replies (91)
Message 2 of 92

ВeekeeCZ
Consultant
Consultant
Accepted solution

T/nil. Not listing missing ones. ignores the case.

 

(defun vl-yes-they-are-all-there ( str / l)
  (foreach e (vl-string->list (strcase str))
    (and (not (vl-position e l))
	 (< 64 e 91)
	 (setq l (cons e l))))
  (= 2015 (apply '+ l)))

 

>> (true? "The quick brown fox jumped over the lazy dog.")
>> nil

 

>> (true? "The quick brown fox jumps over the lazy dog.")
>> T

 

 

0 Likes
Message 3 of 92

Kent1Cooper
Consultant
Consultant
Accepted solution

jumps

Kent Cooper, AIA
0 Likes
Message 4 of 92

Kent1Cooper
Consultant
Consultant
Accepted solution

 

(defun AllLetters (str / chr missing)
  (setq chr 64)
  (while (and (not missing) (< chr 90))
    (setq missing (not (vl-string-position (setq chr (1+ chr)) (strcase str))))
  ); while
  (not missing)
)

 

Command: (allletters "The quick brown fox jumps over the lazy dog.")
T

Command: (allletters "The quick brown fox jumped over the lazy dog.")
nil

Command: (allletters "Pack my box with five dozen liquor jugs.")
T

Command: (allletters "test")
nil

 

In a way, it has the same kind of benefit of (cond) compared to a series of (if) functions -- it checks for the presence of letters only until it finds one missing, and then doesn't need to go any further.

Kent Cooper, AIA
Message 5 of 92

john.uhden
Mentor
Mentor

@ВeekeeCZ and @Kent1Cooper 

I expected that you two would rise to the occasion, BUT

neither of you tested to see if str was a 'STR! 😠

Kent gets credit for remembering the the correct sentence ("jumps" not "jumped") and proving both.

He also gets extra credit for remembering the other famous sentence.

BUT he used an AutoLisp function name as a symbol (chr), but that's because he knew it was okay as long as it was local.

 

Sorry, BeekeeCZ, but Kent leads so far.

Still hoping to hear from gurus like @Hak_vz, @ronjonp, @pbejse, @dbroad et al.

John F. Uhden

0 Likes
Message 6 of 92

Kent1Cooper
Consultant
Consultant
Accepted solution

The converse version, checking that each letter is present so far, rather than whether each one is missing:

(defun AllLetters (str / chr# sofar)
  (setq chr# 64 sofar T)
  (while (and sofar (< chr# 90))
    (setq sofar (vl-string-position (setq chr# (1+ chr#)) (strcase str)))
  ); while
  (numberp sofar)
)

[And I fixed the variable name, but didn't add a check on the (type) of the 'str' argument.] 

 

The (numberp) "wrapper" can be removed if you don't mind the non-nil return being a number, rather than T.

Kent Cooper, AIA
0 Likes
Message 7 of 92

hak_vz
Advisor
Advisor

 

(defun has_all_letters (str / a b c d e dec cnt)
	(cond 
		((= (type str) 'STR)
			(setq dec (cdr(vl-sort (vl-string->list (strcase str)) '<)))
			(cond 
				((= (length dec) 26)(setq a T) (princ "\nThis sentence has 26 letters - TRUE"))
				(T (princ "\nThis sentence doesn't have 26 letters - FALSE"))
			)
			(cond 
				((= (chr (car dec)) "A")(setq b T) (princ "\nFirst alhabetically ordered letter is A - TRUE"))
				((/= (chr (car dec)) "A")(princ "\nFirst alhabetically ordered letter is not A  - FALSE"))
			)
			(cond 
				((= (chr (last dec)) "Z")(setq c T) (princ "\nLast alhabetically ordered letter is Z - TRUE"))
				((/= (chr (last dec)) "Z")(princ "\nLast alhabetically ordered letter is not Z  - FALSE"))
			)
			(setq 
				d T
				cnt -1
			)
			(while (and (and d)(< (setq cnt (1+ cnt))(1- (length dec))))
				(if (/= (- (nth (1+ cnt) dec)(nth cnt dec)) 1) (setq d nil))
			)
			(cond
				((and d)(princ "\nAll letters in this sentence are in sequence - TRUE"))
				(T (princ "\nNot all letters in this sentence are in sequence - FALSE"))
			)
			(setq e (apply 'and (list a b c d)))
			(cond
				 ((not e)(princ "\n\nAll letters from English alphabet are not present - final result:_______ FALSE"))
				 ((and e)(princ "\n\nAll letters from English alphabet are here - final result: _______TRUE"))
			)
		)	
		(T (princ "\nFunction argument is not a string!"))
	)
(princ)
)

 

 

 

Command: (setq str "The quick brown fox jumped over the lazy dog")
Command: (has_all_letters str)
This sentence doesn't have 26 letters - FALSE
First alhabetically ordered letter is A - TRUE
Last alhabetically ordered letter is Z - TRUE
Not all letters in this sentence are in sequence - FALSE
All letters from English alphabet are not present - final result:_______ FALSE

 

 

 

Command: (setq str "The quick brown fox jumps over the lazy dog")
Command: (has_all_letters str)
This sentence has 26 letters - TRUE
First alhabetically ordered letter is A - TRUE
Last alhabetically ordered letter is Z - TRUE
All letters in this sentence are in sequence - TRUE
All letters from English alphabet are here - final result: _______TRUE

 

Miljenko Hatlak

EESignature

Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
0 Likes
Message 8 of 92

Kent1Cooper
Consultant
Consultant
Accepted solution

If you want it to tell you which letter(s) is/are missing:

(defun AllLetters (str / chr# sofar)
  (setq chr# 64 missing "")
  (while (< chr# 90)
    (if (not (vl-string-position (setq chr# (1+ chr#)) (strcase str)))
      (setq missing (strcat missing (chr chr#)))
    ); if
  ); while
  (prompt
    (if (= missing "")
      "\nAll letters present." ; then
      (strcat "\nMissing letter(s): " missing "."); else
    ); if
  ); prompt
  (princ)
)
Kent Cooper, AIA
0 Likes
Message 9 of 92

dbroad
Mentor
Mentor
Accepted solution

Since you're calling the test function from another function that already tests whether or not the argument is a string, that hardly seems necessary.

 

(defun test (str / lst i)
(setq lst (vl-string->list (strcase str)))
(setq i 65)
(while (and (< i 91)
	    (vl-position i lst))
  (setq i (1+ i)))
(= i 91)
)

You could also do a precheck.

(>=(length lst) 26))

 

Architect, Registered NC, VA, SC, & GA.
0 Likes
Message 10 of 92

john.uhden
Mentor
Mentor

That's very close to my first attempt...

(defun @Anonymous? (str / n ok)
  (and
    (= (type str) 'STR)
    (setq str (vl-string->list (strcase str)) n 64 ok T)
    (while (and ok (< n 90))
      (setq ok (vl-position (setq n (1+ n)) str))
    )
    (boundp (quote ok))
  )
)

 so I guess your 2nd version is an improvement. 😁

Here is my 2nd attempt:

(defun istrue (str / chrs)
  (and
    (= (type str) 'STR)
    (setq chrs '(90))
    (repeat (- 90 65)(setq chrs (cons (1- (car chrs)) chrs)))
    (not (vl-position nil (mapcar '(lambda (#)(vl-position # (vl-string->list (strcase str)))) chrs)))
  )
)
;; I tried using...
;; (vl-every 'vl-position chrs (vl-string->list (strcase str)))
;; but I've never figured out how to use vl-every

John F. Uhden

0 Likes
Message 11 of 92

john.uhden
Mentor
Mentor

Yo, Hak,

I didn't require that the sentence be 26 characters long, nor start with A and end with Z, nor be all caps, nor that the letters have to be in any order.

But I admire your perspicacity, much like Abbie on NCIS.

John F. Uhden

0 Likes
Message 12 of 92

john.uhden
Mentor
Mentor

NICE, @dbroad.

So simple.

You just jumped into the lead! 👍

John F. Uhden

0 Likes
Message 13 of 92

hak_vz
Advisor
Advisor
Accepted solution

@john.uhden wrote:

Yo, Hak,

I didn't require that the sentence be 26 characters long, nor start with A and end with Z, nor be all caps, nor that the letters have to be in any order.

But I admire your perspicacity, much like Abbie on NCIS.


a) 26 letters in English alphabet.  Sentence should have at least 26 characters

b) I sort all letters in a list from smallest to largest and have decided to use uppercase

c) But you asked that all letters are here, so in sorted list first is A last is Z

To resolve case with more than 26 letters in a sentence unique filtering is needed.

 

So my algorithm can be summed up:

Take all letters in sentence, convert to integers and use unique filter

Convert to uppercase or lowercase for continuity and re move space

Test is sorted list is in sequence

 

Code was made on the fly so errors are here

 

Miljenko Hatlak

EESignature

Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
0 Likes
Message 14 of 92

john.uhden
Mentor
Mentor

@ВeekeeCZ 

Okay, okay, PROTEST accepted.

1.  You did not use a protected name as a symbol. - TRUE 😊

2.  Other than the input argument, you used only one local. - TRUE 😀

3.  You actually named your function with the silly named I posted. - TRUE 😁

4.  Your function is as good as either of Kent's. - TRUE 😌

5.  Your function is as simple and good as Doug's - FALSE 😢

 

John F. Uhden

0 Likes
Message 15 of 92

john.uhden
Mentor
Mentor
@hak_vz
It hurts me to say this to someone of your imminent eminent stature, but
take another look at Doug's.

John F. Uhden

0 Likes
Message 16 of 92

doaiena
Collaborator
Collaborator
Accepted solution

Here is a quick one from me:

 

(defun test (str)

(= (length (vl-sort (vl-remove-if-not '(lambda (x) (and (> x 64) (< x 91))) (vl-string->list (strcase str))) '<)) 26)
)
0 Likes
Message 17 of 92

john.uhden
Mentor
Mentor

@doaiena 

Very nice!

Slight improvement:

(defun test (str)                                    ; ↓↓↓↓↓↓↓↓
  (= (length (vl-sort (vl-remove-if-not '(lambda (x) (< 64 x 91))
  (vl-string->list (strcase str))) '<)) 26)
)

 Pluses:

1.  You knew (or stumbled on the fact) that vl-sort removes duplicates. 🙂

2.  Zero locals other than input argument. 😀

3.  Very short and sweet. 😃

4.  Very few seem to care about checking if str is a 'STR. 🤔

 

@dbroad ,

You've got some serious competition here (with my assistance).

Of course I haven't checked any of them for speed, but like how many times are you going to repeat this?

John F. Uhden

0 Likes
Message 18 of 92

doaiena
Collaborator
Collaborator

@dbroad's function is hard to beat. vl-position is lightning fast and is going to be called 26 times in he worst case scenario. Definitely the best solution if you ask me.

0 Likes
Message 19 of 92

john.uhden
Mentor
Mentor
@doaiena,
Well, I didn't ask. I guess I should have.🤐
I'm waiting for any late entries.

John F. Uhden

0 Likes
Message 20 of 92

dbroad
Mentor
Mentor
Accepted solution

@doaiena , Your function is a witty one liner.  I like that it doesn't need any local vars.  They're both very fast. Benchmarking it depends on the program used and the order of the functions tested. When tested individually with Rob Bell's first bench version, yours appears slower but I doubt that matters much since both are almost the same time. If there were thousands of strings to test, I would imagine that something like this would be faster than either although this would be slower unless you had the perfect string.

(defun test (str / lst i)
  (setq lst (vl-string->list (strcase str)))
  (setq i 65)
  (and (>= (length lst) 26)
       (while (and (< i 91) (vl-position i lst)) (setq i (1+ i)))
       (= i 91)
       )
  )

This would immediately eliminate strings shorter than 26 characters before looping. 

In college, I found, when writing in APL, that putting too much in a single line was really fun until I started having to debug my work months later. Each greek character could do an immense amount of calculation and I was stringing hundreds of them side by side to do hundreds of lines of Fortran in a single line.

Architect, Registered NC, VA, SC, & GA.