जोसेफस समस्या (बाहर गिनती)


29

चुनौती

एक फ़ंक्शन लिखें जो दो सकारात्मक पूर्णांक n और k को तर्क के रूप में लेता है और प्रत्येक k -th व्यक्ति को गिनने के बाद n से शेष अंतिम व्यक्ति की संख्या लौटाता है ।

यह एक कोड-गोल्फ चुनौती है, इसलिए सबसे छोटा कोड जीतता है।

समस्या

n लोग ( 1 से n तक गिने गए ) एक सर्कल में खड़े हैं और प्रत्येक k को तब तक गिना जाता है जब तक कि एक व्यक्ति शेष न हो (संबंधित विकिपीडिया लेख देखें )। इस अंतिम व्यक्ति की संख्या निर्धारित करें।

जैसे k = 3 के लिए दो लोगों को छोड़ दिया जाएगा और तीसरे को गिना जाएगा। I के लिए n = 7 संख्याओं को क्रम 3 6 2 7 5 1 (विस्तार से 1 2 3 4 5 6 7 1 2 4 5 7 1 4 5 1 4 1 4 ) में गिना जाएगा और इस प्रकार उत्तर 4 है

उदाहरण

J(7,1) = 7      // people are counted out in order 1 2 3 4 5 6 [7]
J(7,2) = 7      // people are counted out in order 2 4 6 1 5 3 [7]
J(7,3) = 4      // see above
J(7,11) = 1
J(77,8) = 1
J(123,12) = 21

जवाबों:


5

GolfScript, 17 बाइट्स

{{@+\)%}+\,*)}:f;

n kस्टैक पर ले जाता है , और स्टैक पर परिणाम छोड़ देता है।

विच्छेदन

यह पुनरावृत्ति का उपयोग करता है (विकिपीडिया लेख में वर्णित) पुनरावृत्ति के g(n,k) = (g(n-1,k) + k) % nसाथ g(1, k) = 0एक गुना द्वारा प्रतिस्थापित किया गया।

{          # Function declaration
           # Stack: n k
  {        # Stack: g(i-1,k) i-1 k
    @+\)%  # Stack: g(i,k)
  }+       # Add, giving stack: n {k block}
  \,*      # Fold {k block} over [0 1 ... n-1]
  )        # Increment to move from 0-based to 1-based indexing
}:f;

क्या आप एक स्पष्टीकरण जोड़ सकते हैं, कृपया?
शर्लक

@ शर्लक 9, मैं यह पता लगाने में कामयाब रहा कि लगभग 3.5 साल बीत जाने के बावजूद मैं क्या कर रहा था। कौन कहता है कि गोल्फस्क्रिप्ट केवल-पढ़ने के लिए है? ;)
पीटर टेलर

अहम। s / read / write /
पीटर टेलर

माफ़ कीजिये। मैंने केवल दो या तीन दिन पहले गोल्फस्क्रिप्ट सीखना शुरू किया है और हर बार जब भी मैं आपका कोड पढ़ता हूं, मैं सोचता रहता था कि मैंने कुछ याद किया है। ... ठीक है, मैं अभी भी कुछ याद कर रहा हूं, तह {k block}करना [0..n-1]आपको g(0,k) 0 kशुरू करने के लिए कैसे मिलता है ? क्षमा करें, यदि मैं इन प्रश्नों को गलत स्थान पर पोस्ट कर रहा हूं।
शर्लक

@ शरलॉक 9, फोल्ड पेयरवाइज काम करता है, इसलिए सबसे पहले इसका मूल्यांकन किया जाता है 0 1 block। बहुत आसानी से, ऐसा होता है g(1, k) (2-1) block। इसलिए इसके g(1,k) 1बजाय शुरू हो रहा है g(0,k) 0। फिर ब्लॉक को निष्पादित करने के बाद, यह सरणी से अगले आइटम को धक्का देता है ( 2) और ब्लॉक को फिर से निष्पादित करता है, आदि
पीटर टेलर

14

Minsky रजिस्टर मशीन (25 गैर-हाल्ट राज्य)

तकनीकी रूप से एक कार्य नहीं है, लेकिन यह एक कंप्यूटिंग प्रतिमान में है, जिसमें प्रति कार्य नहीं है ...

यह मेरी पहली एमआरएम व्याख्या चुनौती के मुख्य परीक्षण के मामले में थोड़ी भिन्नता है : Minsky रजिस्टर मशीन के रूप में जोसेफस समस्या

