How to count the number of repetitions for every single number? - lua

So I have a for loop that loops 100 times and each time it generates a random number from 1 to 100. For some statistics, I need to count how many times each number repeats. I have no idea how to make it other than manually.
One = 0
Two = 0
Three = 0
Four = 0
Five = 0
for i=1, 100 do
number = GetRandomNumber(1, 5, 1.5)
if number == 1 then
One = One + 1
elseif number == 2 then
Two = Two + 1
elseif number == 3 then
Three = Three + 1
elseif number == 4 then
Four = Four + 1
elseif number == 5 then
Five = Five + 1
end
end
This is how I currently count, but I don't want to manually type for every number. How can I make this simpler?

I do it as such:
number_counter, number = {}, 0
for i = 1, 100 do
number = GetRandomNumber(1, 5, 1.5)
if number_counter[number] then
number_counter[number] = number_counter[number] + 1
else
number_counter[number] = 1
end
end
This is, of course, assuming there are no half points (not sure what the 1.5 is for). Then you can just call number_counter[#] to see what its value is.

Related

Filter the first n cases in SPSS based on condition

I have a database in SPSS structured like the following table:
ID
Gender
Age
Var1
Var...
1
0
7
3
...
2
1
8
4
...
3
1
9
5
...
4
1
9
2
...
I want to select only the first n (e.g.: 150) cases, where Gender = 1 and Age = 9, so in the table above the 3. and 4. case. How can I do it? Thanks!
compute filter_ = $sysmis.
compute counter_ = 0.
if $casenum=1 and (Gender = 1 and Age = 9) counter_ =1 .
do if $casenum <> 1.
if ~(Gender = 1 and Age = 9) counter_ = lag(counter).
if (Gender = 1 and Age = 9) counter_ = lag(counter) +1.
end if.
compute filter_ = (Gender = 1 and Age = 9 and counter<= 150).
execute.
I am not sure if this is the most efficient way, but it gets the job done. We use the counter_ variable to assign an order number for each record which satisfies the condition ("counting" records with meet the criteria, from the top of the file downwards). Then create a filter of the first 150 such records.
The below will select the first 150 cases where gender=1 AND age=9 (assuming 150 cases meet that criteria).
N 150.
SELECT IF (Gender=1 AND Age=9).
EXE .
Flipping the order of N and SELECT IF () would yield the same result. You can read more about N in the IBM documentation

A better way on improving my roman numeral decoder

Quick explanation, I have recently started using codewars to further improve my programming skills and my first challenge was to make a roman numeral decoder, I went through many versions because I wasnt satisfied with what I had, So I am asking if there is an easier way of handling all the patterns that roman numerals have, for example I is 1 but if I is next to another number it takes it away for example V = 5 but IV = 4.
here is my CODE:
function Roman_Numerals_Decoder (roman)
local Dict = {I = 1, V = 5, X = 10, L = 50, C = 100, D = 500, M = 1000}
local number = 0
local i = 1
while i < #roman + 1 do
local letter = roman:sub(i,i) -- Gets the current character in the string roman
if roman:sub(i,i) == "I" and roman:sub(i + 1,i + 1) ~= "I" and roman:sub(i + 1,i + 1) ~= "" then -- Checks for the I pattern when I exists and next isnt I
number = number + (Dict[roman:sub(i +1,i + 1)] - Dict[roman:sub(i,i)]) -- Taking one away from the next number
i = i + 2 -- Increase the counter
else
number = number + Dict[letter] -- Adds the numbers together if no pattern is found, currently checking only I
i = i + 1
end
end
return number
end
print(Roman_Numerals_Decoder("MXLIX")) -- 1049 = MXLIX , 2008 = MMVIII
at the moment I am trying to get 1049 (MXLIX) to work but I am getting 1069, obviously I am not following a rule and I feel like its more wrong then it should be because usually if its not correct its 1 or 2 numbers wrong.
The algorithm is slightly different: you need to consider subtraction when the previous character has less weight than the next one.
function Roman_Numerals_Decoder (roman)
local Dict = {I = 1, V = 5, X = 10, L = 50, C = 100, D = 500, M = 1000}
local num = 0
local i = 1
for i=1, #roman-1 do
local letter = roman:sub(i,i) -- Gets the current character in the string roman
local letter_p = roman:sub(i+1,i+1)
if (Dict[letter] < Dict[letter_p]) then
num = num - Dict[letter] -- Taking one away from the next number
print("-",Dict[letter],num)
else
num = num + Dict[letter] -- Adds the numbers together if no pattern is found, currently checking only I
print("+",Dict[letter],num)
end
end
num = num + Dict[roman:sub(-1)];
print("+",Dict[roman:sub(-1)], num)
return num
end
print(Roman_Numerals_Decoder("MXLIX")) -- 1049 = MXLIX , 2008 = MMVIII

Torch: Concatenating tensors of different dimensions

I have a x_at_i = torch.Tensor(1,i) that grows at every iteration where i = 0 to n. I would like to concatenate all tensors of different sizes into a matrix and fill the remaining cells with zeroes. What is the most idiomatic way to this. For example:
x_at_1 = 1
x_at_2 = 1 2
x_at_3 = 1 2 3
x_at_4 = 1 2 3 4
X = torch.cat(x_at_1, x_at_2, x_at_3, x_at_4)
X = [ 1 0 0 0
1 2 0 0
1 2 3 0
1 2 3 4 ]
If you know n and assuming you have access to your x_at_i easily at each iteration I would try something like
X = torch.Tensor(n, n):zero()
for i = 1, n do
X[i]:narrow(1, 1, i):copy(x_at[i])
end

Torch tensors swapping dimensions

I came across these two lines (back-to-back) of code in a torch project:
im4[{1,{},{}}] = im3[{3,{},{}}]
im4[{3,{},{}}] = im3[{1,{},{}}]
What do these two lines do? I assumed they did some sort of swapping.
This is covered in indexing in the Torch Tensor Documentation
Indexing using the empty table {} is shorthand for all indices in that dimension. Below is a demo which uses {} to copy an entire row from one matrix to another:
> a = torch.Tensor(3, 3):fill(0)
0 0 0
0 0 0
0 0 0
> b = torch.Tensor(3, 3)
> for i=1,3 do for j=1,3 do b[i][j] = (i - 1) * 3 + j end end
> b
1 2 3
4 5 6
7 8 9
> a[{1, {}}] = b[{3, {}}]
> a
7 8 9
0 0 0
0 0 0
This assignment is equivalent to: a[1] = b[3].
Your example is similar:
im4[{1,{},{}}] = im3[{3,{},{}}]
im4[{3,{},{}}] = im3[{1,{},{}}]
which is more clearly stated as:
im4[1] = im3[3]
im4[3] = im3[1]
The first line assigns the values from im3's third row (a 2D sub-matrix) to im4's first row and the second line assigns the first row of im3 to the third row of im4.
Note that this is not a swap, as im3 is never written and im4 is never read from.

Lua with calculator script

I'm trying to create a calculator for my own use . I don't know how to make it so that when the user inputs e.g. 6 for the prompt lets the user type in 6 numbers. So if I wrote 7 , it would give me an option to write 7 numbers and then give me the answer, And if i wrote 8 it will let me write 8 numbers...
if choice == "2" then
os.execute( "cls" )
print("How many numbers?")
amountNo = io.read("*n")
if amountNo <= 2 then print("You cant have less than 2 numbers.")
elseif amountNo >= 14 then print("Can't calculate more than 14 numbers.")
elseif amountNo <= 14 and amountNo >= 2 then
amountNmb = amountNo
if amountNmb = 3 then print(" Number 1")
print("Type in the numbers seperating by commas.")
local nmb
print("The answer is..")
The io.read formats are a bit limiting.
If you want a comma-separated list to be typed, I suggested reading a whole line and then iterating through each value:
local line = io.input("*l")
local total = 0
-- capture a sequence of non-comma chars, which then might be followed by a comma
-- then repeat until there aren't any more
for item in line:gmatch("([^,]+),?") do
local value = tonumber(item)
-- will throw an error if item does not represent a number
total = total + value
end
print(total)
This doesn't limit the count of values to any particular value—even an empty list works. (It is flawed in that it allows the line to end with a comma, which is ignored.)
From what I understand, you want the following:
print "How many numbers?"
amountNo = io.read "*n"
if amountNo <= 2 then
print "You can't have less than 2 numbers."
elseif amountNo >= 14 then
print "Can't calculate more than 14 numbers."
else
local sum = 0
for i = 1, amountNo do
print( ('Enter number %s'):format(i) )
local nmb = io.read '*n'
sum = sum + nmb
end
print( ('The sum is: %s'):format(sum) )
end
If the user separates the numbers with commas, they don't need to state how many they want to add, you can just get them all with gmatch. Also with the right pattern you can ensure you only get numbers:
local line = io.input()
local total = 0
-- match any number of digits, skipping any non-digits
for item in line:gmatch("(%d+)") do
total = total + item
end
With input '4 , 6 , 1, 9,10, 34' (no quotes), then print(total) gives 64, the correct answer

Resources