Python Brute Forcer? - python

I had a general idea in mind for a way to brute force a password, but being just a python novice, i'm not sure where to go from here...
So far I have the following:
password = "myPaSs123"
ll = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]
ul = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]
n = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]
s = ["!", "#", "#", "$", "%", "^", "&"]
full = ll+ul+n+s
crackedPass = []
def guesser():
guess = 0
for i in full:
for x in range(len(password)):
if i == password:
crackedPass.append(i)
print "Password found: " + str(crackedPass)
guesser()
I now have no clue what to do from here. If someone has some insight to this topic, I would love any help. Thank you!

You could try something like this but will NOT be efficient:
def all_combinations_with_len(lst,min_len,max_len):
for i in xrange(min_len,max_len+1):
for j in list(itertools.product(*([lst]*i))):
yield j
Then you can use:
list(all_combinations_with_len(['a','b','c'],2,5))
[('a', 'a'), ('a', 'b'), ('a', 'c'), ('b', 'a'), ('b', 'b'), ('b', 'c'), ('c', 'a'), ('c', 'b'), ('c', 'c'), ('a', 'a', 'a'), ('a', 'a', 'b'), ('a', 'a', 'c'), ('a', 'b', 'a'), ('a', 'b', 'b'), ('a', 'b', 'c'), ('a', 'c', 'a'), ('a', 'c', 'b'), ('a', 'c', 'c'), ('b', 'a', 'a'), ('b', 'a', 'b'), ('b', 'a', 'c'), ('b', 'b', 'a'), ('b', 'b', 'b'), ('b', 'b', 'c'), ('b', 'c', 'a'), ('b', 'c', 'b'), ('b', 'c', 'c'), ('c', 'a', 'a'), ('c', 'a', 'b'), ('c', 'a', 'c'), ('c', 'b', 'a'), ('c', 'b', 'b'), ('c', 'b', 'c'), ('c', 'c', 'a'), ('c', 'c', 'b'), ('c', 'c', 'c'), ('a', 'a', 'a', 'a'), ('a', 'a', 'a', 'b'), ('a', 'a', 'a', 'c'), ('a', 'a', 'b', 'a'), ('a', 'a', 'b', 'b'), ('a', 'a', 'b', 'c'), ('a', 'a', 'c', 'a'), ('a', 'a', 'c', 'b'), ('a', 'a', 'c', 'c'), ('a', 'b', 'a', 'a'), ('a', 'b', 'a', 'b'), ('a', 'b', 'a', 'c'), ('a', 'b', 'b', 'a'), ('a', 'b', 'b', 'b'), ('a', 'b', 'b', 'c'), ('a', 'b', 'c', 'a'), ('a', 'b', 'c', 'b'), ('a', 'b', 'c', 'c'), ('a', 'c', 'a', 'a'), ('a', 'c', 'a', 'b'), ('a', 'c', 'a', 'c'), ('a', 'c', 'b', 'a'), ('a', 'c', 'b', 'b'), ('a', 'c', 'b', 'c'), ('a', 'c', 'c', 'a'), ('a', 'c', 'c', 'b'), ('a', 'c', 'c', 'c'), ('b', 'a', 'a', 'a'), ('b', 'a', 'a', 'b'), ('b', 'a', 'a', 'c'), ('b', 'a', 'b', 'a'), ('b', 'a', 'b', 'b'), ('b', 'a', 'b', 'c'), ('b', 'a', 'c', 'a'), ('b', 'a', 'c', 'b'), ('b', 'a', 'c', 'c'), ('b', 'b', 'a', 'a'), ('b', 'b', 'a', 'b'), ('b', 'b', 'a', 'c'), ('b', 'b', 'b', 'a'), ('b', 'b', 'b', 'b'), ('b', 'b', 'b', 'c'), ('b', 'b', 'c', 'a'), ('b', 'b', 'c', 'b'), ('b', 'b', 'c', 'c'), ('b', 'c', 'a', 'a'), ('b', 'c', 'a', 'b'), ('b', 'c', 'a', 'c'), ('b', 'c', 'b', 'a'), ('b', 'c', 'b', 'b'), ('b', 'c', 'b', 'c'), ('b', 'c', 'c', 'a'), ('b', 'c', 'c', 'b'), ('b', 'c', 'c', 'c'), ('c', 'a', 'a', 'a'), ('c', 'a', 'a', 'b'), ('c', 'a', 'a', 'c'), ('c', 'a', 'b', 'a'), ('c', 'a', 'b', 'b'), ('c', 'a', 'b', 'c'), ('c', 'a', 'c', 'a'), ('c', 'a', 'c', 'b'), ('c', 'a', 'c', 'c'), ('c', 'b', 'a', 'a'), ('c', 'b', 'a', 'b'), ('c', 'b', 'a', 'c'), ('c', 'b', 'b', 'a'), ('c', 'b', 'b', 'b'), ('c', 'b', 'b', 'c'), ('c', 'b', 'c', 'a'), ('c', 'b', 'c', 'b'), ('c', 'b', 'c', 'c'), ('c', 'c', 'a', 'a'), ('c', 'c', 'a', 'b'), ('c', 'c', 'a', 'c'), ('c', 'c', 'b', 'a'), ('c', 'c', 'b', 'b'), ('c', 'c', 'b', 'c'), ('c', 'c', 'c', 'a'), ('c', 'c', 'c', 'b'), ('c', 'c', 'c', 'c'), ('a', 'a', 'a', 'a', 'a'), ('a', 'a', 'a', 'a', 'b'), ('a', 'a', 'a', 'a', 'c'), ('a', 'a', 'a', 'b', 'a'), ('a', 'a', 'a', 'b', 'b'), ('a', 'a', 'a', 'b', 'c'), ('a', 'a', 'a', 'c', 'a'), ('a', 'a', 'a', 'c', 'b'), ('a', 'a', 'a', 'c', 'c'), ('a', 'a', 'b', 'a', 'a'), ('a', 'a', 'b', 'a', 'b'), ('a', 'a', 'b', 'a', 'c'), ('a', 'a', 'b', 'b', 'a'), ('a', 'a', 'b', 'b', 'b'), ('a', 'a', 'b', 'b', 'c'), ('a', 'a', 'b', 'c', 'a'), ('a', 'a', 'b', 'c', 'b'), ('a', 'a', 'b', 'c', 'c'), ('a', 'a', 'c', 'a', 'a'), ('a', 'a', 'c', 'a', 'b'), ('a', 'a', 'c', 'a', 'c'), ('a', 'a', 'c', 'b', 'a'), ('a', 'a', 'c', 'b', 'b'), ('a', 'a', 'c', 'b', 'c'), ('a', 'a', 'c', 'c', 'a'), ('a', 'a', 'c', 'c', 'b'), ('a', 'a', 'c', 'c', 'c'), ('a', 'b', 'a', 'a', 'a'), ('a', 'b', 'a', 'a', 'b'), ('a', 'b', 'a', 'a', 'c'), ('a', 'b', 'a', 'b', 'a'), ('a', 'b', 'a', 'b', 'b'), ('a', 'b', 'a', 'b', 'c'), ('a', 'b', 'a', 'c', 'a'), ('a', 'b', 'a', 'c', 'b'), ('a', 'b', 'a', 'c', 'c'), ('a', 'b', 'b', 'a', 'a'), ('a', 'b', 'b', 'a', 'b'), ('a', 'b', 'b', 'a', 'c'), ('a', 'b', 'b', 'b', 'a'), ('a', 'b', 'b', 'b', 'b'), ('a', 'b', 'b', 'b', 'c'), ('a', 'b', 'b', 'c', 'a'), ('a', 'b', 'b', 'c', 'b'), ('a', 'b', 'b', 'c', 'c'), ('a', 'b', 'c', 'a', 'a'), ('a', 'b', 'c', 'a', 'b'), ('a', 'b', 'c', 'a', 'c'), ('a', 'b', 'c', 'b', 'a'), ('a', 'b', 'c', 'b', 'b'), ('a', 'b', 'c', 'b', 'c'), ('a', 'b', 'c', 'c', 'a'), ('a', 'b', 'c', 'c', 'b'), ('a', 'b', 'c', 'c', 'c'), ('a', 'c', 'a', 'a', 'a'), ('a', 'c', 'a', 'a', 'b'), ('a', 'c', 'a', 'a', 'c'), ('a', 'c', 'a', 'b', 'a'), ('a', 'c', 'a', 'b', 'b'), ('a', 'c', 'a', 'b', 'c'), ('a', 'c', 'a', 'c', 'a'), ('a', 'c', 'a', 'c', 'b'), ('a', 'c', 'a', 'c', 'c'), ('a', 'c', 'b', 'a', 'a'), ('a', 'c', 'b', 'a', 'b'), ('a', 'c', 'b', 'a', 'c'), ('a', 'c', 'b', 'b', 'a'), ('a', 'c', 'b', 'b', 'b'), ('a', 'c', 'b', 'b', 'c'), ('a', 'c', 'b', 'c', 'a'), ('a', 'c', 'b', 'c', 'b'), ('a', 'c', 'b', 'c', 'c'), ('a', 'c', 'c', 'a', 'a'), ('a', 'c', 'c', 'a', 'b'), ('a', 'c', 'c', 'a', 'c'), ('a', 'c', 'c', 'b', 'a'), ('a', 'c', 'c', 'b', 'b'), ('a', 'c', 'c', 'b', 'c'), ('a', 'c', 'c', 'c', 'a'), ('a', 'c', 'c', 'c', 'b'), ('a', 'c', 'c', 'c', 'c'), ('b', 'a', 'a', 'a', 'a'), ('b', 'a', 'a', 'a', 'b'), ('b', 'a', 'a', 'a', 'c'), ('b', 'a', 'a', 'b', 'a'), ('b', 'a', 'a', 'b', 'b'), ('b', 'a', 'a', 'b', 'c'), ('b', 'a', 'a', 'c', 'a'), ('b', 'a', 'a', 'c', 'b'), ('b', 'a', 'a', 'c', 'c'), ('b', 'a', 'b', 'a', 'a'), ('b', 'a', 'b', 'a', 'b'), ('b', 'a', 'b', 'a', 'c'), ('b', 'a', 'b', 'b', 'a'), ('b', 'a', 'b', 'b', 'b'), ('b', 'a', 'b', 'b', 'c'), ('b', 'a', 'b', 'c', 'a'), ('b', 'a', 'b', 'c', 'b'), ('b', 'a', 'b', 'c', 'c'), ('b', 'a', 'c', 'a', 'a'), ('b', 'a', 'c', 'a', 'b'), ('b', 'a', 'c', 'a', 'c'), ('b', 'a', 'c', 'b', 'a'), ('b', 'a', 'c', 'b', 'b'), ('b', 'a', 'c', 'b', 'c'), ('b', 'a', 'c', 'c', 'a'), ('b', 'a', 'c', 'c', 'b'), ('b', 'a', 'c', 'c', 'c'), ('b', 'b', 'a', 'a', 'a'), ('b', 'b', 'a', 'a', 'b'), ('b', 'b', 'a', 'a', 'c'), ('b', 'b', 'a', 'b', 'a'), ('b', 'b', 'a', 'b', 'b'), ('b', 'b', 'a', 'b', 'c'), ('b', 'b', 'a', 'c', 'a'), ('b', 'b', 'a', 'c', 'b'), ('b', 'b', 'a', 'c', 'c'), ('b', 'b', 'b', 'a', 'a'), ('b', 'b', 'b', 'a', 'b'), ('b', 'b', 'b', 'a', 'c'), ('b', 'b', 'b', 'b', 'a'), ('b', 'b', 'b', 'b', 'b'), ('b', 'b', 'b', 'b', 'c'), ('b', 'b', 'b', 'c', 'a'), ('b', 'b', 'b', 'c', 'b'), ('b', 'b', 'b', 'c', 'c'), ('b', 'b', 'c', 'a', 'a'), ('b', 'b', 'c', 'a', 'b'), ('b', 'b', 'c', 'a', 'c'), ('b', 'b', 'c', 'b', 'a'), ('b', 'b', 'c', 'b', 'b'), ('b', 'b', 'c', 'b', 'c'), ('b', 'b', 'c', 'c', 'a'), ('b', 'b', 'c', 'c', 'b'), ('b', 'b', 'c', 'c', 'c'), ('b', 'c', 'a', 'a', 'a'), ('b', 'c', 'a', 'a', 'b'), ('b', 'c', 'a', 'a', 'c'), ('b', 'c', 'a', 'b', 'a'), ('b', 'c', 'a', 'b', 'b'), ('b', 'c', 'a', 'b', 'c'), ('b', 'c', 'a', 'c', 'a'), ('b', 'c', 'a', 'c', 'b'), ('b', 'c', 'a', 'c', 'c'), ('b', 'c', 'b', 'a', 'a'), ('b', 'c', 'b', 'a', 'b'), ('b', 'c', 'b', 'a', 'c'), ('b', 'c', 'b', 'b', 'a'), ('b', 'c', 'b', 'b', 'b'), ('b', 'c', 'b', 'b', 'c'), ('b', 'c', 'b', 'c', 'a'), ('b', 'c', 'b', 'c', 'b'), ('b', 'c', 'b', 'c', 'c'), ('b', 'c', 'c', 'a', 'a'), ('b', 'c', 'c', 'a', 'b'), ('b', 'c', 'c', 'a', 'c'), ('b', 'c', 'c', 'b', 'a'), ('b', 'c', 'c', 'b', 'b'), ('b', 'c', 'c', 'b', 'c'), ('b', 'c', 'c', 'c', 'a'), ('b', 'c', 'c', 'c', 'b'), ('b', 'c', 'c', 'c', 'c'), ('c', 'a', 'a', 'a', 'a'), ('c', 'a', 'a', 'a', 'b'), ('c', 'a', 'a', 'a', 'c'), ('c', 'a', 'a', 'b', 'a'), ('c', 'a', 'a', 'b', 'b'), ('c', 'a', 'a', 'b', 'c'), ('c', 'a', 'a', 'c', 'a'), ('c', 'a', 'a', 'c', 'b'), ('c', 'a', 'a', 'c', 'c'), ('c', 'a', 'b', 'a', 'a'), ('c', 'a', 'b', 'a', 'b'), ('c', 'a', 'b', 'a', 'c'), ('c', 'a', 'b', 'b', 'a'), ('c', 'a', 'b', 'b', 'b'), ('c', 'a', 'b', 'b', 'c'), ('c', 'a', 'b', 'c', 'a'), ('c', 'a', 'b', 'c', 'b'), ('c', 'a', 'b', 'c', 'c'), ('c', 'a', 'c', 'a', 'a'), ('c', 'a', 'c', 'a', 'b'), ('c', 'a', 'c', 'a', 'c'), ('c', 'a', 'c', 'b', 'a'), ('c', 'a', 'c', 'b', 'b'), ('c', 'a', 'c', 'b', 'c'), ('c', 'a', 'c', 'c', 'a'), ('c', 'a', 'c', 'c', 'b'), ('c', 'a', 'c', 'c', 'c'), ('c', 'b', 'a', 'a', 'a'), ('c', 'b', 'a', 'a', 'b'), ('c', 'b', 'a', 'a', 'c'), ('c', 'b', 'a', 'b', 'a'), ('c', 'b', 'a', 'b', 'b'), ('c', 'b', 'a', 'b', 'c'), ('c', 'b', 'a', 'c', 'a'), ('c', 'b', 'a', 'c', 'b'), ('c', 'b', 'a', 'c', 'c'), ('c', 'b', 'b', 'a', 'a'), ('c', 'b', 'b', 'a', 'b'), ('c', 'b', 'b', 'a', 'c'), ('c', 'b', 'b', 'b', 'a'), ('c', 'b', 'b', 'b', 'b'), ('c', 'b', 'b', 'b', 'c'), ('c', 'b', 'b', 'c', 'a'), ('c', 'b', 'b', 'c', 'b'), ('c', 'b', 'b', 'c', 'c'), ('c', 'b', 'c', 'a', 'a'), ('c', 'b', 'c', 'a', 'b'), ('c', 'b', 'c', 'a', 'c'), ('c', 'b', 'c', 'b', 'a'), ('c', 'b', 'c', 'b', 'b'), ('c', 'b', 'c', 'b', 'c'), ('c', 'b', 'c', 'c', 'a'), ('c', 'b', 'c', 'c', 'b'), ('c', 'b', 'c', 'c', 'c'), ('c', 'c', 'a', 'a', 'a'), ('c', 'c', 'a', 'a', 'b'), ('c', 'c', 'a', 'a', 'c'), ('c', 'c', 'a', 'b', 'a'), ('c', 'c', 'a', 'b', 'b'), ('c', 'c', 'a', 'b', 'c'), ('c', 'c', 'a', 'c', 'a'), ('c', 'c', 'a', 'c', 'b'), ('c', 'c', 'a', 'c', 'c'), ('c', 'c', 'b', 'a', 'a'), ('c', 'c', 'b', 'a', 'b'), ('c', 'c', 'b', 'a', 'c'), ('c', 'c', 'b', 'b', 'a'), ('c', 'c', 'b', 'b', 'b'), ('c', 'c', 'b', 'b', 'c'), ('c', 'c', 'b', 'c', 'a'), ('c', 'c', 'b', 'c', 'b'), ('c', 'c', 'b', 'c', 'c'), ('c', 'c', 'c', 'a', 'a'), ('c', 'c', 'c', 'a', 'b'), ('c', 'c', 'c', 'a', 'c'), ('c', 'c', 'c', 'b', 'a'), ('c', 'c', 'c', 'b', 'b'), ('c', 'c', 'c', 'b', 'c'), ('c', 'c', 'c', 'c', 'a'), ('c', 'c', 'c', 'c', 'b'), ('c', 'c', 'c', 'c', 'c')]
Or:
for i in combinations_with_replacement_max_len(full,1,SOME_NUMBER):
password = ''.join(i)
compare_password_and_other_stuff(password)
Bear in mind that THIS IS NOT how passwords are cracked and expect long running times for large SOME_NUMBER.

