Lua: 'for' loop problems (string.gsub) - lua

I'm making a lua script for custom encrypting a string, but I can't find a loop that substitutes the letter to a number correspondent to the alphabet table.
It must return something like this:
"hello"
> 8, 4, 12, 12, 15
That'll be the first part of the encryption proccess but I can't program such a loop, any help? (Script below:)
local text = "what"
local key = math.random(100000, 500000)
local pie = math.pi
local n = 26
local alpha = { a = 1, b = 2, c = 3, d = 4, e = 5, f = 6 , g = 7, h = 8, i = 9, j = 10,
k = 11, l = 12, m = 13, n = 14, o = 15, p = 16, q = 17, r = 18, s = 19, t = 20, u = 21, v = 22, w = 23, x = 24, y = 25, z = 26}
function enumerate(str)
return str:gsub("%l", function(c) return c.char(c:byte()-96) end):byte(1,-1)
end
UPDATE: New question, how do I return the numbers as:
46, 68, 46, 32, 4, 12, 18, 15, 23, 32, 15, 23, 5, 8
Instead of a string or with whitespaces:
"46 68 46 32 4 12 18 15 23 32 15 23 5 8"

You just have to collect each char on a table with explode + encode (see below) and then call unpack (or table.unpack) to get a tuple.
First explode:
function explode(str)
local ret = {}
for c in str:gmatch(".") do
table.insert(ret, c)
end
return ret
end
The encoding part can be done this way:
local BASE_CHAR = ("a"):byte()
function encode(c)
return c:byte() - BASE_CHAR + 1
end
Putting everything together:
unpack = unpack or table.unpack -- Handling lua 5.1 or higher
function enumerate(str) -- Keeping the original name
local exploded = {}
for i, c in ipairs(explode(str)) do
exploded[i] = encode(c)
end
return unpack(exploded)
end
And a test:
print(enumerate("test"))
Which yields the following result:
20 5 19 20
Note:
I prefer to keep results in table and only unpack if necessary. This way you can manipulate the table the way you want and it's more convenient than dealing with tuples:
function enumerate(str) -- Keeping the original name
local exploded = {}
for i, c in ipairs(explode(str)) do
exploded[i] = encode(c)
end
return exploded
end
print(unpack(enumerate("test")))
And if you want a string:
print(table.concat(enumerate("test"), ", "))
Hope this solves the problem

Related

Lua Logitech - Sensitivity adjustment

Good day to everyone.
I want to create a "No Recoil" scenario with the ability to specify my own aiming sensitivity value.
At the moment, the code that you can see below works exclusively with one setting, namely with the dpi800 and the in-game sensitivity on the X and Y axes equal to 7, is it possible to make it so that I can change literally two digits, for example, not 7, but 9 or 10 and so on, and the script changed using some formula values in line 7(r_p["Weapon1"]) and 8(r_p["Weapon2"])
local r_p = {Weapon1}
local r_o = r_p[o_s_a] or {Weapon2}
local o_s_a = "Weapon2"
local n_o_s_a = {Weapon2 = "Weapon1", Weapon1 = "Weapon2"}
r_p["Weapon1"] = {0, 0, 0, 0, 25, 100, -1, 17, 600, -1, 20, 500, -1, 21, 800}
r_p["Weapon2"] = {0, 0, 0, 0, 22, 150, -1, 17, 400, -1, 20, 700, -1, 20, 300, -1, 20, 150, -2, 21, 400, -2, 21, 550, -2, 21, 300, -2, 21, 250, -2, 21, 100}
function Log()
if not IsKeyLockOn("scrolllock") then
ClearLog()
OutputLogMessage("Current mode: List of weapons | Scroll lock is OFF\n\n")
OutputLogMessage("Selected: %s\n\n", o_s_a)
OutputLogMessage(" (%s) | Weapon1 (%s) | Weapon2\n\n", o_s_a == "Weapon1", o_s_a == "Weapon2")
end
end
function OnEvent(event, arg)
EnablePrimaryMouseButtonEvents(true)
if event == "MOUSE_BUTTON_PRESSED" and arg == 5 and IsModifierPressed("lctrl") and not IsKeyLockOn("scrolllock") then
o_s_a = n_o_s_a[o_s_a]
r_o = r_p[o_s_a] or {}
Log()
else if event == "MOUSE_BUTTON_PRESSED" and arg == 1 and IsMouseButtonPressed(3) and not IsKeyLockOn("capslock") then
for xy = 3, #r_o, 3 do
local c_t = GetRunningTime()
local h_r = r_o[xy-2]
local v_r = r_o[xy-1]
local r_d = r_o[xy]
repeat
local d_t = GetRunningTime() - c_t, r_d
MoveMouseRelative(h_r, v_r)
Sleep(10)
until d_t >= r_d or not IsMouseButtonPressed(1) or not IsMouseButtonPressed(3)
if not IsMouseButtonPressed(1) or not IsMouseButtonPressed(3) then break end
end
end
end
end
I tried using multiplayer, but in this version you can use only 2 values, where sensitivity 12 is standard, when you activate multiplayer, all your sensitivity settings are divided by 2 and as a result you get sensitivity 6, but this is a bit not the option that I need.
Thank you very much for any help if all.
You can modify the values on-the-fly instead of changing values in lines 7(r_p["Weapon1"]) and 8(r_p["Weapon2"]).
Replace the following lines
local h_r = r_o[xy-2]
local v_r = r_o[xy-1]
with
local h_r = round(r_o[xy-2] * sens / 6)
local v_r = round(r_o[xy-1] * sens / 6)
where sens is a variable with default value 6, but you can modify it.
round is a function, define it before OnEvent:
function round(x)
return math.floor(x + 0.5)
end
sens = 6
UPDATE:
The solution above has a drawback: due to rounding errors, the cursor gradually shifts to the left and/or to the top.
The solution below accumulates fractional parts to avoid such shift.
Define the function MoveMouseRelativeFractional which accepts fractional arguments and use it instead of the standard MoveMouseRelative.
The definition should be inserted at the very beginning of the whole script:
local remainder_fractional_x, remainder_fractional_y = 0, 0
local function MoveMouseRelativeFractional(x, y)
x = remainder_fractional_x + x
y = remainder_fractional_y + y
local x_int = math.floor(x + 0.5)
local y_int = math.floor(y + 0.5)
remainder_fractional_x = x - x_int
remainder_fractional_y = y - y_int
MoveMouseRelative(x_int, y_int)
end
Remove round:
local h_r = r_o[xy-2] * sens / 13
local v_r = r_o[xy-1] * sens / 13
Replace MoveMouseRelative with MoveMouseRelativeFractional:
MoveMouseRelativeFractional(h_r, v_r)

Lua shuffle with repeating cycle

Having some Lua trouble with a a modification of Fisher-Yates shuffle in place. For example, let's say I have a 16 item table (sequence). I want to shuffle integers 1-4 then apply the shuffled pattern in the table to 1-4, 5-8, 9-12, 13-16. So:
{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }
with a 4 item shuffling pattern of 4,2,3,1 would become:
{ 4, 2, 3, 1, 8, 6, 7, 5, 12, 10, 11, 9, 16, 14, 15, 13 }
The code here is from context and includes the "rising edge" input I am using to reshuffle. If you look at the test pic below you can see that yes, it shuffles each section in place, but it reshuffles each section -- I want the shuffled pattern to repeat.
t = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}
range = 4
local function ShuffleInPlace(t)
for i = #t, 2, -1 do
local j = math.random(1, range)
local k = (math.floor(i/(range+.001)))*range + j
t[i], t[j] = t[j], t[i]
end
end
-- initialize new table for shuffling
if s == nil then s = {} end
-- use gate rising edge to shuffle
if prev == nil then prev = 0 end
if gate > 0 and prev <= 0 then
s = t
ShuffleInPlace(s)
end
prev = gate
Test pic:
LMD, thank you, your helpful reply is uncovering a solution (by creating the shuffled "pattern" sequence first, outside the iterator). (Still some issues with the first value I'm working out. And I might be looking at some biproducts of the not-so-great math.random function, but that's another story). I'm a novice so any suggestions are appreciated!
-- range input is 0 to 1
seqRange = math.floor(range*(#t*.99))
local function ShuffleRange(x)
if rdm == nil then rdm = {} end
for m = 1, x do rdm[m] = m end
for m = #rdm, 2, -1 do
local j = math.random(m)
rdm[m], rdm[j] = rdm[j], rdm[m]
return rdm[m]
end
end
local function ShuffleInPlace(t)
y = ShuffleRange(seqRange)
for i = #t, 2, -1 do
local j = (math.floor(i/(seqRange*1.001)))*seqRange + y
t[i], t[j] = t[j], t[i]
end
end
Here's how I would do it, implementing the simple approach of first generating a series of swaps and then applying that to the sublists of length n:
math.randomseed(os.time()) -- seed the random
local t = {}; for i = 1, 16 do t[i] = i end -- build table
local n = 4 -- size of subtables
local swaps = {} -- list of swaps of offsets (0-based)
for i = 0, n - 1 do
-- Insert swap into list of swaps to carry out
local j = math.random(i, n - 1)
table.insert(swaps, {i, j})
end
-- Apply swaps to every subtable from i to i + n
for i = 1, #t, n do
for _, swap in ipairs(swaps) do
-- Swap: First add offsets swap[1] & swap[2] respectively
local a, b = i + swap[1], i + swap[2]
t[a], t[b] = t[b], t[a]
end
end
print(table.concat(t, ", "))
Example output: 4, 2, 1, 3, 8, 6, 5, 7, 12, 10, 9, 11, 16, 14, 13, 15

How to update/reload table key values

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])

