Last active
February 17, 2020 18:25
-
-
Save ZevEisenberg/52330bf5a28549db91bb29512b808f05 to your computer and use it in GitHub Desktop.
Find how long it takes for an async siteswap to loop
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// main.swift | |
// Swapper | |
// | |
// Created by Zev Eisenberg on 12/4/17. | |
// Copyright © 2017 Zev Eisenberg. All rights reserved. | |
// | |
// Code ported from https://www.reddit.com/r/juggling/comments/7839h0/find_number_of_beats_to_loop_a_given_siteswap/douuezu/ | |
// It finds how many beats you would have to juggle an async siteswap pattern before | |
// all the balls are back in their starting state. | |
func gcd(_ m: Int, _ n: Int) -> Int { | |
var a = 0 | |
var b = max(m, n) | |
var r = min(m, n) | |
while r != 0 { | |
a = b | |
b = r | |
r = a % b | |
} | |
return b | |
} | |
assert(gcd(3, 6) == 3) | |
assert(gcd(15, 20) == 5) | |
assert(gcd(16, 20) == 4) | |
func lcm(_ m: Int, _ n: Int) -> Int { | |
return m / gcd(m, n) * n | |
} | |
assert(lcm(10, 8) == 40) | |
extension Array where Element: Numeric { | |
var sum: Element { | |
return reduce(into: 0, { $0 += $1 }) | |
} | |
} | |
extension BinaryInteger { | |
var isOdd: Bool { | |
return self % 2 == 1 | |
} | |
var doubledIfOdd: Self { | |
if isOdd { | |
return self * 2 | |
} | |
return self | |
} | |
} | |
assert([1, 2, 3].sum == 6) | |
assert(1.doubledIfOdd == 2) | |
assert(4.doubledIfOdd == 4) | |
//let siteswap = [1, 2, 3, 4, 5, 6, 7] | |
//let siteswap = [5, 0, 1] | |
//let siteswap = [5, 1] | |
let siteswap = [9, 7, 5, 3, 1] | |
//let siteswap = [4, 4, 1] | |
//let siteswap = [7, 4, 4] | |
//let siteswap = [4, 2] | |
var tested = Array(repeating: false, count: siteswap.count) | |
var loops: [[Int]] = [] | |
var loopNum = 0 | |
// First, find the loops in the siteswap. Examples: | |
// - the loops in 1234567 are (124, 365, 7). | |
// - the loops in 51 are (51). | |
// - the loops in 42 are (4, 2). | |
for i in 0..<siteswap.count where !tested[i] && siteswap[i] != 0 { | |
var curTest = i | |
inner: while true { | |
if tested[curTest] { | |
loopNum += 1 | |
break inner | |
} | |
else { | |
if loops.count <= loopNum { | |
loops.append([]) | |
} | |
loops[loopNum].append(siteswap[curTest]) | |
tested[curTest] = true | |
curTest = (curTest + siteswap[curTest]) % siteswap.count | |
} | |
} | |
} | |
print(loops) | |
let leastCommonMultiple = loops.map { loop in loop.sum.doubledIfOdd }.reduce(into: 1, { $0 = lcm($0, $1) }) | |
print(leastCommonMultiple) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment