Creating 2d string indexed tables in Lua - lua

I need to create a table like:
M = {"A"={"a1"=0, "a2"= 1}, "B"={"b1"=2,"b2"=3}}
but this is what I got: " '}' expected near '=' "
Is there anyway to do/simulate this?

foo.bar is the syntactic sugar of foo["bar"], there are no double quotes in the the former syntax:
M = {A = {a1 = 0, a2 = 1}, B = {b1 = 2, b2 =3 }}

Related

could this be a F# 6 indexer bug?

let's consider this code:
type T =
{
a: int
}
let d =
[
"a", [{a = 0}; {a = 1}; {a = 2}]
"b", [{a = 3}; {a = 4}; {a = 5}]
] |> Map
If I want to access the data with a = 0:
d.["a"].[0].a <- works
d["a"].[0].a <- now works with F#6
d["a"][0] <- returns {a = 0}
but
d["a"][0].a <- typecheck error This value is not a function and cannot be applied.
if I wrap the expression in parenthesis:
(d["a"][0]).a <- it works
Is this expected, or could it be a F#6 parsing bug?
In the end, this was done for compatibility reasons; see the reply by Don Syme:
https://github.com/dotnet/fsharp/issues/12549#event-5840475607
A request to allow this notation was posted and seems approved.
https://github.com/fsharp/fslang-suggestions/issues/1109

How to get all diagonal from an array of words in Ruby?

I have an array in Ruby
words = ["horses", "follow", "useful", "offset"]
Reference:
h o r s e s
f o l l o w
u s e f u l
o f f s e t
I want to get a list of all its diagonals like this.
Here is want I expect in result:
["o", "uf", "fsf", "hoes", "olfe", "rlut", "sol", "ew", "s"]
Would be helpful if anyone can help me a bit on this. Thanks
Try that:
words = ["horses", "follow", "useful", "offset"]
words.reverse.each_with_index.map{|s,i| " " * i + s }.inject(Array.new(words.size + words.last.size-1,"")) do |a,s|
s.chars.each_with_index do |c,i|
a[i] = c + a[i]
end
a
end.map(&:strip)
# => ["o", "uf", "fsf", "hoes", "olfe", "rlut", "sol", "ew", "s"]
At first words.reverse.each_with_index.map{|s,i| " " * i + s } builds array with whitespace offset:
offset
useful
follow
horses
Inject creates array of empty strings and inside main block each string chars are prepended to proper array element

Parsing expressions ! chain of operators

hi I know how to parse expressions (incl. brackets).
But normally parsing expressions assumes "operand operator operand".
F.e. :
5 + 12
( 5 * 6 ) + 11
( 3 + 4 ) + ( 5 * 2)
As you can see the values are always two.
What I'm looking for is mechanism (grammar) than can parse chain of similar operators as a single item i.e. greedy
F.e. let say I have the following expression :
5 + 4 + 2 + 7 * 6 * 2
=> sum(5 + 4 + 2)
+
=> mult(7 * 6 * 2)
I want the parser to gobble the sum as one single "action", the same for multiplication.
Here is one example of NON-working grammar, but may be you can get the idea what I want to do (python - LEPL module) :
def build_grammar2(self):
spaces = Token('[ \t]+')[:]
plus = Token('\+')
left_bracket = Token('\(')
right_bracket = Token('\)')
mult = Token('\*')
bit_var = Token('[a-zA-Z0-9_!\?]+')
# with Separator(~spaces):
expr, group2 = Delayed(), Delayed()
mul_node = bit_var & (~mult & bit_var)[1:] > Node
add_node = bit_var & (~plus & bit_var)[1:] > Node
node = mul_node | add_node
parens = ~left_bracket & expr & ~right_bracket
group1 = parens | node
add = group1 & ~plus & group2 > Node
group2 += group1 | add
mul = group2 & ~mult & expr > Node
expr += group2 | mul
self.grammar = expr
This is pretty much what you get with pyparsing:
import pyparsing as pp
add_op = pp.oneOf("+ -")
mul_op = pp.oneOf("* /")
operand = pp.pyparsing_common.number | pp.pyparsing_common.identifier
arith = pp.infixNotation(operand,
[
("-", 1, pp.opAssoc.RIGHT),
(mul_op, 2, pp.opAssoc.LEFT),
(add_op, 2, pp.opAssoc.LEFT),
])
print(arith.parseString("1+2-3+X*-7*6+Y*(3+2)").asList())
prints
[[1, '+', 2, '-', 3, '+', ['X', '*', ['-', 7], '*', 6], '+', ['Y', '*', [3, '+', 2]]]]
If you just parse numbers, you can make the parser also do parse-time eval by adding parse actions to each level of precedence (pp.pyparsing_common.number auto-converts numeric strings to int or float):
operand = pp.pyparsing_common.number
op_fn = {
'*': lambda a,b: a*b,
'/': lambda a,b: a/b,
'+': lambda a,b: a+b,
'-': lambda a,b: a-b,
}.get
def binop(t):
t_iter = iter(t[0])
ret = next(t_iter)
for op, val in zip(t_iter, t_iter):
ret = op_fn(op)(ret, val)
return ret
arith = pp.infixNotation(operand,
[
("-", 1, pp.opAssoc.RIGHT, lambda t: -t[1]),
(mul_op, 2, pp.opAssoc.LEFT, binop),
(add_op, 2, pp.opAssoc.LEFT, binop),
])
print(arith.parseString("1+2-3+8*-7*6+4*(3+2)"))
Prints:
[-316]

