Background (feel free to skip)
Ordinals are the abstract representation of well-orders. A well-order of a set is a total order, which basically means that every element in the set can be compared against any other element in the set, and one of them is either smaller or larger. Also there are no cycles.
The crucial difference between total orders and well-orders is that a well order is always well-founded. This means that every nonempty subset of a well-ordered set has a least element, which implies that an infinite descending chain is impossible; An infinite sequence \$a_1\gt a_2\gt a_3\gt a_4 \gt ...\$ doesn't exist.
This is useful for many things, one of them being proving that recursion terminates. For example, here is the definition of the Ackermann function:
\$ A(0,n)=n+1\\ A(m+1,0)=A(m,1)\\ A(m+1,n+1)=A(m,A(m+1,n)) \$
Can you see why it always terminates? We call the Ackermann function with a 2-tuple of natural numbers, and when we recurse, the tuple is smaller under the standard tuple ordering (lexicographic ordering: first compare the first elements, then the second ones). Because the standard tuple ordering is a well-ordering (\$\omega^2\$ in fact), the recursion must eventually terminate.
With the knowlege that \$\omega^2\$ is well-founded we were able to prove that the Ackermann function is total. There are of course larger ordinals, one of them being \$\varepsilon_0\$. All ordinals below \$\varepsilon_0\$ can be represented with a simple ordinal notation using ragged lists.
We can use the standard lexicographic ordering of ragged lists. However there is a problem. The ordering, while a total order, is not a well order. For example, [ [[]] ] > [ [], [[]] ] > [ [], [], [[]] ] > [ [], [], [], [[]] ] > ...
There is a solution though. We can just make sure that in every list, the elements are in decreasing order. This means that [ [], [[]] ]
is not an ordinal, since [[]]
is larger than []
Here is a table of some valid ordinal notations
Notation | Value |
---|---|
[] |
\$0\$ |
[[]] |
\$\omega^0=1\$ |
[[],[]] |
\$\omega^0+\omega^0=2\$ |
[[[]]] |
\$\omega^{\omega^0}=\omega\$ |
[[[[]],[]],[],[]] |
\$\omega^{\omega^{\omega^0}+\omega^0}+\omega^0+\omega^0=\omega^{\omega+1}+2\$ |
Task
You are given a ragged list containing only lists. Your task is to determine if that list is an ordinal. A list is an ordinal iff each of its elements are ordinals, and the list is decreasing.
Comparison between ordinals can be done with simple lexicographic comparison. That is, given two lists, compare the first elements. If they are equal, compare the second ones and so on. If one of the lists runs out of elements, that list is smaller.
For example, say you got the ragged list [a,b,c,d]
. You must first make sure that a
, b
, c
and d
are ordinals. Then, make sure that \$a\ge b\ge c\ge d\$, using lexicographic ordering. If both conditions are true, then it's an ordinal. When there is just one element in the list, the second condition is always true. And when the list is empty, both conditions are vacuously true.
Standard decision-problem rules apply.
Test cases
[] -> True
[[]] -> True
[[[]]] -> True
[[], []] -> True
[[[[]]]] -> True
[[[], []]] -> True
[[[]], []] -> True
[[], [[]]] -> False
[[], [], []] -> True
[[[[[]]]]] -> True
[[[[], []]]] -> True
[[[[]], []]] -> True
[[[], [[]]]] -> False
[[[], [], []]] -> True
[[[[]]], []] -> True
[[[], []], []] -> True
[[[]], [[]]] -> True
[[[]], [], []] -> True
[[], [[[]]]] -> False
[[], [[], []]] -> False
[[], [[]], []] -> False
[[], [], [[]]] -> False
[[], [], [], []] -> True
[[[[[[]]]]]] -> True
[[[[[], []]]]] -> True
[[[[[]], []]]] -> True
[[[[], [[]]]]] -> False
[[[[], [], []]]] -> True
[[[[[]]], []]] -> True
[[[[], []], []]] -> True
[[[[]], [[]]]] -> True
[[[[]], [], []]] -> True
[[[], [[[]]]]] -> False
[[[], [[], []]]] -> False
[[[], [[]], []]] -> False
[[[], [], [[]]]] -> False
[[[], [], [], []]] -> True
[[[[[]]]], []] -> True
[[[[], []]], []] -> True
[[[[]], []], []] -> True
[[[], [[]]], []] -> False
[[[], [], []], []] -> True
[[[[]]], [[]]] -> True
[[[], []], [[]]] -> True
[[[[]]], [], []] -> True
[[[], []], [], []] -> True
[[[]], [[[]]]] -> False
[[[]], [[], []]] -> False
[[[]], [[]], []] -> True
[[[]], [], [[]]] -> False
[[[]], [], [], []] -> True
[[], [[[[]]]]] -> False
[[], [[[], []]]] -> False
[[], [[[]], []]] -> False
[[], [[], [[]]]] -> False
[[], [[], [], []]] -> False
[[], [[[]]], []] -> False
[[], [[], []], []] -> False
[[], [[]], [[]]] -> False
[[], [[]], [], []] -> False
[[], [], [[[]]]] -> False
[[], [], [[], []]] -> False
[[], [], [[]], []] -> False
[[], [], [], [[]]] -> False
[[], [], [], [], []] -> True
[[[[[[[]]]]]]] -> True
[[[[[[], []]]]]] -> True
[[[[[[]], []]]]] -> True
[[[[[], [[]]]]]] -> False
[[[[[], [], []]]]] -> True
[[[[[[]]], []]]] -> True
[[[[[], []], []]]] -> True
[[[[[]], [[]]]]] -> True
[[[[[]], [], []]]] -> True
[[[[], [[[]]]]]] -> False
[[[[], [[], []]]]] -> False
[[[[], [[]], []]]] -> False
[[[[], [], [[]]]]] -> False
[[[[], [], [], []]]] -> True
[[[[[[]]]], []]] -> True
[[[[[], []]], []]] -> True
[[[[[]], []], []]] -> True
[[[[], [[]]], []]] -> False
[[[[], [], []], []]] -> True
[[[[[]]], [[]]]] -> True
[[[[], []], [[]]]] -> True
[[[[[]]], [], []]] -> True
[[[[], []], [], []]] -> True
[[[[]], [[[]]]]] -> False
[[[[]], [[], []]]] -> False
[[[[]], [[]], []]] -> True
[[[[]], [], [[]]]] -> False
[[[[]], [], [], []]] -> True
[[[], [[[[]]]]]] -> False
[[[], [[[], []]]]] -> False
[[[], [[[]], []]]] -> False
[[[], [[], [[]]]]] -> False
[[[], [[], [], []]]] -> False
[[[], [[[]]], []]] -> False
[[[], [[], []], []]] -> False
[[[], [[]], [[]]]] -> False
[[[], [[]], [], []]] -> False
[[[], [], [[[]]]]] -> False
[[[], [], [[], []]]] -> False
[[[], [], [[]], []]] -> False
[[[], [], [], [[]]]] -> False
[[[], [], [], [], []]] -> True
[[[[[[]]]]], []] -> True
[[[[[], []]]], []] -> True
[[[[[]], []]], []] -> True
[[[[], [[]]]], []] -> False
[[[[], [], []]], []] -> True
[[[[[]]], []], []] -> True
[[[[], []], []], []] -> True
[[[[]], [[]]], []] -> True
[[[[]], [], []], []] -> True
[[[], [[[]]]], []] -> False
[[[], [[], []]], []] -> False
[[[], [[]], []], []] -> False
[[[], [], [[]]], []] -> False
[[[], [], [], []], []] -> True
[[[[[]]]], [[]]] -> True
[[[[], []]], [[]]] -> True
[[[[]], []], [[]]] -> True
[[[], [[]]], [[]]] -> False
[[[], [], []], [[]]] -> True
[[[[[]]]], [], []] -> True
[[[[], []]], [], []] -> True
[[[[]], []], [], []] -> True
[[[], [[]]], [], []] -> False
[[[], [], []], [], []] -> True
[[[[]]], [[[]]]] -> True
[[[], []], [[[]]]] -> False
[[[[]]], [[], []]] -> True
[[[], []], [[], []]] -> True
[[[[]]], [[]], []] -> True
[[[], []], [[]], []] -> True
[[[[]]], [], [[]]] -> False
[[[], []], [], [[]]] -> False
[[[[]]], [], [], []] -> True
[[[], []], [], [], []] -> True
[[[]], [[[[]]]]] -> False
[[[]], [[[], []]]] -> False
[[[]], [[[]], []]] -> False
[[[]], [[], [[]]]] -> False
[[[]], [[], [], []]] -> False
[[[]], [[[]]], []] -> False
[[[]], [[], []], []] -> False
[[[]], [[]], [[]]] -> True
[[[]], [[]], [], []] -> True
[[[]], [], [[[]]]] -> False
[[[]], [], [[], []]] -> False
[[[]], [], [[]], []] -> False
[[[]], [], [], [[]]] -> False
[[[]], [], [], [], []] -> True
[[], [[[[[]]]]]] -> False
[[], [[[[], []]]]] -> False
[[], [[[[]], []]]] -> False
[[], [[[], [[]]]]] -> False
[[], [[[], [], []]]] -> False
[[], [[[[]]], []]] -> False
[[], [[[], []], []]] -> False
[[], [[[]], [[]]]] -> False
[[], [[[]], [], []]] -> False
[[], [[], [[[]]]]] -> False
[[], [[], [[], []]]] -> False
[[], [[], [[]], []]] -> False
[[], [[], [], [[]]]] -> False
[[], [[], [], [], []]] -> False
[[], [[[[]]]], []] -> False
[[], [[[], []]], []] -> False
[[], [[[]], []], []] -> False
[[], [[], [[]]], []] -> False
[[], [[], [], []], []] -> False
[[], [[[]]], [[]]] -> False
[[], [[], []], [[]]] -> False
[[], [[[]]], [], []] -> False
[[], [[], []], [], []] -> False
[[], [[]], [[[]]]] -> False
[[], [[]], [[], []]] -> False
[[], [[]], [[]], []] -> False
[[], [[]], [], [[]]] -> False
[[], [[]], [], [], []] -> False
[[], [], [[[[]]]]] -> False
[[], [], [[[], []]]] -> False
[[], [], [[[]], []]] -> False
[[], [], [[], [[]]]] -> False
[[], [], [[], [], []]] -> False
[[], [], [[[]]], []] -> False
[[], [], [[], []], []] -> False
[[], [], [[]], [[]]] -> False
[[], [], [[]], [], []] -> False
[[], [], [], [[[]]]] -> False
[[], [], [], [[], []]] -> False
[[], [], [], [[]], []] -> False
[[], [], [], [], [[]]] -> False
[[], [], [], [], [], []] -> True