डिजाइनिंग फंक्शन f (f (n)) == -n


841

एक प्रश्न जो मुझे अपने अंतिम साक्षात्कार में मिला:

एक फ़ंक्शन डिज़ाइन करें f, जैसे:

f(f(n)) == -n

जहां n32 बिट हस्ताक्षरित पूर्णांक है ; आप जटिल संख्याओं का उपयोग नहीं कर सकते हैं।

यदि आप संख्याओं की पूरी श्रृंखला के लिए इस तरह के फ़ंक्शन को डिज़ाइन नहीं कर सकते हैं, तो इसे संभव सबसे बड़ी श्रेणी के लिए डिज़ाइन करें।

कोई विचार?


2
यह साक्षात्कार किस नौकरी के लिए था?
tymtam

जवाबों:


377

कैसा रहेगा:

f (n) = साइन (n) - (-1) n * n

पायथन में:

def f(n): 
    if n == 0: return 0
    if n >= 0:
        if n % 2 == 1: 
            return n + 1
        else: 
            return -1 * (n - 1)
    else:
        if n % 2 == 1:
            return n - 1
        else:
            return -1 * (n + 1)

पायथन स्वचालित रूप से पूर्णांक को मनमानी लंबाई की लंबाई के लिए बढ़ावा देता है। अन्य भाषाओं में सबसे बड़ा धनात्मक पूर्णांक अतिप्रवाह होगा, इसलिए यह एक को छोड़कर सभी पूर्णांकों के लिए काम करेगा।


इसे वास्तविक संख्याओं के लिए काम करने के लिए आपको n (-1) n के साथ बदलने की आवश्यकता है { ceiling(n) if n>0; floor(n) if n<0 }

C # में (किसी भी दोहरे के लिए काम करता है, अतिप्रवाह स्थितियों को छोड़कर):

static double F(double n)
{
    if (n == 0) return 0;

    if (n < 0)
        return ((long)Math.Ceiling(n) % 2 == 0) ? (n + 1) : (-1 * (n - 1));
    else
        return ((long)Math.Floor(n) % 2 == 0) ? (n - 1) : (-1 * (n + 1));
}

10
-1 के लिए टूट गया, क्योंकि -1 * 0 अभी भी 0 है
जोएल कोएहॉर्न

3
नहीं, यह नहीं है। f (-1) = 0. f (0) = 1
1800 सूचना

5
हालांकि यह 1 के लिए टूट गया है। f (1) = 0. f (0) = 1
1800 सूचना

18
हम्म, भी और विषम संख्या के साथ राज्य की बचत, मुझे लगता है कि होना चाहिए।
अज्ञात

38
मुझे लगता है कि सबसे महत्वपूर्ण बात वास्तविक फ़ंक्शन नहीं है (असीम रूप से कई समाधान हैं), लेकिन प्रक्रिया जिसके द्वारा आप इस तरह के फ़ंक्शन का निर्माण कर सकते हैं।
पियोन

440

आपने यह नहीं कहा कि उन्हें किस तरह की भाषा की उम्मीद थी ... यहाँ एक स्थिर समाधान (हास्केल) है। यह मूल रूप से 2 सबसे महत्वपूर्ण बिट्स के साथ खिलवाड़ कर रहा है:

f :: Int -> Int
f x | (testBit x 30 /= testBit x 31) = negate $ complementBit x 30
    | otherwise = complementBit x 30

यह एक गतिशील भाषा (पायथन) में बहुत आसान है। बस जाँच करें कि क्या तर्क एक संख्या X है और एक लैम्ब्डा लौटाता है जो रिटर्न -X:

def f(x):
   if isinstance(x,int):
      return (lambda: -x)
   else:
      return x()

23
कूल, मुझे यह पसंद है ... जावास्क्रिप्ट में समान दृष्टिकोण: var f = function (n) {return (टाइपो एन == 'फंक्शन')? n (): फंक्शन () {रिटर्न-एन; }}
मार्क रेनॉफ

यह शायद सिर्फ इतना है कि मेरा हास्केल बहुत रूखा है, लेकिन क्या आपने इसकी जाँच की है (f 0)? ऐसा लगता है कि (f 0x80000000) के रूप में एक ही परिणाम का उत्पादन करना चाहिए, कम से कम अगर हम 32-बिट ints के साथ wraparound अंकगणित (नकारात्मक संचालन पर) के साथ काम कर रहे हैं। और यह बुरा होगा।
डेरिक बेकन

11
क्या औसत साक्षात्कारकर्ता को यह भी पता होगा कि एक लंबोदर निर्माण क्या है ?
जेरेमी पॉवेल

4
बेशक, इस तरह की-चीटिंग ट्रिक हास्केल में भी काम करती है, भले ही यह स्थिर हो class C a b | a->b where { f :: a->b }:; instance C Int (()->Int) where { f=const.negate }; instance C (()->Int) Int where { f=($()) }
लेफ्टनैबाउटआउट

4
क्या? आपको यह विचार कहां से मिला कि टाइपो एफ (एन) === 'फंक्शन', विशेष रूप से, जहां एन एक संख्या है और आप एक नंबर वापस आने की उम्मीद करते हैं? मुझे समझ नहीं आ रहा है कि यहां एक इंस्टेंस केस कैसे लागू हो सकता है। मैं पायथन को अच्छी तरह से नहीं बोलता, लेकिन जेएस में एक फ़ंक्शन प्रकार के लिए तर्क की जाँच इस मामले में स्पष्ट गलत है। केवल संख्यात्मक समाधान यहां लागू होता है। f एक फ़ंक्शन है, f (n) संख्या है।
हैरी

284

यहां इस बात का प्रमाण दिया गया है कि इस तरह का एक फ़ंक्शन सभी संख्याओं के लिए मौजूद नहीं हो सकता है, अगर यह अतिरिक्त जानकारी का उपयोग नहीं करता है (32 बिट्स को छोड़कर):

हमारे पास f (0) = 0. (प्रमाण: मान लीजिए f (0) = x। तब f (x) = f (f (0)) = -0 = 0. अब, -x = f (f / x) )) = f (0) = x, जिसका अर्थ है कि x = 0.)

इसके अलावा, किसी भी xऔर के लिए y, मान लीजिए f(x) = y। हम f(y) = -xतो चाहते हैं । और f(f(y)) = -y => f(-x) = -y। संक्षेप में: यदि f(x) = y, फिर f(-x) = -y, और f(y) = -x, और f(-y) = x

तो, हमें 4 के सेट में 0 को छोड़कर सभी पूर्णांकों को विभाजित करने की आवश्यकता है, लेकिन हमारे पास ऐसे पूर्णांक की एक विषम संख्या है; इतना ही नहीं, यदि हम उस पूर्णांक को हटा दें जिसमें सकारात्मक प्रतिरूप नहीं है, तब भी हमारे पास 2 (mod4) संख्याएँ हैं।

यदि हम 2 अधिकतम संख्याओं को छोड़ देते हैं (एब्स मान द्वारा), तो हम फ़ंक्शन प्राप्त कर सकते हैं:

int sign(int n)
{
    if(n>0)
        return 1;
    else 
        return -1;
}

int f(int n)
{
    if(n==0) return 0;
    switch(abs(n)%2)
    {
        case 1:
             return sign(n)*(abs(n)+1);
        case 0:
             return -sign(n)*(abs(n)-1);
    }
}   

बेशक एक अन्य विकल्प, 0 का अनुपालन नहीं करना है, और बोनस के रूप में हटाए गए 2 नंबर प्राप्त करें। (लेकिन यह सिर्फ एक मूर्खतापूर्ण है अगर।)


29
मैं विश्वास नहीं कर सकता कि मुझे एक अच्छा प्रक्रियात्मक समाधान खोजने के लिए इसे नीचे पढ़ना पड़ा जो कि वैश्विक चर या चाल के बिना नकारात्मक संख्याओं को संभालता है जो कोड को बाधित करते हैं। अगर मैं आपको एक से अधिक बार वोट कर सकता हूं, तो मैं करूंगा।
काइल सिमेक

