Scheme string-ref and char-whitespace? using - string

(define len (string-length "James ApR23Trb&%25G)(=?vqa"))
(define (divide-string str)
(let (x)
(if (char-whitespace? (string-ref str x))
(substring str (+ 1 x) (- len 1))
(printf "an invalid input!"))
))
(divide-string "James ApR23Trb&%25G)(=?vqa")
I have a string with divided into a blank space. I need to handle two
substring. One is till blank space and the other one is from blank
space. But i could not handle the index of blank space with x.
Any help will be appraciated. Thank you even now.

Try regexp-split:
> (regexp-split #rx"\\s" "James ApR23Trb&%25G)(=?vqa")
'("Jame" " ApR23Trb&%25G)(=?vqa")
Here \\s matches whitespace.
Oops. I mistook the question for a Racket question.
In a Scheme implementation: search for split in the documentation
and see what your implementation of choice has available.

Related

In DrRacket how do I check if a string has a certain amount of characters, as well how do I determine what the first character in a string is

Basically I have a problem, here is the information needed to solve the problem.
PigLatin. Pig Latin is a way of rearranging letters in English words for fun. For example, the sentence “pig latin is stupid” becomes “igpay atinlay isway upidstay”.
Vowels(‘a’,‘e’,‘i’,‘o’,and‘u’)are treated separately from the consonants(any letter that isn’t a vowel).
For simplicity, we will consider ‘y’ to always be a consonant. Although various forms of Pig Latin exist, we will use the following rules:
(1) Words of two letters or less simply have “way” added on the end. So “a” becomes “away”.
(2) In any word that starts with consonants, the consonants are moved to the end, and “ay” is added. If a word begins with more than two consonants, move only the first two letters. So “hello” becomes “ellohay”, and “string” becomes “ringstay”.
(3) Any word which begins with a vowel simply has “way” added on the end. So “explain” becomes “explainway”.
Write a function (pig-latin L) that consumes a non-empty (listof Str) and returns a Str containing the words in L converted to Pig Latin.
Each value in L should contain only lower case letters and have a length of at least 1.
I understand that i need to set three main conditions here, i'm struggling with Racket and learning the proper syntax to write out my solutions. first I need to make a conditions that looks at a string and see if it's length is 2 or less to meet the (1) condition. For (2) I need to look at the first two characters in a string, i'm assuming I have to convert the string into a list of char(string->list). For (3) I understand I just have to look at the first character in the string, i basically have to repeat what I did with (2) but just look at the first character.
I don't know how to manipulate a list of char though. I also don't know how to make sure string-length meets a criteria. Any assistance would be appreciated. I basically have barely any code for my problem since I am baffled on what to do here.
An example of the problem is
(pig-latin (list "this" "is" "a" "crazy" "exercise")) =>
"isthay isway away azycray exerciseway"
The best strategy to solve this problem is:
Check in the documentation all the available string procedures. We don't need to transform the input string to a list of chars to operate upon it, and you'll find that there are existing procedures that meet all of our needs.
Write helper procedures. In fact, we only need a procedure that tells us if a string contains a vowel at a given position; the problem states that only a-z characters are used so we can negate this procedure to also find consonants.
It's also important to identify the best order to write the conditions, for example: conditions 1 and 3 can be combined in a single case. This is my proposal:
(define (vowel-at-index? text index)
(member (string-ref text index)
'(#\a #\e #\i #\o #\u)))
(define (pigify text)
; cases 1 and 3
(cond ((or (<= (string-length text) 2)
(vowel-at-index? text 0))
(string-append text "way"))
; case 2.1
((and (not (vowel-at-index? text 0))
(vowel-at-index? text 1))
(string-append (substring text 1)
(substring text 0 1)
"ay"))
; case 2.2
(else
(string-append (substring text 2)
(substring text 0 2)
"ay"))))
(define (pig-latin lst)
(string-join (map pigify lst)))
For the final step, we only need to apply the pigify procedure to each element in the input, and that's what map does. It works as expected:
(pig-latin '("this" "is" "a" "crazy" "exercise"))
=> "isthay isway away azycray exerciseway"

Convert string to title case - Emacs Lisp

I am looking for an elisp function that accepts a string and returns the same in title case (i.e., all words capitalized, except for "a", "an", "on", "the", etc.).
I found this script, which requires a marked region.
Only, I need a function that accepts a string variable, so I can use it with replace-regex. I would love to see a version of the above script that can accept either or...
Something like this?
(progn
(defun title-case (input) ""
(let* (
(words (split-string input))
(first (pop words))
(last (car(last words)))
(do-not-capitalize '("the" "of" "from" "and" "yet"))) ; etc
(concat (capitalize first)
" "
(mapconcat (lambda (w)
(if (not(member (downcase w) do-not-capitalize))
(capitalize w)(downcase w)))
(butlast words) " ")
" " (capitalize last))))
(title-case "the presentation of this HEADING OF my own from my keyboard and yet\n"))
I'd say that the script you linked to does a good job at title casing. You can use it as-is.
That leaves us with two more questions:
How can we make it accept a string?
How can we write a function which accepts both a string or a (marked) region?
Working with strings in Emacs is idiomatically done in temporary buffers which are not displayed. You could write a wrapper like this:
(defun title-capitalization-string (s)
(with-temp-buffer
(erase-buffer)
(insert s)
(title-capitalization (point-min)
(point-max))
(buffer-substring-no-properties (point-min)
(point-max))))
Now, for a function which magically does what you mean, consider something like this:
(defun title-capitalization-dwim (&optional arg)
(interactive)
(cond
(arg
(title-capitalization-string arg))
((use-region-p)
(title-capitalization-string
(buffer-substring-no-properties (region-beginning)
(region-end))))
(t
(title-capitalization-string
(buffer-substring-no-properties (point-at-bol)
(point-at-eol))))))
It accepts an optional argument, or an active region or falls back to the text on the current line. Note that this function is not really useful when used interactively, because it doesn't show any effects. Hat tip also to https://www.emacswiki.org/emacs/titlecase.el
License
I put all this code under the Apache License 2.0 and the GPL 2.0 (or later at your option) in addition to the site's default license.
Use M-x
upcase-initials-region is an interactive built-in function in ‘C
source code’.
(upcase-initials-region BEG END)
Upcase the initial of each word in the region. This means that each
word’s first character is converted to either title case or upper
case, and the rest are left unchanged. In programs, give two
arguments, the starting and ending character positions to operate on.

Function which verifies if a string is includes in an other one in Lisp

I am trying to write a function which verifies if a string is included in another one in Lisp but I cannot
For example :
(string-include 'abd 'abbbe) => nil
(string-include 'ghf 'dghfd) => ghf
Here is my function:
(defun string-include (string1 string2)
(cond
((not string1) 0)
((not string2) 0)
((.... (string1) (string2)) (string1 (string-include string1 (cdr string2))))
((string-include string1 (cdr string2)) ) )
Return an index or the substring, not a symbol
In your question, you used this example:
(string-include 'abd 'abbbe) => nil
(string-include 'ghf 'dghfd) => ghf
Assuming that you're returning the symbols nil and ghf, you'll run into an ambiguity if you ever want to check whether a string contains the substring NIL. E.g., with this approach, you'll have:
(string-include 'nil 'vanilla) => nil
Did that return nil because "NIL" is in "VANILLA", because it isn't? It's ambiguous and you can't tell. Instead, you could return the actual string, since the string "NIL" is a true value. Even better, if you return the index of the string, then you find out where in the other string the first string appears. That's the way that the built in function search behaves, for instance.
Directly, using SEARCH
You can implement this in terms of search:
(defun substringp (needle haystack &key (test 'char=))
"Returns the index of the first occurrence of the string designated
by NEEDLE within the string designated by HAYSTACK, or NIL if it does
not occur. Characters within the string are compared by TEST, which
defaults to CHAR= (for case-sensitive comparison)."
(search (string needle)
(string haystack)
:test test))
Note the use of the string function to convert from string designators (characters, strings, and symbols) to the strings that they designate. Remember that with the standard settings, the reader upcases the names of symbols, so the symbol cat designates the string "CAT". Finally, since this returns the result from search, it does double duty for you: it returns the index of the first occurrence if there is an occurrence, and nil otherwise. Remember that everything except nil is a true value (even 0), so you can use the result as a boolean or as an index (as long as you check that it's not nil). Here are some examples:
CL-USER> (substringp "cat" "concatenate")
3
CL-USER> (substringp "dog" "concatenate")
NIL
;; Default upcasing of symbol names means that the
;; result of 'cat is a symbol named "CAT", which is not
;; in "concatenate".
CL-USER> (substringp 'cat "concatenate")
NIL
;; You can test the characters with CHAR-EQUAL, which
;; is case insensitive, in which case "CAT" is in
;; "concatenate".
CL-USER> (substringp 'cat "concatenate" :test 'char-equal)
3
Using recursion
Your code, and the code that uselpa showed in another answer, are more recursive in nature. That in and of itself is not a problem, but recursive string processing in Common Lisp is prone to a few pitfalls. It's inefficient to make lots of new stings by using subseq, so lots of sequence functions in Common Lisp take :start and :end arguments, or in the case of functions that take two sequences, :start1, :end1, :start2, and :end2 arguments. By using these, you can recurse and change the indices into the strings, rather than creating entirely new strings. For instance, string= lets you compare two strings.
;; "toc" is in both "octocat" and "toccata"
CL-USER> (string= "octocat" "toccata" :start1 2 :end1 5 :end2 3)
T
Working with these kinds of functions requires a bit of care to make sure you don't provide any indices that are out of range, but it's not too bad, and you don't end up copying any strings. Here's a version of substringp that accepts these start and end parameters, and uses a local recursive function to do the actual processing.
(defun substringp (string1 string2
&key
(start1 0) (end1 nil)
(start2 0) (end2 nil))
"Returns the index of the first occurence of the substring of
STRING1 bounded by START1 and END1 within the substring of STRING2
bounded by START2 and END2, or NIL if the string does not appear. The
index is a position within STRING2 as a whole."
;; First, compute the actual strings designated by STRING1 and
;; STRING2, and the values for END1 and END2, which default to the
;; length of the respective strings. Also get the length of the
;; substring in STRING1 that we're looking for. This is done just
;; once. The actual recursive portion is handled by the local
;; function %SUBSTRINGP.
(let* ((string1 (string string1))
(string2 (string string2))
(end1 (or end1 (length string1)))
(end2 (or end2 (length string2)))
(len1 (- end1 start1)))
(labels ((%substringp (start2 &aux (end2-curr (+ start2 len1)))
(cond
;; If end2-curr is past end2, then we're done, and
;; the string was not found.
((not (< end2-curr end2)) nil)
;; Otherwise, check whether the substrings match. If
;; they do, return the current start2, which is the
;; index of the substring within string2.
((string= string1 string2
:start1 start1 :end1 end1
:start2 start2 :end2 end2-curr)
start2)
;; If that doesn't match, then recurse, starting one
;; character farther into string2.
(t (%substringp (1+ start2))))))
(%substringp start2))))
Judging by your code, what you are looking for is something like this:
(defun string-include (string1 string2)
(cond
((zerop (length string1)) nil) ; string1 is empty (no need to test it every time)
((> (length string1) (length string2)) nil) ; string1 is longer than string2
((string= string1 (subseq string2 0 (length string1))) string1) ; string2 starts with string1
(t (string-include string1 (subseq string2 1))))) ; otherwise shorten string2 by 1 and start over
This works but it is inefficient and not idiomatic Common Lisp. Just make sure that you actually pass strings and not symbols like in your example:
? (string-include "abd" "abbbe")
NIL
? (string-include "ghf" "dghfd")
"ghf"
Of course, Joshua's answer is the recommended solution.
EDIT
Added a version that works with both symbols and strings (but returns strings anyway). I took the opportunity to include one of Joshua's suggestions:
(defun string-include (string1 string2)
(let* ((string1 (string string1)) (length1 (length string1)))
(if (zerop length1)
nil
(labels ((sub (s)
(cond
((> length1 (length s)) nil)
((string= string1 s :end2 (length string1)) string1)
(t (sub (subseq s 1))))))
(sub (string string2))))))
Testing:
? (string-include "abd" "abbbe")
NIL
? (string-include "ghf" "dghfd")
"ghf"
? (string-include 'abd 'abbbe)
NIL
? (string-include 'ghf 'dghfd)
"GHF"
? (string-include "ghf" '|dghfd|)
"ghf"
? (string-include '|ghf| "dghfd")
"ghf"

Clojure: Idiomatic Way to Insert a Char in a String

I have a string in Clojure and a character I want to put in between the nth and (n+1)st character. For example: Lets say the string is "aple" and I want to insert another "p" between the "p" and the "l".
(prn
(some-function "aple" "p" 1 2))
;; prints "apple"
;; ie "aple" -> "ap" "p" "le" and the concatenated back together.
I'm finding this somewhat challenging, so I figure I am missing information about some useful function(s) Can someone please help me write the "some-function" above that takes a string, another string, a start position and an end position and inserts the second string into the first between the start position and the end position? Thanks in advance!
More efficient than using seq functions:
(defn str-insert
"Insert c in string s at index i."
[s c i]
(str (subs s 0 i) c (subs s i)))
From the REPL:
user=> (str-insert "aple" "p" 1)
"apple"
NB. This function doesn't actually care about the type of c, or its length in the case of a string; (str-insert "aple" \p 1) and (str-insert "ale" "pp" 1) work also (in general, (str c) will be used, which is the empty string if c is nil and (.toString c) otherwise).
Since the question asks for an idiomatic way to perform the task at hand, I will also note that I find it preferable (in terms of "semantic fit" in addition to the performance advantage) to use string-oriented functions when dealing with strings specifically; this includes subs and functions from clojure.string. See the design notes at the top of the source of clojure.string for a discussion of idiomatic string handling.

Make String from Sequence of Characters

This code does not work as I expected. Could you please explain why?
(defn make-str [s c]
(let [my-str (ref s)]
(dosync (alter my-str str c))))
(defn make-str-from-chars
"make a string from a sequence of characters"
([chars] make-str-from-chars chars "")
([chars result]
(if (== (count chars) 0) result
(recur (drop 1 chars) (make-str result (take 1 chars))))))
Thank you!
This is very slow & incorrect way to create string from seq of characters. The main problem, that changes aren't propagated - ref creates new reference to existing string, but after it exits from function, reference is destroyed.
The correct way to do this is:
(apply str seq)
for example,
user=> (apply str [\1 \2 \3 \4])
"1234"
If you want to make it more effective, then you can use Java's StringBuilder to collect all data in string. (Strings in Java are also immutable)
You pass a sequence with one character in it to your make-str function, not the character itself. Using first instead of take should give you the desired effect.
Also there is no need to use references. In effect your use of them is a gross misuse of them. You already use an accumulator in your function, so you can use str directly.
(defn make-str-from-chars
"make a string from a sequence of characters"
([chars] (make-str-from-chars chars ""))
([chars result]
(if (zero? (count chars))
result
(recur (drop 1 chars) (str result (first chars))))))
Of course count is not very nice in this case, because it always has to walk the whole sequence to figure out its length. So you traverse the input sequence several times unnecessarily. One normally uses seq to identify when a sequence is exhausted. We can also use next instead of drop to save some overhead of creating unnecessary sequence objects. Be sure to capture the return value of seq to avoid overhead of object creations later on. We do this in the if-let.
(defn make-str-from-chars
"make a string from a sequence of characters"
([chars] (make-str-from-chars chars ""))
([chars result]
(if-let [chars (seq chars)]
(recur (next chars) (str result (first chars)))
result)))
Functions like this, which just return the accumulator upon fully consuming its input, cry for reduce.
(defn make-str-from-chars
"make a string from a sequence of characters"
[chars]
(reduce str "" chars))
This is already nice and short, but in this particular case we can do even a little better by using apply. Then str can use the underlying StringBuilder to its full power.
(defn make-str-from-chars
"make a string from a sequence of characters"
[chars]
(apply str chars))
Hope this helps.
You can also use clojure.string/join, as follows:
(require '[clojure.string :as str] )
(assert (= (vec "abcd") [\a \b \c \d] ))
(assert (= (str/join (vec "abcd")) "abcd" ))
There is an alternate form of clojure.string/join which accepts a separator. See:
http://clojuredocs.org/clojure_core/clojure.string/join

Resources