# The die is cast!

Your task in this kata is to write a "dice roller" that interprets a subset of [dice notation](http://en.wikipedia.org/wiki/Dice_notation).

# Description

In most role-playing games, die rolls required by the system are given in the form `AdX`. `A` and `X` are variables, separated by the letter **d**, which stands for *die* or *dice*.

 - `A` is the number of dice to be rolled (usually omitted if 1).
 - `X` is the number of faces of each die.

Here are some examples of input:

# Modifiers

As an addition to the above rules the input may also contain modifiers in the form `+N` or `-N` where `N` is an integer.

Here are some examples of input containing modifiers:

*Modifiers must be applied **after** all dice has been summed up.*

# Output

Your function must support two types of output depending on the second argument; *verbose* and *summed*.

## Summed output
If the verbose flag isn't set your function should sum up all the dice and modifiers and return the result as an integer.

## Verbose output
With the verbose flag your function should return an object/hash containing an array (`dice`) with all the dice rolls, and a integer (`modifier`) containing the sum of the modifiers which defaults to zero.

Example of verbose output:

# Invalid input
Here are some examples of invalid inputs:

# Additional information

 - Your solution should ignore all whitespace.
 - `roll` should return `false` for invalid input.

Difficulty: introductory

Starter code:

def roll(desc, verbose=False):
	

Solutions:
import re, random

def roll(desc, verbose=False):
    if not isinstance(desc,str): return False
    
    ans = re.findall(r'^(\d*)d(\d+)(([+\-]\d+)*)$', desc.replace(' ',''))
    
    if len(ans) == 0: return False
    
    dct = {i: eval(v) for i,v in enumerate(ans[0]) if v}
    dices = {'dice':     [ 1+random.randrange(dct[1]) for i in range(dct.get(0, 1)) ],
             'modifier': dct.get(2, 0) }
    
    return dices if verbose else sum(dices['dice']) + dices['modifier']

from random import randint

def roll(desc, verbose=False):
    try:
        a, x, *d = desc.replace(' ', '').replace('-', '+-').replace('+', 'd').split('d')
        dice = [randint(1, int(x)) for _ in range(int(a or '1'))]
        modifier = sum(map(int, d))
        if verbose:
            return {'dice': dice, 'modifier': modifier}
        else:
            return sum(dice) + modifier
    except:
        return False

from regex import findall, match
from random import randint # This is useless here seeing the test cases but let's do it well

def roll(desc, verbose=False):
    if not (isinstance(desc, str) and match(r"^(?: *(\d*d\d+|[+-]\d+))+$", desc)): return False
    dices, modifiers = [], 0
    for x in findall(r"(?: *(\d*d\d+|[+-]\d+))", desc):
        if 'd' in x:
            a, b = (1, int(x[1:])) if x[0] == 'd' else map(int, x.split('d'))
            dices.extend(randint(1, b) for _ in range(a))
        else:
            modifiers += int(x)
    return {"dice":dices, "modifier":modifiers} if verbose else sum(dices) + modifiers

import re
import random

def roll(desc, verbose=False):
    if isinstance(desc, str):
        desc_cleared = re.sub(r'\s', '', desc)
        match = re.match(r'^(\d*)d(\d+)((?:[+-]\d+)*)$', desc_cleared)
        if match:
            (dices, sides, modifiers) = match.groups()
            dices, sides = [int(x) if x else 1 for x in [dices, sides]]
            modifier = eval(modifiers) if modifiers else 0
            rolls = [random.randint(1, sides) for _ in range(dices)]
            return {'dice': rolls, 'modifier': modifier} if verbose else sum(rolls) + modifier
    return False

import re
from random import randint


def roll(desc, verbose=False):
    if not desc:
        return False
    m = re.match(r'^(\d*)d(\d+)(.*)$', desc)
    if not m:
        return False
    num_dice, sides, modifiers = m.groups()
    try:
        modifier = sum(
            int(a) for a in re.sub(r'([-+])', ' \g<1>', modifiers).split())
    except ValueError:
        return False
    nums = [randint(1, int(sides)) for _ in range(int(num_dice or 1))]
    if verbose:
        return {'dice': nums, 'modifier': modifier}
    return sum(nums) + modifier


from random import randint
def roll(desc, verbose=False):
    if not desc:
        return False
    desc = desc.replace(' ', '') 
    for letter in desc:
        if letter.isalpha() and letter != 'd':
            return False
    if desc != desc.replace('++', '+').replace('--','-'):
        return False
    
    operations = '-+'
    rolls = []
    result = ''
    
    for each in operations:
        desc = desc.replace(each, f' {each} ')
    for i, part in enumerate(desc.split(' ')):
        if 'd' in part:
            part = resolve(part, verbose)
            rolls.extend(part)
            result += str(sum(part))
        else:
            result += part
    result = eval(result)
    if verbose:
        return {'dice' : rolls, "modifier" : result - sum(rolls)}
    return result
    

def resolve(dice, verbose = None):
    dice = dice.split('d')
    d,t = list(map(int, dice)) if dice[0] != '' else (1, int(dice[1]))
    return [randint(1,t) for _ in range(d)]


import re #who needs random!
def roll(desc, v=False):
    try:
        q,d,m = re.search('^(\d*)d(\d+)(.*)$',desc.replace(' ','')).groups()
        r = [int(d)]*int(q or 1)
        m = eval(re.search('^(([+-]\d+)+)$',m).groups()[0]) if m else 0
        return { 'dice': r, 'modifier': m } if v else sum(r)+m
    except:
        return False

import re
from random import randint as d
def roll(desc, verbose=False):
    try:
        desc=desc.replace(' ','')
        if desc[0] =='d': desc= '1'+desc
        s=re.search('^(\d+)d(\d+)(([+-]?\d+)*)$',desc).groups()
        m = eval(s[2]) if s[2] != '' else 0 
        res = { 'dice': [d(1,int(s[1]))] * int(s[0]), 'modifier': m }
        return res if verbose else sum(res['dice'])+res['modifier']
    except:
        return False


def roll(desc, verbose=False):   
    if not desc:
        return False
    desc="".join(desc.split())  
    temp=""
    for i in desc:
        if i in "+-":
            break
        temp+=i
    for i in temp:
        if i not in "1234657890d":
            return False
    remain=desc[len(temp):]
    for i in remain:
        if i not in "1234657890d+-":
            return False
    for i in range(len(remain)-1):
        if remain[i+1] in "+-" and remain[i] in "+-":
            return False
    remain=eval(remain) if remain else 0
    temp=temp.split("d")    
    temp[0]=1 if not temp[0] else int(temp[0])
    return { "dice": [1]*temp[0], "modifier": remain } if verbose else 1*temp[0]+remain

import re
from random import randint

def roll(desc, verbose=False):
    if not isinstance(desc, str):
        return False
    match = re.match(r'^(\d*)d(\d+)((?:[+-]\d+)*)$', desc.replace(' ', ''))
    if match:
        dices, side, modifiers = match.groups()
        dices = int(dices) if dices else 1
        modifier = eval(modifiers) if modifiers else 0
        res = list(randint(1, int(side)) for _ in range(dices))
        return {'dice': res, 'modifier': modifier} if verbose else sum(res) + modifier
    return False