अच्छा अवलोकन, वहाँ किसी भी में अशून्य पूर्णांकों का एक विषम संख्या है कि n हस्ताक्षर किए बिट्स।
एंड्रेस जान टैक

यह मेरा जवाब भी होगा, लेकिन किनारे मामले n = -2147483648(न्यूनतम मूल्य) से सावधान रहें ; आप abs(n)उस मामले में नहीं कर सकते , और परिणाम अपरिभाषित (या एक अपवाद) होगा।
कर्क ब्रॉडहर्स्ट

1
@ a1kmm: क्षमा करें, ऊपर -2 should -2³¹ होना चाहिए था। वैसे भी, जहाँ मामला f (0) the 0 (और इसलिए f (0) = - 2 case) वास्तव में सबसे आसान मामला है, क्योंकि हमने दिखाया कि इन दोनों को बाकी हिस्सों से काट दिया गया है। दूसरे मामले पर हमें विचार करने की जरूरत है कि कुछ x (0, x ≠ -2³¹ के लिए f (0) = 0, लेकिन f (x) = - 2³¹ है। उस स्थिति में, f (-2³¹) = f (f (x)) = - x (नोट -x -2 such नहीं हो सकता, क्योंकि ऐसा कोई x मौजूद नहीं है)। आगे चलकर f (-x) = y। फिर f (y) = f (f (-x)) = x। फिर y -2 नहीं हो सकता (जैसा कि f (y) = x, लेकिन f (-2 =) = - x, और x 0 नहीं है)। तो, -2 f = एफ (एक्स) = एफ (एफ (वाई)) = - वाई, जो असंभव है। तो वास्तव में 0 और -2 indeed को बाकी हिस्सों से काट दिया जाना चाहिए (किसी और चीज की छवि नहीं)।
श्रीवत्सआर

1
@ क्या कोई हस्ताक्षरित शून्य नहीं हैं, अगर (जैसा कि मैं मानता हूं) हम दो-के-पूरक 32-बिट पूर्णांक के बारे में बात कर रहे हैं।
गोफ्री

146

C ++ में ओवरलोडिंग के लिए धन्यवाद:

double f(int var)
{
 return double(var);
} 

int f(double var)
{
 return -int(var);
}

int main(){
int n(42);
std::cout<<f(f(n));
}

4
दुर्भाग्य से, नाम की गड़बड़ी के कारण, जिन कार्यों को आप "एफ" कहते हैं, उनमें वास्तव में अजीब नाम हैं।
pyon

1
मैंने ऐसा कुछ सोचा है, लेकिन सी में सोचकर, यह फेंक दिया गया ... अच्छा काम!
लीरान ओरवी

@ रुई क्रेवरियो: यह .NET 3.5+ में काम नहीं करेगा क्योंकि लेखक ने वेरिएबल नाम को एक चर नाम के रूप में उपयोग करना चुना है।
क्रेड्स

72
तकनीकी रूप से ... यह वह नहीं है जो सवाल मांगता है। आपने 2 एफ () फ़ंक्शन, एफ (इंट) और एफ (फ्लोट) को परिभाषित किया है और सवाल "डिजाइन ए फंक्शन एफ () ..."
पूछते हैं

2
@elcuco तकनीकी रूप से, निश्चित रूप से, लेकिन तार्किक रूप से यह एक कार्य है जिसमें कई अधिभार हैं (आप उस के साथ f (f (42)) कर सकते हैं)। चूंकि परिभाषा मापदंडों और रिटर्न वैल्यू के बारे में कुछ नहीं कहती है, इसलिए मैं इसे तकनीकी परिभाषा के रूप में स्वीकार कर सकता हूं।
मर्क टोमन

135

या, आप प्रीप्रोसेसर का दुरुपयोग कर सकते हैं:

#define f(n) (f##n)
#define ff(n) -n

int main()
{
  int n = -42;
  cout << "f(f(" << n << ")) = " << f(f(n)) << endl;
}

तो आप कोनराड "ले चिफरे" रूडोल्फ होंगे? मैं अपना कोट लूंगा। हाँ, मुझे पूरी "शून्य मुख्य" चीज़ के बारे में पता है, लेकिन एक "वापसी 0" जोड़ते हुए; बस इतना अतिरिक्त प्रयास
;;

25
@Skizz, int से मुख्य रिटर्न c ++ में भी आवश्यक नहीं है यहां तक ​​कि int रिटर्न वैल्यू के साथ ... तो यह सही है कि आप वास्तव में एक कम चरित्र टाइप करते हैं!
डैन ओल्सन

10
Skizz हमेशा गाली पूर्वप्रक्रमक: डी
आर्निस Lapsa

23
यह एक समारोह नहीं है ..तो यह एक मान्य समाधान नहीं है
smerlin

3
@smerlin: यह तकनीकी रूप से एक इनलाइन फ़ंक्शन है जो इनलाइन फ़ंक्शन को लौटाता है: दोनों के शरीर का संकलन समय पर, या उससे पहले किया जाता है। इससे बहुत अधिक कुशल नहीं हो सकता।
जॉन पूर्डी

103

यह सभी नकारात्मक संख्याओं के लिए सही है।

    f (n) = abs (n)

चूँकि वहाँ एक से अधिक ऋणात्मक संख्याएँ हैं, क्योंकि टॉक्सो पूरक पूर्णांकों के लिए धनात्मक संख्याएँ हैं, समाधान की f(n) = abs(n)तुलना में एक और मामले के लिए मान्य f(n) = n > 0 ? -n : nहै जो उसी के समान है f(n) = -abs(n)। आपको एक मिला ...: डी

अपडेट करें

नहीं, यह एक मामले के लिए मान्य नहीं है, क्योंकि मुझे सिर्फ लिटबॅट की टिप्पणी से मान्यता प्राप्त है ... abs(Int.Min)बस अतिप्रवाह होगा ...

मैंने मॉड 2 की जानकारी का उपयोग करने के बारे में सोचा, भी, लेकिन निष्कर्ष निकाला, यह काम नहीं करता ... जल्दी। यदि सही किया जाता है, तो यह सभी नंबरों के लिए काम करेगा सिवाय इसके Int.Minक्योंकि यह अतिप्रवाह करेगा।

अपडेट करें

मैं इसके साथ थोड़ी देर के लिए खेला, एक अच्छा सा हेरफेर चाल की तलाश में, लेकिन मुझे एक अच्छा एक-लाइनर नहीं मिला, जबकि मॉड 2 समाधान एक में फिट बैठता है।

    f (n) = 2n (abs (n)% 2) - n + sgn (n)

C # में, यह निम्नलिखित बन जाता है:

public static Int32 f(Int32 n)
{
    return 2 * n * (Math.Abs(n) % 2) - n + Math.Sign(n);
}

सभी मूल्यों के लिए इसे काम करने के लिए, आपको एक ब्लॉक में गणना को शामिल Math.Abs()करना होगा (n > 0) ? +n : -nऔर शामिल करना होगा unchecked। तब आप Int.Minखुद भी मैप हो जाते हैं जैसे कि अनियंत्रित नकार करता है।

अपडेट करें

एक अन्य उत्तर से प्रेरित होकर मैं यह बताने जा रहा हूं कि फ़ंक्शन कैसे कार्य करता है और इस तरह के फ़ंक्शन का निर्माण कैसे किया जाता है।

शुरू में ही शुरू कर देता है। फ़ंक्शन fको बार-बार दिए गए मान पर लागू किया जाता है, जो nमानों के अनुक्रम को दर्शाते हैं।

    n => f (n) => f (f (n)) => f (f (f (n))) => f (f (f (n)))) => ...

