सचिव समस्या का समाधान करें


13

सचिव समस्या इस प्रकार के रूप में वर्णित एक प्रसिद्ध समस्या है:

  1. आपको एक नए सचिव की आवश्यकता है
  2. आपके पास एन आवेदक हैं जो आप एक समय में एक साक्षात्कार कर सकते हैं
  3. आप साक्षात्कार के बाद प्रत्येक आवेदक को स्कोर करने में सक्षम हैं। आपका स्कोरिंग सिस्टम दो आवेदकों को एक ही स्कोर कभी नहीं देगा
  4. एक आवेदक का साक्षात्कार करने के बाद, आपको तत्काल "हाँ" या "नहीं" देना होगा
  5. आप उच्चतम स्कोर के साथ आवेदक चाहते हैं

समाधान पहले floor(N/e)आवेदकों का साक्षात्कार करना है , और फिर पहले आवेदक को स्वीकार करना है जिसमें पिछले सभी आवेदकों की तुलना में अधिक अंक हैं। यदि कोई भी आवेदक अधिक नहीं है, तो अंतिम आवेदक को वापस करें। दिलचस्प रूप से पर्याप्त है, यह शीर्ष आवेदक 1/eको समय देता है। यूलर की संख्याe को संदर्भित करता है । का मान प्राप्त करने के लिए , आप बिलिन का उपयोग कर सकते हैं , या इसे कम से कम 5 दशमलव बिंदुओं पर हार्डकोड कर सकते हैं ।elog

इनपुट:

अद्वितीय गैर-नकारात्मक पूर्णांक का एक गैर-खाली सरणी से अधिक नहीं 2^31-1

आउटपुट:

चुने हुए उम्मीदवार का प्रतिनिधित्व करने वाला पूर्णांक। स्पष्ट होने के लिए एल्गोरिथ्म है:

  1. floor(N/e)सरणी के पहले तत्वों में अधिकतम तत्व का पता लगाएं ।
  2. शेष तत्वों के माध्यम से Iterate करें, और पहला तत्व जो चरण 1 पर पाए जाने वाले अधिकतम से अधिक है, वापस करें।
  3. यदि कोई भी तत्व उच्च नहीं है, तो अंतिम तत्व वापस करने से।

उदाहरण के लिए, मान लें कि आपकी सरणी थी [2,7,4,3,9,20], इसलिए N = 6और floor(N/e) = 2। सरणी के पहले 2 तत्व हैं [2,7]। का कमाल [2,7]है 7। शेष तत्व हैं [4,3,9,20]। पहला तत्व जो अधिक से अधिक 7है 9, इसलिए हम लौटते हैं 9

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

[0]         => 0
[100]       => 100
[100, 45]   => 100
[0, 1]      => 0
[45, 100]   => 45
[1, 4, 5]   => 4
[1, 5, 4]   => 5
[5, 4, 1]   => 1
[5, 1, 4]   => 4
[4, 1, 5]   => 5
[56, 7, 37, 73, 90, 59, 65, 61, 29, 16, 47, 77, 60, 8, 1, 76, 36, 68, 34, 17, 23, 26, 12, 82, 52, 88, 45, 89, 94, 81, 3, 24, 43, 55, 38, 33, 15, 92, 79, 87, 14, 75, 41, 98, 31, 58, 53, 72, 39, 30, 2, 0, 49, 99, 28, 50, 80, 91, 83, 27, 64, 71, 93, 95, 11, 21, 6, 66, 51, 85, 48, 62, 22, 74, 69, 63, 86, 57, 97, 32, 84, 4, 18, 46, 20, 42, 25, 35, 9, 10, 19, 40, 54, 67, 70, 5, 44, 13, 78, 96]
=> 98
[10, 68, 52, 48, 81, 39, 85, 54, 3, 21, 31, 59, 28, 64, 42, 90, 79, 12, 63, 41, 58, 57, 13, 43, 74, 76, 94, 51, 99, 67, 49, 14, 6, 96, 18, 17, 32, 73, 56, 7, 16, 60, 61, 26, 86, 72, 20, 62, 4, 83, 15, 55, 70, 29, 23, 35, 77, 98, 92, 22, 38, 5, 50, 82, 1, 84, 93, 97, 65, 37, 45, 71, 25, 11, 19, 75, 78, 44, 46, 2, 53, 36, 0, 47, 88, 24, 80, 66, 87, 40, 69, 27, 9, 8, 91, 89, 34, 33, 95, 30]
=> 30

