पूर्णांक की सूची से संतुलित BST बनाएँ


15

पूर्णांक की एक अद्वितीय, क्रमबद्ध सूची को देखते हुए, पुनरावृत्ति का उपयोग किए बिना एक संतुलित द्विआधारी-खोज ट्री को एक सरणी के रूप में दर्शाया गया है।

उदाहरण के लिए:

func( [1,2,3,5,8,13,21] ) => [5,2,13,1,3,8,21]

शुरू करने से पहले, एक संकेत: हम इस समस्या को एक टन सरल कर सकते हैं ताकि हमें वास्तव में इनपुट पूर्णांक (या उस मामले के लिए कोई तुलनीय वस्तु!) के बारे में सोचना न पड़े।

यदि हम जानते हैं कि इनपुट सूची पहले से ही क्रमबद्ध है, तो यह सामग्री अप्रासंगिक है। हम केवल मूल सरणी में सूचकांकों के संदर्भ में इसके बारे में सोच सकते हैं।

इनपुट सरणी का एक आंतरिक प्रतिनिधित्व तब बनता है:

func( [0,1,2,3,4,5,6] ) => [3,1,5,0,2,4,6]

इसका मतलब यह है कि तुलनात्मक वस्तुओं से निपटने के लिए कुछ लिखने के बजाय, हमें वास्तव में केवल एक फ़ंक्शन लिखने की ज़रूरत है जो रेंज [0, n) से परिणामी सरणी में मैप करता है। एक बार जब हमारे पास नया ऑर्डर होता है, तो हम केवल रिटर्न सरणी बनाने के लिए मानचित्रण को वापस इनपुट में मानों पर लागू कर सकते हैं।

मान्य समाधान चाहिए:

  • शून्य-तत्व सरणी को स्वीकार करें और खाली सरणी लौटाएं।
  • लंबाई n के पूर्णांक सरणी को स्वीकार करें और पूर्णांक सरणी वापस करें
    • N और 2 मिनट की अगली उच्चतम शक्ति के बीच की लंबाई 1. (उदाहरण के लिए, इनपुट आकार 13 के लिए 13 और 15 के बीच कहीं भी)।
    • एरे जो एक बीएसटी का प्रतिनिधित्व करता है जहां रूट नोड 0 पर है और ऊंचाई लॉग (एन) के बराबर है जहां 0 एक लापता नोड (या nullअगर आपकी भाषा की अनुमति देता है तो एक समान मूल्य ) का प्रतिनिधित्व करता है । खाली नोड्स, यदि मौजूद हैं, तो केवल पेड़ के अंत में मौजूद होना चाहिए (जैसे, [2,1,0])

इनपुट पूर्णांक सरणी में निम्नलिखित गारंटी है:

  • मान 32-बिट हस्ताक्षरित पूर्णांक शून्य से अधिक हैं।
  • मूल्य अद्वितीय हैं।
  • मान स्थिति शून्य से बढ़ते क्रम में हैं।
  • मान विरल हो सकते हैं (यानी, एक दूसरे से सटे हुए नहीं)।

एससीआई कैरेक्टर काउंट काउंट द्वारा सबसे अधिक ट्रिक कोड जीतता है, लेकिन मुझे किसी विशेष भाषा के लिए सुरुचिपूर्ण समाधान देखने में भी दिलचस्पी है।

परीक्षण के मामलों

सरल युक्त सरणियों के लिए आउटपुट 1के लिए nविभिन्न के लिए n। जैसा कि ऊपर वर्णित है, अनुगामी 0एस वैकल्पिक हैं।

[]
[1]
[2,1,0]
[2,1,3]
[3,2,4,1,0,0,0]
[4,2,5,1,3,0,0]
[4,2,6,1,3,5,0]
[4,2,6,1,3,5,7]
[5,3,7,2,4,6,8,1,0,0,0,0,0,0,0]
[6,4,8,2,5,7,9,1,3,0,0,0,0,0,0]
[7,4,9,2,6,8,10,1,3,5,0,0,0,0,0]
[8,4,10,2,6,9,11,1,3,5,7,0,0,0,0]
[8,4,11,2,6,10,12,1,3,5,7,9,0,0,0]
[8,4,12,2,6,10,13,1,3,5,7,9,11,0,0]
[8,4,12,2,6,10,14,1,3,5,7,9,11,13,0]
[8,4,12,2,6,10,14,1,3,5,7,9,11,13,15]

इस साइट पर सभी प्रश्न, चाहे एक प्रोग्रामिंग पहेली या एक कोड गोल्फ, एक उद्देश्य प्राथमिक जीत मानदंड होना चाहिए, ताकि यह निर्विवाद रूप से तय हो सके कि कौन सी प्रविष्टि जीतनी चाहिए।
हावर्ड

@ हावर्ड धन्यवाद। विजेता के लिए निश्चित मानदंड के साथ अद्यतन किया गया।
जेक व्हार्टन

1
कुछ परीक्षण मामलों के लिए बहुत उपयोगी होगा जो कठिन मामलों को कवर करते हैं, बजाय (वर्तमान में) सिर्फ सबसे आसान एक।
पीटर टेलर

क्या पुनर्मुद्रण का कोई कारण है? ऐसा नहीं है कि मैं एक पुनरावर्ती समाधान देख रहा हूं, लेकिन यह कृत्रिम और अनावश्यक दोनों लगता है।
dmckee --- पूर्व-संचालक बिल्ली का बच्चा

1
क्या कोई समझा सकता है कि सूची एक BST का प्रतिनिधित्व कैसे करती है?
justinpc

जवाबों:


4

रूबी , 143

s=ARGV.size;r,q=[],[[0,s]];s.times{b,e=q.shift;k=Math::log2(e-b).to_i-1;m=(e-b+2)>(3<<k)?b+(2<<k)-1:e-(1<<k);r<<ARGV[m];q<<[b,m]<<[m+1,e]};p r

यह निम्नलिखित कोड का एक (शिथिल) संकुचित संस्करण है जो मूल रूप से पेड़ पर एक BFS करता है।

def l(n)
    k = Math::log2(n).to_i-1
    if n+2 > (3<<k) then
        (2<<k)-1
    else
        n-(1<<k) 
    end
end

def bfs(tab)
  result = []
  queue = [[0,tab.size]]
  until queue.empty? do
    b,e = queue.shift
    m = b+l(e-b)
    result << tab[m]
    queue << [b,m] if b < m
    queue << [m+1,e] if m+1 < e
  end
  result
end

p bfs(ARGV)

इसके अलावा, क्योंकि यह बीएफएस है, डीएफएस नहीं, गैर-पुनरावर्ती समाधान की आवश्यकता महत्वपूर्ण नहीं है, और यह कुछ भाषाओं को नुकसान में डालती है।

संपादित करें: फिक्स्ड समाधान, अपनी टिप्पणी के लिए @PeterTaylor को धन्यवाद!


@PeterTaylor 4 के बाईं ओर 3 लगाने का इरादा था, लेकिन कोई खाली नहीं है, इसलिए यह गलत है। यह बात बताने के लिए धन्यवाद!
dtldarek

@PeterTaylor दोपहर के भोजन के लिए निश्चित है, इसे अब काम करना चाहिए।
dtldarek

4

जावा , 252

ठीक है, यहाँ मेरा प्रयास है। मैं बिट संचालन के साथ खेल रहा हूं और मैं मूल सरणी में सूचकांक से BST में एक तत्व के सूचकांक की गणना करने के इस प्रत्यक्ष तरीके के साथ आया हूं।

संकुचित संस्करण

public int[]b(int[]a){int i,n=1,t;long x,I,s=a.length,p=s;int[]r=new int[(int)s];while((p>>=1)>0)n++;p=2*s-(1l<<n)+1;for(i=0;i<s;i++){x=(i<p)?(i+1):(p+2*(i-p)+1);t=1;while((x&1<<(t-1))==0)t++;I=(1<<(n-t));I|=((I-1)<<t&x)>>t;r[(int)I-1]=a[i];}return r;}

लंबा संस्करण नीचे दिया गया है।

