8
1
This challenge posed an algorithm for encoding an integer n as another integer r. What follows is a succinct explanation of that algorithm, using n=60 as an example.
The original algorithm
First, we encode the number as a string of brackets.
- If
n = 1, return an empty string. - Otherwise, we take
n's prime decomposition sorted ascending and replace each element with its prime index (1-indexed) in brackets.60 = 2*2*3*5 => [1][1][2][3] - Do this recursively until all we have are brackets.
[1][1][2][3] => [][][[1]][[2]] => [][][[]][[[1]]] => [][][[]][[[]]]
- If
Once we have our string of brackets, we convert that into an integer with the following process.
- Convert each opening bracket to a
1and each closing bracket to a0.[][][[]][[[]]] => 10101100111000 - Remove all trailing
0s and the final1.10101100111000 => 1010110011 - Convert the final string of
0s and1s from binary to an integer.1010110011 => 691
- Convert each opening bracket to a
Decoding this encoding
An interesting property of this algorithm is that it is not surjective. Not every integer can be the result of this encoding.
- Firstly, the binary representation of the result
r, must bebalance-ablein that the number of0s must never exceed the number of1s. A short falsey test case is4, which is100in binary. - Secondly, the brackets in the binary representation must be
sorted ascendingwhen the final1and trailing0s are appended once more. A short falsey test case is12 <= 1100 <= 110010 <= (())().
However, just determining if a number is decode-able in this way would make for a short challenge. Instead, the challenge is to repeatedly decode a given input until either an un-decode-able number or a cycle is reached, and returning the resulting sequence of numbers.
The challenge
- Given a number
1 <= r <= 2**20 = 1048576, return the sequence of numbers thatrsuccessively decodes into, starting withritself and ending with an un-decode-able number or a cycle. - If an un-decode-able number is given as input, such as
4or12, will return a list containing only the input. - A sequence ending in a cycle should be indicated in some way, either by appending or prepending a marker (pick any non-positive integer, string, list, etc. as a marker, but keep it consistent), or by repeating the cycle in some way (repeating the first element, repeating the whole cycle, repeating infinitely, etc.).
- On the off chance that any of the sequences are infinite (by increasing forever, for example), consider it undefined behavior.
- This is code golf. Smallest number of bytes wins.
A worked example of decoding
1 -> 1 -> 1100 -> [[]] -> [2] -> 3
-> 3 -> 11 -> 111000 -> [[[]]] -> [[2]] -> [3] -> 5
-> 5 -> 101 -> 101100 -> [][[]] -> 2*[2] -> 2*3 -> 6
-> 6 -> 110 -> 110100 -> [[][]] -> [2*2] -> [4] -> 7
-> 7 -> 111 -> 11110000 -> [[[[]]]] -> [[[2]]] -> [[3]] -> [5] -> 11
-> 11 -> 1011 -> 10111000 -> [][[[]]] -> 2*[[2]] -> 2*[3] -> 2*5 -> 10
-> 10 -> 1010 -> 101010 -> [][][] -> 2*2*2 -> 8
-> 8 -> 1000 ERROR: Unbalanced string
Test cases
4 -> [4]
12 -> [12]
1 -> [1, 3, 5, 6, 7, 11, 10, 8]
2 -> [2, 4]
13 -> [13, 13] # cycle is repeated once
23 -> [23, 22, 14, 17]
51 -> [51, 15, 31, 127, 5381]
691 -> [691, 60]
126 -> [126, 1787, 90907]
1019 -> [1019, 506683, 359087867, 560390368728]
Suggestions and feedback for this challenge are most welcome. Good luck and good golfing!
Sandbox. – user202729 – 2017-12-14T06:52:24.257
How does
1give3? – Leaky Nun – 2017-12-14T12:15:25.090@LeakyNun
1--(append an1and trailing zeros)-->1100-->[[]]-->[[1]]-->[2]-->3– Colera Su – 2017-12-14T12:58:18.2876->110->110100which isn't valid, right? So should input1give[1,3,5,6]? – dylnan – 2017-12-15T04:55:08.800And for 7:
7->111->11110000->[[[[]]]]->4th prime = 7? Maybe I don't understand the algorithm – dylnan – 2017-12-15T05:00:59.870@dylnan
6->110->110100->[[][]]->[2*2]->[4]->7->111->11110000->[[[[]]]]->[[[2]]]->[[3]]->[5]->11. I hope this helps you understand the algorithm better. – Sherlock9 – 2017-12-15T06:43:10.393Yes it does, thank you – dylnan – 2017-12-15T17:17:33.917