How can I simplify or clean up this anagram method?
test_words.group_by{|w| w.each_char.sort}.values
would give
[
["cars", "racs", "scar"],
["for"],
["potatoes"],
["four"],
["creams", "scream"]
]
Not able to solve anagram by group?
Here is how you can do it :
str = "scream cars for four scar creams"
str.split.group_by{|a| a.chars.sort}.select{|k,v| v.size > 1 }.values
# => [["scream", "creams"], ["cars", "scar"]]
Check the characters inside two strings are the same in Ruby
You could do like this:
a = 'scar'
b = 'cars'
a.chars.sort == b.chars.sort
# => true
a = 'cars'
b = 'carcass'
a.chars.sort == b.chars.sort
# => false
times function's values changes outside the loop
An easy/simple way to do this I think is as below:
array = []
4.times do |e|
e = e + 1
array << e
end
p array.join(',')
output: "1,2,3,4"
The above will print all the items separated by a comma, also this might be helpful join docs
Check how many character need to be deleted to make an anagram in Python
You can use collections.Counter
for this:
from collections import Counter
def makeAnagram(a, b):
return sum((Counter(a) - Counter(b) | Counter(b) - Counter(a)).values())
Counter(x)
(where x is a string) returns a dictionary that maps characters to how many times they appear in the string.
Counter(a) - Counter(b)
gives you a dictionary that maps characters which are overabundant in b
to how many times they appear in b
more than the number of times they appear in a
.
Counter(b) - Counter(a)
is like above, but for characters which are overabundant in a
.
The |
merges the two resulting counters. We then take the values of this, and sum them to get the total number of characters which are overrepresented in either string. This is equivalent to the minimum number of characters that need to be deleted to form an anagram.
As for why your code doesn't work, I can't pin down any one problem with it. To obtain the code below, all I did was some simplification (e.g. removing unnecessary variables, looping over a and b together, removing == True
and == False
, replacing t
with a set
, giving variables descriptive names, etc.), and the code began working. Here is that simplified working code:
def makeAnagram(a, b):
c = 0 # count of characters to be deleted to make these two strings anagrams
seen = set() # set of previously checked characters
for character in a + b:
if character not in seen:
seen.add(character)
c += abs(a.count(character) - b.count(character))
return c
I recommend you make it a point to learn how to write simple/short code. It may not seem important compared to actually tackling the algorithms and getting results. It may seem like cleanup or styling work. But it pays off enormously. Bug are harder to introduce in simple code, and easier to spot. Oftentimes simple code will be more performant than equivalent complex code too, either because the programmer was able to more easily see ways to improve it, or because the more performant approach just arose naturally from the cleaner code.
How to anagram digit in python?
Your solution has a few problems, aside from the indentation and the missing colon.
First of all your are using print
which automatically adds a line break, so that might not be what you want the result to look like. You could store the result in a string which you append the latest character to and then print it once at the end.
Further, you are using a variable s
which was never used before. In thise case it should be a
as you want to strip off the last digit using an integer division by 10. Note that in this case, this will only work like that in Python 2, as Python 3 will use a float division there (e.g. 15 / 10 == 1.5
). You can prevent that by explicitly using the integer division there (this will also make your intend more clear): s = s // 10
(note the two slashes).
Lastly, you are incrementing the variable i
without ever using it, so you can just get rid of it.
In the end, it might look like this:
def reverse (a):
rev = ''
while a > 1:
rev += str(a % 10)
a = a // 10
A shorter solution, utilizing the fact that you can just reverse strings:
>>> num = 123
>>> rev = int(str(num)[::-1])
>>> rev
321
If you leave out the int()
, you can even keep trailing/leading zeros and get a string instead:
>>> num = 3210
>>> str(num)[::-1]
'0123'
Why does destroying two different mainloop windows on tkinter freeze the program?
Try only import tkinter as tk more often since it's better for the namespace. This answer is for addressing your EDIT.
import tkinter as tk
def clock(root):
global rootA
def countdown(time):
if time == -1:
destroyer() #invokes the destroy function
else:
if time == 0:
label.configure(text="TIME UP!")
else:
label.configure(text="Time remaining: %d seconds" % time)
rootA.after(1000, countdown, time-1)
rootA = tk.Toplevel(root) #Made it a tk.Toplevel instead of a new root
rootA.protocol("WM_DELETE_WINDOW", destroyer) #set the window close protocol
rootA.title("COUNTDOWN CLOCK")
label = tk.Label(rootA, width=30)
label.pack(padx=20, pady=20)
countdown(15)
class AnswerEntry(tk.Tk):
def __init__(self):
super().__init__() #I changed tk.Tk.__init__(self) to this
self.title("REMEMBER TO PRESS THE BUTTONS!") #I placed them here since they are the same thing
self.geometry("500x150")
self["bg"] = "aquamarine"
self.protocol("WM_DELETE_WINDOW", destroyer)
self.anagram = tk.Label(self, text="Your anagram solution", bg="light cyan", font=(None, 15), width=18, height=2, anchor=tk.E)
self.numerics = tk.Label(self, text="Player number (1 or 2)", bg="light cyan", font=(None, 14), width=19, height=2, padx=4, anchor=tk.E)
self.anagram.grid(row=1, sticky=tk.E, pady=1)#Changed all your 'W' and 'E'... to 'tk.W' and 'tk.E'
self.numerics.grid(row=2, padx=(7,0), pady=5)
self.solution = tk.Text(self, height=2, width=17,font=(None,15))
self.number = tk.Text(self, height=2, width=17, font=(None, 15))
self.solution.grid(row=1, column=1)
self.number.grid(row=2, column=1)
self.button1 = tk.Button(self, text=" SUBMIT YOUR NAME ", bg="cyan", fg="black", width=20, height=1, font=(None, 11), anchor=tk.W, command=self.answer)
self.button2 = tk.Button(self, text="SUBMIT PLAYER NUMBER ", bg="cyan", fg="black", font=(None, 11), padx=3, command=self.the_number)
self.button1.grid(row=100, column=1, sticky=tk.E)
self.button2.grid(row=100, column=0, sticky=tk.W)
def answer(self):
global playerAnswer
playerAnswer = self.solution.get('1.0', tk.END)
def the_number(self):
global playerNumber
playerNumber = self.number.get('1.0', tk.END)
def destroyer():
rootA.destroy() #When the window closes
root.destroy()
if __name__ == '__main__':
root = AnswerEntry()
clock(root)
root.mainloop()
please write a new question next time so more people could get to it. Since your EDIT was a completely different question.
Related Topics
Upsert Multiple Records with Mongodb
Ruby Converting Utc to User's Time Zone
Why Is My Ruby Git Script Hook Run with the Wrong $Path
How to Make a Ruby Script Using Trollop for Command Line Parsing
How to Include Ё in [А-Я] Regexp Char Interval
Ruby Class Object Garbage Collection
Trouble Installing Ruby 1.9.2 with Rvm MAC Os X
Rails - X-Sendfile + Temporary Files
Post Redirect Get Pattern in Rails
How to Get Gmail Oauth or Xauth Tokens with Omniauth
Best Way to Find_Or_Create_By_Id But Update the Attributes If the Record Is Found
Using Passphrase Callback in Ruby Gpgme
Scoping Date Attribute for This Week
Ruby: Too Many Open Files @ Rb_Sysopen