public static int[] makeBst(int[] array) {
  long size = array.length;
  int[] bst = new int[array.length];

  int nbits = 0;
  for (int i=0; i<32; i++) 
    if ((size & 1<<i)!=0) nbits=i+1;

  long padding = 2*size - (1l<<nbits) + 1;

  for (int i=0; i<size; i++) {
    long index2n = (i<padding)?(i+1):(padding + 2*(i-padding) + 1);

    int tail=1;
    while ((index2n & 1<<(tail-1))==0) tail++;
    long bstIndex = (1<<(nbits-tail));
    bstIndex = bstIndex | ((bstIndex-1)<<tail & index2n)>>tail;

    bst[(int)(bstIndex-1)] = array[i];
  }
 return bst;
}

आपको एक वर्ण गणना की आवश्यकता है, और यह वर्तमान में गोल्फ नहीं है।
dmckee --- पूर्व-संचालक

@ मिकी ने एक संपीड़ित संस्करण और एक वर्ण गणना शामिल करने के लिए पोस्ट को संपादित किया है
mikail sheikh

अच्छा प्रदर्शन। मैं शर्त लगाता हूँ कि उन स्थानों में से कुछ अनावश्यक हैं। सी में, int[] b(int[] a)बस के रूप में अच्छी तरह से व्यक्त किया है int[]b(int[]a)
dmckee --- पूर्व-संचालक बिल्ली का बच्चा

आपके पास a.lengthसरणी आवंटन में है। इसे बदलें sfor (कई बार के बीच अंतरिक्ष से छुटकारा । लूप के लिए प्रत्येक एक int i=0और भी बनाता है int t=0n( int n=0,i,t;) के साथ बनाएं और फिर केवल i=0लूप और t=1अंदर। भीतर long xऔर long Iसाथ की घोषणा करें sऔर बस लूप ( long s=a.length,I,x;और x=../ I=..) में आरंभ करें । आपको बाइनरी के आसपास रिक्त स्थान की आवश्यकता नहीं होनी चाहिए &
जेक व्हार्टन

साथ ही, I=I|..लिखा जा सकता हैI|=..
जेक व्हार्टन

3
def fn(input):
    import math
    n = len(input)
    if n == 0:
        return []
    h = int(math.floor(math.log(n, 2)))
    out = []
    last = (2**h) - 2**(h+1) + n

    def num_children(level, sibling, lr):
        if level == 0:
            return 0
        half = 2**(level-1)
        ll_base = sibling * 2**level + lr * (half)
        ll_children = max(0, min(last, ll_base + half - 1) - ll_base + 1)
        return 2**(level-1) - 1 + ll_children

    for level in range(h, -1, -1):
        for sibling in range(0, 2**(h-level)):
            if level == 0 and sibling > last:
                break
            if sibling == 0:
                last_sibling_val = num_children(level, sibling, 0)
            else:
                last_sibling_val += 2 + num_children(level, sibling - 1, 1) \
                    + num_children(level, sibling, 0)
            out.append(input[last_sibling_val])
    return out

2

यह निश्चित नहीं है कि अगर यह पेड़ के अंत में खाली नोड्स की आपकी आवश्यकता के अनुरूप है और यह निश्चित रूप से संक्षिप्तता के लिए कोई पुरस्कार नहीं जीतेगा, लेकिन मुझे लगता है कि यह सही है और इसमें परीक्षण के मामले हैं :)

public class BstArray {
    public static final int[] EMPTY = new int[] { };
    public static final int[] L1 = new int[] { 1 };
    public static final int[] L2 = new int[] { 1, 2 };
    public static final int[] L3 = new int[] { 1, 2, 3 };
    public static final int[] L4 = new int[] { 1, 2, 3, 5 };
    public static final int[] L5 = new int[] { 1, 2, 3, 5, 8 };
    public static final int[] L6 = new int[] { 1, 2, 3, 5, 8, 13 };
    public static final int[] L7 = new int[] { 1, 2, 3, 5, 8, 13, 21 };
    public static final int[] L8 = new int[] { 1, 2, 3, 5, 8, 13, 21, 35 };
    public static final int[] L9 = new int[] { 1, 2, 3, 5, 8, 13, 21, 35, 56 };
    public static final int[] L10 = new int[] { 1, 2, 3, 5, 8, 13, 21, 35, 56, 91 };