प्रश्न मांग करता है f(f(n)) = -n, कि fतर्क को नकारने के दो क्रमिक अनुप्रयोग हैं । आगे के दो f- चार के कुल आवेदन - तर्क को फिर से उपज nफिर से नकारना ।

    n => f (n) => -n => f (f (f (n))) => n => f (n) => ...

अब लंबाई चार का एक स्पष्ट चक्र है। स्थानापन्न x = f(n)और यह देखते हुए कि प्राप्त समीकरण f(f(f(n))) = f(f(x)) = -xरखती है, निम्नलिखित अर्जित करता है।

    n => x => -n => -x => n => ...

तो हम दो संख्याओं के साथ लंबाई चार का एक चक्र प्राप्त करते हैं और दो संख्याओं को नकार दिया जाता है। यदि आप चक्र को एक आयत के रूप में कल्पना करते हैं, तो नकारात्मक मूल्य विपरीत कोनों पर स्थित हैं।

इस तरह के एक चक्र के निर्माण के कई समाधानों में से एक n से शुरू होने वाला है।

 n => एक को नकारा और घटाया
-n - 1 = - (n + 1) => एक जोड़ें
-n => नकारात्मक और एक जोड़ें
 n + 1 => एक घटाओ
 n

एक ठोस उदाहरण ऐसे चक्र का है +1 => -2 => -1 => +2 => +1। हम लगभग कर चुके हैं। यह देखते हुए कि निर्मित चक्र में एक विषम धनात्मक संख्या होती है, इसका उत्तराधिकारी भी और दोनों संख्याएँ नकारात्मक होती हैं, हम पूर्णांकों को आसानी से कई ऐसे चक्रों में विभाजित कर सकते हैं ( 2^32जो कि चार में से एक है) और एक ऐसा फ़ंक्शन मिला है जो स्थितियों को संतुष्ट करता है।

लेकिन हमें शून्य की समस्या है। चक्र में सम्‍मिलित होना चाहिए 0 => x => 0क्‍योंकि शून्य अपने आप में नकारात्‍मक है। और क्योंकि चक्र पहले से ही 0 => xयह बताता है 0 => x => 0 => x। यह केवल लंबाई दो का एक चक्र है और xदो अनुप्रयोगों के बाद खुद में बदल जाता है, में नहीं -x। सौभाग्य से एक मामला है जो समस्या को हल करता है। यदि Xशून्य शून्य के बराबर होता है, तो हम केवल शून्य वाले लंबाई का एक चक्र प्राप्त करते हैं और हमने उस समस्या को हल कर दिया है कि शून्य एक निश्चित बिंदु है f

किया हुआ? लगभग। हमारे पास 2^32संख्याएँ हैं, शून्य एक निश्चित बिंदु है जो 2^32 - 1संख्याओं को छोड़ता है , और हमें उस संख्या को चार संख्याओं के चक्रों में विभाजित करना चाहिए। बुरा जो 2^32 - 1चार में से एक नहीं है - लंबाई चार के किसी भी चक्र में नहीं तीन संख्याएँ रहेंगी।

मैं समाधान 3 बिट पर हस्ताक्षर किए से लेकर itegers के छोटे सेट का उपयोग के शेष भाग की व्याख्या करेगा -4करने के लिए +3। हम शून्य के साथ किया जाता है। हमारा एक पूरा चक्र है +1 => -2 => -1 => +2 => +1। अब हम शुरू होने वाले चक्र का निर्माण करते हैं +3

    +3 => -4 => -3 => +4 => +3

समस्या यह है कि +43 बिट पूर्णांक के रूप में प्रतिनिधित्व योग्य नहीं है। हम इसे +4नकार -3कर प्राप्त करेंगे +3- जो अभी भी एक वैध 3 बिट पूर्णांक है - लेकिन फिर एक +3(बाइनरी 011) को जोड़ने से बाइनरी 100मिलती है। अहस्ताक्षरित पूर्णांक के रूप में व्याख्या की गई है, +4लेकिन हमें इसे हस्ताक्षरित पूर्णांक के रूप में व्याख्या करना होगा -4। तो वास्तव -4में इस उदाहरण के लिए या Int.MinValueसामान्य मामले में पूर्णांक अंकगणितीय निषेध का दूसरा निश्चित बिंदु है - 0 और Int.MinValueउन्हें मैप किया जाता है। तो चक्र वास्तव में इस प्रकार है।

    +3 => -4 => -3 => -4 => -3

यह लंबाई दो का एक चक्र है और इसके अलावा +3चक्र के माध्यम से प्रवेश करता है -4। परिणाम -4में सही ढंग से दो फ़ंक्शन अनुप्रयोगों के बाद खुद को मैप किया जाता है, दो फ़ंक्शन अनुप्रयोगों के बाद +3सही ढंग से मैप किया जाता है -3, लेकिन -3दो फ़ंक्शन अनुप्रयोगों के बाद गलती से खुद को मैप किया जाता है।

इसलिए हमने एक फ़ंक्शन का निर्माण किया जो सभी पूर्णांकों के लिए काम करता है लेकिन एक। क्या हम बेहतर कर सकते हैं? हम नहीं कर सकते। क्यों? हमें लंबाई चार के चक्रों का निर्माण करना होगा और चार पूर्णांक तक पूरे पूर्णांक रेंज को कवर करने में सक्षम हैं। शेष मान दो निश्चित बिंदु हैं 0और Int.MinValueउन्हें स्वयं और दो मनमाने ढंग से पूर्णांक में मैप किया जाना चाहिए xऔर -xदो फ़ंक्शन अनुप्रयोगों द्वारा एक दूसरे के लिए मैप किया जाना चाहिए।

इसके विपरीत नक्शा बनाने के xलिए -xउन्हें चार चक्र बनाने होंगे और उन्हें उस चक्र के विपरीत कोनों पर स्थित होना चाहिए। परिणाम में 0और Int.MinValueविपरीत कोनों पर भी होना चाहिए। यह सही ढंग से नक्शा करेगा xऔर -xदो निश्चित बिंदुओं 0और Int.MinValueदो फ़ंक्शन अनुप्रयोगों के बाद स्वैप करेगा और दो असफल इनपुट के साथ हमें छोड़ देगा। इसलिए ऐसा फ़ंक्शन बनाना संभव नहीं है जो सभी मूल्यों के लिए काम करता है, लेकिन हमारे पास एक है जो एक को छोड़कर सभी मूल्यों के लिए काम करता है और यह सबसे अच्छा है जिसे हम प्राप्त कर सकते हैं।


मानदंडों को पूरा नहीं करता है: abs (abs (n))! = -N
Dan Olson

यकीन है कि यह करता है, सभी नकारात्मक संख्याओं के लिए, जैसे उसने कहा। यह सवाल का हिस्सा था: यदि आप एक सामान्य के साथ नहीं आ सकते हैं, तो उस एक के साथ आएँ जो व्यापक सीमा तक संभव हो।
jalf

यह उत्तर कम से कम उतना ही अच्छा है जितना कि मारज सिनोवाइक और रॉलैंड शॉ द्वारा दिया गया उत्तर, यह सिर्फ संख्याओं की एक अलग श्रेणी के लिए काम करता है
1800 सूचना

19
यार, तुम भी बस "अद्यतन" से छुटकारा पा सकते हो और सिर्फ एक एकजुट सही उत्तर लिख सकते हो। नीचे 3/4 ("एक अन्य उत्तर से प्रेरित") कमाल है।
एंड्रेस जान टैक

1
मुझे वास्तव में नकारात्मक संख्याओं के लिए एब्स-सॉल्यूशन पसंद है। सरल और आसानी से समझा।
थोरबजोरन रावन एंडरसन

97

जटिल संख्याओं का उपयोग करके, आप किसी संख्या को दो चरणों में नकारने के कार्य को प्रभावी रूप से विभाजित कर सकते हैं:

  • i से गुणा करें, और आपको n * i मिलता है, जो n ° 90 ° प्रति-दक्षिणावर्त घुमाया जाता है
  • मैं फिर से गुणा करें, और आप -n प्राप्त करें

