How to Simplify or Clean Up This Anagram Method

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



Leave a reply



Submit