    public static void main(String[] args) {
        for (int[] list : Arrays.asList(EMPTY, L1, L2, L3, L4, L5, L6, L7, L8, L9, L10)) {
            System.out.println(Arrays.toString(list) + " => " + Arrays.toString(bstListFromList(list)));
        }
    }

    private static int[] bstListFromList(int[] orig) {
        int[] bst = new int[nextHighestPowerOfTwo(orig.length + 1) - 1];

        if (orig.length == 0) {
            return bst;
        }

        LinkedList<int[]> queue = new LinkedList<int[]>();
        queue.push(orig);

        int counter = 0;
        while (!queue.isEmpty()) {
            int[] list = queue.pop();
            int len = list.length;

            if (len == 1) {
                bst[counter] = list[0];
            } else if (len == 2) {
                bst[counter] = list[1];
                queue.add(getSubArray(list, 0, 1));
                queue.add(new int[] { 0 });
            } else if (len == 3) {
                bst[counter] = list[1];
                queue.add(getSubArray(list, 0, 1));
                queue.add(getSubArray(list, 2, 1));
            } else {
                int divide = len / 2;
                bst[counter] = list[divide];
                queue.add(getSubArray(list, 0, divide));
                queue.add(getSubArray(list, divide + 1, len - (divide + 1)));
            }
            counter++;
        }

        return bst;
    }

    private static int nextHighestPowerOfTwo(int n) {
        n--;
        n |= n >> 1;
        n |= n >> 2;
        n |= n >> 4;
        n |= n >> 8;
        n |= n >> 16;
        n++;

        return n;
    }

    private static int[] getSubArray(int[] orig, int origStart, int length) {
        int[] list = new int[length];
        System.arraycopy(orig, origStart, list, 0, length);
        return list;
    }
}

2

गोल्फस्क्रिप्ट ( 99 89)

~]:b[]:^;{b}{{:|.,.2base,(2\?:&[-)&2/]{}$0=&(2/+:o[=]^\+:^;|o<.!{;}*|o)>.!{;}*}%:b}while^p

मूल रूप से मेरे पायथन समाधान का एक सीधा बंदरगाह, उसी तरह से काम करता है।

शायद अधिक "गोल्फ" के साथ थोड़ा सुधार किया जा सकता है, पहले से ही @ पेटर्टायलर के इनपुट के साथ 10 वर्णों में सुधार हुआ है :)


मुझे लगता है कि यह 70 से अधिक में संभव होना चाहिए, हालांकि मैंने अभी भी अपने गोल्फस्क्रिप्ट जवाब को काफी हद तक समाप्त नहीं किया है। हालांकि आपके लिए कुछ आसान सुधार हैं। !{;}{}ifसिर्फ !{;}*इसलिए हो सकता है क्योंकि !लौटने की गारंटी देता है 0या 1। आप चर के लिए गैर अक्षरात्मक टोकन का उपयोग कर सकते हैं, इसलिए यदि आप उपयोग करते हैं, ^बजाय r, |के बजाय x, &के बजाय yआप सभी कि खाली स्थान के समाप्त कर सकते हैं।
पीटर टेलर

@PeterTaylor धन्यवाद, गैर अल्फ़ान्यूमेरिक चर के बारे में पता नहीं था, अभी भी गोल्फस्क्रिप्ट के लिए बहुत नया है :)
जोआचिम

2

जावा 192

आउटपुट में इंडेक्स के लिए इनपुट में मैप्स इंडेक्स

int[]b(int[]o){int s=o.length,p=0,u=s,i=0,y,r[]=new int[s],c[]=new int[s];while((u>>=1)>0)p++;for(int x:o){y=p;u=i;while(u%2>0){y--;u/=2;}r[(1<<y)-1+c[y]++]=x;i+=i>2*s-(1<<p+1)?2:1;}return r;}