बड़ी बात यह है कि आपको किसी विशेष हैंडलिंग कोड की आवश्यकता नहीं है। बस मैं गुणा करके काम करता हूं।

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

मैंने 8-बिट डेटा पर हस्ताक्षर करते हुए, निम्नलिखित आंकड़े पर यह कल्पना करने की कोशिश की। आपको 32-बिट पूर्णांक के लिए इसे स्केल करना होगा। प्रारंभिक n के लिए अनुमत सीमा -64 से +63 है। सकारात्मक n के लिए फ़ंक्शन क्या करता है:

  • यदि n 0..63 (प्रारंभिक सीमा) में है, तो फंक्शन कॉल 64 जोड़ता है, n की सीमा 64..127 (इंटरमीडिएट डिग्री) है।
  • यदि n 64..127 (इंटरमीडिएट रेंज) में है, तो फ़ंक्शन 64 से n घटाता है, n की रेंज में मैपिंग करता है।

नकारात्मक n के लिए, फ़ंक्शन मध्यवर्ती श्रेणी -65 ..- 128 का उपयोग करता है।

वैकल्पिक शब्द


4
@geschema, आपने उन अच्छे ग्राफिक्स को बनाने के लिए किस टूल का उपयोग किया?
jwfearn

10
क्षमा करें, यह प्रश्न स्पष्ट रूप से कहता है कि कोई जटिल संख्या नहीं है।
रुई क्रोवेरो

6
@ लीरन: मैंने ओमनीग्रैफ़ल (मैक-ओनली) का इस्तेमाल किया
geschema

39
+1 मुझे लगता है कि यह सबसे अच्छा जवाब है। मुझे नहीं लगता कि लोग पर्याप्त पढ़ते हैं, क्योंकि उन्होंने कहा कि प्रश्न में कहा गया है कि जटिल संख्या का उपयोग नहीं किया जा सकता है। मैंने पूरी बात पढ़ी, और आपने पूछे गए प्रश्न के गैर-जटिल समाधान के लिए मंच को निर्धारित करने के लिए जटिल संख्या में समाधान का वर्णन किया। बहुत अच्छी तरह से किया।
jrista

1
@jrista सभी समाधान एक दूसरे आयाम का उपयोग करते हैं, जो कि सभी 'जटिल संख्याएं' वास्तव में हैं (अधिकांश उपयोग विषम बनाम समान, और ऊपर उपयोग floatबनाम int)। '4 एलीमेंट रिंग' जो कई उत्तरों का वर्णन करती है, 4 राज्यों की आवश्यकता है, जिन्हें 2 राज्यों के साथ प्रत्येक के 2 आयामों के रूप में दर्शाया जा सकता है। समस्या यह जवाब के साथ कि यह अतिरिक्त संसाधन स्थान की आवश्यकता होती है (-64..63 के लिए केवल 'काम करता है', फिर भी जरूरत है -128..127 अंतरिक्ष) और स्पष्ट रूप से सूत्र लिखा राज्य नहीं है!
कर्क ब्रॉडहर्स्ट

65

Int.MaxValue और int.MinValue को छोड़कर काम करता है

    public static int f(int x)
    {

        if (x == 0) return 0;

        if ((x % 2) != 0)
            return x * -1 + (-1 *x) / (Math.Abs(x));
        else
            return x - x / (Math.Abs(x));
    }

चित्रमय


यकीन नहीं हो रहा था कि यह क्यों ठुकरा दिया गया। किस इनपुट के लिए यह विफल रहता है?
रॉड्रिक चैपमैन

आप साइनम फ़ंक्शन का उपयोग क्यों नहीं करते?
कोमोनॉड

1
छवि वास्तव में अच्छी है। भेजें 0करने के लिए 0और -2147483648करने के लिए -2147483648, निषेध ऑपरेटर के लिए के बाद से इन दो संख्याओं के ठीक अंक x => -x। बाकी संख्याओं के लिए, ऊपर की छवि में तीर का पालन करें। के रूप में SurDin के जवाब और अपनी टिप्पणी से स्पष्ट है, इस मामले में दो नंबर हो जाएगा, 2147483647और -2147483647कोई अन्य जोड़ी के साथ अदला-बदली के लिए छोड़ दिया है।
जेपी स्टिग नीलसन

यह एक स्माइली की तरह दिखता है - बहुत झुर्रियों के साथ
अंशुल

48

प्रश्न कुछ भी नहीं कहता है कि इनपुट प्रकार और फ़ंक्शन का वापसी मूल्य क्या fहोना चाहिए (कम से कम जिस तरह से आपने इसे प्रस्तुत किया है) ...

... बस जब n एक 32-बिट पूर्णांक है तब f(f(n)) = -n

तो, कैसे के बारे में कुछ पसंद है

Int64 f(Int64 n)
{
    return(n > Int32.MaxValue ? 
        -(n - 4L * Int32.MaxValue):
        n + 4L * Int32.MaxValue);
}

यदि n 32-बिट पूर्णांक है, तो कथन f(f(n)) == -nसत्य होगा।

जाहिर है, इस दृष्टिकोण को और भी व्यापक संख्या में काम करने के लिए बढ़ाया जा सकता है ...


2
ख़ुशामदी। चरित्र की सीमा।
जो फिलिप्स

2
हाँ, मैं एक समान दृष्टिकोण पर काम कर रहा था। तुम मुझे यह हालांकि हराया। +1 :)
जलफ

1
बहुत चालाक! यह जटिल संख्याओं का उपयोग करते हुए (और प्रभावी रूप से समान) के करीब है, जो स्पष्ट और आदर्श समाधान होगा लेकिन यह स्पष्ट रूप से अस्वीकृत है। स्वीकार्य संख्या की सीमा के बाहर काम करना।
कर्क ब्रॉडहर्स्ट

48

जावास्क्रिप्ट (या अन्य गतिशील रूप से टाइप की गई भाषा) के लिए आप फ़ंक्शन को एक इंट या ऑब्जेक्ट स्वीकार कर सकते हैं और दूसरे को वापस कर सकते हैं। अर्थात

function f(n) {
    if (n.passed) {
        return -n.val;
    } else {
        return {val:n, passed:1};
    }
}

दे रही है

js> f(f(10))  
-10
js> f(f(-10))
10

वैकल्पिक रूप से आप ओवरलोडिंग का उपयोग जोरदार टाइप की हुई भाषा में कर सकते हैं, हालांकि इससे नियम टूट सकते हैं

int f(long n) {
    return n;
}

long f(int n) {
    return -n;
}

उत्तरार्द्ध का अर्थ "एक" (एकवचन) फ़ंक्शन की आवश्यकता नहीं है। :)
आकर्षित

उत्तर का दूसरा भाग निकालें और यह एक सही उत्तर है।
23

@ आकर्षित किया, इसीलिए मैंने उल्लेख किया कि यह नियमों को तोड़ सकता है
कोबाल

2
जावास्क्रिप्ट में, एक फ़ंक्शन एक ऑब्जेक्ट है और इसलिए एक राज्य रख सकता है।
नोसरेडना

1
IMO: फ़ंक्शन f (n) {वापसी n.passed? -n.val: {val: n, pass: 1}} अधिक पठनीय और छोटा है।
सैम्यूडी

46

आपके प्लेटफ़ॉर्म के आधार पर, कुछ भाषाएँ आपको फ़ंक्शन में स्थिति बनाए रखने की अनुमति देती हैं। VB.Net, उदाहरण के लिए:

Function f(ByVal n As Integer) As Integer
    Static flag As Integer = -1
    flag *= -1

    Return n * flag
End Function

IIRC, C ++ ने भी इसकी अनुमति दी। मुझे संदेह है कि वे एक अलग समाधान की तलाश कर रहे हैं।

