Skip to content

Instantly share code, notes, and snippets.

@algrant
Created September 28, 2022 00:26
Show Gist options
  • Save algrant/3a4ab4c4228b288043ca83f3229d1743 to your computer and use it in GitHub Desktop.
Save algrant/3a4ab4c4228b288043ca83f3229d1743 to your computer and use it in GitHub Desktop.
ASCII - Asalato Rhythms (aka patica, kass-kass, kashaka)
# find two handed rhythms
# every char in pattern represents a beat, clicks can happen on or off beat.
patterns = {
# heli
"h": [0, 0],
# den den
"dd": [1, 0, 1, 0],
# air turn
"at": [1, 0, 0, 0],
# flip flop
"ffg": [1, 0, 0, 1, 0, 0],
}
patterns_with_reverse_helis = {
# flip flop with reverse heli
"frfg": [1, 0, 0, 0, 0, 1, 0, 0],
# den den with reverse heli
"drd": [1, 0, 0, 0, 1, 0],
}
def pattern_to_rhythm(pattern):
out = []
n = ""
for c in pattern:
n += c
if n in patterns:
out += patterns[n]
n = ""
if n != "":
raise Exception(f"Could not match combination '{n}'")
return out
def test():
tests = [
["ffg", [1, 0, 0, 1, 0, 0]],
["h", [0, 0]],
["dd", [1, 0, 1, 0]],
["at", [1, 0, 0, 0]],
]
for input, output in tests:
print(pattern_to_rhythm(input) == output)
def rhythm_to_string(rhythm):
if rhythm[0] in (0, 1):
return "".join(["/" if r == 1 else " " for r in rhythm])
out = ""
left = rhythm[0]
right = rhythm[1]
for i in range(len(rhythm[0])):
if left[i] and right[i]:
out += "X"
elif left[i]:
out += "/"
elif right[i]:
out += "\\"
else:
out += "."
return out
def format_pattern(pattern):
if type(pattern) == str:
print("_".join(list(pattern)) + "_")
print(rhythm_to_string(pattern_to_rhythm(pattern)))
else:
left = pattern[0]
right = pattern[1]
print("_".join(list(left)) + "_")
print(rhythm_to_string([pattern_to_rhythm(left), pattern_to_rhythm(right)]))
print("_".join(list(right)) + "_")
# format_pattern(["ffgh", "ddat"])
def pattern_combos(n):
options = []
for string in patterns.keys():
if len(string) <= n:
options.append(string)
out = []
for option in options:
if len(option) == n:
out.append(option)
else:
for opt in pattern_combos(n - len(option)):
out.append(option + opt)
return out
def filtered_pattern_combos(n):
all = pattern_combos(n)
filtered = []
for pattern in all:
if "hh" in pattern:
continue
if "dddd" in pattern:
continue
if "atat" in pattern:
continue
filtered.append(pattern)
return filtered
def all_hands(n):
patterns = filtered_pattern_combos(n)
n = 0
for x in range(len(patterns)):
for y in range(x + 1, len(patterns)):
n += 1
print(f"{n}.")
format_pattern([patterns[x], patterns[y]])
print("")
all_hands(4)
# todo -- filter out repetitions of patterns (i.e. a length 5 pattern should not contain a length 4 pattern, we should just skip that one).
# find two handed patterns
# every char represents a beat, clicks can happen on or off beat.
patterns = {
# heli
"h": [0, 0],
# den den
"dd": [1, 0, 1, 0],
# air turn
"at": [1, 0, 0, 0],
# flip flop
"ffg": [1, 0, 0, 1, 0, 0],
}
patterns_with_reverse_helis = {
# flip flop with reverse heli
"frfg": [1, 0, 0, 0, 0, 1, 0, 0],
# den den with reverse heli
"drd": [1, 0, 0, 0, 1, 0],
}
def pattern_to_rhythm(pattern):
out = []
n = ""
for c in pattern:
n += c
if n in patterns:
out += patterns[n]
n = ""
if n != "":
raise Exception(f"Could not match combination '{n}'")
return out
def test():
tests = [
["ffg", [1, 0, 0, 1, 0, 0]],
["h", [0, 0]],
["dd", [1, 0, 1, 0]],
["at", [1, 0, 0, 0]],
]
for input, output in tests:
print(pattern_to_rhythm(input) == output)
def rhythm_to_string(rhythm):
if rhythm[0] in (0, 1):
return "".join(["/" if r == 1 else " " for r in rhythm])
out = ""
left = rhythm[0]
right = rhythm[1]
for i in range(len(rhythm[0])):
if left[i] and right[i]:
out += "X"
elif left[i]:
out += "/"
elif right[i]:
out += "\\"
else:
out += "."
return out
def format_pattern(pattern):
if type(pattern) == str:
print("_".join(list(pattern)) + "_")
print(rhythm_to_string(pattern_to_rhythm(pattern)))
else:
left = pattern[0]
right = pattern[1]
print("_".join(list(left)) + "_")
print(rhythm_to_string([pattern_to_rhythm(left), pattern_to_rhythm(right)]))
print("_".join(list(right)) + "_")
# format_pattern(["ffgh", "ddat"])
def pattern_combos(n):
options = []
for string in patterns.keys():
if len(string) <= n:
options.append(string)
out = []
for option in options:
if len(option) == n:
out.append(option)
else:
for opt in pattern_combos(n - len(option)):
out.append(option + opt)
return out
def filtered_pattern_combos(n):
all = pattern_combos(n)
filtered = []
for pattern in all:
if "hh" in pattern:
continue
if "dddd" in pattern:
continue
if "atat" in pattern:
continue
filtered.append(pattern)
return filtered
def all_hands(n):
patterns = filtered_pattern_combos(n)
n = 0
for x in range(len(patterns)):
for y in range(x + 1, len(patterns)):
n += 1
print(f"{n}.")
format_pattern([patterns[x], patterns[y]])
print("")
all_hands(4)
TODO:
1. filter out repetitions of patterns (i.e. a length 5 pattern should not contain a length 4 pattern, we should just skip that one).
Generate a list of two handed asalato patterns
1.
h_d_d_h_
..X./...
h_a_t_h_
2.
h_d_d_h_
..X./\..
h_f_f_g_
3.
h_d_d_h_
\.X.X...
d_d_a_t_
4.
h_d_d_h_
\./.X.\.
a_t_d_d_
5.
h_d_d_h_
\./\/...
f_f_g_h_
6.
h_a_t_h_
..X..\..
h_f_f_g_
7.
h_a_t_h_
\.X.\...
d_d_a_t_
8.
h_a_t_h_
\./.\.\.
a_t_d_d_
9.
h_a_t_h_
\./\....
f_f_g_h_
10.
h_f_f_g_
\.X.\/..
d_d_a_t_
11.
h_f_f_g_
\./.\/\.
a_t_d_d_
12.
h_f_f_g_
\./\./..
f_f_g_h_
13.
d_d_a_t_
X./.X.\.
a_t_d_d_
14.
d_d_a_t_
X./\/...
f_f_g_h_
15.
a_t_d_d_
X..\/./.
f_f_g_h_
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment