Your task is to validate rhythm with a meter.

_________________________________________________
Rules:

1. Rhythmic division requires that in one whole note (1) there are two half notes (2) or four quarter notes (4) or eight eighth notes (8). 
Examples: 1 = 2 + 2, 1 = 4 + 4 + 4 + 4 ... 
Note that: 2 = 4 + 4, 4 = 8 + 8, 2 = 8 + 8 + 4 ... 

2. Meter gives an information how many rhythmic types of notes should be in one bar. Bar is the the primary section of a musical score.
Examples: 
          4/4 -> 4 quarter notes in a bar
          5/2 -> 5 half notes in a bar
          3/8 -> 3 eighth notes in a bar
Note that: 
for 4/4 valid bars are: '4444', '88888888', '2488' ...
for 5/2 valid bars are: '22222', '2244244', '8888244888844' ...
for 3/8 valid bars are: '888', '48' ...

3. Anacrusis occurs when all bars but the first and last are valid, and the notes in the first and last bars when combined would also make a valid bar.

Examples: 
for 4/4 valid anacrusis is -> 44|...|44 or 88|...|888888 or 2|...|488 
for 5/2 valid anacrusis is -> 22|...|222 or 222|...|22 or  2244|...|244
for 3/8 valid anacrusis is -> 8|...|88 or 4|...|8 or 8|...|4
Note:
When anacrusis is valid but other bars in score are not -> return 'Invalid rhythm'
________________________________________________

Input:
meter - array: eg. [4, 4],
score - string, bars separated with '|': eg. '4444|8484842|888'

Output:
string message: 'Valid rhythm', 'Valid rhythm with anacrusis' or 'Invalid rhythm'

Difficulty: introductory

Starter code:

def validate_rhythm(meter, score):
	

Solutions:
def is_valid_bar(bar, meter):
    total = 0
    for n in bar:
        n = int(n)
        if n & (n - 1):
            return False
        total += 1.0 / n
    return total == meter

def validate_rhythm(meter, score):
    n, d = meter
    if d & (d - 1):
        return "Invalid rhythm"
    bars = score.split("|")
    meter = float(n) / d
    if all(is_valid_bar(bar, meter) for bar in bars[1:-1]):
        if all(is_valid_bar(bar, meter) for bar in (bars[0], bars[-1])):
                return "Valid rhythm"
        if len(bars) > 1 and is_valid_bar(bars[0] + bars[-1], meter):
                return "Valid rhythm with anacrusis"
    return "Invalid rhythm"

from fractions import Fraction


VALID_CHARS = {"1", "2", "4", "8"}


def note_sum(s):
    return sum(Fraction(1, x) for x in map(int, s))


def validate_rhythm(meter, score):
    if meter[1] not in [1, 2, 4, 8]:
        return "Invalid rhythm"
    ss = score.split("|")
    if not all(s and all(x in VALID_CHARS for x in s) for s in ss):
        return "Invalid rhythm"

    note = Fraction(*meter)
    if all(note_sum(s) == note for s in ss):
        return "Valid rhythm"
    ss[0] += ss.pop()
    if all(note_sum(s) == note for s in ss):
        return "Valid rhythm with anacrusis"
    return "Invalid rhythm"

from functools import reduce

def validate_rhythm(meter, score):
    num, den, meter = *meter, int.__truediv__(*meter)
    bars = [[int(d) for d in bar] for bar in score.split("|")]
    prod = den * reduce(int.__mul__, (n for bar in bars for n in bar))
    if not prod & (prod - 1):
        divs = [sum(1/n for n in bar) for bar in bars]
        if all(div == meter for div in divs[1:-1]):
            if all(div == meter for div in (divs[0], divs[-1])):
                return "Valid rhythm"
            if divs[1:] and divs[0] + divs[-1] == meter:
                return "Valid rhythm with anacrusis"
    return "Invalid rhythm"


def validate_rhythm(meter, score):
    if [c for c in score if c not in '|1248'] or meter[1] not in [1,2,4,8] : return 'Invalid rhythm'
    bar = meter[0] * 8 / meter[1]
    l = [len(b) for b in score.replace('4', '88').replace('2', '8'*4).replace('1', '8'*8).split('|')]
    if all(i == bar for i in l): return 'Valid rhythm'
    if l[0] + l[-1] == bar and all(i == bar for i in l[1:-1]): return 'Valid rhythm with anacrusis'
    return 'Invalid rhythm'