एक और विचार यह है कि चूंकि उन्होंने फ़ंक्शन के लिए पहली कॉल के परिणाम को परिभाषित नहीं किया था, आप इसे नियंत्रित करने के लिए विषम / समरूपता का उपयोग कर सकते थे:

int f(int n)
{
   int sign = n>=0?1:-1;
   if (abs(n)%2 == 0)
      return ((abs(n)+1)*sign * -1;
   else
      return (abs(n)-1)*sign;
}

सभी सम संख्याओं के परिमाण में एक जोड़ें, सभी विषम संख्याओं के परिमाण से घटाएं। दो कॉल के परिणाम में एक ही परिमाण होता है, लेकिन एक कॉल जहां यह यहां तक ​​कि हम साइन स्वैप करते हैं। ऐसे कुछ मामले हैं जहां यह काम नहीं करेगा (-1, अधिकतम या मिनट इंट), लेकिन यह अब तक सुझाए गए किसी भी चीज़ से बेहतर काम करता है।


1
मेरा मानना ​​है कि यह MAX_INT के लिए काम करता है क्योंकि यह हमेशा विषम होता है। यह MIN_INT और -1 के लिए काम नहीं करता है।
Airsource Ltd

9
यह एक समारोह नहीं है अगर इसके दुष्प्रभाव हैं।
nos

12
यह गणित में सही हो सकता है, लेकिन यह प्रोग्रामिंग में अप्रासंगिक है। तो सवाल यह है कि क्या वे गणितीय समाधान या प्रोग्रामिंग समाधान की तलाश कर रहे हैं। लेकिन यह देखते हुए कि यह एक प्रोग्रामिंग जॉब के लिए है ...
रयान लंडी

+1 मैं "स्थिर इंट एक्स" के साथ सी में एक पोस्ट करने जा रहा था जो आउटपुट की उपेक्षा के साथ एक फीफो को लागू कर रहा था। लेकिन यह काफी करीब है।
फाकलर

2
@ एनोस: हाँ यह है, यह सिर्फ संदर्भात्मक पारदर्शी नहीं है।
क्लार्क गैबेल

26

जावास्क्रिप्ट अपवादों को छोड़कर।

function f(n) {
    try {
        return n();
    }
    catch(e) { 
        return function() { return -n; };
    }
}

f(f(0)) => 0

f(f(1)) => -1


मुझे संदेह है कि अपवादों का उपयोग इस तरह से पहले किया गया है ... :)
NoBugs

+1 आउट ऑफ द बॉक्स थिंकिंग। ठंडा! लेकिन उत्पादन कोड में मैं सिर्फ सुरक्षित होने के लिए टाइपोफ का उपयोग करूंगा।

21

सभी 32-बिट मानों के लिए (चेतावनी के साथ कि -0 -2147483648 है)

int rotate(int x)
{
    static const int split = INT_MAX / 2 + 1;
    static const int negativeSplit = INT_MIN / 2 + 1;

    if (x == INT_MAX)
        return INT_MIN;
    if (x == INT_MIN)
        return x + 1;

    if (x >= split)
        return x + 1 - INT_MIN;
    if (x >= 0)
        return INT_MAX - x;
    if (x >= negativeSplit)
        return INT_MIN - x + 1;
    return split -(negativeSplit - x);
}

आपको मूल रूप से प्रत्येक -x => x => -x लूप को ay => -y => y पाश के साथ जोड़ना होगा। इसलिए मैंने इसके विपरीत पक्षों को जोड़ा split

उदाहरण के लिए 4 बिट पूर्णांक:

0 => 7 => -8 => -7 => 0
1 => 6 => -1 => -6 => 1
2 => 5 => -2 => -5 => 2
3 => 4 => -3 => -4 => 3

21

एक सी ++ संस्करण, शायद नियमों को कुछ हद तक झुका रहा है, लेकिन सभी संख्यात्मक प्रकारों (फ्लोट्स, इन्टस, डबल्स) और यहां तक ​​कि क्लास प्रकार के लिए काम करता है जो एकतरफा ऋण को अधिभारित करते हैं:

template <class T>
struct f_result
{
  T value;
};

template <class T>
f_result <T> f (T n)
{
  f_result <T> result = {n};
  return result;
}

template <class T>
T f (f_result <T> n)
{
  return -n.value;
}

void main (void)
{
  int n = 45;
  cout << "f(f(" << n << ")) = " << f(f(n)) << endl;
  float p = 3.14f;
  cout << "f(f(" << p << ")) = " << f(f(p)) << endl;
}

अच्छा विचार। एक विकल्प के रूप में, आप शायद संरचना को खो सकते हैं और इसके बजाय एक फ़ंक्शन एक पॉइंटर लौटाता है, दूसरा फ़ंक्शन डेरेफेरेंस और नेगेट करता है।
इम्बु

20

x86 एएसएम (एटी एंड टी स्टाइल):

; input %edi
; output %eax
; clobbered regs: %ecx, %edx
f:
    testl   %edi, %edi
    je  .zero

    movl    %edi, %eax
    movl    $1, %ecx
    movl    %edi, %edx
    andl    $1, %eax
    addl    %eax, %eax
    subl    %eax, %ecx
    xorl    %eax, %eax
    testl   %edi, %edi
    setg    %al
    shrl    $31, %edx
    subl    %edx, %eax
    imull   %ecx, %eax
    subl    %eax, %edi
    movl    %edi, %eax
    imull   %ecx, %eax
.zero:
    xorl    %eax, %eax
    ret

कोड की जाँच की, सभी संभव 32 बिट पूर्णांक पारित कर दिया, -2147483647 (अंडरफ्लो) के साथ त्रुटि।


19

ग्लोबल्स का उपयोग करता है ... लेकिन ऐसा है?

bool done = false
f(int n)
{
  int out = n;
  if(!done)
  {  
      out = n * -1;
      done = true;
   }
   return out;
}

3
सुनिश्चित नहीं है कि यह प्रश्न पूछने वाले का इरादा था, लेकिन "बॉक्स से बाहर सोच" के लिए +1।
लीरान ओरवी

5
सशर्त रूप से "किया = सही" कहने के बजाय, आपको हमेशा "किया = किया!" कहना चाहिए, इस तरह से आपके फ़ंक्शन को एक से अधिक बार उपयोग किया जा सकता है।
क्रिस लुत्ज़

@ क्रिस, सच करने के लिए किया गया सेटिंग के बाद से अगर एक ((किया)) ब्लॉक के अंदर है, यह किया = के बराबर है! किया है, लेकिन! गणना की जरूरत नहीं है (या कंपाइलर द्वारा अनुकूलित, अगर यह काफी स्मार्ट है) ।
nsayer

1
मेरा पहला विचार भी एक वैश्विक चर का उपयोग करके इसे हल करना था, भले ही यह इस विशेष प्रश्न के लिए धोखा देने जैसा महसूस हो। मैं फिर भी तर्क दूंगा कि एक वैश्विक चर समाधान प्रश्न में विशिष्टताओं को देखते हुए सबसे अच्छा समाधान है। एक वैश्विक का उपयोग करना यह समझना बहुत आसान बनाता है कि क्या हो रहा है। मैं सहमत हूँ कि एक किया! = किया बेहतर होगा, हालांकि। बस कि अगर खंड के बाहर ले जाएँ।
बुजुर्ग

3
तकनीकी रूप से, राज्य को बनाए रखने वाली कोई भी चीज़ एक फ़ंक्शन नहीं है, बल्कि एक राज्य मशीन है। द्वारा परिभाषा , एक समारोह हमेशा एक ही इनपुट के लिए एक ही उत्पादन देता है।
टेड हॉप

19

यह पर्ल समाधान पूर्णांक, फ्लोट और स्ट्रिंग्स के लिए काम करता है

sub f {
    my $n = shift;
    return ref($n) ? -$$n : \$n;
}

कुछ परीक्षण डेटा आज़माएं।

