function table_merge(t1, t2)
for _, v in ipairs(t2) do
table.insert(t1, v)
end
end
function getMaster(tbl, rules)
local result = false
for _, rule in ipairs(rules) do
for i, v in ipairs(tbl) do
result = v
if tostring(v) ~= tostring(rule) then
result = false
break
end
end
if result then break end
end
return result
end
function start(data, rules)
local master_key, master_val
local _temp, continue = {}, true
for i, tbl in ipairs(data) do
local master = getMaster(tbl, rules)
if master and master ~= master_val then
continue = true
end
if continue then
if master then
master_key = i
master_val = master
elseif tbl[#tbl] == master_val then
tbl[#tbl] = nil
table.insert(_temp[master_key], master_val)
elseif master_key then
continue = false
end
end
_temp[i] = tbl
end
local result = {}
for i, tbl in ipairs(_temp) do
table_merge(result, tbl)
end
return table.concat(result, "")
end
-- RULES
local rules = { 0, 1}
local data = {
{ 0, 0, 0, 0, 0, 0 },
{ 1, 1, 1, 1, 1, 0 },
{ 0, 0, 0, 8, 1, 0 },
{ 1, 1, 1, 1, 8, 8 },
{ 0, 0, 0, 0, 0, 0 },
}
start(data, rules)
OUTPUT:
000000001111100081111188000000
The expected results should be this:
000000001111110008111188000000
How do I achieve the required results? the table can contain more than six elements but initially it is six. so when all the elements are 1, it will check the next immediate Table to see if the last element is also one; if true it removes it and adds to the six making seven, it will then check again for the next immediate table if the last digit is 1, if true it removes that also and adds to the seven making 8. It will check again and if false return to where it left. So here the table whose element were removed become five in number.
So I was hoping that they could satisfy the rule also if all the five elemnts are 1 or 0. But it seems only the six elements satisfy the rule...
I hope it's clear Thanks
function table_merge(t1, t2)
for _, v in ipairs(t2) do
table.insert(t1, v)
end
end
function getMaster(tbl, rules, w)
local result = false
for _, rule in ipairs(rules) do
for i = 1, w do
local v = tbl[i]
result = v
if tostring(v) ~= tostring(rule) then
result = false
break
end
end
if result then break end
end
return result
end
function start(data, rules)
local width = #data[1] -- assuming all data rows have the same width
local master_keys = {}
local master_values = {}
local continue_idx = width + 1
for i, tbl in ipairs(data) do
for w = width, 1, -1 do
if w >= continue_idx and tbl[w] == master_values[w] then
table.insert(data[master_keys[w]], master_values[w])
tbl[w] = nil
else
local master = getMaster(tbl, rules, w)
if master then
master_keys[w] = i
master_values[w] = master
continue_idx = w
else
continue_idx = w + 1
end
break
end
end
end
local result = {}
for i, tbl in ipairs(data) do
table_merge(result, tbl)
end
return table.concat(result, "")
end
-- RULES
local rules = { 0, 1 }
local data = {
{ 0, 0, 0, 0, 0, 0 },
{ 1, 1, 1, 1, 1, 0 },
{ 0, 0, 0, 8, 1, 0 },
{ 1, 1, 1, 1, 8, 8 },
{ 0, 0, 0, 0, 0, 0 },
}
print(start(data, rules))
Related
So, i have a script where i am inputting 3 words in a string and putting them into a small table and i only need this script to print a new table i can copy and paste, so i just need to print what the table would look like this is the script currently have
local tbl = {
{1, "", 0},
{2, "", 0},
{3, "", 0}
}
local input = "i hate debugging"
local words = {}
x = 0
repeat
x = x + 1
for i, v in ipairs(tbl) do
if tonumber(v[1]) == x then
for word in input:gmatch"[^ ,\r\n]+" do
table.insert(words, word)
end
end
end
until x == 1
and the desired output should look like this
{1, "i", 0},
{2, "hate", 0},
{3, "debugging", 0},
The question isn't very clear, and OP goal is not clear, but it seems that you may want something like this:
local tbl = {
{ 1, "", 0 },
{ 2, "", 0 },
{ 3, "", 0 }
}
local input = "i hate debugging"
local nextWord = input:gmatch"[^ ,\r\n]+"
for k, t in ipairs(tbl) do
t[2] = nextWord() or ""
end
-- Display updated `tbl`
print("updated tbl")
for k, v in ipairs(tbl) do
print(string.format('{ %d, "%s", %d },', v[1], v[2], v[3]))
end
gmatch returns an iterator, so you can just call this iterator repeatedly to get successive matches. You can loop over tbl, calling the iterator each time to set the string. When the iterator is out of matches it will return nil, so the code sets the string to "" when the iterator is exhausted.
Program output:
updated tbl
{ 1, "i", 0 },
{ 2, "hate", 0 },
{ 3, "debugging", 0 },
Creating A New Table From Input
OP has clarified in a comment that a new table should be created from the input. Here is a function createWordTable that creates and returns a fresh table from a string of words. The printWordTable function is just a utility function to show the contents of a word table.
function createWordTable(wordString)
local wordTbl = {}
local i = 1
for w in wordString:gmatch"[^ ,\r\n]+" do
wordTbl[i] = { i, w, 0 }
i = i + 1
end
return wordTbl
end
function printWordTable(wordTbl)
for k, v in ipairs(wordTbl) do
print(string.format('{ %d, %s, %d }', v[1], v[2], v[3]))
end
end
Sample interaction:
> wtbl = createWordTable("one, two, three")
> printWordTable(wtbl)
{ 1, one, 0 }
{ 2, two, 0 }
{ 3, three, 0 }
> wtbl = createWordTable("one, two, three, four, five")
> printWordTable(wtbl)
{ 1, one, 0 }
{ 2, two, 0 }
{ 3, three, 0 }
{ 4, four, 0 }
{ 5, five, 0 }
I don't know where to put the variables.
local frontflips, backflips = 0, 0
local upVector = cv.DesiredCF.UpVector
local lastDirection = "None"
-- local process = "None" -- FRontflip or backflip
local physics; physics = game:GetService("RunService").Heartbeat:Connect(function()
local lookVector = cart.PrimaryPart.CFrame.LookVector
local dotProduct = lookVector:Dot(upVector)
if ( math.abs(dotProduct) < .3) then
--// Facing downwards
if (lastDirection == "backflip") then
backflips = backflips + 1
frontflips = math.clamp(frontflips - 1, 0, 10)
elseif lastDirection == "frontflip" then
frontflips = frontflips + 1
backflips = math.clamp(backflips - 1, 0, 10)
end
lastDirection = "None"
elseif (dotProduct > .8) and lastDirection == "None" then
--// In the process of a back-flip
lastDirection = "backflip"
elseif dotProduct < -.8 and lastDirection == "None" then
lastDirection = "frontflip"
end
-- warn("Dot is ",dotProduct, " and ",lastDirection)
end)
When I do 1 frontflip it tells me
But now when I do 2 frontflips it tells me I only did 1.
If I remove the
frontflips = math.clamp(frontflips - 1, 0, 10)
and
backflips = math.clamp(backflips - 1, 0, 10)
then when I do 2 frontflips
the result tells me
I have performed 2 frontflips and 1 backflip.
local seq = { 1, 2, 3, 4, 5 } -- obviously, it's a sequence.
local non_seq = { 1, 2, 3, nil, 5 } -- but it's not.
The defination about sequence: The Length Operator
This question is in chapter 5 of Programming in Lua 4st.
Any comments I would greatly appreciate
You linked the information you need for your answer.
A border in Lua 5.3 is defined as:
(border == 0 or t[border] ~= nil) and t[border + 1] == nil
A proper sequence can only contain one border. However to cover some other condition the code does require a bit more leg work, such as validating the index can be in a sequence.
function is_sequence(t)
local borders = 0
if t[1] ~= nil then -- all sequences must start at 1.
for index in pairs(t) do
if natural_index(index) and t[index + 1] == nil then
borders = borders + 1
if borders > 1 then
break
end
end
end
end
return borders == 1 or valid_no_borders(t) and borders == 0
end
function natural_index(index)
return type(index) == "number" and index > 0 and math.floor(index) == index
end
function valid_no_borders(t)
result = true
for k in pairs(t) do
if natural_index(k) then
result = false
break
end
end
return t[1] == nil and result
end
-- Tests
local seqs = {
{ 1, 2, 3, 4, 5 }, -- obviously, it's a sequence.
{ 1, 2, 3, 4, ["potato"] = 5 },
{ 1, 2, [3.3] = 3 },
{ [2.2] = 2 },
{ [-1] = -1, [0] = 0, 1, 2, 3 },
{},
}
for _, v in ipairs(seqs) do
print("seq: ", is_sequence(v))
end
local non_seqs ={
{ 1, 2, 3, nil, 5 }, -- but it's not.
{ [2] = 2 },
}
for _, v in ipairs(non_seqs) do
print("non_seq: ", is_sequence(v))
end
Results
seq: true
seq: true
seq: true
seq: true
seq: true
seq: true
non_seq: false
non_seq: false
This method has the benefit of only evaluating each element once and exiting as early as possible if the table is not a valid sequence.
There might be a better way, but the first thing I could come up with would look something like this:
local function sequence(tab)
local border
for index in ipairs(tab) do
border = index
end
for index in pairs(tab) do
if type(index)=="number" and index > border then
return false
end
end
end
The problem is that you need to iterate over the table twice; the first time up to the first border, then either until the first integer key larger than the first border, or through the entire table if it is indeed a sequence.
As #Nifim pointed out, you can also implement the definition directly. A slightly improved version of their answer:
local function natural(value)
return type(value)=="number" and value >= 1 and value % 1 == 0
end
local function sequence(tab)
-- 0 can be a border even when it's nil
if tab[1] == nil then
for index in pairs(tab) do
if natural(index) then
return false
end
end
else
local border = false
for index in pairs(tab) do
if natural(index) and tab[index+1]==nil then
if border then
return false
else
border = true
end
end
end
end
return true
end
All you need to do is check if the array part of the table has any holes.
local function isSequence(t)
for k in pairs(t) do
-- Is k an integer greater than 1 whose previous value is nil?
if
type(k) == 'number' and k == math.floor(k) and k > 1 and t[k - 1] == nil
then
return false
end
end
return true
end
If you detect an integer key greater than 1 whose previous value is nil, then the table must have at least 2 borders, making it an invalid sequence. One is somewhere between 0 and that key, and the other is somewhere after that key.
How can i update a key value using another key value as variable which is inside the same table?
local t = {}
t.playerPosition = {x = 0, y = 0, z = 0}
t.positions = {t.playerPosition.x + 1, t.playerPosition.y + 1, t.playerPosition.z + 1}
Then few lines later i update playerPosition
t.playerPosition = {x = 125, y = 50, z = 7}
And then if i print out...
result
t.positions[1] -- outputs 1
t.positions[2] -- outputs 1
t.positions[3] -- outputs 1
expected result
t.positions[1] -- outputs 126
t.positions[2] -- outputs 51
t.positions[3] -- outputs 8
As you can see key positions isnt updating, what could i do to make it possible?
t.positions = {t.playerPosition.x + 1, t.playerPosition.y + 1, t.playerPosition.z + 1}
In the above line, the expressions are evaluated once, and the resulting values are assigned to fields of the subtable. After this point, changes to the fields of t.playerPosition will not cause a reflected change in t.positions.
Metatables can be used to enable such behaviour, by dynamically calculating results when accessing the fields of t.positions.
local t = {}
t.playerPosition = { x = 0, y = 0, z = 0 }
t.positions = setmetatable({}, {
__newindex = function () return false end,
__index = function (_, index)
local lookup = { 'x', 'y', 'z' }
local value = t.playerPosition[lookup[index]]
if value then
return value + 1
end
end
})
print(t.positions[1], t.positions[2], t.positions[3])
t.playerPosition = {x = 125, y = 50, z = 7}
print(t.positions[1], t.positions[2], t.positions[3])
In my game I've made a feature where you can sprint.
I've separated the animation part of the script from the main sprinting part.
I got the error message "Workspace.Vlo_tz.SprintingAnimation:19: Expected ')' (to close '(' at column 29), got ','".
This code is for the animation of the character and the sprinting bar
local UIS = game:GetService('UserInputService')
local Player = game.Players.LocalPlayer
local Character = Player.Character
local players = game:GetService("Players")
local stamina = players.LocalPlayer.PlayerGui.StaminaHealth.MainFrame.Stamina
UIS.InputBegan:connect(function(input)
local humanoid = Player.Character.Humanoid
if input.KeyCode == Enum.KeyCode.LeftShift and humanoid:GetState() == Enum.HumanoidStateType.RunningNoPhysics and humanoid.MoveDirection.Magnitude > 0 then
local Anim = Instance.new('Animation')
Anim.AnimationId = 'rbxassetid://05168161960'
PlayAnim = Character.Humanoid:LoadAnimation(Anim)
PlayAnim:Play()
while true do
wait(0.05)
if stamina.Position <= (-0.343, 0, 0.274, 0) then
stamina.Position = UDim2.new(-0.343, 0, 0, 0)
else
stamina.Position = stamina.Position - UDim2.new(0.01, 0, 0, 0)
end
end
end
end)
UIS.InputEnded:connect(function(input)
if input.KeyCode == Enum.KeyCode.LeftShift then
PlayAnim:Stop()
while true do
wait(0.005)
if stamina.Position >= (0.487, 0, 0.274, 0) then
stamina.Position = UDim2.new(0.487, 0, 0, 0)
else
stamina.Position = stamina.Position + UDim2.new(0.01, 0, 0, 0)
end
end
end
end)
local humanoid = Player.Character.Humanoid
if humanoid.MoveDirection.Magnitude == 0 then
PlayAnim:Stop()
while true do
wait(0.005)
if stamina.Position >= (0.487, 0, 0.274, 0) then
stamina.Position = UDim2.new(0.487, 0, 0, 0)
else
stamina.Position = stamina.Position + UDim2.new(0.01, 0, 0, 0)
end
end
end
Line 19 is this : if stamina.Position <= (-0.343, 0, 0.274, 0) then
You have this check in a few different places, but this is not valid lua and you cannot compare UDim2 values like this. You'll have to inspect the values individually.
local isLessThanX = stamina.Position.X.Scale <= -0.343
local isLessThanY = stamina.Position.Y.Scale <= 0.274
if isLessThanX and isLessThanY then