This is what you wanted i belive, the problem is im just giving you answer for your problem and i belive you do not understand this code i have posted so let me explain in great detail!
Your code is ok but is just nasty in terms of reading this code i have posted is what you wanted to achieve but with a greater understanding of what you wanted to do...
(1st) we import the functions: itertools, math, and os
They give us a great amount of function for use in the program...
Then we have the alphabet which is simple enough it contains the alphabet or chars as i like to call them since they are chars after all.
The rest is up to you to read this is not a tutorial but reading through what i have gave you should give the lines to color in behind happy coding brother's/sister's !
import itertools, math
import os
Alphabet = ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890") # Add or remove whatevs you think will be in the password you're cracking (example, [symbols])
counter = 1
CharLength = 1
range_num = int(raw_input("Enter range: "))
stopper = range_num + 1
filename = "bruteforce_%r.txt" % (range_num)
f = open(filename, 'a')
#n_1 = len(Alphabet)
#n_2 = n_1 - 1 # <-- total useless peice of garbage that could of been great in vurtual life
#n_3 = '0' * n_2
#n = '1' + n_3
x = range_num
y = len(Alphabet)
amount = math.pow(y, x)
total_items = math.pow(y, x)
for CharLength in range(range_num, stopper):
passwords = (itertools.product(Alphabet, repeat = CharLength))
for i in passwords:
counter += 1
percentage = (counter / total_items) * 100
amount -= 1
i = str(i)
i = i.replace("[", "")
i = i.replace("]", "")
i = i.replace("'", "")
i = i.replace(" ", "")
i = i.replace(",", "")
i = i.replace("(", "")
i = i.replace(")", "")
f.write(i)
f.write('\n')
print "Password: %r\tPercentage: %r/100\tAmount left: %r" % (i, int(percentage), amount)
if i == '0'* range_num:
print "*Done"
f.close()
exit(0)
else:
pass