दीर्घ संस्करण:

static int[] bfs(int[] o) {
  int rowCount = 32 - Integer.numberOfLeadingZeros(o.length); // log2
  int slotCount = (1<<rowCount) - 1; // pow(2,rowCount) - 1

  // number of empty slots at the end
  int emptySlots = slotCount - o.length;
  // where we start to be affected by these empty slots
  int startSkippingAbove = slotCount - 2 * emptySlots; // = 2 * o.length - slotCount

  int[] result = new int[o.length];
  int[] rowCounters = new int[rowCount]; // for each row, how many slots in that row are taken
  int i = 0; // index of where we would be if this was a complete tree (no trailing empty slots)
  for (int x : o) {
    // the row (depth) a slot is in is determined by the number of trailing 1s
    int rowIndex = rowCount - Integer.numberOfTrailingZeros(~i) - 1;
    int colIndex = rowCounters[rowIndex]++; // count where we are
    int rowStartIndex = (1 << rowIndex) - 1; // where this row starts in the result array

    result[rowStartIndex + colIndex] = x;

    i++;
    // next one has to jump into a slot that came available by not having slotCount values
    if (i > startSkippingAbove) i++;
  }

  return result;
}

2

वोल्फ्राम मैथमेटिका 11, 175 बाइट्स

