How long will it take for a program to print a truth table for n propositional symbols?
(Symbols: P1, P2, ..., Pn)
Can't seem to crack this question, not quite sure how to calculate this instance.
It will take time proportional to at least n*2^n. Each of the propositional symbols can assume one of two values - true or false. The portion of the truth table that lists all possible assignments of n such variables must have at least 2 * 2 * … * 2 (n times) = 2^n rows of n entries each; and that's not even counting the subexpressions that make up the rest of the table. This lower bound is tight since we can imagine the proposition P1 and P2 and … and Pn and the following procedure taking time Theta(n*2^n) to write out the answer:
fill up P1's column with 2^(n-1) TRUE and then 2^(n-1) FALSE
fill up P2's column with 2^(n-2) TRUE and then 2^(n-2) FALSE, alternating
…
fill up Pn's column with 1 TRUE and 1 FALSE, alternating
fill up the last column with a TRUE at the top and FALSE all the way down
If you have more complicated propositions then you should probably take the number of subexpressions as another independent variable since that could have an asymptotically relevant effect (using n propositional symbols, you can have arbitrarily many unique subexpressions that must be given their own columns in a complete truth table).
Related
The reference manual has this to say about the table.move function, introduced in Lua 5.3:
table.move (a1, f, e, t [,a2])
Moves elements from table a1 to table a2, performing the equivalent to the following multiple assignment: a2[t],··· = a1[f],···,a1[e]. The default for a2 is a1. The destination range can overlap with the source range. The number of elements to be moved must fit in a Lua integer.
This description leaves a lot to be desired. I'm hoping for a general, canonical explanation of the function that goes into more detail than the reference manual. (Oddly, I could not find such an explanation anywhere on the web, perhaps because the function is fairly new.)
Particular points I am still confused on after reading the reference manual's explanation a few times:
When it says "move", that means the items are being removed from their original location, correct? Do the indices of items above the removed items shift down to fill the gaps? If so, and we're moving within the same table, does t point to the original location before anything starts moving?
Is there some significance to the choice of index letters f, e, and t?
There is no similar function in any other language I know. What's an example of how I might use this? Since it's one of only seven table functions, I presume it's quite useful.
Moves elements from table a1 to table a2, performing the equivalent to the following multiple assignment a2[t],··· = a1[f],···,a1[e]
Maybe they could have added the information this is done using consecutive integer values from f to e.
If you know Lua a bit more you'll know that a Lua table has no order. So the only way to make that code work is to use consecutive integer keys. Especially as the documentation mentions a source range.
Giving the equivalent syntax is the most unambiguous way of describing a function.
If you know the very basic concept of multiple assignment in Lua (see 3.3.3. Assignment) , you know what this function does.
table.move(a1, 1, 4, 6, a2) would copy a1[1], a1[2], a1[3], a1[4] into a2[6], a2[7], a2[8], a2[9]
The most common usecase is probably to get a subset of a list.
local values = {1,45,1,44,123,2354,321,745,1231}
old syntax:
local subset = {}
for i = 3, 7 do
table.insert(subset, values[i])
end
new:
local subset = table.move(values, 5, 7, 1, {})
Or maybe you quickly want to remove the last 3 values from a table?
local a = {1,2,3,4,5,6,7}
table.move({}, 1,3,#a-2, a)
if a table of N integer is present how to check if an element is repeating if present it shows message that table has repeating elements, if this is to be achieved in minimum time complexity
Hash table is the way to go (ie normal Lua table). Just loop over each integer and place it into the table as the key but first check if the key already exists. If it does then you have a repeat value. So something like:
values = { 1, 2, 3, 4, 5, 1 } -- input values
local htab = {}
for _, v in ipairs(values) do
if htab[v] then print('duplicate value: ' .. v)
else htab[v] = true end
end
With small integer values the table will use an array so will be O(1) to access. With larger and therefore sparser values the values will be in the hash table part of the table which can just be assumed to be O(1) as well. And since you have N values to insert this is O(N).
Getting faster than O(N) should not be possible since you have to visit each value in the list at least once.
I am trying to bulk insert multiple records simultaneously into a KDB+ database:
> trades:([]time:`datetime$();side:`symbol$();qty:`float$();price:`float$();exch:`symbol$();sym:`symbol$())
> t: .z.z / intentionally the same time
> `trades insert (t t;`buy `sell;10 10;10 10;`exch `exch;`sym `sym)
However It raises an error at the sym column
'sym
[0] `depths insert (t t;`buy `sell;10 10;10 10; `exch `exch;`sym `sym)
^
Have no Idea what I could be doing wrong here, but it seems to be value invariant i.e. it always raises an error on the last column irrespective of the value provided.
Could someone please advise me how I should go about inserting bulk records into kdb+ with an time index as depicted above.
Thanks
In your original insert statement, you had spaces between
`sym `sym
,
`exch `exch
and `buy `sell. The spaces between the symbols makes it an apply or index instead of a list which you desire.
Additionally, because you have specified your qty and price as
float
, you would have to specify the numbers as float when you are inserting to the
trades
table.
The following line should accomplish what you are intending to do:
`trades insert (2#t;`buy`sell;10 10f;10 10f;`exch`exch;`sym`sym)
Lastly, I would recommend changing the schema for the qtycolumn to int/long, as quantity generally does not require decimal points.
Hope this helps!
Daniel is on the money. To expand on his answer, q will collate space-separated lists into a single object for numeric values, and even then the type specification must be only present for the last item. Further details on list creation can be found here.
q)a:10f 10f
'10f
q)a:10 10f
Secondly, it's common for those learning kdb to often encounter type errors when appending to tables. The problem in this case is that kdb is not promoting a list of homogeneous atoms to a wider type (which is expected behaviour). The following is a useful little lambda for letting you know where you are going wrong when performing insert or upsert operations:
q)trades:([]time:`datetime$();side:`symbol$();qty:`float$();price:`float$();exch:`symbol$();sym:`symbol$())
q)rows:(t,t;`buy`sell;10 10;10 10;`exch`exch;`sym`sym)
q)insertTest:{[tab;rows] m:0!meta tab; wh: where not m[`t] ~' rt:.Q.ty each rows; #[flip;;enlist] `item`currType`expectedType!(m[`c] wh;rt wh; m[`t] wh)}
item currType expectedType
---------------------------
qty j f
price j f
from fig we can see that Arsenal have won three match consecutively but I could not write the query.
Here is a query that should return the maximum number of consecutive wins for Arsenal:
MATCH (a:Club {name:'Arsenal FC'})-[r:played_with]-(:Club)
WITH ((CASE a.name WHEN r.home THEN 1 ELSE -1 END) * (TOINT(r.score[0]) - TOINT(r.score[1]))) > 0 AS win, r
ORDER BY TOINT(r.time)
RETURN REDUCE(s = {max: 0, curr: 0}, w IN COLLECT(win) |
CASE WHEN w
THEN {
max: CASE WHEN s.max < s.curr + 1 THEN s.curr + 1 ELSE s.max END,
curr: s.curr + 1}
ELSE {max: s.max, curr: 0}
END
).max AS result;
The WITH clause sets the win variable to true iff Arsenal won a particular game. Notice that the ORDER BY clause converts the time property to an integer, because the ordering of numeric strings does not work properly if the strings could be of different lengths (I am being a bit picky here, admittedly). The REDUCE function is used to calculate the maximum number of consecutive wins.
======
Finally, here are some suggestions for some improvements to your data model. For example:
It looks like your played_with relationship always points from the home team to the away team. If so, you can get rid of the redundant home and away properties, and you can also rename the relationship type to HOSTED to make the direction of the relationship more clear.
The scores and time should be stored as integers, not strings. That would make your queries more efficient, and easier to write and understand.
You could also consider splitting the scores property into two scalar properties, say homeScore and awayScore, which would make your code more clear. There seems to be no advantage to storing the scores in an array.
If you made all the above suggested changes, then you would just need to change the beginning of the above query to this:
MATCH (a:Club {name:'Arsenal FC'})-[r:HOSTED]-(:Club)
WITH ((CASE a WHEN STARTNODE(r) THEN 1 ELSE -1 END) * (r.homeScore - r.awayScore)) > 0 AS win, r
ORDER BY r.time
...
I have data consisting of n key-value pairs in a table, A
I'd like to produce another table, B of size (n+1) x (n+1), where the first row/column are the keys of the original table, and entry (i,j) is some function of the ith and jth value
Ex:
A:
K|V
---
a 1
b 2
c 3
B:
a b c
a f(1,1) f(1,2) f(1,3)
b f(2,1) f(2,2) f(2,3)
c f(3,1) f(3,2) f(3,3)
Depends on the function you need. Assuming B2:B4 contains {1,2,3} , The following can be done. Each will use different functions and will add or subtract in different ways. The first one is the only one, that'll work in the exact way you asked, but that's just for Matrix multiplication - You could maybe use that as base and do other functions on it as needed.
=ARRAYFORMULA(MMULT(--(B2:B4), --TRANSPOSE(B2:B4)))
=ARRAYFORMULA((--(B2:B4)/--TRANSPOSE(B2:B4)))
=ARRAYFORMULA((--(B2:B4)+--TRANSPOSE(B2:B4)))
=ARRAYFORMULA((--(B2:B4)---TRANSPOSE(B2:B4)))