How to look for anagrams in 1 or 2 dictionaries? - comparison

This is our code now:
#anagram is a word formed by rearranging the letters of a different word
text = open("words.txt")
counter = 0
d = {}
e = {}
for word in text:
w = word
a = list(word)
s = sorted(a)
counter += 1
d[counter] = s
e[counter] = s
print(d)
print(e)
We want to ask python to show us the words which have the same values/letters. So for example: AAB is the same as BAA.
Our file exists from:
aba
aab
acaba
ackba
abaca
casaba
Does anyone know how to program this?

Related

How do I make it look like the picture in Lua

This is my code
local level = 5
for i = 1, level do
local text = ""
for j = 1, i do
text = text..""
end
for j = 1, level-i, 1 do
text = text.." "
end
for j = 1+level, level+(level-i) do
text = text.." "
end
for j = 1, level + i-level do
text = text..""
end
print(text)
end
I want the result to be similar to the one in the picture.
Here is what your code looks like with proper formatting.
local level = 5
for i = 1, level do
local text = ""
for j = 1, i do
text = text..""
end
for j = 1, level-i, 1 do
text = text.." "
end
for j = 1+level, level+(level-i) do
text = text.." "
end
for j = 1, level + i-level do
text = text..""
end
print(text)
end
Your current code prints... well... an empty string. You haven't yet added the characters it's to display to be on par with the image.
The amount of characters per row is 9. So you ideally need 9 characters per row. You will also be incrementing the number once per row. The amount of characters per row also increases by 2; one on each side.
We can use the string.rep(string, number) function to duplicate a 'string' 'number' times. You can feed in your current level into that so it generates 1 2 or 3 depending on the line the number of times. Then you have whitespace to worry about. You can use string.rep again along with a bit of distance math to calculate the amount of whitespace you need from what you take up. Then finally throw everything together concatenated trailing with the first string and print.
local levels = 5
local columns = 9
for i=1, levels do
local str = string.rep(i, i)
local padding = columns - (#str * 2) + 1
print(str .. string.rep(" ", padding) .. str)
end

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

Why does "array[index]" return "nil"?

this problem seems very simple but I cannot find a solution for it, actually I don't even know what is wrong!!!
So basically I have this Lua code:
io.write("\nPlease provide the message to be decyphered: ")
message = io.read()
seq = #message
ffib = {}
a = 0
b = 1
c = a + b
fib = 0
while c < (seq - 10) do
fib = fib + 1
ffib[fib] = c
a = b
b = c
c = a + b
end
decyphered = ""
for i = 1,seq do
decyphered = table.concat{decyphered, message:sub(ffib[i],ffib[i])}
end
io.write("\nDecyphered message: ", decyphered, "\n\n")
and trying to access ffib[fib] returns nil. So trying to message:sub(ffib[i]... later throws an error.
When I try accessing ffib's values manually, ffib[1] for example, it works alright, it's only when trying to access it with an iterator that it screws up.
Somewhere else in my code I have this:
io.write("\nPlease provide the message to be cyphered: ")
message = io.read()
cyphered = ""
seq = #message
ffib = {}
a = 0
b = 1
c = a + b
for fib = 1,seq do
ffib[fib] = c
a = b
b = c
c = a + b
end
which is basically the same thing but instead of using a while loop, it uses a for loop, and it works just fine!
Please help me solve this I am going insane.
Alright, I figured it out!
io.write("\nPlease provide the message to be decyphered: ")
message = io.read()
seq = #message
ffib = {}
a = 0
b = 1
c = a + b
fib = 0
while c < (seq - 10) do
fib = fib + 1
ffib[fib] = c
a = b
b = c
c = a + b
end
decyphered = ""
for i = 1,seq do <--------------
decyphered = table.concat{decyphered, message:sub(ffib[i],ffib[i])}
end
io.write("\nDecyphered message: ", decyphered, "\n\n")
I was using the wrong variable in the for loop, so it was looping through the entire message length instead of the fibonacci array length, the "nil" values were indexes out of bounds!
To correct this, I simply changed seq for #ffib in that For Loop, marked by an arrow.
Thanks everyone who tried to help me anyway!
this part doesn't make much sense I think
while c < (seq - 10) do
Why the minus 10? ffib will have less entries than seq while in the loop after that you expect a value in ffib from 1 to seq
And even if you change it to
while c < seq do
Then there still won't be enough for messages larger than length 2.
If anything, you might want to do
while c < (seq + 10) do
But even there you will run into an issue when the message is a certain length.
I'm also not familiar with that algorithm, but it looks pretty weird to me and I wonder what it actually establishes

Parsing and count words from multi lines text in Lua

Say I have the multi-lines text:
str = [[
The lazy dog sleeping on the yard.
While a lazy old man smoking.
The yard never green again.
]]
I can split each words using:
for w in str:gmatch("%S+") do print(w) end
But how I can get results as an example:
The = 3 words, line 1,3
Lazy = 2 words, line 1,2
Dog = 1 word, line 1
..and so on?
Thank you
You could detect the \n using gmatch like you are already to count the words.
The pattern would be something like "[^\n]+" and the code something like this:
local str = [[
The lazy dog sleeping on the yard.
While a lazy old man smoking.
The yard never green again.
]]
local words = {}
local lines = {}
local line_count = 0
for l in str:gmatch("[^\n]+") do
line_count = line_count + 1
for w in l:gmatch("[^%s%p]+") do
w = w:lower()
words[w] = words[w] and words[w] + 1 or 1
lines[w] = lines[w] or {}
if lines[w][#lines[w]] ~= line_count then
lines[w][#lines[w] + 1] = line_count
end
end
end
for w, count in pairs(words) do
local the_lines = ""
for _,line in ipairs(lines[w]) do
the_lines = the_lines .. line .. ','
end
--The = 3 words, line 1,3
print(w .." = " .. count .. " words , lines " .. the_lines)
end
Full output, note i also changed the pattern you used for capturing the words to "[^%s%p]+" i did this to remove the . that was getting attached to smoking, again, and yard.
smoking = 1 words , lines 2,
while = 1 words , lines 2,
green = 1 words , lines 3,
never = 1 words , lines 3,
on = 1 words , lines 1,
lazy = 2 words , lines 1,2,
the = 3 words , lines 1,3,
again = 1 words , lines 3,
man = 1 words , lines 2,
yard = 2 words , lines 1,3,
dog = 1 words , lines 1,
old = 1 words , lines 2,
a = 1 words , lines 2,
sleeping = 1 words , lines 1,

Minimum Change Maker Returning Optimal Solution and No Solution

I need Help adding a if clause to my Change Maker, so that if say I have denominations of coins that can't equal the input coin value. For Example I have Coins worth 2,4,6 and I have a Value of 1. I Want it to return Change Not Possible I tried adding a clause to it below but when I test it I get 1.#INF
I also am curious how I can find the optimal coin solution, So on top of saying the minimum number of coins it returns the optimal coin setup if there is one.
function ChangeMaking(D,n)
--[[
//Applies dynamic programming to find the minimum number of coins
//of denominations d1< d2 < . . . < dm where d1 = 1 that add up to a
//given amount n
//Input: Positive integer n and array D[1..m] of increasing positive
// integers indicating the coin denominations where D[1]= 1
//Output: The minimum number of coins that add up to n
]]
F = {} -- F is List Array of Coins
m = tablelength(D)
F[0] = 0
for i =1,n do
temp = math.huge
j = 1
while j <= m and i >= D[j] do
temp = math.min(F[ i - D[j] ], temp)
j = j + 1
end
F[i] = temp + 1
end
--I wanted to Catch the failed Solution here but I return 1.#INF instead
--if F[n] <= 0 and F[n] == 1.#INF then print("No Change Possible") return end
return F[n]
end
function main()
--[[
//Prints a Greeting, Asks for Denominations separated by spaces.
// Iterates through the input and assigns values to table
// Table is then input into ChangeMaker, and a while loop takes an n value for user input.
// User Enters 0 to end the Loop
]]
io.write("Hello Welcome the to Change Maker - LUA Edition\nEnter a series of change denominations, separated by spaces: ")
input = io.read()
deno = {}
for num in input:gmatch("%d+") do table.insert(deno,tonumber(num)) end
local i = 1
while i ~= 0 do
io.write("Please Enter Total for Change Maker, When Finished Enter 0 to Exit: ")
input2 = io.read("*n")
if input2 ~= 0 then io.write("\nMinimum # of Coins: " .. ChangeMaking(deno,input2).."\n") end
if input2 == 0 then i=0 print("0 Entered, Exiting Change Maker") end
end
end
function tablelength(T)
--[[
//Function for grabbing the total length of a table.
]]
local count = 0
for _ in pairs(T) do count = count + 1 end
return count
end
main()

Resources