g[l_]:=(x[a_]:=Floor@Min[i-#/2,#]&@(i=Length[a]+1;2^Ceiling@Log2[i]/2);Join@@Table[Cases[l//.{{}->{},b__List:>(n[Take[b,#-1],b[[#]],Drop[b,#]]&@x[b])},_Integer,{m}],{m,x[l]}])

फ़ंक्शन g[l]इनपुट a List(जैसे l={1,2,3,4,...}) के रूप में लेता है और Listवांछित फॉर्म का रिटर्न देता है । यह निम्नानुसार काम करता है:

  • x[a_]:=Floor@Min[i-#/2,#]&@(i=Length[a]+1;2^Ceiling@Log2[i]/2) एक सूची लेता है और संबंधित BST की जड़ ढूंढता है।
    • i=Length[a]+1 सूची की लंबाई के लिए शॉर्टकट
    • 2^Ceiling@Log2[i]/2 जड़ के मूल्य पर ऊपरी बाध्य
    • Min[i-#/2,#]&@(...)दो में से कम से कम तर्क है #कि अंदर क्या है के लिए खड़ा है(...)
  • l//.{...} बार-बार बदलने वाले नियम लागू करें l
  • {}->{} कुछ नहीं करना है (यह एक अनंत लूप से बचने के लिए किनारे का मामला है)
  • b__List:>(n[Take[b,#-1],b[[#]],Drop[b,#]]&@x[b])एक Listमें विभाजित करें{{lesser}, root, {greater}}
  • Cases[...,_Integer,{m}] सभी पूर्णांकों को स्तर (गहराई) पर लें m
  • Table[...,{m,1,x[l]}]सभी mके लिए x[l](जो वास्तव में आवश्यकता से अधिक है)।

इसे चलाकर परखा जा सकता है

Table[g[Range[a]], {a, 0, 15}]//MatrixForm

इस कार्यान्वयन में अनुगामी शून्य शामिल नहीं हैं।


1

पायथन ( 175 171)

काफी संक्षेप में, अभी भी काफी पठनीय है;

def f(a):
 b=[a]
 while b:
  c,t=((s,2**(len(bin(len(s)))-3))for s in b if s),[]
  for x,y in c:
   o=min(len(x)-y+1,y/2)+(y-1)/2
   yield x[o]
   t+=[x[:o],x[o+1:]]
  b=t

यह परिणाम वापस देता है, इसलिए आप इसे या तो लूप कर सकते हैं या (प्रदर्शन उद्देश्यों के लिए) इसे सूची के रूप में प्रिंट कर सकते हैं;

>>> for i in range(1,17): print i-1,list(f(range(1,i)))
 0 []
 1 [1]
 2 [2, 1]
 3 [2, 1, 3]
 4 [3, 2, 4, 1]
 5 [4, 2, 5, 1, 3]
 6 [4, 2, 6, 1, 3, 5]
 7 [4, 2, 6, 1, 3, 5, 7]
 8 [5, 3, 7, 2, 4, 6, 8, 1]
 9 [6, 4, 8, 2, 5, 7, 9, 1, 3]
10 [7, 4, 9, 2, 6, 8, 10, 1, 3, 5]
11 [8, 4, 10, 2, 6, 9, 11, 1, 3, 5, 7]
12 [8, 4, 11, 2, 6, 10, 12, 1, 3, 5, 7, 9]
13 [8, 4, 12, 2, 6, 10, 13, 1, 3, 5, 7, 9, 11]
14 [8, 4, 12, 2, 6, 10, 14, 1, 3, 5, 7, 9, 11, 13]
15 [8, 4, 12, 2, 6, 10, 14, 1, 3, 5, 7, 9, 11, 13, 15]

@dtldarek उनकी टिप्पणी को हटाया जा रहा है, लेकिन यह अब परीक्षण मामलों को पारित करने के लिए लगता है।
जोआचिम इस्कासन

मैंने अपनी टिप्पणी को नष्ट कर दिया, ऐसा न हो कि लोग यह कहते हुए एक टिप्पणी के कारण @ dtldarek के उत्थान से बच जाएं।
पीटर टेलर

@PeterTaylor खैर, आपके विचार के लिए धन्यवाद ;-)
dtldarek

1

जावा

यह एक प्रत्यक्ष गणना समाधान है। मुझे लगता है कि यह काम करता है, लेकिन इसका एक व्यावहारिक रूप से सहज साइड इफेक्ट है। यह जो सरणी पैदा करता है वह भ्रष्ट हो सकता है लेकिन किसी भी तरह से नहीं जो खोजों को प्रभावित करेगा। 0 (शून्य) नोड्स का उत्पादन करने के बजाय, यह अगम्य नोड्स का उत्पादन करेगा, अर्थात् नोड्स पहले ही खोज के दौरान पेड़ में पहले ही मिल चुके होंगे। यह अनियमित आकार के बाइनरी सर्च ट्री सरणी पर 2 आकार के बाइनरी सर्च ट्री सरणी की नियमित शक्ति के सूचक सरणी को मैप करके काम करता है। कम से कम, मुझे लगता है कि यह काम करता है।

import java.util.Arrays;

public class SortedArrayToBalanceBinarySearchTreeArray
{
    public static void main(String... args)
    {
        System.out.println(Arrays.toString(binarySearchTree(19)));
    }

    public static int[] binarySearchTree(int m)
    {
        int n = powerOf2Ceiling(m + 1);
        int[] array = new int[n - 1];

        for (int k = 1, index = 1; k < n; k *= 2)
        {
            for (int i = 0; i < k; ++i)
            {
                array[index - 1] = (int) (.5 + ((float) (m)) / (n - 1)
                        * (n / (2 * k) * (1 + 2 * index) - n));
                ++index;
            }
        }

        return array;
    }

    public static int powerOf2Ceiling(int n)
    {
        n--;
        n |= n >> 1;
        n |= n >> 2;
        n |= n >> 4;
        n |= n >> 8;
        n |= n >> 16;
        n++;

        return n;
    }

}

यहां एक अधिक संघनित संस्करण है (बस फ़ंक्शन और नीचे जोड़े गए नाम)। इसे अभी भी सफेद स्थान मिला है, लेकिन मुझे जीत की चिंता नहीं है। इसके अलावा यह संस्करण वास्तव में एक सरणी लेता है। दूसरे ने सिर्फ सरणी में उच्चतम सूचकांक के लिए एक इंट लिया।

public static int[] b(int m[])
{
    int n = m.length;
    n |= n >> 1;
    n |= n >> 2;
    n |= n >> 4;
    n |= n >> 8;
    n |= n >> 16;
    n++;

    int[] a = new int[n - 1];

    for (int k = 1, j = 1, i; k < n; k *= 2)
    {
        for (i = 0; i < k; ++i)
        {
            a[j - 1] = m[(int) (.5 + ((float) m.length) / (n - 1)
                    * (n / (2 * k) * (1 + 2 * j) - n)) - 1];
            ++j;
        }
    }

    return a;
}

चूंकि यह कोड-गोल्फ है , अपने तरीकों / नामों / आदि को यथासंभव छोटा करें; सभी व्हाट्सएप (और अनावश्यक तरीकों / सामग्री) को हटा दें, और वर्ण गणना डालें। नहीं तो आपका कमाल कर दिया।
जस्टिन

@ जेक व्हार्टन मैं वास्तव में आपके प्रत्यक्ष मानचित्रण समाधान को देखना चाहूंगा। मैं 100% निश्चित नहीं हूँ कि मेरा बहुत बड़े सरणियों के लिए काम करता है क्योंकि यह एक निरंतर गणितीय मानचित्रण पर निर्भर करता है जिसके मूल्य गोल हो जाते हैं। यह निश्चित रूप से काम करने लगता है, लेकिन मुझे यकीन नहीं है कि इसे कैसे साबित किया जाए।

1

गोल्फस्क्रिप्ट ( 79 77) 70 )

चूंकि प्रश्न में उदाहरण एक फ़ंक्शन का उपयोग करता है, इसलिए मैंने इसे एक फ़ंक्शन बनाया है। {}:f;एक अभिव्यक्ति को छोड़ने के लिए हटाने से जो स्टैक पर इनपुट लेता है और स्टैक पर BST छोड़ देता है, 5 वर्णों को बचाएगा।

{[.;][{{.!!{[.,.)[1]*{(\(@++}@(*1=/()\@~]}*}%.{0=}%\{1>~}%.}do][]*}:f;

ऑनलाइन डेमो (ध्यान दें: ऐप थोड़ा गर्म हो सकता है: 3 सेकंड में चलने से पहले मेरे लिए दो बार समय समाप्त हो गया)।

संरचना दिखाने के लिए व्हॉट्सएप के साथ:

{
    # Input is an array: wrap it in an array for the working set
    [.;]
    [{
        # Stack: emitted-values working-set
        # where the working-set is essentially an array of subtrees
        # For each subtree in working-set...
        {
            # ...if it's not the empty array...
            .!!{
                # ...gather into an array...
                [
                    # Get the size of the subtree
                    .,
                    # OEIS A006165, offset by 1
                    .)[1]*{(\(@++}@(*1=
                    # Split into [left-subtree-plus-root right-subtree]
                    /
                    # Rearrange to root left-subtree right-subtree
                    # where left-subtree might be [] and right-subtree might not exist at all
                    ()\@~
                ]
            }*
        }%
        # Extract the leading element of each processed subtree: these will join the emitted-values
        .{0=}%
        # Create a new working-set of the 1, or 2 subtrees of each processed subtree
        \{1>~}%
        # Loop while the working-set is non-empty
        .
    }do]
    # Stack: [[emitted values at level 0][emitted values at level 1]...]
    # Flatten by joining with the empty array
    []*
}:f;

1

जे , 52 बाइट्स

t=:/:(#/:@{.(+:,>:@+:@i.@>:@#)^:(<.@(2&^.)@>:@#`1:))

फ़ंक्शन बाइनरी ट्री ऑर्डर में क्रमबद्ध सूची और रिटर्न लेता है

ध्यान दें कि पेड़ों का आकार समान होता है, लेकिन निचला स्तर छोटा होता है

  • `1: 1 से शुरू करें
  • <.@(2&^.)@>:@# log2 के फर्श द्वारा लंबाई (लंबाई + 1)
  • +: , >:@+:@i.@>:@# लूप: विषम संख्या 1,3 .. 2 * लंबाई + 1 के साथ अंतिम वेक्टर के डबल को जोड़ता है
  • # /:@{. केवल आवश्यक संख्या में आइटम लें और उनके क्रमबद्ध सूचकांक प्राप्त करें
  • /: दिए गए इनपुट के लिए उन प्रकार के सूचकांकों को लागू करें

TIO


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.