For example if there is string = "wbwwbw" and I want to replace "w" to "bw" and "b" to "w" so that if I print the string out it can be "bwwbwbwwbw"?
In your case you can replace the "b" with an "x", something that is not present in your string and that you can definitely find again at a later point.
After that you replace the "w" with "bw".
The last stage is to replace all "x" with "w".
This way you are using a temporary storage for the replacing and can use the built-in functions of your language of choice for the replacing.
Just make sure that your temporary pattern is definitely not present in your original string. Otherwise you get a different result than you expect.
Try iterating the string char by char:
str = 'wbwwbw'
str2 = ''
for c in str:
if c == 'w':
str2 += 'bw'
elif c == 'b':
str2 += 'w'
assert str2 == 'bwwbwbwwbw'
Related
I want to use a variable that references an arithmetic operator within an if statement expression as shown below:
str = { '>60', '>60', '>-60', '=0' }
del = 75
function decode_prog(var1, var2)
op = string.sub(var1, 1, 1)
vb = tonumber(string.sub(var1, 2, 3))
if var2 op vb then
print("condition met")
else
print('condition not meet')
end
end
for i = 1, #str do
decode_prog(str[i], del)
end
When the above code executes, it should either print "condition met" or "condition not met" based on the result of the operation, however I am instead receiving an error.
You cannot substitute a native Lua operator with a variable that references a function, the only way to go about what you are attempted to do is to create a set of functions within an associative array and set the index as a reference to the respective operation you want to conduct.
Looking at your list, you have a greater than (>) and equal to (=). We create a table for these operations that takes two parameters as follows.
local operators = {
[">"] = function(x, y) return x > y end,
["="] = function(x, y) return x == y end,
-- Add more operations as required.
}
You can then invoke the respective function from the decode_prog function by obtaining the operation character from the string, along with the numeric value itself - this is possible because you can obtain the function from the associative array where the index is the string of the operation we want to conduct.
local result = operators[op](var2, number)
This calls upon the operators array, uses the op to determine which index we need to go to for our appropriate operation, and returns the value.
Final Code:
str = { '>60', '>60', '>-60', '=0' }
del = 75
local operators = {
[">"] = function(x, y) return x > y end,
["="] = function(x, y) return x == y end,
}
function decode_prog(var1, var2)
local op = string.sub(var1, 1, 1) -- Fetch the arithmetic operator we intend to use.
local number = tonumber(string.sub(var1, 2)) -- Strip the operator from the number string and convert the result to a numeric value.
local result = operators[op](var2, number) -- Invoke the respective function from the operators table based on what character we see at position one.
if result then
print("condition met")
else
print('condition not meet')
end
end
for i = 1, #str do
decode_prog(str[i], del)
end
I can't make much sense of your code or what you want to achieve doing that but if could simply use load.
You build your expression as a string and run it. Of course you should take care of two character operators like >= which I did not and you should validate your input.
local str={'>60','>60','>-60','=0'}
local del=75
function decode_prog(var1, var2)
local operator = var1:sub(1,1):gsub("=", "==")
local expr = string.format("return %d %s %s", var2,operator, var1:sub(2))
print(string.format("condition %smet", load(expr)() and "" or "not "))
end
for i,v in ipairs(str) do
decode_prog(v, del)
end
A very simple way would be to add a condition for each supported operator:
function decode_prog(var1, var2)
op = string.sub(var1, 1, 1)
vb = tonumber(string.sub(var1, 2)) --remove the last argument and use tonumber()
if vb == nil then return end --if the string does not contain number
if (op == ">" and var2 > vb) or (op == "=" and var2 == vb) --[[add more conditions here]] then
print("condition met")
else
print("condition not met")
end
end
I changed the vb=string.sub(var1,2,3) line too.
This form vb = tonumber(string.sub(var1, 2)) will allow use of numbers that have any number of digits and added tonumber() which will allow us to catch not-a-number errors when comparison would probably fail.
Then I added a logic to determine what the operator is and if the condition is met.
Operator limitations:
This will only work with operators that are one character and operator such as >= will not be possible unless you use a different character for it. ≥ will not play nicely, since it is multiple characters.
So, essentially i'm trying to create a function that solves for the value of x.
for example, x + 4 = 8
So I'm trying to make it so, it replaces x with "" and then it gets the symbol in front of it in this case, "+" and replaces it with ""
but In Order to do so, and not remove an imaginary symbol behind it, I need to make it check if the index is 1.
My Brain Hurts.
Here's what I have for the function, I deleted some of the code for getting the index, cause It didn't work.
mathMod.solveExpression = function(variable, expression)
if (string.find(expression, "=") == nil) then
-- void
else
-- continue with search but with variable
if (string.find(expression, variable) == nil) then
-- void
else
-- ooh time for some sneaky equations
local copy = expression
for i = 1, #expression do
local c = expression:sub(i,i)
if (expression == c) then
end
end
end
end
end
/ Link To My Code`https://pastebin.com/DnKPdw2q /
If your equations are all of the form var op a = b, try this code, which uses Lua pattern matching:
s=" x + 4 = 8 "
var,op,a,b = s:match("(%w+)%s*(%p)%s*(%d+)%s*=%s*(%d+)")
print(var,op,a,b)
The pattern captures the first word as the var, skips spaces, captures a punctuation char as the operation, skips spaces, captures operand a, skips the equal sign possibly surrounded by spaces, and finally captures operand b.
let tag:String = "+1"
for str in readFile do
let feature = str.Split [|' '; '\t'|]
if feature.[8] = "0" then
tag = "-1"
else
tag = "+1"
printf "\n%s %s\n" feature.[8] tag
The code changes tries to change the value of tag to "-1" if feature.[8] is 0, or "+1" otherwise. However the tag variable value remains "+1" throughout, irrespective of whatever the value feature.[8] is.
How does one deal with simple value changes based on conditional statement in F#?
#John Palmer has your answer, but I'll add a bit to it...
Note that the reason why your code compiles but does not work as you expect is because the = operator used in the context of tag = "-1" and tag = "+1" is the equality operator. So those expressions are valid but return a bool value. However, you should be receiving the following warning:
This expression should have type 'unit', but has type 'bool'. Use
'ignore' to discard the result of the expression, or 'let' to bind the
result to a name.
It would serve you well to heed that warning in your F# coding adventures.
Also note that you can write your algorithm in a purely functional way (without mutable variables) using Seq.fold (among other alternative functional approaches):
let tag =
readFile
|> Seq.fold
//we use the wild card match _ here because don't need the
//tag state from the previous call
(fun _ (str:string) ->
let feature = str.Split [|' '; '\t'|]
//return "-1" or "+1" from the if / then expression,
//which will become the state value in the next call
//to this function (though we don't use it)
if feature.[8] = "0" then
"-1"
else
"+1")
("+1") //the initial value of your "tag"
You need to use a mutable variable - by default variables in F# are constant. Also, <- is the assignment operator.
let mutable tag:String = "+1"
for str in readFile do
let feature = str.Split [|' '; '\t'|]
if feature.[8] = "0" then
tag <- "-1"
else
tag <- "+1"
printf "\n%s %s\n" feature.[8] tag
for str in readFile do
let feature = str.Split [|' '; '\t'|]
let tag = if feature.[8] = "0" then "-1" else "+1"
printf "\n%s %s\n" feature.[8] tag
I am developing Pascal language parser in Haskell using Parsec library and I need to re-define some tokens defined in Parsec.Token class.
Speeking of it, here is my case:
I need to change how stringLiteral token is matched. In default definition, it is something between char '"' (see this), but I need it to be between '\'' (apostrophes). How can I do this modification to Parsec behavior?
Thanks!!!
You are talking about adjusting the field of a data type named GenTokenParser. It looks like you are using a function that automatically fills in the data type with sensible defaults and you just want to adjust one thing, here you go:
myMakeTokenParser langDef =
let default = makeTokenParser langDef
in default { stringLiteral = newStringLit }
where
newStringLit = lexeme (
do{ str <- between (char '\'')
(char '\'' <?> "end of string")
(many stringChar)
; return (foldr (maybe id (:)) "" str)
}
<?> "literal string")
I am trying to write an ANTLR grammar for the PHP serialize() format, and everything seems to work fine, except for strings. The problem is that the format of serialized strings is :
s:6:"length";
In terms of regexes, a rule like s:(\d+):".{\1}"; would describe this format if only backreferences were allowed in the "number of matches" count (but they are not).
But I cannot find a way to express this for either a lexer or parser grammar: the whole idea is to make the number of characters read depend on a backreference describing the number of characters to read, as in Fortran Hollerith constants (i.e. 6HLength), not on a string delimiter.
This example from the ANTLR grammar for Fortran seems to point the way, but I don't see how. Note that my target language is Python, while most of the doc and examples are for Java:
// numeral literal
ICON {int counter=0;} :
/* other alternatives */
// hollerith
'h' ({counter>0}? NOTNL {counter--;})* {counter==0}?
{
$setType(HOLLERITH);
String str = $getText;
str = str.replaceFirst("([0-9])+h", "");
$setText(str);
}
/* more alternatives */
;
Since input like s:3:"a"b"; is valid, you can't define a String token in your lexer, unless the first and last double quote are always the start and end of your string. But I guess this is not the case.
So, you'll need a lexer rule like this:
SString
: 's:' Int ':"' ( . )* '";'
;
In other words: match a s:, then an integer value followed by :" then one or more characters that can be anything, ending with ";. But you need to tell the lexer to stop consuming when the value Int is not reached. You can do that by mixing some plain code in your grammar to do so. You can embed plain code by wrapping it inside { and }. So first convert the value the token Int holds into an integer variable called chars:
SString
: 's:' Int {chars = int($Int.text)} ':"' ( . )* '";'
;
Now embed some code inside the ( . )* loop to stop it consuming as soon as chars is counted down to zero:
SString
: 's:' Int {chars = int($Int.text)} ':"' ( {if chars == 0: break} . {chars = chars-1} )* '";'
;
and that's it.
A little demo grammar:
grammar Test;
options {
language=Python;
}
parse
: (SString {print 'parsed: [\%s]' \% $SString.text})+ EOF
;
SString
: 's:' Int {chars = int($Int.text)} ':"' ( {if chars == 0: break} . {chars = chars-1} )* '";'
;
Int
: '0'..'9'+
;
(note that you need to escape the % inside your grammar!)
And a test script:
import antlr3
from TestLexer import TestLexer
from TestParser import TestParser
input = 's:6:"length";s:1:""";s:0:"";s:3:"end";'
char_stream = antlr3.ANTLRStringStream(input)
lexer = TestLexer(char_stream)
tokens = antlr3.CommonTokenStream(lexer)
parser = TestParser(tokens)
parser.parse()
which produces the following output:
parsed: [s:6:"length";]
parsed: [s:1:""";]
parsed: [s:0:"";]
parsed: [s:3:"end";]