def validate_rhythm(meter, score):
    scores = score.split('|')
    anacrusis = False
    if 16 % meter[1] : return 'Invalid rhythm'
    for i, score in enumerate(scores): 
        sums = sum(16/int(s) for s in score)
        if sums < meter[0] * 16 / meter[1]:
            if i == len(scores) -1 or i == 0:
                anacrusis = True
            else:
                return 'Invalid rhythm'
        elif sums > meter[0] * 16 / meter[1]: return 'Invalid rhythm'
    if anacrusis:
        return 'Valid rhythm with anacrusis'
    else:
        return 'Valid rhythm'

def validate_rhythm(meter, score):
    from fractions import Fraction
    if meter[1] not in [1,2,4,8]:
        return 'Invalid rhythm'
    
    time_signature = Fraction(*meter)
    bars = [sum(Fraction(1, int(c)) for c in bar) for bar in score.split('|')]

    if all(bar == time_signature for bar in bars):
        return 'Valid rhythm'
    
    if all(bar == time_signature for bar in bars[1:-1]) and bars[0] + bars[-1] == time_signature:
        return 'Valid rhythm with anacrusis'
        
    return 'Invalid rhythm'

def validate_rhythm(m, score):
    t = m[0]/m[1]
    if t == 1 and m[0] not in [1,2,4,8]: return 'Invalid rhythm'
    a = score.split('|')
    
    for c in score:
        if c not in '|1248': return 'Invalid rhythm'
    
    for s in a[1:-1]:
        if sum([1/int(c) for c in s]) != t:
            return 'Invalid rhythm'
    
    bool = True
    for s in [a[0],a[-1]]:
        if sum([1/int(c) for c in s]) != t:
            bool = False
    if bool: return 'Valid rhythm'
    
    if sum([1/int(c) for c in a[0]+a[-1]]) == t:
        return 'Valid rhythm with anacrusis'
    
    return 'Invalid rhythm'


def validate_rhythm(meter, score):
    a, b = meter
    if not set(score) <= set('1248|') or b not in (1, 2, 4, 8): 
        return 'Invalid rhythm'
    bars = [sum(1 / int(x) for x in bar) for bar in score.split('|')]
    m = a / b
    if all(x == m for x in bars): 
        return 'Valid rhythm'
    if len(bars) >= 2 and all(x == m for x in bars[1:-1] + [bars[0] + bars[-1]]):
        return 'Valid rhythm with anacrusis'
    return 'Invalid rhythm'

def validate_rhythm(meter, score):
    if meter[1] not in (1,2,4,8):
        return "Invalid rhythm"
    
    score = score.translate(score.maketrans("1248", "8421"))
    target = meter[0] * 8 // meter[1]
    
    def valid(s):
        return sum(int(c) for c in s) == target
    
    bars = score.split("|")
    if any(not valid(bar) for bar in bars[1:-1]):
        return "Invalid rhythm"
    
    if valid(bars[0]) and valid(bars[-1]):
        return "Valid rhythm"
    
    if valid(bars[0] + bars[-1]):
        return "Valid rhythm with anacrusis"
    else:
        return "Invalid rhythm"

def validate_rhythm(meter, score):
    print(score)
    if meter[1] not in [1,2,4,8]:
        return "Invalid rhythm"
    goal = meter[0]*(1/meter[1])
    print(goal)
    score = [[1/int(f) for f in i] for i in score.split("|")]
    
    if len(score) == 1:
        if goal == sum([sum(i) for i in score]):
            return 'Valid rhythm'
        else:
            return 'Invalid rhythm'
    for i in score[1:-1]:
        if sum(i) != goal:
            return "Invalid rhythm"
    if sum(score[0]) + sum(score[-1]) == goal:
        return 'Valid rhythm with anacrusis'
    if sum(score[0]) + sum(score[-1]) != goal*2:
        return "Invalid rhythm"
    return "Valid rhythm"