आपका समाधान होना चाहिए O(n), जहां nसरणी की लंबाई है। यदि आपकी भाषा में एक बिलियन है जो एक सरणी की अधिकतम पाता है, तो आप मान सकते हैं कि फ़ंक्शन लेता है O(n)(और उम्मीद है कि यह करता है)।

मानक कमियां लागू होती हैं, और यह एक , इसलिए अपनी पसंदीदा भाषा में सबसे कम उत्तर दें!


1
क्या eइस्तेमाल किया जाना चाहिए?
16

2
@voidpigeon मैं इसे का अनुमान en.wikipedia.org/wiki/E_(mathematical_constant)
दरवाज़े

1
आह, अब मैं समझता हूं कि एल्गोरिथ्म कैसे काम करता है। मुझे लगा कि आपके दूसरे पैराग्राफ का मतलब है कि आप फर्श (एन / ई) के बाद उम्मीदवारों का साक्षात्कार कभी नहीं करेंगे।
दरवाज़े

1
मैंने विशेष रूप से पूछा क्योंकि कुछ भाषाओं में, यह सटीकता के 5 दशमलव अंकों के साथ एक चर को परिभाषित करने की तुलना में कम है, वास्तव में बिलिन e(जैसे पायथन, जहां e=2.71828की तुलना में कम है import math;math.E) का उपयोग करना है
Mego

1
नोट: `1 / e प्रतिशत समय।` वास्तव में बुरा होगा। यह 1 / ई की संभावना है, जो कि लगभग 37% बार है
edc65

जवाबों:


4

जेली, 13 बाइट्स

L:Øe³ḣȯ-Ṁ<i1ị

निश्चित रूप से एक ओ (एन) एल्गोरिदम, उम्मीद है कि एक ओ (एन) कार्यान्वयन। इसे ऑनलाइन आज़माएं!

यह काम किस प्रकार करता है

L:Øe³ḣȯ-Ṁ<i1ị  Main link. Argument: A (list of scores)

L              Get the length of A.
 :Øe           Divide the length by e, flooring the result.
    ³ḣ         Retrieve the that many scores from the beginning of A.
      ȯ-       Logical OR; replace an empty list with -1.
        Ṁ      Compute the maximum of those scores.
         <     Compare each score in A with that maximum.
          i1   Find the first index of 1 (0 if not found).
            ị  Retrieve the element of A at that index (the last one if 0).

3

सीजाम, 20 बाइट्स

q~___,1me/i<:e>f>1#=

डेनिस के सुझाव के समान ही काम करता है।

q~___                     Read array, duplicate three times
      ,                   Consume one to find the length
       1me/i              Push e then divide and take floor
            <             Take that many elements from the list
             :e>          Find maximum (Thanks to Dennis)
                f>        Label array elements larger than this as 1
                  1#      Find the first one (won't be in set of elements we've looked in)
                    =     Take that element from the final copy of the array. -1 gives us the last element as required

$W=रैखिक समय में नहीं चलता है।
डेनिस

उरग, तुम सही हो। क्या सीजेएम में अधिकतम खोजने का कोई बेहतर तरीका है जो आप जानते हैं?
एक सीमन्स

1
:e>(अधिकतम घटाएं)
डेनिस

@ डेनिस धन्यवाद!
एक सीमन्स

2

जावा, 128 118 बाइट्स

a->{int c=(int)(a.length/Math.E),i=0,m=-1,t=0;for(;i<a.length;i++){t=a[i];if(i<c)m=t>m?t:m;if(t>m)return t;}return t;}

इंडेंट:

static Function<Integer[], Integer> secretary2 = a -> {
    int c = (int) (a.length/Math.E),     // c = floor(N/E)
        i = 0, m = -1, t = 0;            // declare vars early to save bytes
    for (;i<a.length;i++) {              // for each element of input
        t = a[i];                        // cache element to save bytes
        if (i<c)                         // if before c
            m = t>m ? t : m;             // m = max(m, element)
        if (t>m)                         // if element > m
            return t;                    // return: we've found our best
    }                                    // if never found a good element
    return t;                            // return the last element
};