Related

How to pop item from list and push it back to list based on condition using python

I have list with urls for crawling.['http://domain1.com','http://domain1.com/page1','http://domain2.com']
Code:
prev_domain = ''
while urls:
url = urls.pop()
if base_url(url) == prev_domain: # base_url is custom function return domain of an url
urls.append(url) # is this is possible?
continue
else:
crawl(url)
Basically I dont want to crawl webpages of same domain continuously. Continuosly crawling a domain url, return http response status code with 429: Too Many Requests. The user has sent too many requests in a given amount of time ("rate limiting"). To by-pass this issue, I'm planning to go with below logic.
Loop through all items in the list and compare current element base url with previously processed element base url.
If base urls are different then process for next step, otherwise do not process current element, just append this element to the same list.
Note : If urls in list are of same domain, make delay in processing each element and then execute.
Please provide your thoughts.
Your algorithm is almost correct, but not the implementation:
>>> L = [1,2,3]
>>> L.pop()
3
>>> L.append(3)
>>> L
[1, 2, 3]
That's why your program loops forever: if the domain is the same as the previous domain, you just append then pop then append, then.... What you need is not a stack, it's a round robin:
>>> L.pop()
3
>>> L.insert(0, 3)
>>> L
[3, 1, 2]
Let's take a shuffled list of permutations of "abcd":
>>> L = [('b', 'c', 'd', 'a'), ('d', 'c', 'b', 'a'), ('a', 'c', 'd', 'b'), ('c', 'd', 'a', 'b'), ('b', 'd', 'a', 'c'), ('b', 'a', 'd', 'c'), ('b', 'c', 'a', 'd'), ('a', 'b', 'd', 'c'), ('d', 'a', 'b', 'c'), ('a', 'b', 'c', 'd'), ('d', 'c', 'a', 'b'), ('a', 'd', 'c', 'b'), ('d', 'a', 'c', 'b'), ('c', 'd', 'b', 'a'), ('d', 'b', 'c', 'a'), ('d', 'b', 'a', 'c'), ('a', 'd', 'b', 'c'), ('b', 'd', 'c', 'a'), ('c', 'b', 'd', 'a'), ('c', 'a', 'b', 'd'), ('b', 'a', 'c', 'd')]
The first letter is the domain. Here's a slightly modified version of your code:
>>> prev = None
>>> while L:
... e = L.pop()
... if L and e[0] == prev:
... L.insert(0, e)
... else:
... print(e)
... prev = e[0]
('b', 'a', 'c', 'd')
('c', 'a', 'b', 'd')
('b', 'd', 'c', 'a')
('a', 'd', 'b', 'c')
('d', 'b', 'a', 'c')
('c', 'd', 'b', 'a')
('d', 'a', 'c', 'b')
('a', 'd', 'c', 'b')
('d', 'c', 'a', 'b')
('a', 'b', 'c', 'd')
('d', 'a', 'b', 'c')
('a', 'b', 'd', 'c')
('b', 'c', 'a', 'd')
('c', 'd', 'a', 'b')
('a', 'c', 'd', 'b')
('d', 'c', 'b', 'a')
('b', 'c', 'd', 'a')
('c', 'b', 'd', 'a')
('d', 'b', 'c', 'a')
('b', 'a', 'd', 'c')
('b', 'd', 'a', 'c')
The modification is: if L and, because if the last element of the list domain is prev, then you'll loop forever with your one element list: pop, same as prev, insert, pop, ...(as with pop/append)
Here's another option: create a dict domain -> list of urls:
>>> d = {}
>>> for e in L:
... d.setdefault(e[0], []).append(e)
>>> d
{'b': [('b', 'c', 'd', 'a'), ('b', 'd', 'a', 'c'), ('b', 'a', 'd', 'c'), ('b', 'c', 'a', 'd'), ('b', 'd', 'c', 'a'), ('b', 'a', 'c', 'd')], 'd': [('d', 'c', 'b', 'a'), ('d', 'a', 'b', 'c'), ('d', 'c', 'a', 'b'), ('d', 'a', 'c', 'b'), ('d', 'b', 'c', 'a'), ('d', 'b', 'a', 'c')], 'a': [('a', 'c', 'd', 'b'), ('a', 'b', 'd', 'c'), ('a', 'b', 'c', 'd'), ('a', 'd', 'c', 'b'), ('a', 'd', 'b', 'c')], 'c': [('c', 'd', 'a', 'b'), ('c', 'd', 'b', 'a'), ('c', 'b', 'd', 'a'), ('c', 'a', 'b', 'd')]}
Now, take an element of every domain and clear the dict, then loop until the dict is empty:
>>> while d:
... for k, vs in d.items():
... e = vs.pop()
... print (e)
... d = {k: vs for k, vs in d.items() if vs} # clear the dict
...
('b', 'a', 'c', 'd')
('d', 'b', 'a', 'c')
('a', 'd', 'b', 'c')
('c', 'a', 'b', 'd')
('b', 'd', 'c', 'a')
('d', 'b', 'c', 'a')
('a', 'd', 'c', 'b')
('c', 'b', 'd', 'a')
('b', 'c', 'a', 'd')
('d', 'a', 'c', 'b')
('a', 'b', 'c', 'd')
('c', 'd', 'b', 'a')
('b', 'a', 'd', 'c')
('d', 'c', 'a', 'b')
('a', 'b', 'd', 'c')
('c', 'd', 'a', 'b')
('b', 'd', 'a', 'c')
('d', 'a', 'b', 'c')
('a', 'c', 'd', 'b')
('b', 'c', 'd', 'a')
('d', 'c', 'b', 'a')
The output is more uniform.
Check the following code snippet,
urls = ['http://domain1.com','http://domain1.com/page1','http://domain2.com']
crawl_for_urls = {}
for url in urls:
domain = base_url(url)
if domain not in crowl_for_urls:
crawl_for_urls.update({domain:url})
crawl(url)
crawl() will be called only for unique domain.
Or you can use:
urls = ['http://domain1.com','http://domain1.com/page1','http://domain2.com']
crawl_for_urls = {}
for url in urls:
domain = base_url(url)
if domain not in crowl_for_urls:
crawl_for_urls.update({domain:[url]})
crawl(url)
else:
crawl_for_urls.get(domain, []).append(url)
This way you can categories the URL's based on domain and also can use crawl() for unique domain.

