Related
I am trying to align some fairly long equations the way I would usually do with LaTeX in groff. The general form I am aiming for:
A = B + C
= D * E
+ F * G
= H + I = J
In LaTeX I would do this as follows:
\documentclass[fleqn]{article}
\usepackage{amsmath}
\begin{document}
\begin{alignat*}{3}
A
& = B + C \\
& =
\begin{aligned}[t]
& D * E \\
& + F * G
\end{aligned} \\
& = H + I
&& = J
\end{alignat*}
\end{document}
In eqn, equation alignment is accomplished with the mark and lineup commands. Quoting Kernighan and Cherry from Typesetting Mathematics 2nd Ed (found here) on how these work:
The word mark may appear once at any place in an equation. It remembers the horizontal position where it appeared. Successive equations can contain one occurence of the word lineup. The place where lineup appears is made to line up with the place marked by the previous mark if at all possible.
Upon reading this I was under the impression that the system does not prohibit both aligning with the previous mark with lineup as well as setting a new mark within the same line of an equation, e.g. I would expect the following:
.PP
.EQ I
A mark =
B + C
.EN
.EQ I
lineup = mark
D * E
.EN
.EQ I
lineup + F * G
.EN
to produce something like this:
A = B + C
= D * E
+ F * G
That is not the case, however. eqn aligns the plus sign with the equals:
A = B + C
= D * E
+ F * G
and produces a warning:
eqn:test.ms:10: multiple marks and lineups
I compile my .ms files with a small script:
eqn $1 -Tpdf | groff -ms -Tpdf > ${1/%.ms/.pdf}
I would like to know if there is some macro that would let me store multiple horizontal offsets (or how to define one). Some clarification as to how exactly mark and lineup macros work would also help.
It is very disappointing that eqn does not allow a new mark to be set. Here is a poor workaround that might be of some use. It consists of repeating the first equation but with the keyword mark in the new position, and diverting the output to nowhere so it does not appear. .di is a base troff to start and end a diversion.
.EQ I
A mark = B + C
.EN
.EQ I
lineup = D * E
.EN
.di mydump
.EQ I
A = mark B + C
.EN
.di
.EQ I
lineup + F * G
.EN
Note, you can also use eqn commands like fwd 99 to move right 99/100 ems, where an em is about the width of the character "m".
Here's a possible solution for having a second mark on the same line as lineup. It uses the base troff sequence \k to mark the current horizontal position into a register myposn. There is then an eqn macro mylineup which calls the eqn special command to run a troff define MyLineup which "returns" a character that has a horizontal movement of myposn units. Before the call eqn sets up some registers with the word following the call, and expects them to be updated to whatever output is desired at that point. We do not use this dummy word, which can be anything, but must not be omitted. For example,
.de MyLineup
. ds 0s "\h'\\n[myposn]u'
. nr 0w \\n[myposn]u
. nr 0h 0
. nr 0d 0
. nr 0skern 0
. nr 0skew 0
..
.EQ I
define mymark '\k[myposn]'
define mylineup 'special MyLineup'
A mark = B + C
.EN
.EQ I
lineup = mymark D * E
.EN
.EQ I
mylineup dummy + F * G
.EN
The lines from .de to .. are the MyLineup definition. The two define lines should be in the first equation. Thereafter, mymark and mylineup dummy can be used in place of mark and lineup. The original mark and lineup are unchanged. If necessary, the real mark can be used again in the line with mylineup, and so on.
To generalise this to having many marks is complicated. The first problem is that mymark is just an eqn define and cannot take a number parameter. It cannot use the special command because it needs to be inline. A trivial solution is just to create a lot of definitions at the start:
define mymark1 '\k[myposn1]'
define mymark2 '\k[myposn2]'
The second problem is that when eqn calls MyLineup it does not pass the following argument ("dummy" which we intend to change to "1") as a parameter of the call, but in the variable 0s; also the string is embedded in formatting code and is actually (in my test anyway) \f[R]\,1\/\fP. So we need to substring the number out of this, with .substring 0s 7 -6. The modified macro and test is:
.\" gets passed 0s = \f[R]\,1\/\fP !!! not just 1
.de MyLineup
. substring 0s 7 -6
. ds 0s \\h'\\n[myposn\\*[0s]]u'
. nr 0w \\n[myposn\\*[0s]]u
. nr 0h 0
. nr 0d 0
. nr 0skern 0
. nr 0skew 0
..
.EQ I
define mymark1 '\k[myposn1]'
define mymark2 '\k[myposn2]'
define mylineup 'special MyLineup'
A mark = B + C
.EN
.EQ I
lineup = mymark1 D * mymark2 E
.EN
.EQ I
mylineup 1 + F * G
.EN
.EQ I
mylineup 2 + X
.EN
.EQ I
lineup = H + I
.EN
I may have been misled by there being several .EQ calls in your example. I was assuming there would be text between the calls and the equations. However, if the intention is to have a single, multi-line equation, it can be done using matrix (or perhaps lpile too). For example,
.nr PS 20p
.nr VS 24p
.PP
.EQ
matrix {
lcol { A }
lcol { = above = above ~ above = }
lcol { B + C above D * E above + F * G above H + I }
lcol { ~ above ~ above ~ above = J }
}
.EN
How can i transform this following string:
string = "1,2,3,4"
into a table:
table = {1,2,3,4}
thanks for any help ;)
Let Lua do the hard work:
s="1,2,3,4"
t=load("return {"..s.."}")()
for k,v in ipairs(t) do print(k,v) end
Below is the code adapted from the Scribunto extension to MediaWiki. It allows to split strings on patterns that can be longer than one character.
-- Iterator factory
function string:gsplit (pattern, plain)
local s, l = 1, self:len()
return function ()
if s then
local e, n = self:find (pattern, s, plain)
local ret
if not e then
ret = self:sub (s)
s = nil
elseif n < e then
-- Empty separator!
ret = self:sub (s, e)
if e < l then
s = e + 1
else
s = nil
end
else
ret = e > s and self:sub (s, e - 1) or ''
s = n + 1
end
return ret
end
end, nil, nil
end
-- Split function that returns a table:
function string:split (pattern, plain)
local ret = {}
for m in self:gsplit (pattern, plain) do
ret [#ret + 1] = m
end
return ret
end
-- Test:
local str = '1,2, 3,4'
print ('table {' .. table.concat (str:split '%s*,%s*', '; ') .. '}')
You can use gmatch and the pattern (%d+) to create an iterator and then populate the table.
local input = "1,2,3,4"
local output = {}
for v in input:gmatch("(%d+)") do
table.insert(output, tonumber(v))
end
for _,v in pairs(output) do
print(v)
end
The pattern (%d+) will capture any number of digits(0-9).
This is a narrow solution, it does not handle blank entries such as
input = "1,2,,4"
output = {1,2,4}
It also does not care what the delimitator is, or if it is even consistent for each entry.
input = "1,2 3,4"
output = {1,2,3,4}
Reference:
Lua 5.3 Manual, Section 6.4 – String Manipulation: string.gmatch
FHUG: Understanding Lua Patterns
even if i use gsub to change white space to _ the if statement still get error attempt to index a nil value i wonder whats the problem.i cant use pairs since that's the instruction my teacher gave.
this is the code sorry in advance im a beginner.
text = "ib c e d f"
text = string.lower(text)
b = text:gsub("%s+", "_")
for k=1, #b do
if not string.sub(b, k,k) or string.sub(b, k,k) ~= " " then
if a[i][2] == string.sub(b, k,k) then
print(yes)
end
end
There are some syntax error on your code snippet which causes the error you mentioned. The gsub function is actually working just fine.
text = "ib c e d f"
text = string.lower(text)
b = text:gsub("%s+", "_") --> this gsub is working just fine
for k=1, #b do
if not string.sub(b, k,k) or string.sub(b, k,k) ~= " " then
if a[i][2] == string.sub(b, k,k) then --> you didn't assign any table called "a" before --> attempting to index a nil value
print(yes)
end
--> haven't close the "if not string.sub" function with an end
end --> this is the end for the loop "for k"
I am just wildly guessing that you want to compare the result string with the original string. Since your question is so enigmatic, I could only offer you this code below for your reference:
text = "ab c d e f "
text = string.lower(text)
output = text:gsub("%s", "_")
for k = 1, #output do
local char = string.sub(output, k, k)
local originalChar = string.sub(text, k, k)
if (originalChar ~= " ") and (char == originalChar) then
print(char .. " --> OK")
end
end
The gsub pattern uses %s instead of %s+ so that each space is converted to an underscore to allow simple unit test (char by char comparison). Code snippet available here.
I got this problem in a coding challenge. I couldn't solve it on time but I still want to know how could it be done. I am not very familiar with expression trees and I found it hard to model the problem. The description goes like this:
Input: expression_tree | sequence_of_operations
The input is a single line of text with a expression tree and a sequence of operations separated by | character and ended by a \n newline character. Spaces are allowed in the input but should be ignored.
The expression tree is a sequence of 1-character variables A-Z and with sub expression trees formed by parenthesis (expression_tree). Examples: AB, A(B C D), (AB)C((DE)F)
The sequence of operations is a string of with characters R (reverse) or S (simplify)
Reverse means reverse the order of everything in expression tree. Applying reverse twice in a row cancels out.
Example: (AB)C((DE)F) | R should print (F(ED))C(BA)
Simplify means remove the parentheses around the very first element in the expression tree and each of its subexpression trees. Applying S multiple times should have same result as applying S once.
Example: (AB)C((DE)F) | S should print ABC(DEF)
Output: Read the expression tree and apply the sequence of operations from left to right to the expression tree, print out the result without characters.
What I would like to know the most is how to model the expression tree to handle the parentheses and how does the simplify operation should work?
'''
Examples are as follows :
INPUT:
(AB)(C(DE))/SS
(((AB)C)D)E/SS
(((AB)C)D)E/SR
(AB)C((DE)F)/SRS
(AB(CD((EF)G)H))(IJ)/SRS
(AB(CD((EF)G)H))(IJ)/SSSRRRS
(A(B(C)D)E(FGH(IJ)))/SRRSSRSSRRRSSRS
(A(BC(D(E((Z)K(L)))F))GH(IJK))/S
-------------------------------
OUTPUT:
AB(C(DE))
ABCDE
EDCBA
FEDCBA
JI(H(GFE)DC)BA
JI(H(GFE)DC)BA
JIHFGE(D(C)B)A
A(BC(D(E(ZK(L)))F))GH(IJK)/S
'''
'''
operationReverse function returns a reversed expression tree
Example : AB(CD) -> (DC)BA
'''
def operationReverse(expression):
'''============== Reversing the whole expressions ================'''
expression = expression[::-1]
expression = list(expression)
'''========= Replace Closing brace with Opening brace and vice versa ========='''
for x in range(0, len(expression)):
if(expression[x] != ')' and expression[x] != '('):
continue
elif(expression[x] == ")"):
expression[x] = "("
else:
expression[x] = ")"
expression = ''.join(expression)
return expression
'''
operationSimplify function returns a simplified expression tree
Example : (AB)(C(DE)) -> AB(C(DE))
operationSimplify uses recursion
'''
def operationSimplify(expression):
'''========= If no parenthesis found then return the expression as it is because it is already simplified ========='''
'''========= This is also the base condition to stop recursion ============='''
if(expression.find('(')==-1):
return expression
'''If 1st character is opening brace then find its correspoinding closing brace and remove them and call the function by passing the values between the opening and closing brace'''
if(expression[0] == '('):
x = 1
#numOfOpeningBrackets = maintains the count of opening brackets for finding it's corresponding closing bracket
numOfOpeningBrackets = 1
while(x < len(expression)):
if(expression[x] != ')' and expression[x] != '('):
x = x + 1
continue
elif(expression[x] == "("):
numOfOpeningBrackets = numOfOpeningBrackets + 1
x = x + 1
else:
numOfOpeningBrackets = numOfOpeningBrackets - 1
if(numOfOpeningBrackets == 0):
posOfCloseBracket = x
break
x = x + 1
expression = operationSimplify(expression[1:posOfCloseBracket]) + expression[posOfCloseBracket+1:]
'''========= If no parenthesis found then return the expression as it is because it is already simplified ========='''
if(expression.find('(')==-1):
return expression
'''========= Find the opening brace and it's closing brace and new expression tree will be concatenation of start of string till opening brace including the brace and string with in the opening brace and closing brace passed as an argument to the function itself and the remaining string ========='''
x = 0
#numOfOpeningBrackets = maintains the count of opening brackets for finding it's corresponding closing bracket
recursion = False
numOfOpeningBrackets = 0
while (x < len(expression)):
if(expression[x] != ')' and expression[x] != '('):
x = x + 1
elif(expression[x] == "("):
if(numOfOpeningBrackets == 0 or recursion == True):
numOfOpeningBrackets = 0
recursion = False
posOfStartBracket = x
y = x
numOfOpeningBrackets = numOfOpeningBrackets + 1
x = x + 1
else:
numOfOpeningBrackets = numOfOpeningBrackets - 1
if(numOfOpeningBrackets == 0):
posOfCloseBracket = x
x = y
expression=expression[0:posOfStartBracket+1]+operationSimplify(expression[posOfStartBracket+1:posOfCloseBracket])+expression[posOfCloseBracket:]
recursion = True
x = x + 1
return expression
'''
solution fucntion prints the final result
'''
def solution(inputString):
'''========= Remove the spaces from the input ==============='''
#inputString = inputString.replace("\n","")
inputString = inputString.replace(" ","")
inputString = inputString.replace("\t","")
#inputString = inputString.replace("()","")
'''=============== The substring before '/' is expression tree and substring after '/' is sequence of operations ======================'''
#posOfSlash = Position Of Slash Character
posOfSlash = inputString.find('/')
if(posOfSlash == -1):
print (inputString)
return
#expressionTree = Expression Tree
expressionTree = inputString[0:posOfSlash]
#seqOfOp = sequence of operations to be performed
seqOfOp = inputString[posOfSlash+1:]
'''============ If sequence Of Operations is empty then print the expression tree as it is ============== '''
if(len(seqOfOp)==0):
print(expressionTree)
return
'''============= Removing all the pairs of RR from the sequence Of Operations =================='''
seqOfOp = seqOfOp.replace(r+r,'')
'''============ All mulptiple S are replaced by one single S ================'''
while(seqOfOp.find(s+s) != -1):
seqOfOp = seqOfOp.replace(s+s,s)
'''============ If to perform operation R then call operationReverse() else if to perform operation S call operationSimplify() ================'''
for x in range (0 , len(seqOfOp)):
if(seqOfOp[x] == r):
expressionTree = operationReverse(expressionTree)
else :
expressionTree = operationSimplify(expressionTree)
print(expressionTree)
return
'''======= Global variables r and s representing operations R and S'''
r = 'R'
s = 'S'
while True:
try:
inputString = input()
'''==================== Calling function solution ======================'''
solution(inputString)
except EOFError:
break
I try to remove 1 whitespace from this string:
m y r e a l n a m e i s d o n a l d d u c k
Expected result:
my real name is donald duck
My code are:
def solve_cipher(input)
input.split('').map { |c| (c.ord - 3).chr }.join(' ') # <- Here I tried everything
end
puts solve_cipher('p| uhdo qdph lv grqdog gxfn')
# => m y r e a l n a m e i s d o n a l d d u c k
I tried everything to solve my problem, example:
input.....join(' ').squeeze(" ").strip # => m y r e a l n a m e...
or
input.....join.gsub(' ','') # => myrealnameisdonaldduck
or
input.....join(' ').lstrip # => m y r e a l n a m e...
and so on...
Well, you could split the string into words first, then split each word into characters. Using the same method you used in your code, it could look like this.
def solve_cipher(input) input.split(' ').map{ |w| w.split('').map { |c| (c.ord - 3).chr}.join('')}.join(' ') end
When joining the characters in the same word, we put no space between them; when joining the words together we put one space between them.
As stated in the question, you are using Rails, so you can also try squish method:
def solve_cipher( input )
input.split(' ').map(&:squish).join(' ')
end
str = "m y r e a l n a m e i s d o n a l d d u c k"
str.gsub(/\s(?!\s)/,'')
#=> "my real name is donald duck"
The regex matches a whitespace character not followed by another whitespace character and replaces the matched characters with empty strings. (?!\s) is a negative lookahead that matches a whitespace.
If more than two spaces may be present between words, first replace three or more spaces with two spaces, as follows.
str = "m y r e a l n a m e i s d o n a l d d u c k"
str.gsub(/\s{3,}/, " ").gsub(/\s(?!\s)/,'')
#=> "my real name is donald duck"
I know that it is not a fancy way of doing it but you could just try to create a new string and have a function traversal(input) with a counter initiated at 0, that would return this new string.
It would go through your input (which is here your string) and if the counter is 0 and it sees a space it just ignores it, increments a counter and go to the next character of the string.
If the counter is different of 0 and it sees a space it just concatenates it to the new string.
And if the counter is different of 0 and it sees something different of a space, it concatenates it to the new string and counter equals 0 again.
The trick is to use a capture group
"m y r e a l n a m e i s d o n a l d d u c k".gsub(/(\s)(.)/, '\2')
=> "my real name is donald duck