रजिस्टरों में इनपुट nऔर k; रजिस्टर में उत्पादन r; यह माना जाता है कि r=i=t=0प्रवेश पर। पहले दो पड़ाव निर्देश त्रुटि के मामले हैं।


मुझे लगता है कि आपको अपनी मशीन को थोड़ा समायोजित करना होगा। अगर मैं इसे सही ढंग से पढ़ता हूँ तो आउटपुट शून्य-अनुक्रमित है, है ना?
हॉवर्ड

मैं दूसरे तरीके से सोच रहा था: अगर k=1तब r=0। हम्म, मुझे इस बारे में एक बार फिर से सोचना है ...
हॉवर्ड

जैसा कि मैंने आपका आरेख पढ़ा है, iबस उसी समय से गिना जा रहा 2है nजब rतक रजिस्टर है जो परिणाम जमा करता है।
हॉवर्ड

@ हॉवर्ड, मैंने उन टिप्पणियों को देखा जब मैंने पहली बार यह लिखा था और आप सही थे। ओह। अब सही किया गया है (मेरा मानना ​​है - बाद में अधिक अच्छी तरह से परीक्षण करेगा)।
पीटर टेलर

7

अजगर, ३६

मैंने विकिपीडिया से सूत्र का उपयोग भी किया है:

J=lambda n,k:n<2or(J(n-1,k)+k-1)%n+1

उदाहरण:

>>> J(7,3)
4
>>> J(77,8)
1
>>> J(123,12)
21


5

C, 40 वर्ण

यह बहुत ही अधिक फार्मूला है जो उपरोक्त लिंक्ड विकिपीडिया लेख देता है:

j(n,k){return n>1?(j(n-1,k)+k-1)%n+1:1;}

विविधता के लिए, यहां एक कार्यान्वयन है जो वास्तव में सिमुलेशन (99 वर्ण) चलाता है:

j(n,k,c,i,r){char o[999];memset(o,1,n);for(c=k,i=0;r;++i)(c-=o[i%=n])||(o[i]=!r--,c=k);
return i;}

4
एक चरित्र बचाओ j(n,k){return--n?(j(n,k)+k-1)%-~n+1:1;}:।
बदसूरत

5

डीसी, 27 बाइट्स

[d1-d1<glk+r%1+]dsg?1-skrxp

विकिपीडिया लेख से पुनरावृत्ति का उपयोग करता है। स्पष्टीकरण:

# comment shows what is on the stack and any other effect the instructions have
[   # n
d   # n, n
1-  # n-1, n
d   # n-1, n-1, n
1<g # g(n-1), n ; g is executed only if n > 1, conveniently g(1) = 1
lk+ # g(n-1)+(k-1), n; remember, k register holds k-1
r%  # g(n-1)+(k-1) mod n
1+  # (g(n-1)+(k-1) mod n)+1
]
dsg # code for g; code also stored in g
?   # read user input => k, n, code for g
1-  # k-1, n, code for g
sk  # n, code for g; k-1 stored in register k
r   # code for g, n
x   # g(n)
p   # prints g(n)

4

जे, 45 अक्षर