List all TSP route combinations (5 vertices)

I want to list all TSP route combinations.
There are 5 vertices and thus 10 edges:
All the edges are as follows:
edges = [('A', 'B'), ('A', 'C'), ('A', 'D'), ('A', 'E'), ('B', 'C'), ('B', 'D'), ('B', 'E'), ('C', 'D'), ('C', 'E'), ('D', 'E')]
Note: ('A', 'B') is the same as ('B', 'A'), same goes for the other edges.
I want to list all route combinations where you start at A and visit each other number and end at A.
This is what I got so far:
edges = [('A', 'B'), ('A', 'C'), ('A', 'D'), ('A', 'E'), ('B', 'C'), ('B', 'D'), ('B', 'E'), ('C', 'D'), ('C', 'E'), ('D', 'E')]
x = list(itertools.permutations(['A','B','C','D','E', 'A'], 6))
b = 1
for i in x:
if i[-1] == 'A' and i[0] == 'A':
print(i, b)
b += 1
However, I don't want duplicate routes. How do I sort those out?
Eg.
A->B->C->A is the same as A->C->B->A, and should not be counted/listed twice.
You can use recursion with a generator:
edges = [('A', 'B'), ('A', 'C'), ('A', 'D'), ('A', 'E'), ('B', 'C'), ('B', 'D'), ('B', 'E'), ('C', 'D'), ('C', 'E'), ('D', 'E')]
def all_paths(graph, start, end=None, _flag = None, _pool = [], _seen= []):
if start == end:
yield _pool
else:
for a, b in graph:
if a == start and a not in _seen:
yield from all_paths(graph, b, end=_flag, _flag=_flag, _pool = _pool+[b], _seen =_seen+[a])
results = list(all_paths(edges+[(b, a) for a, b in edges], 'A', _flag = 'A'))
filtered = [a for i, a in enumerate(results) if not any(len(c) == len(a) and all(h in c for h in a) for c in results[:i])]
Output:
[['B', 'C', 'D', 'E', 'A'], ['B', 'C', 'D', 'A'], ['B', 'C', 'E', 'A'], ['B', 'C', 'A'], ['B', 'D', 'E', 'A'], ['B', 'D', 'A'], ['B', 'E', 'A'], ['B', 'A'], ['C', 'D', 'E', 'A'], ['C', 'D', 'A'], ['C', 'E', 'A'], ['C', 'A'], ['D', 'E', 'A'], ['D', 'A'], ['E', 'A']]