print $_, ' ', f(f($_)), "\n" for -2, 0, 1, 1.1, -3.3, 'foo' '-bar';

आउटपुट:

-2 2
0 0
1 -1
1.1 -1.1
-3.3 3.3
foo -foo
-bar +bar

लेकिन यह इसे एक इंट नहीं रखता है। आप अनिवार्य रूप से int "n" में वैश्विक चर डेटा संग्रहीत कर रहे हैं ... सिवाय इसके कि कोई int नहीं है अन्यथा आप ऐसा नहीं कर सकते। उदाहरण के लिए यदि nमैं एक स्ट्रिंग था तो मैं 548 बना सकता है "First_Time_548" और फिर अगली बार यह फ़ंक्शन के माध्यम से चलता है ... यदि (उपसर्ग == First_Time_ ")" First_Time_ "को" - "
Renshaw

@AlbertRenshaw यकीन नहीं है कि आप उन विचारों को प्राप्त करते हैं। (१) निश्चित रूप से यहाँ कोई वैश्विक चर शामिल नहीं हैं। (2) यदि आप फ़ंक्शन को एक इंट देते हैं, तो आपको एक इंट बैक मिलेगा - या एक इंट का संदर्भ, यदि आप फ़ंक्शन को विषम संख्या में कहते हैं। (३) शायद सबसे बुनियादी रूप से, यह पर्ल है । सभी व्यावहारिक उद्देश्यों के लिए, इन्टस और तार पूरी तरह से विनिमेय हैं। स्ट्रिंग्स जो संख्याओं की तरह दिखती हैं, अधिकांश संदर्भों में संख्याओं के साथ-साथ पूरी तरह से कार्य करेगी, और जब भी संख्याएं प्रसन्नतापूर्वक कड़े हो जाएंगी।
FMc

क्षमा करें, मुझे यह पता नहीं है कि ऐसा प्रतीत होता है कि आप एक वैश्विक सरणी haha ​​का उपयोग कर रहे थे
अल्बर्ट रेनशॉ

18

किसी ने कभी नहीं कहा कि f (x) को एक ही प्रकार का होना चाहिए।

def f(x):
    if type(x) == list:
        return -x[0]
    return [x]


f(2) => [2]
f(f(2)) => -2

16

मैं वास्तव में समस्या का हल खुद देने की कोशिश नहीं कर रहा हूं, लेकिन कुछ टिप्पणियां हैं, क्योंकि प्रश्न में कहा गया है कि यह समस्या एक (नौकरी?) साक्षात्कार का हिस्सा थी:

  • मैं सबसे पहले पूछूंगा कि "ऐसे कार्य की आवश्यकता क्यों होगी? यह किस बड़ी समस्या का हिस्सा है?" बजाय मौके पर वास्तविक समक्ष समस्या को हल करने की कोशिश करने के। इससे पता चलता है कि मैं कैसे सोचता हूं और मैं इस तरह की समस्याओं से कैसे निपटता हूं। कौन जानता है? यहां तक ​​कि वास्तविक कारण यह हो सकता है कि पहली बार में एक साक्षात्कार में सवाल पूछा जाए। यदि जवाब है "कभी आप बुरा नहीं मानते हैं, तो इसकी आवश्यकता है, और मुझे बताएं कि आप इस फ़ंक्शन को कैसे डिज़ाइन करेंगे।" मैं तो ऐसा करना जारी रखूंगा।
  • फिर, मैं C # टेस्ट केस कोड लिखूंगा जो मैं उपयोग करूंगा (स्पष्ट: लूप int.MinValueटू से int.MaxValue, और प्रत्येक nके लिए उस रेंज कॉल में f(f(n))और परिणाम की जांच कर -nरहा है ), बता रहा हूं कि मैं इस तरह के फ़ंक्शन को प्राप्त करने के लिए टेस्ट ड्रिवेन डेवलपमेंट का उपयोग करूंगा।
  • केवल तभी जब साक्षात्कारकर्ता मुझसे समस्या के समाधान के लिए पूछ रहा है, मैं वास्तव में कोशिश करना शुरू कर दूंगा और साक्षात्कार के दौरान छद्म कोड को स्क्रिबल करने की कोशिश करूंगा और किसी प्रकार का उत्तर प्राप्त करूंगा। हालांकि, मुझे नहीं लगता कि मैं नौकरी लेने के लिए कूद रहा हूं अगर साक्षात्कारकर्ता किसी भी तरह का संकेत होगा कि कंपनी क्या है ...

ओह, यह उत्तर मानता है कि साक्षात्कार C # प्रोग्रामिंग संबंधी स्थिति के लिए था। निश्चित रूप से एक मूर्खतापूर्ण जवाब होगा यदि साक्षात्कार गणित से संबंधित स्थिति के लिए था। ;-)


7
आप भाग्यशाली हैं कि उन्होंने 32 इंट के लिए कहा, अगर यह 64 बिट साक्षात्कार था तो आप परीक्षण चलाने के बाद जारी नहीं रखेंगे ;-)
alex2k8

वास्तव में, अगर मैं वास्तव में उस परीक्षण को लिखने के लिए एक बिंदु पर पहुंचूंगा और एक साक्षात्कार के दौरान इसे चलाऊंगा। ;-) मेरी बात: मैं एक इंटरव्यू में उस बिंदु पर नहीं आने की कोशिश करूँगा। प्रोग्रामिंग "मेरी राय में कोड की पंक्तियों को कैसे लिखता है" की तुलना में "सोचने का एक तरीका" अधिक है।
peSHIr

7
एक वास्तविक साक्षात्कार में इस सलाह का पालन न करें। साक्षात्कारकर्ता आपसे अपेक्षा करता है कि आप वास्तव में प्रश्न का उत्तर देंगे। प्रश्न की प्रासंगिकता पर सवाल उठाना आपको कुछ भी नहीं खरीदेगा लेकिन यह साक्षात्कारकर्ता को परेशान कर सकता है। एक तुच्छ परीक्षा को डिजाइन करने से आपको उत्तर के करीब कोई कदम नहीं आता है, और आप इसे साक्षात्कार में नहीं चला सकते हैं। यदि आपको अतिरिक्त जानकारी (32 बिट) मिलती है, तो यह पता लगाने की कोशिश करें कि यह कैसे उपयोगी हो सकता है।
स्टीफन हास्टीन

एक साक्षात्कारकर्ता जो अधिक जानकारी मांगने पर नाराज़ हो जाता है (जबकि संभवतः प्रक्रिया में उसके प्रश्न की प्रासंगिकता पर सवाल उठाता है) एक साक्षात्कारकर्ता नहीं है, जो मुझे जरूरी है कि मैं / के साथ काम करना चाहता हूं। इसलिए मैं इंटरव्यू में उस तरह के सवाल पूछता रहूंगा। यदि वे इसे पसंद नहीं करते हैं, तो मैं शायद दोनों समय हमारे आगे बर्बाद करने को रोकने के लिए साक्षात्कार समाप्त कर दूंगा। पसंद नहीं है "मैं केवल आदेशों का पालन कर रहा था" मन एक बिट सेट। क्या आप..?
peSHIr

16

मैं आपको 2 सबसे महत्वपूर्ण बिट्स बदल दूंगा।

00.... => 01.... => 10.....

01.... => 10.... => 11.....

10.... => 11.... => 00.....

11.... => 00.... => 01.....

जैसा कि आप देख सकते हैं, यह केवल एक अतिरिक्त है, बाहर किए गए बिट को छोड़कर।

मुझे जवाब कैसे मिला? मेरा पहला विचार सिर्फ समरूपता की आवश्यकता थी। 4 जहां मैंने शुरू किया था, वापस पाने के लिए। पहले मैंने सोचा, यह 2 बिट्स ग्रे कोड है। तब मुझे लगा कि वास्तव में मानक बाइनरी पर्याप्त है।