2

जावास्क्रिप्ट (ईएस 6) 64

(a,l=a.length/Math.E,x)=>(a.every(v=>--l>0?x>v?1:x=v:(z=v)<x),z)

कम गोल्फ वाला

(
 a, 
 l=a.length/Math.E, // limit for stage 1
 x // init at undefined
)=>(
  a.every(v => --l > 0 // checking for >0 no need to floor
          ? x>v?1:x=v // stage 1, find max in x, always return truthy
          : (z=v)<x ) // stage 2, set z to current value and exit early if z>x
  , z // at last z has the last seen value
)

परीक्षा

f=(a,l=a.length/Math.E,x)=>(a.every(v=>--l>0?x>v?1:x=v:(z=v)<x),z)

console.log=x=>O.textContent+=x+'\n'

;[ 
 [0], [100], [0,1], [1,2,3],
 [100, 45],
 [45, 100],
 [1, 4, 5],
 [1, 5, 4],
 [5, 4, 1],
 [5, 1, 4],
 [4, 1, 5],   
 [10, 68, 52, 48, 81, 39, 85, 54, 3, 21, 31, 59, 28, 64, 42, 90, 79, 12, 63, 41, 58, 57, 13, 43, 74, 76, 94, 51, 99, 67, 49, 14, 6, 96, 18, 17, 32, 73, 56, 7, 16, 60, 61, 26, 86, 72, 20, 62, 4, 83, 15, 55, 70, 29, 23, 35, 77, 98, 92, 22, 38, 5, 50, 82, 1, 84, 93, 97, 65, 37, 45, 71, 25, 11, 19, 75, 78, 44, 46, 2, 53, 36, 0, 47, 88, 24, 80, 66, 87, 40, 69, 27, 9, 8, 91, 89, 34, 33, 95, 30],
[56, 7, 37, 73, 90, 59, 65, 61, 29, 16, 47, 77, 60, 8, 1, 76, 36, 68, 34, 17, 23, 26, 12, 82, 52, 88, 45, 89, 94, 81, 3, 24, 43, 55, 38, 33, 15, 92, 79, 87, 14, 75, 41, 98, 31, 58, 53, 72, 39, 30, 2, 0, 49, 99, 28, 50, 80, 91, 83, 27, 64, 71, 93, 95, 11, 21, 6, 66, 51, 85, 48, 62, 22, 74, 69, 63, 86, 57, 97, 32, 84, 4, 18, 46, 20, 42, 25, 35, 9, 10, 19, 40, 54, 67, 70, 5, 44, 13, 78, 96]
].forEach(t=>{
  var r=f(t)
  console.log(r+' : '+t)
})
<pre id=O></pre>


1

रूबी, 64 बाइट्स

->a{m=a[0...c=a.size/Math::E].max
a[c..-1].find{|n|n>m}||a[-1]}

2
@Doorknob यह पहली मंजिल (N / e) तत्वों के माध्यम से एक बार अधिकतम खोजने के लिए छोर देता है, फिर सबसे खराब स्थिति में बाकी सूची के माध्यम से प्रत्येक तत्व की तुलना में अधिकतम करने के लिए छोरों। दोनों भागों में प्रति तत्व केवल एक तुलना है।
17

आह, यह सही है। मैंने गलत समझा और सोचा कि आप प्रत्येक पुनरावृत्ति में अधिकतम पा रहे हैं।
दरवाज़े

1
वास्तव में, मुझे लगता है कि यह अभी भी हे (एन) है यदि आप बस a.findदूसरे चरण में करते हैं, हालांकि स्पष्ट रूप से यह बहुत कम कुशल है।
हिस्टोक्रैट

1
आप (0...c)उस श्रेणी के लिए उपयोग कर सकते हैं जो c को बाहर करती है।
हिस्टोक्रेट

@ हिस्टोक्रेट हाँ, यह ओ (2 एन) होना चाहिए जो ओ (एन) है
ऐसा नहीं है कि चार्ल्स

1

PARI / GP , 70 बाइट्स

यह एक सिंगलटन दिए जाने पर जीपी के पुराने संस्करणों पर परेशानी हो सकती है, लेकिन यह कम से कम 18487 संशोधन से काम करता है।

