I have an array of arrays. I'm trying to go through each array in my main array and compare the index's against variables. If they are larger than the variables I want to delete that array from the parent array. At the minute when I run the below code when comparing against b, it works the first time and deletes the array but doesn't seem to run again and delete the rest of the arrays where index > b. Any help appreciated.
The following function should print 14 but currently it's printing 16.
a = 4
b = 2
c = 5
n = 5
def count_configurations(a, b, c, n)
a = (0..a).to_a
b = (0..b).to_a
c = (0..c).to_a
big = [a.max, b.max, c.max].max
big = (0..big).to_a
arrays = big.repeated_permutation(3).to_a
solutions = []
arrays.each do |array|
sum = 0
array.each { |a| sum+=a }
if sum == n
solutions << array
end
end
solutions = solutions.uniq
solutions.each do |solution|
if solution[0] > a.max
solutions.delete(solution)
end
end
solutions.each do |solution|
if solution[1] > b.max
solutions.delete(solution)
end
end
solutions.each do |solution|
if solution[2] > c.max
solutions.delete(solution)
end
end
puts solutions.count
end
Assuming solutions contains the proper array, here you go, instead of three each loops:
solutions = solutions.uniq.reject do |solution|
solution[0] > a.max || solution[1] > b.max || solution[2] > c.max
end
Details: Enumerable#reject.
Related
I made a class that represents a matrix using a multidimensional array. The initialize method goes through every position and sets the value of the elements to the one specified, and the to_s method does the same but it just concatenates every element to a string. I'm writing an insert method that changes the value of the element of a given position to a given value, but it changes a whole value instead of just an element.
class Matrix
attr_accessor :rows, :cols, :arr
# Goes through the matrix setting everything with the "n" value
def initialize(r, c, n = "a")
#rows = r
#cols = c
#arr = Array.new(#rows)
tmpArray = Array.new(#cols)
i = 0
while i < #rows
j = 0
while j < #cols
tmpArray[j] = n
j += 1
end
#arr[i] = tmpArray
i += 1
end
return #arr
end
def to_s
i = 0
str = String.new
while i < #rows
j = 0
str << "("
while j < #cols
str << " "
if #arr[i][j].is_a?String
str << #arr[i][j]
else
str << #arr[i][j].to_s
end
j += 1
end
str << " )\n"
i += 1
end
return str
end
# Calls and prints to_s
def write
print self.to_s
return self.to_s
end
# Rewrites the element (r, c) as the value in "n"
def insert(r, c, n)
#arr[r][c] = n
self.write
return self
end
end
The thing is that, when I print the matrix I notice that I didn't change just an element, but a whole column of the matrix.
a = Matrix.new(2, 2, 0)
a.insert(0, 0, 1)
a.write
# Expected output: ( 1 0 )
# ( 0 0 )
# Real output: ( 1 0 )
# ( 1 0 )
The to_s method isn't failing. I already made a trace of it and tested it. I'm printing the real values that are in the positions of the matrix.
Your program calls Array.new only twice, and it doesn't create arrays using any other methods, and it doesn't use dup or clone to copy any arrays. Therefore, you only have two different array objects in your program. Each element of #arr actually points to the same row array.
One idea for a solution would be to replace this line:
#arr[i] = tmpArray
with this:
#arr[i] = tmpArray.dup
However, your code is pretty long and I have not tried running it, so I do not know if that would be a complete solution.
I have a question regarding indexing and loops in MATLAB. I have a vector of length n (named data in the code below). I want to examine this vector 4 elements at a time inside of a for loop. How can I do this? My attempt included below does not work because it will exceed the array dimensions at the end of the loop.
for k = 1:length(data)
index = k:k+3;
cur_data = data(index);
pre_q_data1 = cur_data(1);
pre_q_data2 = cur_data(2);
% Interweaving the data
q = [pre_q_data1; pre_q_data2];
qdata = q(:)';
pre_i_data1 = cur_data(3);
pre_i_data2 = cur_data(4);
i = [pre_i_data1; pre_i_data2];
idata = i(:)';
end
You shouldn't have k go all the way to length(data) if you're planning on indexing up to k+3.
I've also taken the liberty of greatly simplifying your code, but feel free to ignore that!
for k = 1:length(data)-3
% maximum k = length(data)-3, so maximum index = length(data)-3+3=length(data)
index = k:k+3;
cur_data = data(k:k+3);
% Interweaving the data
q = cur_data(1:2); % transpose at end of line here if need be
i = cur_data(3:4); % could just use data(k+2:k+3) and not use cur_data
end
Sorry if this is a dumb question, I'm a fairly inexperienced programmer.
I'm trying to return all values within an array using Lua. I can return individual elements by calling their index (ex. read_data[2]) but since the number of elements in the array is variable, I cannot simply type this out. My code:
function readformatEvent()
local read_data = {}
local duplicate
local unique_data = {}
for i=1,16 do
read_data[i] = readResult(i):readData()
end
for i=1,16 do
duplicate = 0
for j=(i+1),15 do
if read_data[i] == read_data[j] then
duplicate = 1
end
end
if duplicate == 0 then
unique_data[i] = read_data[i]
end
end
return unique_data
end
unique_data is an array consisting of unique values from the array read_data. read_data can consist of 1 to 16 elements. Being able to see the full array would help me continue to craft the code as a troubleshooting technique.
Thank you,
A short example of what you could do:
-- some example table
t = {1,2,4,5,1,2,7,8,5,4,9,3}
-- for every value v in t
for k,v in pairs(t) do
-- check v vs all remaining values in t
for m,w in pairs(t) do
-- but not vs v itself
if k ~= m then
-- remove any non unique values from t
if w == v then
t[m] = nil
t[k] = nil
end
end
end
end
-- print the result
for k,v in pairs(t) do
print(v)
end
Thanks for all the help. Here is the code that ended up working. I'm sure it's not efficient, but I'm getting the correct output now.
function readformatEvent()
function readformatEvent()
local read_data = {}
local unique_data = {}
local count = 1
local output = ""
local codes = readResult():readCount()
--create array from captured read data
for i=1,16 do
read_data[i] = readResult(i):readData()
end
--turn 2nd duplicate in the array into a nil value
for k,v in pairs(read_data) do
for m,w in pairs(read_data) do
if k ~= m then
if w == v then
read_data[m] = nil
end
end
end
end
--remove the nils from the array
for i=1,16 do
if read_data[i] ~= nil then
unique_data[count] = read_data[i]
count = count+1
end
end
--output unique values in correct format
if count == 12 and codes == 16 then
count = count - 1
else
count = count - 2
end
for i=1,count-1 do
output = output..unique_data[i]..", "
end
return output..unique_data[count]
end
I have 2 cell arrays which are "celldata" and "data" . Both of them store strings inside. Now I would like to check each element in "celldata" whether in "data" or not? For example, celldata = {'AB'; 'BE'; 'BC'} and data={'ABCD' 'BCDE' 'ACBE' 'ADEBC '}. I would like the expected output will be s=3 and v= 1 for AB, s=2 and v=2 for BE, s=2 and v=2 for BC, because I just need to count the sequence of the string in 'celldata'
The code I wrote is shown below. Any help would be certainly appreciated.
My code:
s=0; support counter
v=0; violate counter
SV=[]; % array to store the support
VV=[]; % array to store the violate
pairs = ['AB'; 'BE'; 'BC']
%celldata = cellstr(pairs)
celldata = {'AB'; 'BE'; 'BC'}
data={'ABCD' 'BCDE' 'ACBE' 'ADEBC '} % 3 AB, 2 BE, 2 BC
for jj=1:length(data)
for kk=1:length(celldata)
res = regexp( data(jj),celldata(kk) )
m = cell2mat(res);
e=isempty(m) % check res array is empty or not
if e == 0
s = s + 1;
SV(jj)=s;
v=v;
else
s=s;
v= v+1;
VV(jj)=v;
end
end
end
If I am understanding your variables correctly, s is the number of cells which the substring AB, AE and, BC does not appear and v is the number of times it does. If this is accurate then
v = cellfun(#(x) length(cell2mat(strfind(data, x))), celldata);
s = numel(data) - v;
gives
v = [1;1;3];
s = [3;3;1];
Say that I have an empty array as follows:
s=[];
Say that for instance we have the following loop:
for j=1:2
for i=1:10
if a(i,j)>0
...
end
end
end
Instead of ..., I want to add elements to s. How do you do that in MatLab?
I would recommend you avoid loops altogether. They are slow in MATLAB.
Let's say you want to set all values in S(i,j) to 1 that correspond to A(i,j) > 0. You could do:
S = zeros(size(A)); % always a good idea to initialize your array
S(A > 0) = 1; % and done.
More succinctly:
S = A > 0;
This specifies that you are changing the values of S to 1 corresponding to those values of A where A > 0.
If you want to set the value of S to the corresponding value of A then you would just use:
S = A(A > 0);
Keep track of another index and just add elements as you go along:
idx = 1
for j=1:2
for i=1:10
if a(i,j)>0
s(idx) = a(i,j)
idx = idx + 1
end
end
end
Though for your particular problem, you could just write
a(a>0)