Kolakoski sequence: Difference between revisions
Content added Content deleted
(Add Rust implementation) |
|||
Line 1,379: | Line 1,379: | ||
</pre> |
</pre> |
||
=={{header|Rust}}== |
|||
<lang rust> |
|||
use itertools::Itertools; |
|||
fn get_kolakoski_sequence(iseq: &[usize], size: &usize) -> Vec<usize> { |
|||
assert!(*size > 0); |
|||
assert!(!iseq.is_empty()); |
|||
let mut kseq: Vec<usize> = Vec::default(); |
|||
// create an itertor which keeps repeating the initial sequence infinitely |
|||
let repeater = iseq.iter().cloned().cycle(); |
|||
// push the very first element, repeated as many times as the number |
|||
kseq.extend_from_slice(&vec![*iseq.get(0).unwrap()].repeat(*iseq.get(0).unwrap())); |
|||
//start cycling throught the initial sequence, but skip the very first one |
|||
for (k_counter, elem) in repeater.enumerate().skip(1) { |
|||
// push the given element |
|||
kseq.push(elem); |
|||
// and repeat the current element as many times |
|||
// as it's needed based on the previous elements |
|||
kseq.extend_from_slice(&vec![elem].repeat(*kseq.get(k_counter).unwrap() - 1)); |
|||
// finish generation when the Kolakoski sequence has reached the given length |
|||
if kseq.len() >= *size { |
|||
break; |
|||
} |
|||
} |
|||
// truncate it as it might have more elements than needed |
|||
kseq[0..*size].to_vec() |
|||
} |
|||
fn is_kolakoski(kseq: &[usize]) -> bool { |
|||
assert!(!kseq.is_empty()); |
|||
// calculate the RLE |
|||
let rle: Vec<usize> = kseq |
|||
.iter() |
|||
.batching(|it| { |
|||
it.next() |
|||
.map(|v| it.take_while_ref(|&v2| v2 == v).count() + 1) |
|||
}) |
|||
.collect(); |
|||
rle.iter().zip(kseq).filter(|&(a, b)| a == b).count() == rle.len() |
|||
} |
|||
fn main() { |
|||
let lengths = vec![20, 20, 30, 30]; |
|||
let seqs = vec![vec![1, 2], vec![2, 1], vec![1, 3, 1, 2], vec![1, 3, 2, 1]]; |
|||
for (seq, length) in seqs.iter().zip(&lengths) { |
|||
let kseq = get_kolakoski_sequence(&seq, length); |
|||
println!("Starting sequence: {:?}", seq); |
|||
println!("Kolakoski sequence: {:?}", kseq); |
|||
println!("Possible Kolakoski sequence? {:?}", is_kolakoski(&kseq)); |
|||
} |
|||
} |
|||
</lang> |
|||
{{out}} |
|||
<pre> |
|||
Starting sequence: [1, 2] |
|||
Kolakoski sequence: [1, 2, 2, 1, 1, 2, 1, 2, 2, 1, 2, 2, 1, 1, 2, 1, 1, 2, 2, 1] |
|||
Possible Kolakoski sequence? true |
|||
Starting sequence: [2, 1] |
|||
Kolakoski sequence: [2, 2, 1, 1, 2, 1, 2, 2, 1, 2, 2, 1, 1, 2, 1, 1, 2, 2, 1, 2] |
|||
Possible Kolakoski sequence? true |
|||
Starting sequence: [1, 3, 1, 2] |
|||
Kolakoski sequence: [1, 3, 3, 3, 1, 1, 1, 2, 2, 2, 1, 3, 1, 2, 2, 1, 1, 3, 3, 1, 2, 2, 2, 1, 3, 3, 1, 1, 2, 1] |
|||
Possible Kolakoski sequence? true |
|||
Starting sequence: [1, 3, 2, 1] |
|||
Kolakoski sequence: [1, 3, 3, 3, 2, 2, 2, 1, 1, 1, 1, 1, 3, 3, 2, 2, 1, 1, 3, 2, 1, 1, 1, 1, 3, 3, 3, 2, 2, 1] |
|||
Possible Kolakoski sequence? false |
|||
</pre> |
|||
=={{header|Sidef}}== |
=={{header|Sidef}}== |
||
{{trans|Ruby}} |
{{trans|Ruby}} |