Lua loop shuffle list

i have a problem with my Script if i try to loop thought my list the output is completly random shuffled
minimal Code:
list = {
numbers = {
number1 = 1,
number2 = 2,
number3 = 3,
number4 = 4,
number5 = 5,
number6 = 6,
number7 = 7,
}
}
for k, numbers in pairs(list) do
for k, number in pairs(numbers) do
print(number)
end
end
output:
5
7
2
3
4
6
1
the only fix i figured out is to remove the variables number1 to number7
and just enter the numbers
Lua tables do not have an order.
In addition to that you're using pairs which internally uses next.
From the Lua manual:
The order in which the indices are enumerated is not specified, even
for numeric indices. (To traverse a table in numerical order, use a
numerical for.)
In your case the keys have a numeric component so you could simply create them in a numeric loop.
local numbers = {
number1 = 1,
number2 = 2,
number3 = 3,
number4 = 4,
number5 = 5,
number6 = 6,
number7 = 7,
}
for i = 1, 7 do
print(numbers["number"..i])
end
For other non-numeric keys you would have to use a second table that lists the keys in an ordered sequence:
local numbers = { bob = 1, bill = 3, john = 2}
local orderedKeys = { "bob", "john", "bill"}
for k,v in ipairs(orderedKeys) do
print(numbers[v])
end
A numeric loop will always work for any integer keys.
local numbers = {
[0] = 0,
[5] = 5,
[3] = 3,
[1] = 0,
}
for i = 0, 5 do
if numbers[i] then
print(numbers[i])
end
end
Read through this carefully:
A table with exactly one border is called a sequence. For instance,
the table {10, 20, 30, 40, 50} is a sequence, as it has only one
border (5). The table {10, 20, 30, nil, 50} has two borders (3 and 5),
and therefore it is not a sequence. (The nil at index 4 is called a
hole.) The table {nil, 20, 30, nil, nil, 60, nil} has three borders
(0, 3, and 6) and three holes (at indices 1, 4, and 5), so it is not a
sequence, too. The table {} is a sequence with border 0. Note that
non-natural keys do not interfere with whether a table is a sequence.
Things like ipairs, the length operator #, table.sort, table.concat and others only work with sequences.
Keys that do not contribute to the sequence are ignored by those functions. You can only loop over all keys of a table with next or pairs respectively. But then order is not guaranteed.

Splitting an interger into an array

I need to split the integer into an array.
For example,
The integer variable a equals 48.
a = 48
I need to split the 48 into an array based on the count of 10.
I need to get the array as below,
arr = [ 10, 20, 30, 40, 48]
EDIT:-
I tried following code and it work fine.
max = 48
arr = []
j = 0
for i in 1..max
if i % 10 == 0
arr[j] = i
j = j + 1
end
end
if max % 10 != 0
arr[j] = max
end
p arr
# => [10, 20, 30, 40, 48]
But if I have a bignum integer it will take more time. Is there any built-in method to this like a split for string.
I know the split method and also I know how to split the string into an array based one the character available in the string. but I don't know how to use the split method splitting the integer into an array based on the count.
Any one please explain me how to do this ?
Thanks in advance!
Starting with a = 48 then try:
(10..a).step(10).to_a.push(a) #=> [10, 20, 30, 40, 48]
Using Range#step to increment the range by steps of ten before converting to an array and finally appending your value of a. Alternatively you can also write:
10.step(a,10).to_a << a #=> [10, 20, 30, 40, 48]
You can try this
a = 48
array = []
(1..a/10).each{|x| array.push(x*10)}
a%10 != 0 ? array.push(a) : array
#=> [10, 20, 30, 40, 48]
I suggest this solution feel free to change some code mistakes since im not familiar with ruby :
$a = 48
$num = 10
array = Array.new
while $num < $a do
array << $num
$num +=10
end
array << $a
You can use map and lambda in this case.
a = 48
arr = ((1..a/10).map(&->(x){x*10}) << a).uniq
p arr
# => [10, 20, 30, 40, 48]
For all elements in Range (1..a/10) (in this case 1..4), map method call lambda function. This lambda have one argument and return x*10 (for first element 1*10 # => 10) and add all results to the array.
I hope this helps.

Resources