इस दृष्टिकोण के साथ समस्या यह है कि यह दो तारीफ नकारात्मक संख्याओं के साथ काम नहीं करता है (जो कि प्रत्येक आधुनिक सीपीयू उपयोग करता है)। इसलिए मैंने अपना समान उत्तर हटा दिया।
तमस Czinege

प्रश्न 32-बिट हस्ताक्षरित पूर्णांक निर्दिष्ट करता है। यह समाधान 32-बिट हस्ताक्षरित पूर्णांक के दो-पूरक या किसी-पूरक प्रतिनिधित्व के लिए काम नहीं करता है। यह केवल साइन-एंड-परिमाण अभ्यावेदन के लिए काम करेगा, जो आधुनिक कंप्यूटर (फ्लोटिंग पॉइंट नंबरों के अलावा) में बहुत ही असामान्य हैं।
जेफरी एल व्हाइटलेज

1
@DrJokepu - वाह, छह महीने बाद - jinx!
जेफरी एल व्हाइटलेज

क्या आपको फ़ंक्शन के अंदर साइन-और-परिमाण प्रतिनिधित्व के लिए संख्याओं को परिवर्तित करने की आवश्यकता नहीं है, रूपांतरण करें, फिर इसे वापस करने से पहले मूल पूर्णांक प्रतिनिधित्व जो भी है उसे वापस कन्वर्ट करें?
बिल माइकेल

मुझे यह पसंद है कि आपने मूल रूप से एक काल्पनिक बिट की शुरुआत करके जटिल संख्याओं को लागू किया :)
jabirali

16

यहां एक समाधान है जो आवश्यकता से प्रेरित है या दावा करता है कि इस समस्या को हल करने के लिए जटिल संख्याओं का उपयोग नहीं किया जा सकता है।

-1 के वर्गमूल से गुणा करना एक विचार है, जो केवल इसलिए विफल लगता है क्योंकि -1 में पूर्णांकों पर वर्गमूल नहीं होता है। लेकिन गणितज्ञ जैसे कार्यक्रम के साथ खेलना उदाहरण के लिए समीकरण देता है

(1849436465 2 +1) मॉड (2 32 -3) = 0।

और यह -1 के वर्गमूल के रूप में लगभग उतना ही अच्छा है। फ़ंक्शन के परिणाम को एक हस्ताक्षरित पूर्णांक होना चाहिए। इसलिए मैं एक संशोधित मोडुलो ऑपरेशन मॉड (x, n) का उपयोग करने जा रहा हूं जो पूर्णांक y को x modulo n के अनुरूप बनाता है जो कि 0 के सबसे करीब है। केवल कुछ ही प्रोग्रामिंग भाषाओं में एक मोड्यूलो ऑपरेशन है, लेकिन इसे आसानी से परिभाषित किया जा सकता है। । अजगर में यह है:

def mods(x, n):
    y = x % n
    if y > n/2: y-= n
    return y

उपरोक्त समीकरण का उपयोग करके, समस्या को अब हल किया जा सकता है

def f(x):
    return mods(x*1849436465, 2**32-3)

यह f(f(x)) = -xसीमा में सभी पूर्णांकों के लिए संतुष्ट करता है । इस श्रेणी के परिणाम भी हैं, लेकिन निश्चित रूप से गणना को 64-बिट पूर्णांक की आवश्यकता होगी।[-231-2, 231-2]f(x)


13

C # 2 ^ 32 की श्रेणी के लिए - 1 नंबर, सभी int32 नंबर को छोड़कर (Int32.MinValue)

    Func<int, int> f = n =>
        n < 0
           ? (n & (1 << 30)) == (1 << 30) ? (n ^ (1 << 30)) : - (n | (1 << 30))
           : (n & (1 << 30)) == (1 << 30) ? -(n ^ (1 << 30)) : (n | (1 << 30));

    Console.WriteLine(f(f(Int32.MinValue + 1))); // -2147483648 + 1
    for (int i = -3; i <= 3  ; i++)
        Console.WriteLine(f(f(i)));
    Console.WriteLine(f(f(Int32.MaxValue))); // 2147483647

प्रिंट:

2147483647
3
2
1
0
-1
-2
-3
-2147483647

यह भी f (0) के लिए काम नहीं करता है जो कि 1073741824 है। f (1073741824) = 0. f (f (1073741824)) = 1073741824
Dinah

आप आम तौर पर साबित कर सकते हैं कि किसी भी बिट आकार के दो पूरक पूर्णांक प्रकार के लिए, फ़ंक्शन को कम से कम दो इनपुट मानों के लिए काम नहीं करना पड़ता है
आलसी

12

अनिवार्य रूप से फ़ंक्शन को उपलब्ध रेंज को आकार 4 के चक्र में विभाजित करना है, एन के चक्र के विपरीत छोर पर -n के साथ। हालाँकि, 0 आकार 1 के एक चक्र का हिस्सा होना चाहिए, क्योंकि अन्यथा 0->x->0->x != -x। 0 अकेले होने के कारण, हमारी सीमा में 3 अन्य मान होने चाहिए (जिनका आकार 4 का गुणक है) 4 तत्वों के साथ एक उचित चक्र में नहीं है।

मैं होने के लिए इन अतिरिक्त अजीब मूल्यों चुना है MIN_INT, MAX_INTऔर MIN_INT+1। इसके अलावा, सही ढंग से MIN_INT+1मैप करेगा MAX_INT, लेकिन वहां अटक जाएं और वापस मैप न करें। मुझे लगता है कि यह सबसे अच्छा समझौता है, क्योंकि इसमें केवल चरम मूल्यों की अच्छी संपत्ति है जो सही तरीके से काम नहीं कर रहे हैं। इसके अलावा, इसका मतलब है कि यह सभी BigInts के लिए काम करेगा ।

int f(int n):
    if n == 0 or n == MIN_INT or n == MAX_INT: return n
    return ((Math.abs(n) mod 2) * 2 - 1) * n + Math.sign(n)

12

किसी ने भी यह नहीं कहा कि इसे स्टेटलेस होना चाहिए।

int32 f(int32 x) {
    static bool idempotent = false;
    if (!idempotent) {
        idempotent = true;
        return -x;
    } else {
        return x;
    }
}

धोखा, लेकिन बहुत सारे उदाहरणों के रूप में नहीं। इससे भी अधिक बुराई यह देखने के लिए स्टैक को देखने के लिए होगी कि क्या आपके कॉलर का पता & f है, लेकिन यह अधिक पोर्टेबल होने वाला है (हालांकि थ्रेड सेफ नहीं है ... थ्रेड-सेफ वर्जन TLS का उपयोग करेगा)। और भी बुरी:

int32 f (int32 x) {
    static int32 answer = -x;
    return answer;
}

बेशक, इनमें से कोई भी MIN_INT32 के मामले के लिए बहुत अच्छी तरह से काम नहीं करता है, लेकिन आपके बारे में बहुत कम कीमती है जब तक कि आपको एक व्यापक प्रकार वापस करने की अनुमति न हो।


आप पते के बारे में पूछने के लिए इसे 'अपग्रेड' कर सकते हैं (हाँ, आपको इसे एक संकेतक के रूप में Ref \ _ द्वारा प्राप्त करना होगा) - C में, उदाहरण के लिए: int f (int & n) {static int * addr = & n; if (addr == & n) {रिटर्न-एन; } एन वापस; }
IUnognPointer

11

मैं एक काल्पनिक ( i ) बिट के रूप में 31 वें बिट का उपयोग करने की कल्पना कर सकता हूं जो कि कुल सीमा का आधा समर्थन करेगा।


यह अधिक जटिल होगा, लेकिन वर्तमान सर्वोत्तम उत्तर की तुलना में अधिक प्रभावी नहीं है
1800 सूचना 21

1
@ 1800 सूचना: दूसरी ओर, डोमेन [-2 ^ 30 + 1, 2 ^ 30-1] सन्निहित है जो गणितीय दृष्टिकोण से अधिक आकर्षक है।
जोहान वाल्टर