Generate all possible comparisons 3 v 3 in a group of 6

I have 6 samples and I would like to generate all possible 3v3 comparisons using python.
So far I've managed to use the combinations function to generate all possible groups of 3. But I fail to generate the match comparisons (if I have CM26 in the first group I don't want to compare it against a group of 3 with it).
def combinations(iterable, r):
# combinations('ABCD', 2) --> AB AC AD BC BD CD
# combinations(range(4), 3) --> 012 013 023 123
pool = tuple(iterable)
n = len(pool)
if r > n:
return
indices = range(r)
yield tuple(pool[i] for i in indices)
while True:
for i in reversed(range(r)):
if indices[i] != i + n - r:
break
else:
return
indices[i] += 1
for j in range(i+1, r):
indices[j] = indices[j-1] + 1
yield tuple(pool[i] for i in indices)
columns = {'CM19':1,'CM20':2,'CM21':3,'CM23':5,'CM25':7,'CM26':8}
for i in combinations(columns,3):
print i
('CM26', 'CM19', 'CM25') ('CM26', 'CM19', 'CM23') ('CM26', 'CM19',
'CM20') ('CM26', 'CM19', 'CM21') ('CM26', 'CM25', 'CM23') ('CM26',
'CM25', 'CM20') ('CM26', 'CM25', 'CM21') ('CM26', 'CM23', 'CM20')
('CM26', 'CM23', 'CM21') ('CM26', 'CM20', 'CM21') ('CM19', 'CM25',
'CM23') ('CM19', 'CM25', 'CM20') ('CM19', 'CM25', 'CM21') ('CM19',
'CM23', 'CM20') ('CM19', 'CM23', 'CM21') ('CM19', 'CM20', 'CM21')
('CM25', 'CM23', 'CM20') ('CM25', 'CM23', 'CM21') ('CM25', 'CM20',
'CM21') ('CM23', 'CM20', 'CM21')
I would like to compare each group to the others but eliminating repetition.
Always pick a triple with the first element present, and use the complement of the set for the other triple.
Here's code.
import itertools
def three_vs_three(xs):
xset = set(xs)
for i1, i2 in itertools.combinations(xs[1:], 2):
triple = set([xs[0], i1, i2])
yield sorted(triple), sorted(xset - triple)
things = ['CM%d' % x for x in 19, 20, 21, 23, 25, 26]
print list(three_vs_three(things))
The two tricks to solving this are the following:
You can use itertools.permutations with the second parameter of 3 to generate sets of 3 elements
You can use set.difference to figure out the compliment for any generated tuple in Step 1
group = set(['A','B','C','D','E','F'])
import itertools
comparisons = [(tuple(i),tuple(set.difference(group,i))) for i in itertools.permutations(group,3)]
Result
[(('A', 'C', 'B'), ('E', 'D', 'F')),
(('A', 'C', 'E'), ('B', 'D', 'F')),
(('A', 'C', 'D'), ('B', 'E', 'F')),
(('A', 'C', 'F'), ('B', 'E', 'D')),
(('A', 'B', 'C'), ('E', 'D', 'F')),
(('A', 'B', 'E'), ('C', 'D', 'F')),
(('A', 'B', 'D'), ('C', 'E', 'F')),
(('A', 'B', 'F'), ('C', 'E', 'D')),
(('A', 'E', 'C'), ('B', 'D', 'F')),
(('A', 'E', 'B'), ('C', 'D', 'F')),
(('A', 'E', 'D'), ('C', 'B', 'F')),
(('A', 'E', 'F'), ('C', 'B', 'D')),
(('A', 'D', 'C'), ('B', 'E', 'F')),
(('A', 'D', 'B'), ('C', 'E', 'F')),
(('A', 'D', 'E'), ('C', 'B', 'F')),
(('A', 'D', 'F'), ('C', 'B', 'E')),
(('A', 'F', 'C'), ('B', 'E', 'D')),
(('A', 'F', 'B'), ('C', 'E', 'D')),
(('A', 'F', 'E'), ('C', 'B', 'D')),
(('A', 'F', 'D'), ('C', 'B', 'E')),
(('C', 'A', 'B'), ('E', 'D', 'F')),
(('C', 'A', 'E'), ('B', 'D', 'F')),
(('C', 'A', 'D'), ('B', 'E', 'F')),
(('C', 'A', 'F'), ('B', 'E', 'D')),
(('C', 'B', 'A'), ('E', 'D', 'F')),
(('C', 'B', 'E'), ('A', 'D', 'F')),
(('C', 'B', 'D'), ('A', 'E', 'F')),
(('C', 'B', 'F'), ('A', 'E', 'D')),
(('C', 'E', 'A'), ('B', 'D', 'F')),
(('C', 'E', 'B'), ('A', 'D', 'F')),
(('C', 'E', 'D'), ('A', 'B', 'F')),
(('C', 'E', 'F'), ('A', 'B', 'D')),
(('C', 'D', 'A'), ('B', 'E', 'F')),
(('C', 'D', 'B'), ('A', 'E', 'F')),
(('C', 'D', 'E'), ('A', 'B', 'F')),
(('C', 'D', 'F'), ('A', 'B', 'E')),
(('C', 'F', 'A'), ('B', 'E', 'D')),
(('C', 'F', 'B'), ('A', 'E', 'D')),
(('C', 'F', 'E'), ('A', 'B', 'D')),
(('C', 'F', 'D'), ('A', 'B', 'E')),
(('B', 'A', 'C'), ('E', 'D', 'F')),
(('B', 'A', 'E'), ('C', 'D', 'F')),
(('B', 'A', 'D'), ('C', 'E', 'F')),
(('B', 'A', 'F'), ('C', 'E', 'D')),
(('B', 'C', 'A'), ('E', 'D', 'F')),
(('B', 'C', 'E'), ('A', 'D', 'F')),
(('B', 'C', 'D'), ('A', 'E', 'F')),
(('B', 'C', 'F'), ('A', 'E', 'D')),
(('B', 'E', 'A'), ('C', 'D', 'F')),
(('B', 'E', 'C'), ('A', 'D', 'F')),
(('B', 'E', 'D'), ('A', 'C', 'F')),
(('B', 'E', 'F'), ('A', 'C', 'D')),
(('B', 'D', 'A'), ('C', 'E', 'F')),
(('B', 'D', 'C'), ('A', 'E', 'F')),
(('B', 'D', 'E'), ('A', 'C', 'F')),
(('B', 'D', 'F'), ('A', 'C', 'E')),
(('B', 'F', 'A'), ('C', 'E', 'D')),
(('B', 'F', 'C'), ('A', 'E', 'D')),
(('B', 'F', 'E'), ('A', 'C', 'D')),
(('B', 'F', 'D'), ('A', 'C', 'E')),
(('E', 'A', 'C'), ('B', 'D', 'F')),
(('E', 'A', 'B'), ('C', 'D', 'F')),
(('E', 'A', 'D'), ('C', 'B', 'F')),
(('E', 'A', 'F'), ('C', 'B', 'D')),
(('E', 'C', 'A'), ('B', 'D', 'F')),
(('E', 'C', 'B'), ('A', 'D', 'F')),
(('E', 'C', 'D'), ('A', 'B', 'F')),
(('E', 'C', 'F'), ('A', 'B', 'D')),
(('E', 'B', 'A'), ('C', 'D', 'F')),
(('E', 'B', 'C'), ('A', 'D', 'F')),
(('E', 'B', 'D'), ('A', 'C', 'F')),
(('E', 'B', 'F'), ('A', 'C', 'D')),
(('E', 'D', 'A'), ('C', 'B', 'F')),
(('E', 'D', 'C'), ('A', 'B', 'F')),
(('E', 'D', 'B'), ('A', 'C', 'F')),
(('E', 'D', 'F'), ('A', 'C', 'B')),
(('E', 'F', 'A'), ('C', 'B', 'D')),
(('E', 'F', 'C'), ('A', 'B', 'D')),
(('E', 'F', 'B'), ('A', 'C', 'D')),
(('E', 'F', 'D'), ('A', 'C', 'B')),
(('D', 'A', 'C'), ('B', 'E', 'F')),
(('D', 'A', 'B'), ('C', 'E', 'F')),
(('D', 'A', 'E'), ('C', 'B', 'F')),
(('D', 'A', 'F'), ('C', 'B', 'E')),
(('D', 'C', 'A'), ('B', 'E', 'F')),
(('D', 'C', 'B'), ('A', 'E', 'F')),
(('D', 'C', 'E'), ('A', 'B', 'F')),
(('D', 'C', 'F'), ('A', 'B', 'E')),
(('D', 'B', 'A'), ('C', 'E', 'F')),
(('D', 'B', 'C'), ('A', 'E', 'F')),
(('D', 'B', 'E'), ('A', 'C', 'F')),
(('D', 'B', 'F'), ('A', 'C', 'E')),
(('D', 'E', 'A'), ('C', 'B', 'F')),
(('D', 'E', 'C'), ('A', 'B', 'F')),
(('D', 'E', 'B'), ('A', 'C', 'F')),
(('D', 'E', 'F'), ('A', 'C', 'B')),
(('D', 'F', 'A'), ('C', 'B', 'E')),
(('D', 'F', 'C'), ('A', 'B', 'E')),
(('D', 'F', 'B'), ('A', 'C', 'E')),
(('D', 'F', 'E'), ('A', 'C', 'B')),
(('F', 'A', 'C'), ('B', 'E', 'D')),
(('F', 'A', 'B'), ('C', 'E', 'D')),
(('F', 'A', 'E'), ('C', 'B', 'D')),
(('F', 'A', 'D'), ('C', 'B', 'E')),
(('F', 'C', 'A'), ('B', 'E', 'D')),
(('F', 'C', 'B'), ('A', 'E', 'D')),
(('F', 'C', 'E'), ('A', 'B', 'D')),
(('F', 'C', 'D'), ('A', 'B', 'E')),
(('F', 'B', 'A'), ('C', 'E', 'D')),
(('F', 'B', 'C'), ('A', 'E', 'D')),
(('F', 'B', 'E'), ('A', 'C', 'D')),
(('F', 'B', 'D'), ('A', 'C', 'E')),
(('F', 'E', 'A'), ('C', 'B', 'D')),
(('F', 'E', 'C'), ('A', 'B', 'D')),
(('F', 'E', 'B'), ('A', 'C', 'D')),
(('F', 'E', 'D'), ('A', 'C', 'B')),
(('F', 'D', 'A'), ('C', 'B', 'E')),
(('F', 'D', 'C'), ('A', 'B', 'E')),
(('F', 'D', 'B'), ('A', 'C', 'E')),
(('F', 'D', 'E'), ('A', 'C', 'B'))]

