3
Statement
Given N distinct integers, output them in order such that
- for any integer J from 2 to N,
- for any K>0 obtainable by dividing J by 2 (rounding down) at least one time,
- the Jth integer output is larger than the Kth if and only if the division by 2 that gave K (i.e., the last division) divided an odd integer.
- for any K>0 obtainable by dividing J by 2 (rounding down) at least one time,
Note: this is for one-based index, as in common language, because it makes the statement less hairy. The motivating code below uses zero-based indexes.
This is a code golf. Output is a list of integers.
Example
Given the first 10 primes (in any order), the output must be in this order
17 7 23 3 13 19 29 2 5 11
which, when rewritten as a binary tree, gives:
17
/---------------\
7 23
/-------\ /------\
3 13 19 29
/-\ /
2 5 11
Note: when walking up in this tree towards its root, the parent is obtained by dividing the (one-based) index by two. The statement's "odd" and "larger" correspond to node at index J being compared to one of it's ancestor node at index K situated on the left and above.
Motivation
This allows search in a static list by monotomy, simpler and typically faster than dichotomy.
// Search t in table *p of length n (with n<=MAX_INT/2 and n>=0)
// Returns the index (zero-based), or -1 for not found
// Assumes table *p is in monotomic order (see below)
int monotomy(const int *p, int n, int t) {
int j;
for( j = 0; j<n; j += (p[j]<t)+j+1 )
if( p[j]==t )
return j;
return -1;
}
// Return 1 iff table *p is in correct order for monotomy
// Table *p of length n is zero-based.
int monotomic(const int *p, int n) {
int j,k,m;
for( j = 2; j<n; ++j)
for ( m = k = j; (k /= 2)>0; m = k)
if ( (p[j-1]>p[k-1]) != (m%2) ) // zero-based indexes
return 0; // incorrect order
return 1; // correct order
}
// monotomy demo
#include <stdio.h>
int main(void) {
const int p[] = { 17, 7, 23, 3, 13, 19, 29, 2, 5, 11, };
#define n (sizeof(p)/sizeof(*p))
int t, i, j;
printf("monotomic = %d\n", monotomic(p, n) );
for( t = i = 0; t<9999; ++t )
if( ( j = monotomy(p, n, t) )>=0 )
printf( "%d\n", p[++i, j] );
if ( i!=n )
printf("Incorrect\n");
return 0;
}
6Usually the tie-breaker is the earliest posted submission. It's not recommended to use running time or speed or anything else as a tie-breaker, since then solvers of this challenge will have to account for those factors too. – Erik the Outgolfer – 2018-02-09T15:00:32.370
2I've VTCed this as unclear; after reading through it 3 times and trying to decipher the lone test case, I still don't know what's being asked of us and, what little I thought I understood is contradicted by the test case. – Shaggy – 2018-02-09T15:04:41.447
Sorry, I don't mean to be obstinate, but I still don't understand why the
5
and the7
have to be where they are rather than flip-flopped. I understand the rest of the number, just not those two. – AdmBorkBork – 2018-02-09T19:06:05.770@AdmBorkBork: the J=9th integer (
– fgrieu – 2018-02-09T19:21:15.7435
) must be smaller than the K=2th (7
) because when dividing J by two (hiving M=4), then by two again (giving K=2), the M=4 (from which K=2 was obtained) is even. See the explanation in version 5 for J=9 and K=2 (removed for it took so much room). Alternatively, runmonotomic()
with the integers in p (zero-based), or/and the whole sample code with a modified order.2FWIW YMMV, but I think another way to say this would be to put the numbers into a left-biased binary tree, and then produce a breadth-first traversal. – recursive – 2018-02-10T04:24:50.377