10

n = [0 .. 2 ^ 31-1] के लिए काम करता है

int f(int n) {
  if (n & (1 << 31)) // highest bit set?
    return -(n & ~(1 << 31)); // return negative of original n
  else
    return n | (1 << 31); // return n with highest bit set
}

10

समस्या बताती है "32-बिट हस्ताक्षरित पूर्णांक" लेकिन यह निर्दिष्ट नहीं करता है कि वे दो-पूरक हैं या लोग-पूरक हैं

यदि आप लोगों के पूरक का उपयोग करते हैं तो सभी 2 ^ 32 मान चार लंबाई के चक्र में होते हैं - आपको शून्य के लिए एक विशेष मामले की आवश्यकता नहीं होती है, और आपको सशर्त की भी आवश्यकता नहीं होती है।

सी में:

int32_t f(int32_t x)
{
  return (((x & 0xFFFFU) << 16) | ((x & 0xFFFF0000U) >> 16)) ^ 0xFFFFU;
}

इससे काम होता है

  1. उच्च और निम्न 16-बिट ब्लॉक का आदान-प्रदान
  2. ब्लॉकों में से एक में बदलना

दो पास होने के बाद हमारे पास मूल मूल्य का बिटवाइज़ उलटा है। जो लोगों में पूरक प्रतिनिधित्व नकार के बराबर है।

उदाहरण:

Pass |        x
-----+-------------------
   0 | 00000001      (+1)
   1 | 0001FFFF (+131071)
   2 | FFFFFFFE      (-1)
   3 | FFFE0000 (-131071)
   4 | 00000001      (+1)

Pass |        x
-----+-------------------
   0 | 00000000      (+0)
   1 | 0000FFFF  (+65535)
   2 | FFFFFFFF      (-0)
   3 | FFFF0000  (-65535)
   4 | 00000000      (+0)

1
विभिन्न आर्किटेक्चर में बाइट-ऑर्डर के बारे में क्या?
स्टीवन

1
सभी अंकगणित 32-बिट है। मैं व्यक्तिगत बाइट्स में हेरफेर नहीं करता हूं, इसलिए बाइट ऑर्डर इसे प्रभावित नहीं करेगा।
वित्तीय वर्ष

यह बहुत करीब लगता है। आप मान सकते हैं कि इनपुट 2-पूरक है। तो आप साइन बिट प्रतिनिधित्व में परिवर्तित होते हैं। अब अंतिम बिट के आधार पर, आप पहले बिट और अंतिम बिट या बस अंतिम बिट को फ्लिप करते हैं। मूल रूप से आप केवल संख्याओं की उपेक्षा करते हैं और हर समय / विषम चक्र भी करते हैं। तो आप विषम से विषम और यहां तक ​​कि 2 कॉल के बाद भी वापस आ जाते हैं। अंत में आप 2-पूरक में परिवर्तित होते हैं। इसके लिए कोड नीचे कहीं पोस्ट किया है।
स्टीफन हास्टीन

9

: डी

boolean inner = true;

int f(int input) {
   if(inner) {
      inner = false;
      return input;
   } else {
      inner = true;
      return -input;
   }
}

5
हो सकता है कि आपको इस बात की भी चर्चा हो कि वैश्विक चर बुरे क्यों हैं यदि वे आपको साक्षात्कार से बाहर नहीं कर सकते हैं!
पाल्स्विम


7

मैं इस दिलचस्प समस्या पर एक गणितज्ञ के रूप में अपनी बात साझा करना चाहता हूं। मुझे लगता है कि मेरे पास सबसे कुशल समाधान है।

अगर मुझे सही से याद है, तो आपने पहले बिट को फ़्लिप करके एक हस्ताक्षरित 32-बिट पूर्णांक को नकार दिया है। उदाहरण के लिए, यदि n = 1001 1101 1110 1011 1110 0000 1110 1010, तो -n = 0001 1101 1110 1011 1110 0000 1110 1010।

तो हम एक फंक्शन एफ को कैसे परिभाषित करते हैं जो एक हस्ताक्षरित 32-बिट पूर्णांक लेता है और एक और हस्ताक्षरित 32-बिट पूर्णांक को उस संपत्ति के साथ वापस करता है जो दो बार एफ ले रहा है पहले बिट को फ़्लिप करने के समान है?

मुझे पूर्णांक जैसी अंकगणितीय अवधारणाओं का उल्लेख किए बिना प्रश्न को फिर से समझने दें।

हम एक फ़ंक्शन f को कैसे परिभाषित करते हैं जो शून्य और लंबाई 32 के अनुक्रम को लेता है और शून्य का अनुक्रम देता है और उसी लंबाई के लोगों के साथ, संपत्ति के साथ जो दो बार f लेती है वह पहली बिट को फ़्लिप करने के समान है?

अवलोकन: यदि आप 32 बिट मामले के लिए उपरोक्त प्रश्न का उत्तर दे सकते हैं, तो आप 64 बिट मामले, 100 बिट मामले आदि के लिए भी उत्तर दे सकते हैं। आप केवल पहले 32 बिट के लिए एफ लागू करते हैं।

अब अगर आप 2 बिट केस के लिए सवाल का जवाब दे सकते हैं, तो वोइला!

और हां यह पता चला है कि पहले 2 बिट्स को बदलना काफी है।

यहाँ छद्म कोड है

1. take n, which is a signed 32-bit integer.
2. swap the first bit and the second bit.
3. flip the first bit.
4. return the result.

टिप्पणी: चरण 2 और चरण 3 को एक साथ (ए, बी) -> (-बी, ए) के रूप में ग्रीष्मकालिन किया जा सकता है। जाना पहचाना? यह आपको विमान के 90 डिग्री रोटेशन और -1 के स्क्वर रूट से गुणा की याद दिलाना चाहिए।

अगर मैं सिर्फ लंबी प्रस्तावना के बिना छद्म कोड प्रस्तुत करता हूं, तो यह टोपी से खरगोश की तरह प्रतीत होगा, मैं यह बताना चाहता था कि मुझे इसका समाधान कैसे मिला।


6
हाँ यह एक दिलचस्प समस्या है। आप अपना गणित जानते हैं। लेकिन यह कंप्यूटर साइंस की समस्या है। इसलिए आपको कंप्यूटर का अध्ययन करने की आवश्यकता है। साइन-परिमाण प्रतिनिधित्व स्वीकार्य है लेकिन यह लगभग 60 साल पहले शैली से बाहर हो गया था। 2-पूरक सबसे लोकप्रिय है।
विंडोज प्रोग्रामर

5
यहां दो बार लागू होने पर आपके फ़ंक्शन दो बिट्स को क्या करता है: (ए, बी) -> (-बी, ए) -> (-ए, -बी)। लेकिन, हम (-ए, बी), नहीं (-ए, -बी) में जाने की कोशिश कर रहे हैं।
बुटी-ऑक्सा

@ बूटी-ऑक्सा, आप सही कह रहे हैं। जैसा कि विंडोज प्रोग्रामर ने कहा कि दो बिट्स ऑपरेशन इस प्रकार होने चाहिए: 00 -> 01 -> 10 -> 11 -> 00. लेकिन फिर मेरा एल्गोरिथ्म साइन-मैग्नीट्यूड प्रतिनिधित्व दर्शाता है जो अब अलोकप्रिय है। ।
यो

तो क्या वह सिर्फ एक बार के बजाय दो बार कदम नहीं उठा सकता है?
नोसरेडना

4
buti-oxa पूरी तरह से सही है: फ़ंक्शन दो इनवोकेशन के बाद भी पहले बिट को फ्लिप नहीं करता है, यह पहले दो बिट्स को फ़्लिप करता है। सभी बिट्स को फ़्लिप करना 2 के पूरक के करीब है, लेकिन यह बिल्कुल सही नहीं है।
लालटुना
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.