v->m=vecmax(v[1..t=#v\exp(1)]);for(i=t+1,#v,v[i]>m&&return(v[i]));v[#v]

1

जावास्क्रिप्ट (ईएस 6), 79 बाइट्स

a=>(m=Math.max(...a.splice(0,a.length/Math.E)),a.slice(a.findIndex(x=>x>m))[0])

काम करता है क्योंकि विफलता पर findIndexलौटता -1है, लेकिन a.slice(-1)[0]वांछित के रूप में सरणी का अंतिम तत्व देता है।


1

पायथन 2, 87 बाइट्स

a=input()
t=int(len(a)/2.71828)
m=max(a[:t]+[-1])
for x in a[t:]:
 if x>m:break
print x

उपयोगकर्ता वर्ग कोष्ठक और अल्पविराम के साथ, एक सूची के रूप में सरणी में प्रवेश करता है। पायथन 2 की input()कमान यहां सुविधाजनक है।

हम इस प्रक्रिया को जल्दी समाप्त करते हैं या नहीं, हम उस अंतिम व्यक्ति को नियुक्त करते हैं जिसे साक्षात्कार मिला है।


1

पर्ल 6, 43 बाइट्स

मुझे लगता है कि यह O (n) है

{@^a.first(*>max @a[^floor @a/e])//@a[*-1]}

1

पायथन 3.5; 110 बाइट्स:

def Interview(h):k=max(h[0:int(len(h)/2.71828)-1]);n=max(h[int(len(h)/2.71828)-1:len(h)-1]);return max([k, n])

मूल रूप से, उपरोक्त क्या है कि यह सबसे पहले एक सरणी प्रदान करता है, "h" जब तक इसमें 5 से अधिक आइटम (अभी के लिए ...) शामिल हैं, पहले में अधिकतम मान (सरणी की लंबाई (len (h) पाता है) )) / यूलर की संख्या (5 दशमलव स्थानों पर) उस सरणी के आइटम, और फिर उस मान को "k" के रूप में लौटाता है। इसके अलावा, बाकी सरणी में "n" अधिकतम मान है। अंत में, फ़ंक्शन से लौटाया गया मान किसी सरणी में "k" और "n" दोनों का अधिकतम मूल्य है।

नोट: max()पायथन का कार्य हे (n) जटिलता है।

नीचे उपरोक्त कोड का एक अधिक पठनीय, गैर-कोड-गोल्फ संस्करण है जिसमें एक यादृच्छिक, अद्वितीय 10-आइटम सरणी प्रदान की गई है, यह पुष्टि करने के लिए कि यह काम करता है:

import random, math

def Interview():
    k = max(h[0:int(len(h)/math.e)-1])
    n = max(h[int(len(h)/math.e)-1:len(h)-1])
    return max([k, n])

h = random.sample(range((2*31)-1), 10)

print(Interview(h))

PPCG में आपका स्वागत है! आप अपने आयात को अलग कर सकते हैं। इसके अलावा, आपको स्वयं सरणी उत्पन्न करने की आवश्यकता नहीं है, इसलिए आप कोड के उस हिस्से को हटा सकते हैं (बस फ़ंक्शन के पैरामीटर के रूप में सरणी हो)
नाथन मेरिल

@NathanMerrill हाँ, मैं ऐसा करने के बारे में सोच रहा था, लेकिन फिर मैंने सोचा कि आप वास्तव में इसे पसंद नहीं करेंगे, लेकिन अब जब मुझे पता है कि वास्तव में कोई फर्क नहीं पड़ता, तो मैं अपना उत्तर संपादित करूँगा। इसके अलावा, अल्पविराम से मेरे आयात को अलग करने के बारे में टिप के लिए धन्यवाद। मैं उस बारे में पूरी तरह से भूल गया था!
आर। काप

अन्य युक्तियां: आपके पास बहुत से अनावश्यक व्हाट्सएप हैं (कॉमा के बाद, बराबर संकेतों के बीच। आपको अंत में प्रिंट स्टेटमेंट की भी आवश्यकता नहीं है।
नाथन मेरिल

@NathanMerrill सुझावों के लिए धन्यवाद! मैं उन लोगों को ध्यान में रखूंगा जैसे मैं अधिक कोड-गोल्फिंग करता हूं! :)
आर। काप
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.