Cascading Style Sheets (CSS) is a style sheet language used for describing the look and formatting of a document written in a markup language. A style sheet consists of a list of rules. Each rule or rule-set consists of one or more selectors, and a declaration block. Selector describes which element it matches.

Sometimes element is matched to multiple selectors. In this case, element inherits multiple styles, from each rule it matches. Rules can override each other. To solve this problem, each selector has it's own 'specificity' - e.g. weight. The selector with greater specificity overrides the other selector.

Your task is to calculate the weights of two selectors and determine which of them will beat the other one.

```python
compare("body p", "div") # returns "body p"
compare(".class", "#id") # returns "#id"
compare("div.big", ".small") # returns "div.big"
compare(".big", ".small") # returns ".small" (because it appears later)
```

For simplicity, all selectors in test cases are CSS1-compatible, test cases don't include pseudoclasses, pseudoelements, attribute selectors, etc. Below is an explanation on how to weight two selectors. You can read more about specificity here.

The simplest selector type is ``tagname`` selector. It writes as a simple  alphanumeric identifier: eg ``body``, ``div``, ``h1``, etc. It has the least weight. If selectors have multiple elements - the selector with more elements win. For example, ``body p`` beats ``div``, because it refers to 2 (nested) elements rather than 1.

Another simple selector is ``.class`` selector. It begins with dot and refer to element with specific ``class`` attribute. Class selectors can also be applied to tagname selectors, so ``div.red`` refer to ```` element. They can be grouped, for example, ``.red.striped``. Class selector beats tagname selector.

The most weighted selector type in stylesheet is ``#id`` selector. It begins with hash sign and refer to element with specific ``id`` attribute. It can also be standalone, or applied to an element. Id selector beats both selector types.

And the least weighted selector is ``*``, which has no specificity and can be beat by any other selector.

Selectors can be combined, for example, ``body #menu ul li.active`` refers to ``li`` element with ``class="active"``, placed inside ``ul`` element, placed inside element width ``id="menu"``, placed inside ``body``.

Specificity calculation is simple. 

Selector with more #id selectors wins
If both are same, the winner is selector with more .class selectors
If both are same, selector with more elements wins
If all of above values are same, the winner is selector that appear last


For example, let's represent the number of ``#id`` , ``.class``, ``tagname`` selectors as array (in order from worst to best):

SelectorSpecificity (#id,.class,tagname)
*0, 0, 0
span0, 0, 1
body p0, 0, 2
.green0, 1, 0
apple.yellow0, 1, 1
div.menu li0, 1, 2
.red .orange0, 2, 0
div.big .first0, 2, 1
#john1, 0, 0
div#john1, 0, 1
body #john span1, 0, 2
menu .item #checkout.active1, 2, 1
#foo div#bar.red .none2, 2, 1

Source: codewars | Difficulty: EASY

Starter code: def compare(a, b):
	

Solutions:
import re

def compare(a, b):
	return a if specificity(a) > specificity(b) else b

def specificity(s):
	return [len(re.findall(r, s)) for r in ('#\\w+', '\\.\\w+', '(^| )\\w+')]


import re

def compare(a, b):

	def scoreCSS(s):
		d = {'#': 0, '.': 0, ' ': 0}
		for c in re.findall('[#\\. ](?=[\\w-])', ' {}'.format(s)):
			d[c] = d[c] + 1
		return (d['#'], d['.'], d[' '])
	return a if scoreCSS(a) > scoreCSS(b) else b


from functools import reduce
import re
SIMPLE_SELECTOR_PATTERN = re.compile('[\\s+~>]+|(\\[[^[]+\\]|[#\\.:]?[^[\\s#\\.:+~>]+)')
SPECIFICITY_PATTERN = re.compile('(^#)|(^[\\.\\[:][^:]?)|(^::|^[^#\\.:[])')

def compare(a, b):
	return max((b, a), key=get_specificity)

def get_specificity(selector):
	return reduce(sum_specificities, list(map(simple_selector_to_specificity, get_simple_selectors(selector))))

def sum_specificities(*specificities):
	return list(map(sum, list(zip(*specificities))))

def simple_selector_to_specificity(simple_selector):
	if simple_selector == '*':
		return [0, 0, 0]
	return [1 if x else 0 for x in SPECIFICITY_PATTERN.match(simple_selector).groups()]

def get_simple_selectors(selector):
	return [match.group(1) for match in SIMPLE_SELECTOR_PATTERN.finditer(selector) if match.group(1)]


tagname = __import__('re').compile('(^|(?<=\\s))[^#\\.*]').findall

def compare(a, b):
	return max(b, a, key=lambda x: (x.count('#'), x.count('.'), len(tagname(x))))


def tokenise(s, split='*#. '):
	buffer = ''
	for c in s:
		if c in split:
			if buffer.strip():
				yield buffer.strip()
				buffer = ''
		buffer += c
	if buffer.strip():
		yield buffer.strip()

def score_selector(selector):
	(low, ids, classes, tags) = (0, 0, 0, 0)
	for part in tokenise(selector):
		if part.startswith('.'):
			classes -= 1
		elif part.startswith('#'):
			ids -= 1
		elif part.startswith('*'):
			low += 1
		else:
			tags -= 1
	return (low, ids, classes, tags)

def compare(a, b):
	return sorted([(score_selector(s), -i, s) for (i, s) in enumerate([a, b])])[0][-1]


import re

def compare(a, b):
	[pa, pb] = [(x.count('#'), x.count('.'), len(re.findall("[\\w']+", x)) - x.count('#') - x.count('.')) for x in [a, b]]
	return a if pa > pb else b


import re

def key(t):
	(i, s) = t
	return (s.count('#'), s.count('.'), len(re.split('(?!<^)[ .#]+', s)), s != '*', i)

def compare(*args):
	return max(enumerate(args), key=key)[1]


def compare(a, b):
	return max((b, a), key=lambda sel: (sel.count('#'), sel.count('.'), sum((not t.startswith(('.', '#', '*')) for t in sel.split()))))