How to use itertools to compute all combinations with repeating elements? [duplicate]

This question already has an answer here:
Which itertools generator doesn't skip any combinations?
(1 answer)
Closed 8 years ago.
I have tried to use itertools to compute all combinations of a list ['a', 'b', 'c'] using combinations_with_replacement with repeating elements. The problem is in the fact that the indices seem to be used to distinguish the elements:
Return r length subsequences of elements from the input iterable allowing individual elements to be repeated more than once.
Combinations are emitted in lexicographic sort order. So, if the input
iterable is sorted, the combination tuples will be produced in sorted
order.
Elements are treated as unique based on their position, not on their
value. So if the input elements are unique, the generated combinations
will also be unique.
Sot this code snippet:
import itertools
for item in itertools.combinations_with_replacement(['a','b','c'], 3):
print (item)
results in this output:
('a', 'a', 'a')
('a', 'a', 'b')
('a', 'a', 'c')
('a', 'b', 'b')
('a', 'b', 'c')
('a', 'c', 'c')
('b', 'b', 'b')
('b', 'b', 'c')
('b', 'c', 'c')
('c', 'c', 'c')
And what I need is the combination set to contain elements like: ('a', 'b', 'a') which seem to be missing. How to compute the complete combination set?
It sounds like you want itertools.product:
>>> from itertools import product
>>> for item in product(['a', 'b', 'c'], repeat=3):
... print item
...
('a', 'a', 'a')
('a', 'a', 'b')
('a', 'a', 'c')
('a', 'b', 'a')
('a', 'b', 'b')
('a', 'b', 'c')
('a', 'c', 'a')
('a', 'c', 'b')
('a', 'c', 'c')
('b', 'a', 'a')
('b', 'a', 'b')
('b', 'a', 'c')
('b', 'b', 'a')
('b', 'b', 'b')
('b', 'b', 'c')
('b', 'c', 'a')
('b', 'c', 'b')
('b', 'c', 'c')
('c', 'a', 'a')
('c', 'a', 'b')
('c', 'a', 'c')
('c', 'b', 'a')
('c', 'b', 'b')
('c', 'b', 'c')
('c', 'c', 'a')
('c', 'c', 'b')
('c', 'c', 'c')
>>>
For such small sequences you could use no itertools at all:
abc = ("a", "b", "c")
print [(x, y, z) for x in abc for y in abc for z in abc]
# output:
[('a', 'a', 'a'),
('a', 'a', 'b'),
('a', 'a', 'c'),
('a', 'b', 'a'),
('a', 'b', 'b'),
('a', 'b', 'c'),
('a', 'c', 'a'),
('a', 'c', 'b'),
('a', 'c', 'c'),
('b', 'a', 'a'),
('b', 'a', 'b'),
('b', 'a', 'c'),
('b', 'b', 'a'),
('b', 'b', 'b'),
('b', 'b', 'c'),
('b', 'c', 'a'),
('b', 'c', 'b'),
('b', 'c', 'c'),
('c', 'a', 'a'),
('c', 'a', 'b'),
('c', 'a', 'c'),
('c', 'b', 'a'),
('c', 'b', 'b'),
('c', 'b', 'c'),
('c', 'c', 'a'),
('c', 'c', 'b'),
('c', 'c', 'c')]

