I'm trying to write a conditional statement where I can skip a specific space then start reading all the characters after it.
I was thinking to use substring but that wouldn't help because substring will only work if I know the exact number of characters I want to skip but in this case, I want to skip a specific space to read characters afterward.
For example:
String text = "ABC DEF W YZ" //number of characters before the spaces are unknown
String test = "A"
if ( test == "A") {
return text (/*escape the first two space and return anything after that*/)
}
You can split your string on " " with tokenize, remove the first N elements from the returned array (where N is the number of spaces you want to ignore) and join what's left with " ".
Supposing your N is 2:
String text = "ABC DEF W YZ" //number of characters before the spaces are unknown
String test = "A"
if ( test == "A") {
return text.tokenize(" ").drop(2).join(" ")
}
I'm trying to reverse the words in a string individually so the words are still in order however just reversed such as "hi my name is" with output "ih ym eman si" however the whole string gets flipped
r = 0
def readReverse(): #creates the function
start = default_timer() #initiates a timer
r = len(n.split()) #n is the users input
if len(n) == 0:
return n
else:
return n[0] + readReverse(n[::-1])
duration = default_timer() - start
print(str(r) + " with a runtime of " + str(duration))
print(readReverse(n))
First split the string into words, punctuation and whitespace with a regular expression similar to this. Then you can use a generator expression to reverse each word individually and finally join them together with str.join.
import re
text = "Hello, I'm a string!"
split_text = re.findall(r"[\w']+|[^\w]", text)
reversed_text = ''.join(word[::-1] for word in split_text)
print(reversed_text)
Output:
olleH, m'I a gnirts!
If you want to ignore the punctuation you can omit the regular expression and just split the string:
text = "Hello, I'm a string!"
reversed_text = ' '.join(word[::-1] for word in text.split())
However, the commas, exclamation marks, etc. will then be a part of the words.
,olleH m'I a !gnirts
Here's the recursive version:
def read_reverse(text):
idx = text.find(' ') # Find index of next space character.
if idx == -1: # No more spaces left.
return text[::-1]
else: # Split off the first word and reverse it and recurse.
return text[:idx][::-1] + ' ' + read_reverse(text[idx+1:])
I'm working on a program that receives as input a board game as follows:
#####
#_ ##
# ##
# #
# .#
#####
1 4 (player initial position, marked with '_')
After receiving the input, the program transforms it to a [String].
This case, it would be:
["#####", "#_ ##", "# ##", "# #", "# .#", "#####", "1 4"]
How can I access position [1,4] and transform '_' to 'o'?
Function must return initial list with that transformation.
Very important note: '_' is never displayed on input, I only used it to make clear where position [1,4] is (therefore, on input we only see a blank space, ' ')
Seems like one of those tasks you might have to solve for online coding games. As others pointed out, lists are not really suited for dealing with coordinates like this. However, if you are not able to use better libraries (like in coding games) you will have to do some more work.
Here is the code from my ghci session (transforming to a proper program is left as an exercise for the reader...):
let input = ["#####", "#_ ##", "# ##", "# #", "# .#", "#####", "1 4"]
let reverseInput = reverse input
let position = head reverseInput
let board = tail reverseInput
let posX = read $ takeWhile (/=' ') position :: Int
let posY = read $ takeWhile (/=' ') $ reverse position :: Int
let (unchangedBoard, changedBoard) = splitAt posY board
let (unchangedRow, changedRow) = splitAt posX $ head changedBoard
let newRow = unchangedRow ++ "o" ++ tail changedRow
let newBoard = unchangedBoard ++ [newRow] ++ tail changedBoard
let finalOutput = reverse newBoard
mapM_ putStrLn finalOutput
Also note this code is very brittle as it uses partial functions all over the place (tail, head, read). You could try to use pattern matching instead to make the code more robust.
I am a beginner coder in haskell, while doing an exercise from the first chapter of this amazing book: http://book.realworldhaskell.org/read/getting-started.html
I came across this issue:
-- test comment
main = interact wordCount
where
wordCount input = show (ls ++ " " ++ ws ++ " " ++ cs ++ "\n")
where
ls = lines input
ws = length words input
cs = length input
wonderbox:ch01 manasapte$ runghc WC < quux.txt
WC.hs:5:9: parse error on input ‘where’
Why can I not nest my wheres ?
Since your second where is attached to the wordCount definition, it needs to be indented more than it. (Although you will still have some other errors afterward.)
Others have already answered. I will just add some more explanation.
Simplifying a bit, the Haskell indentation rule is:
Some keywords start a block of things (where,let,do,case ... of).
Find the first word after such keywords and note its indentation. Name the column it occurs the pivot column.
Start a line exactly on the pivot to define a new entry in the block.
Start a line after the pivot to continue the entry started in the previous lines.
Start a line before the pivot to end the block.
Hence,
where
wordCount input = show (ls ++ " " ++ ws ++ " " ++ cs ++ "\n")
where
ls = lines input
ws = length words input
cs = length input
Actually means
where {
wordCount input = show (ls ++ " " ++ ws ++ " " ++ cs ++ "\n")
;
where { -- same column, new entry
ls = lines input
; -- same column, new entry
ws = length words input
; -- same column, new entry
cs = length input
}
}
which treats the second where as a separate definition unrelated to wordCount. If we indent it more, it will work:
where {
wordCount input = show (ls ++ " " ++ ws ++ " " ++ cs ++ "\n")
where { -- after the pivot, same entry
ls = lines input
;
ws = length words input
;
cs = length input
}
}
the indentation was incorrect, here's the working version:
-- test comment
import Data.List
main = interact wordCount
where wordCount input = unlines $ [concat $ intersperse " " (map show [ls, ws, cs])]
where ls = length $ lines input
ws = length $ words input
cs = length input
How do I trim the starting and ending character of a string in Scala
For inputs such as ",hello" or "hello,", I need the output as "hello".
Is there is any built-in method to do this in Scala?
Try
val str = " foo "
str.trim
and have a look at the documentation. If you need to get rid of the , character, too, you could try something like:
str.stripPrefix(",").stripSuffix(",").trim
Another way to clean up the front-end of the string would be
val ignoreable = ", \t\r\n"
str.dropWhile(c => ignorable.indexOf(c) >= 0)
which would also take care of strings like ",,, ,,hello"
And for good measure, here's a tiny function, which does it all in one sweep from left to right through the string:
def stripAll(s: String, bad: String): String = {
#scala.annotation.tailrec def start(n: Int): String =
if (n == s.length) ""
else if (bad.indexOf(s.charAt(n)) < 0) end(n, s.length)
else start(1 + n)
#scala.annotation.tailrec def end(a: Int, n: Int): String =
if (n <= a) s.substring(a, n)
else if (bad.indexOf(s.charAt(n - 1)) < 0) s.substring(a, n)
else end(a, n - 1)
start(0)
}
Use like
stripAll(stringToCleanUp, charactersToRemove)
e.g.,
stripAll(" , , , hello , ,,,, ", " ,") => "hello"
To trim the start and ending character in a string, use a mix of drop and dropRight:
scala> " hello,".drop(1).dropRight(1)
res4: String = hello
The drop call removes the first character, dropRight removes the last. Note that this isn't "smart" like trim is. If you don't have any extra character at the start of "hello,", you will trim it to "ello". If you need something more complicated, regex replacement is probably the answer.
If you want to trim only commas and might have more than one on either end, you could do this:
str.dropWhile(_ == ',').reverse.dropWhile(_ == ',').reverse
The use of reverse here is because there is no dropRightWhile.
If you're looking at a single possible comma, stripPrefix and stripSuffix are the way to go, as indicated by Dirk.
Given you only want to trim off invalid characters from the prefix and the suffix of a given string (not scan through the entire string), here's a tiny trimPrefixSuffixChars function to quickly perform the desired effect:
def trimPrefixSuffixChars(
string: String
, invalidCharsFunction: (Char) => Boolean = (c) => c == ' '
): String =
if (string.nonEmpty)
string
.dropWhile(char => invalidCharsFunction(char)) //trim prefix
.reverse
.dropWhile(char => invalidCharsFunction(char)) //trim suffix
.reverse
else
string
This function provides a default for the invalidCharsFunction defining only the space (" ") character as invalid. Here's what the conversion would look like for the following input strings:
trimPrefixSuffixChars(" Tx ") //returns "Tx"
trimPrefixSuffixChars(" . Tx . ") //returns ". Tx ."
trimPrefixSuffixChars(" T x ") //returns "T x"
trimPrefixSuffixChars(" . T x . ") //returns ". T x ."
If you have you would prefer to specify your own invalidCharsFunction function, then pass it in the call like so:
trimPrefixSuffixChars(",Tx. ", (c) => !c.isLetterOrDigit) //returns "Tx"
trimPrefixSuffixChars(" ! Tx # ", (c) => !c.isLetterOrDigit) //returns "Tx"
trimPrefixSuffixChars(",T x. ", (c) => !c.isLetterOrDigit) //returns "T x"
trimPrefixSuffixChars(" ! T x # ", (c) => !c.isLetterOrDigit) //returns "T x"
This attempts to simplify a number of the example solutions provided in other answers.
Someone requested a regex-version, which would be something like this:
val result = " , ,, hello, ,,".replaceAll("""[,\s]+(|.*[^,\s])[,\s]+""", "'$1'")
Result is: result: String = hello
The drawback with regexes (not just in this case, but always), is that it is quite hard to read for someone who is not already intimately familiar with the syntax. The code is nice and concise, though.
Another tailrec function:
def trim(s: String, char: Char): String = {
if (s.stripSuffix(char.toString).stripPrefix(char.toString) == s)
{
s
} else
{
trim(s.stripSuffix(char.toString).stripPrefix(char.toString), char)
}
}
scala> trim(",hello",',')
res12: String = hello
scala> trim(",hello,,,,",',')
res13: String = hello