Splitting an interger into an array - ruby-on-rails

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.

Related

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

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.

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

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

How do I split a string given an array of split positions?

I'm using Ruby 2.4 and Rails 5. I have an array of indexes within a line
[5, 8, 10]
How do I take the above array, and a string, and form anotehr array of strings that are split by the above indexes? FOr instance, if the string is
abcdefghijklmn
and split it based ont eh above indexes, I would have an array with the following strings
abcde
fgh
ij
klmn
Try this
str = "abcdefghijklmn"
positions = [5, 8, 10]
parts = [0, *positions, str.size].each_cons(2).map { |a, b| str[a...b] }
# => ["abcde", "fgh", "ij", "klmn"]
Or,
If the positions are constant and known ahead of runtime (for example if they were the format for a phone number or credit card) just use a regexp
str.match(/(.....)(...)(..)(.*)/).captures
# => ["abcde", "fgh", "ij", "klmn"]
This will get the Job done
str = "abcdefghijklmn"
arr_1 = [5, 8, 10]
arr_2, prev = [], 0
(arr_1.length + 1).times do |x|
if arr_1[x] == nil then arr_1[x] = str.size end
arr_2 << str[prev..arr_1[x] -1]
prev = arr_1[x]
end
p arr_2
---------------------------------------
Program Run Output
["abcde", "fgh", "ij", "klmn"]
---------------------------------------
I hope this Helps

Sequence of numbers with multiples of 10

I want show numbers in dropdown like 0,10,20,30,40,60,70
For it I write
0..70
But it generate all numbers from 0 to 70 .I want only multiples of 10
Take a look at Numeric.step.
0.step(70,10).to_a
In addition to Numeric.step
0.step(70,10).to_a
you can also use Range#step:
Range.new(0,70).step(10).to_a
(0..70).step(10).to_a
You could create a new Enumerator for this:
multiples_of_10 = Enumerator.new do |y|
x = 0
loop do
y << x
x += 10
end
end
multiples_of_10.take(8) # => [0, 10, 20, 30, 40, 50, 60, 70]

Resources