Python loop (insert items in a list at dermined places)

I have this code:
number = 2
size = 5
list_b = [("b","b","b")]
list_a = [("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a")]
for i in range(number):
list_a.insert(size,list_b)
print list_a
it gives me this:
[('a', 'a', 'a'),
('a', 'a', 'a'),
('a', 'a', 'a'),
('a', 'a', 'a'),
('a', 'a', 'a'),
('b', 'b', 'b'),
('b', 'b', 'b'),
('a', 'a', 'a'),
('a', 'a', 'a'),
('a', 'a', 'a'),
('a', 'a', 'a'),
('a', 'a', 'a'),
('a', 'a', 'a'),
('a', 'a', 'a'),
('a', 'a', 'a'),
('a', 'a', 'a'),
('a', 'a', 'a'),
('a', 'a', 'a'),
('a', 'a', 'a'),
('a', 'a', 'a'),
('a', 'a', 'a'),
('a', 'a', 'a'),
('a', 'a', 'a'),
('a', 'a', 'a'),
('a', 'a', 'a'),
('a', 'a', 'a'),
('a', 'a', 'a'),
('a', 'a', 'a'),
('a', 'a', 'a'),
('a', 'a', 'a'),
('a', 'a', 'a'),
('a', 'a', 'a'),
('a', 'a', 'a')]
basically, it inserts 2 times the list_b in the position defined by size
I want a loop that repeats itself so that list_b is inserted the number of times defined in number but repeats size times. It difficult to explain, so here is the result that I want:
[('a', 'a', 'a'),
('a', 'a', 'a'),
('a', 'a', 'a'),
('a', 'a', 'a'),
('a', 'a', 'a'),
('b', 'b', 'b'),
('b', 'b', 'b'),
('a', 'a', 'a'),
('a', 'a', 'a'),
('a', 'a', 'a'),
('a', 'a', 'a'),
('a', 'a', 'a'),
('b', 'b', 'b'),
('b', 'b', 'b'),
('a', 'a', 'a'),
('a', 'a', 'a'),
('a', 'a', 'a'),
('a', 'a', 'a'),
('a', 'a', 'a'),
('b', 'b', 'b'),
('b', 'b', 'b'),
('a', 'a', 'a'),
('a', 'a', 'a'),
('a', 'a', 'a'),
('a', 'a', 'a'),
('a', 'a', 'a'),
('b', 'b', 'b'),
('b', 'b', 'b'),
('a', 'a', 'a'),
('a', 'a', 'a'),
('a', 'a', 'a'),
('a', 'a', 'a'),
('b', 'b', 'b'),
('b', 'b', 'b'),...and so on]
EDIT
and if I had this:
list_a = [a, ] * 15
list_b = [b,]
s = 5
n = 2
I want to obtain this:
[b,b,a,a,a,a,a,b,b,b,b,a,a,a,a,a,b,b,b,b,a,a,a,a,a,b,b]
since this is an example and list_a, s and n will vary, how can I do this in one or two loops?
Thanks,
Favolas
For the sake of the argument, I'll call the ('a', 'a', 'a') => a and ('b', 'b', 'b') => b.
number=2
size=5
list_a=["a"]*20
list_b=["b"]
workfor=len(list_a)+(len(list_a)/size)*number*len(list_b)
i=0
while i<workfor:
i+=size
for times in range(number):
for elem in list_b:
list_a.insert(i,elem)
i+=len(list_b)
print list_a
Results in =>
['a', 'a', 'a', 'a', 'a', 'b', 'b', 'a', 'a', 'a', 'a', 'a', 'b', 'b', 'a', 'a', 'a', 'a', 'a', 'b', 'b', 'a', 'a', 'a', 'a', 'a', 'b', 'b']
#!/usr/bin/python
number = 2
size = 5
list_b = [("b","b","b")]
list_a = [("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a"),("a","a","a")]
if __name__ == '__main__':
insertion_count = len(list_a) / size
for j in xrange(insertion_count):
# compute insertion position
pos = (j+1)*size + j * number
for i in range(number):
list_a.insert(pos,list_b)
print list_a
from itertools import chain, izip, repeat
list_a = [('a', 'a', 'a')] * 15
list_b = [('b', 'b', 'b')]
a5b2s = [iter(list_a)] * 5 + [repeat(*list_b)] * 2
list_a[:] = chain.from_iterable(izip(*a5b2s))
>>> s,n=5,2
>>> a=[1,]*17
>>> b=2
>>> for i in range(len(a)//s*s,0,-s):
for j in range(n):
a.insert(i,b)
>>> a
[1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1]

Categories

Resources