j=.[:{.@{:]([:}.]|.~<:@[|~#@])^:(<:@#)>:@i.@[

सिमुलेशन चलाता है।

वैकल्पिक रूप से, सूत्र का उपयोग करके (31 वर्ण):

j=.1:`(1+[|1-~]+<:@[$:])@.(1<[)

मुझे आशा है कि हावर्ड को इस बात से कोई आपत्ति नहीं है कि मैंने जे में एक डायडिक क्रिया के अनुरूप इनपुट प्रारूप को थोड़ा समायोजित किया है।

उपयोग:

   7 j 3
4
   123 j 12
21

4

GolfScript, 32 24 बाइट्स

:k;0:^;(,{))^k+\%:^;}/^)

उपयोग: दो मापदंडों n और k को स्टैक में होने की उम्मीद है और आउटपुट मूल्य छोड़ देता है।

(पुनरावृति दृष्टिकोण और कई अन्य युक्तियों के सुझाव के लिए पीटर टेलर का धन्यवाद)

32 वर्णों का पुराना (पुनरावर्ती) दृष्टिकोण:

{1$1>{1$(1$^1$(+2$%)}1if@@;;}:^;

यह मेरा पहला GolfScript है, तो कृपया मुझे अपनी आलोचनाएं बताएं।


1
1-विशेष opcode है (। इसी प्रकार 1+है )। आपको भंडारण के लिए वर्णमाला वर्णों का उपयोग करने की आवश्यकता नहीं है, इसलिए आप ^इसके बजाय उदाहरण के लिए उपयोग कर सकते हैं Jऔर इसके बाद किसी स्थान की आवश्यकता नहीं है। आपके पास $एक अच्छी तरह से गोल्फ कार्यक्रम में सामान्य रूप से कहीं अधिक एस हैं: विचार करें कि क्या आप कुछ संयोजन का उपयोग करके उन्हें कम कर सकते हैं \@.
पीटर टेलर

@PeterTaylor इन महान सुझावों के लिए बहुत बहुत धन्यवाद! सभी गोल्फस्क्रिप्ट ऑपरेटरों को समझाना बहुत कठिन है और मैंने इन दोनों को बहुत सरलता से अनदेखा कर दिया। केवल पहले दो सुझावों को लागू करके मैं कोड को 5 वर्णों से छोटा करने का प्रबंधन करता हूं। मैं $संदर्भों को हटाने का भी प्रयास करूँगा ।
क्रिस्टियन लुपस्कू

1
इसके अलावा, पुनरावृत्ति वास्तव में GolfScript की बात नहीं है। इसे गोल-गोल घुमाकर और लूप करके देखें। मैं इसे 19 वर्णों तक ले जा सकता हूं (यद्यपि अप्राप्त कोड) इस तरह। संकेत: gविकिपीडिया लेख से फ़ंक्शन को अनियंत्रित करें, और उपयोग करें ,और /
पीटर टेलर

1
{,{\2$+\)%}*)\;}:f;सुनिश्चित करें कि आप समझते हैं कि यह क्यों काम करता है?)
पीटर टेलर

1
एक अंतिम चाल: kलूप के अंदर पहुंचने के लिए 2 वर्णों का उपयोग करने के बजाय और फिर इसे समाप्त करने के लिए 2 अधिक, हम इसे +17 वर्णों तक नीचे जाने के लिए अंदर खींच सकते हैं : {{@+\)%}+\,*)}:f;मुझे संदेह है कि इसमें सुधार किया जा सकता है।
पीटर टेलर





1

सी, 88 वर्ण

सिमुलेशन करता है, सूत्र की गणना नहीं करता है।
सूत्र की तुलना में बहुत लंबा है, लेकिन अन्य सी सिमुलेशन से छोटा है।

j(n,k){
    int i=0,c=k,r=n,*p=calloc(n,8);
    for(;p[i=i%n+1]||--c?1:--r?p[i]=c=k:0;);
    return i;
}

नोट्स:
1. मेमोरी आवंटित करता है और कभी रिलीज नहीं होता है।
2. n*8इसके बजाय आवंटित करता n*4हूं, क्योंकि मैं उपयोग करता हूं p[n]। आवंटित कर सकता है (n+1)*4, लेकिन यह अधिक वर्ण है।


1

सी ++, 166 बाइट्स

golfed:

#include<iostream>
#include <list>
int j(int n,int k){if(n>1){return(j(n-1,k)+k-1)%n+1;}else{return 1;}}
int main(){intn,k;std::cin>>n>>k;std::cout<<j(n,k);return 0;}

Ungolfed:

#include<iostream>
#include <list>
int j(int n,int k){
    if (n > 1){
        return (j(n-1,k)+k-1)%n+1;
    } else {
        return 1;
    }
}
int main()
{
    int n, k;
    std::cin>>n>>k;
    std::cout<<j(n,k);
    return 0;
}

2
आप Jकार्य पर बाइट्स बचा सकते हैं , टर्नरी ऑपरेटर का उपयोग करके।
यति

intnआपके गोल्फ संस्करण में संकलन नहीं होगा
फेलिप

आप अंतरिक्ष में निकाल सकते हैं#include <list>
फेलिप नारदी बतिस्ता

1

जे, 8 बाइट्स

1&|.&.#:

       1&|.&.#: 10
    5

       1&|.&.#: 69
    11

        1&|.&.#: 123456
    115841

        1&|.&.#: 123245678901234567890x NB. x keeps input integral
    98917405212792722853

All credit to Roger Hui, co-inventor of J and all-round uber-genius
www.jsoftware.com for free j software across many platforms

Explanation
    (J works right-to-left)
     #:       convert input to binary
     &.       a&.b <=> perform b, perform a, perform reverse of b
     1&|.     rotate bitwise one bit left

So
    1&|.&.#: 10

    a. #:            convert input (10) TO binary -> 1 0 1 0
    b. 1&|.          rotate result 1 bit left -> 0 1 0 1
    c. due to the &. perform convert FROM binary -> 5 (answer)

1
क्या यह दो इनपुट लेने वाला नहीं है?
आउटगॉल्फ


1

क्यू, 34 बाइट्स

f:{$[x=1;1;1+mod[;x]f[x-1;y]+y-1]}

उपयोग:

q)f .'(7 1;7 2;7 3;7 11;77 8;123 12)
7 7 4 1 1 21


0

हास्केल, 29

विकिपीडिया से सूत्र का उपयोग करना।

1#_=1
n#k=mod((n-1)#k+k-1)n+1

0

जावास्क्रिप्ट (ECMAScript 5), 48 बाइट्स

ECMAScript 5 का उपयोग करना क्योंकि यह प्रश्न पूछे जाने के समय जावास्क्रिप्ट का नवीनतम संस्करण था।

function f(a,b){return a<2?1:(f(a-1,b)+b-1)%a+1}

ईएस 6 संस्करण (गैर-प्रतिस्पर्धात्मक), 33 बाइट्स

f=(a,b)=>a<2?1:(f(a-1,b)+b-1)%a+1

व्याख्या

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



0

8 वें , 82 बाइट्स

कोड

: j >r >r a:new ( a:push ) 1 r> loop ( r@ n:+ swap n:mod ) 0 a:reduce n:1+ rdrop ;

SED (स्टैक इफ़ेक्ट डायग्राम) है:n k -- m

उपयोग और स्पष्टीकरण

एल्गोरिथ्म इस तरह पूर्णांक की एक सरणी का उपयोग करता है: यदि लोगों का मान 5 है, तो सरणी [1,2,3,4,5] होगी

: j \ n k -- m
    >r                               \ save k
    >r a:new ( a:push ) 1 r> loop    \ make array[1:n]
    ( r@ n:+ swap n:mod ) 0 a:reduce \ translation of recursive formula with folding using an array with values ranging from 1 to n
    n:1+                             \ increment to move from 0-based to 1-based indexing
    rdrop                            \ clean r-stack
;

ok> 7 1 j . cr
7
ok> 7 2 j . cr
7
ok> 7 3 j . cr
4
ok> 7 11 j . cr
1
ok> 77 8 j . cr
1
ok> 123 12 j . cr
21

0

जे , 24 बाइट्स

1+1{1([:|/\+)/@,.1|.!.0#

इसे ऑनलाइन आज़माएं!

गतिशील प्रोग्रामिंग समाधान के आधार पर एक पुनरावृत्त दृष्टिकोण।

व्याख्या

1+1{1([:|/\+)/@,.1|.!.0#  Input: n (LHS), k (RHS)
                       #  Make n copies of k
                 1|.!.0   Shift left by 1 and fill with zero
    1          ,.         Interleave with 1
             /@           Reduce using
           +                Addition
        |/\                 Cumulative reduce using modulo
  1{                      Select value at index 1
1+                        Add 1



0

जाप , 15 बाइट्स

_é1-V Å}h[Uõ] Ì

इसे ऑनलाइन आज़माएं!

0-इंडेक्सिंग k द्वारा एक बाइट को बचाया जा सकता है , लेकिन यह वास्तव में एक इंडेक्स नहीं है इसलिए मैंने उसके खिलाफ फैसला किया।

स्पष्टीकरण:

         [Uõ]      :Starting with the array [1...n]
_      }h          :Repeat n-1 times:
 é1-V              : Rotate the array right 1-k times (i.e. rotate left k-1 times)
      Å            : Remove the new first element
              Ì    :Get the last value remaining


0

पॉवरशेल, 56 बाइट्स

param($n,$k)if($n-lt2){1}else{((.\f($n-1)$k)+$k-1)%$n+1}

जरूरी! स्क्रिप्ट अपने आप को पुनरावर्ती कहती है। तो स्क्रिप्ट को f.ps1वर्तमान निर्देशिका में फ़ाइल के रूप में सहेजें । इसके अलावा आप स्क्रिप्ट फ़ाइल के बजाय स्क्रिप्ट ब्लॉक चर कह सकते हैं (नीचे परीक्षण स्क्रिप्ट देखें)। उस कॉल की लंबाई समान है।

टेस्ट स्क्रिप्ट:

$f = {

param($n,$k)if($n-lt2){1}else{((&$f($n-1)$k)+$k-1)%$n+1}

}

@(
    ,(7, 1, 7)
    ,(7, 2, 7)
    ,(7, 3, 4)
    ,(7, 11, 1)
    ,(77, 8, 1)
    ,(123,12, 21)
) | % {
    $n,$k,$expected = $_
    $result = &$f $n $k
    "$($result-eq$expected): $result"
}

आउटपुट:

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