How to solve a system of equations seperated by "and" in maxima?

My student gives me an answer in the form:
x=4 and y=3
Now I want to find out what x and y is in maxima, and give feedback. For example, "x is correct, but y is incorrect". I know that if the student gives the answer as a list, I can do:
solve([x=4, y=3], [x,y])
Is there a way to either convert this and expression to a list, or make maxima find out for me what x and y is directly?
If the input expression is a string, then you can use parse_string:
a: "x=3 and y = 4"$
inpart(parse_string(a),1);
(%o1) x = 3
exp: map(lambda([i],inpart(parse_string(a),i)), [1,2]);
(%o2) [x = 3, y = 4]
solve(exp, [x,y]);
(%o3) [[x = 3, y = 4]]
I assume that you can obtain a Maxima expression from the input via parse_string or some other means.
Let e be the expression. Then subst("and"="[", e) returns an expression which has the operator "[" (i.e., a list) instead of "and".
Another way is to use split:
str:"x=4 and y=3";
spl:split(str,"and");
>>> ["x=4 "," y=3"]
eq:map(parse_string,spl);
>>> [x=4,y=3]

searching in a list for a record with specific fields and ignoring the rest

I have a record defined as:
1> rd(fact, {a,b,c}).
fact
I create three records and put them in a list
2> F1 = #fact{a=1,b=1,c=1}.
#fact{a = 1,b = 1,c = 1}
(3> F2 = #fact{a=2,b=2,c=2}.
#fact{a = 2,b = 2,c = 2}
3> F3 = #fact{a=3,b=3,c=3}.
#fact{a = 3,b = 3,c = 3}
4> L = [F1,F2,F3].
[#fact{a = 1,b = 1,c = 1},
#fact{a = 2,b = 2,c = 2},
#fact{a = 3,b = 3,c = 3}]
Now, I want to check if the list contains a record in which 'a' is 1 and I don't care for the rest of the fields
(dilbert#Martin-PC)21> lists:member(#fact{a=1}, L).
false
(dilbert#Martin-PC)23> lists:member(#fact{a=1,b=1,c=1}, L).
true
How can I accomplish it?
Or you could use keyfind.
lists:keyfind(1, #fact.a, L).
Records are pure syntactic sugar. When you don't specify the values of the other fields in a record declaration the atom 'undefined' is used. Therefore your search is for:
#fact{a=1, b='undefined', c='undefined'}
... which of course doesn't exist.
Try this instead:
lists:any(fun(#fact{a=A}) -> A =:= 1 end, L).
Or list comprehension:
OneList = [E || E <- L, E#fact.a =:= 1]

Resources