FIFO कैश की संख्या याद आती है


35

यह चुनौती वास्तव में सरल है (और अधिक कठिन एक अग्रदूत!)।

संसाधन पहुंच की एक सरणी को देखते हुए (केवल nonnegative पूर्णांकों द्वारा निरूपित) और एक पैरामीटर n, कैश की संख्या को याद करते हैं जो यह मानती है कि हमारी कैश की क्षमता है nऔर पहले-पहले-आउट (FIFO) इजेक्शन का उपयोग करता है जब यह पूर्ण होता है ।

उदाहरण:

4, [0, 1, 2, 3, 0, 1, 2, 3, 4, 0, 0, 1, 2, 3]
0 = not in cache (miss), insert, cache is now [0]
1 = not in cache (miss), insert, cache is now [0, 1]
2 = not in cache (miss), insert, cache is now [0, 1, 2]
3 = not in cache (miss), insert, cache is now [0, 1, 2, 3]
0 = in cache (hit), cache unchanged
1 = in cache (hit), cache unchanged
2 = in cache (hit), cache unchanged
3 = in cache (hit), cache unchanged
4 = not in cache (miss), insert and eject oldest, cache is now [1, 2, 3, 4]
0 = not in cache (miss), insert and eject oldest, cache is now [2, 3, 4, 0]
0 = in cache (hit), cache unchanged
1 = not in cache (miss), insert and eject oldest, cache is now [3, 4, 0, 1]
2 = not in cache (miss), insert and eject oldest, cache is now [4, 0, 1, 2]
3 = not in cache (miss), insert and eject oldest, cache is now [0, 1, 2, 3]

तो इस उदाहरण में 9 मिस थे। शायद एक कोड उदाहरण इसे बेहतर तरीके से समझाने में मदद करता है। पायथन में:

def num_misses(n, arr):
    misses = 0
    cache = []
    for access in arr:
        if access not in cache:
            misses += 1
            cache.append(access)
            if len(cache) > n:
                cache.pop(0)
    return misses

कुछ और टेस्टेसिस (जिसमें अगली चुनौती के लिए एक संकेत होता है - कुछ भी ध्यान देने योग्य?)

0, [] -> 0
0, [1, 2, 3, 4, 1, 2, 3, 4] -> 8
2, [0, 0, 0, 0, 0, 0, 0] -> 1
3, [3, 2, 1, 0, 3, 2, 4, 3, 2, 1, 0, 4] -> 9
4, [3, 2, 1, 0, 3, 2, 4, 3, 2, 1, 0, 4] -> 10

बाइट्स में सबसे छोटा कोड जीतता है।


15
मैं notice anything curious?अब थोड़ी देर के लिए आखिरी बयान देख रहा था ... और बस देखा, कैश की क्षमता को बढ़ाने से जरूरी नहीं कि यादों की संख्या कम हो जाए?!
जुंगह्वान मिन

@JungHwanMin सही! वास्तव में, यह कितना बुरा हो सकता है, यह अबाधित है।
orlp

क्या हम संख्या को एकात्मक में आउटपुट कर सकते हैं?
डायलाॅन

9
बेलाडी के विसंगति और फीफो के रूप में जाना जाने वाला क्लासिक उदाहरण है। विसंगति अपार है
virtualirfan

@dylnan नहीं, क्षमा करें।
orlp

जवाबों:


11

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

विधि # 1: कैश इनपुट को अधिलेखित करता है

करी सिंटैक्स में इनपुट लेता है (cache_size)(list)

n=>a=>a.map(x=>a[a.indexOf(x,k>n&&k-n)<k||k++]=x,k=0)|k

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

कैसे?

हम एक अलग पॉइंटर k का उपयोग करके कैश के साथ इनपुट एरे [a] को ओवरराइट करते हैं , जिसे 0 में इनिशियलाइज़ किया गया है ।

हम a.indexOf(x, k > n && k - n) < kपरीक्षण करते हैं कि क्या x कैश में है।

कैश तेजी से विकसित नहीं कर सकते हैं की तुलना में मूल सरणी, के माध्यम से चला गया है, ताकि प्रत्येक मान पाया जा सकता है की गारंटी है, या तो अंदर या कैश खिड़की से बाहर (यानी indexOf()वापस कभी नहीं होगा -1 )।

एक मान कैश में है यदि यह अधिकतम (0, k - n) और k - 1 (दोनों सीमाएं शामिल) के बीच के सूचकांक पर पाया जाता है, तो उस स्थिति में हम एक [सही] = x करते हैं । यह केवल [] के पीछे अंतर्निहित वस्तु की एक संपत्ति को प्रभावित करता है, लेकिन सरणी [[] को परिवर्तित नहीं करता है । अन्यथा, हम एक [k ++] = x करते हैं

उदाहरण

नीचे 2 के[1, 1, 2, 3, 3, 2, 1, 4] कैश आकार वाले इनपुट के लिए अलग-अलग चरण दिए गए हैं :

  • बोल्ड बॉर्डर: मैप () सूचक
  • ब्रैकेट्स: कैश पॉइंटर k
  • नारंगी: वर्तमान कैश विंडो
  • पीला: समाप्त हो गया कैश मान

विधि # 1


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

विधि # 2: इनपुट के अंत में कैश जोड़ा जाता है

करी सिंटैक्स में इनपुट लेता है (cache_size)(list)

n=>a=>a.map(x=>n*~a.indexOf(~x,-n)||a.push(~x)&k++,k=0)|k

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

कैसे?

क्योंकि इनपुट सरणी [] की गैर-नकारात्मक पूर्णांक शामिल करने की गारंटी है, हम प्रत्येक मूल्य x के एक-पूरक ~ x का उपयोग करके कैश को सुरक्षित रूप से [] के अंत में जोड़ सकते हैं ।

हम n * ~a.indexOf(~x, -n)परीक्षण करने के लिए उपयोग करते हैं कि ~ x अंतिम एन मानों के बीच पाया जाता है या नहीं । जब भी यह परीक्षण विफल होता है, हम ~ x को एक [] में जोड़ते हैं और याद आती है k की संख्या बढ़ जाती है

उदाहरण

नीचे इस विधि का उपयोग करके ऊपर दिए गए उदाहरण के लिए अलग-अलग चरण हैं। क्योंकि कैश मान केवल सरणी के अंत में जोड़े जाते हैं, कोई स्पष्ट कैश पॉइंटर नहीं है।

विधि # 2


10

हास्केल , 50 बाइट्स

f n=length.foldl(\r x->[x|all(/=x)$take n r]++r)[]

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

पूरे कैश इतिहास को संग्रहीत करने और इसकी लंबाई लेने के लिए लिन की विधि पर आधारित है । यूनिरी आउटपुट थोड़ा छोटा होगा:

हास्केल , 47 बाइट्स

n?l=1<$foldl(\r x->[x|all(/=x)$take n r]++r)[]l

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


9

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

lambda n,a:len(reduce(lambda c,i:[i][i in c[:n]:]+c,a,[]))

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

3 बाइट्स के लिए ओव्स के लिए धन्यवाद, और 3 अधिक के लिए xnor।


आपको एक सेट लगाकर बाइट्स को बचाने में सक्षम होना चाहिए c+=, क्योंकि किसी कारण से यह आपके लिए एक सूची में परिवर्तित हो जाता है।
xnor

(आह, हाँ, c+={i}-set(c[-n:])काम करता है, सकारात्मक के लिए n। लेकिन निम्मी ने बताया कि c[-n:]यह गलत है n == 0, इसलिए मैं उपयोग नहीं कर सकता +=, और इसलिए वह भी - बहुत बुरा है।)
लिन

1
@ लीन आह, मैं देख रहा हूं। reduceअभी भी बाइट्स की बचत होती है: lambda n,a:len(reduce(lambda c,i:[i][i in c[:n]:]+c,a,[]))
22

7

आर , 69 64 62 बाइट्स

function(n,A,K={}){for(i in A)K=c(i[!i%in%K[0:n]],K);sum(K|1)}

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

कुछ सुधारों का सुझाव देने के लिए JayCe का धन्यवाद, और एक और युगल के लिए DigEmAll!


मुझे लगता है कि +सामने वाले Fको f(0,{})0 वापस करना है?
JayCe

@ जयकेप, एक Fपूर्व-प्रारंभिक वापसी मूल्य के रूप में अग्रानुक्रम में एक क्लासिक गोल्फ ।
ग्यूसेप

1
एक छोटा सा सुधार । इसके अलावा अगर unary आउटपुट स्वीकार किया जाता है तो आप शायद कुछ बाइट्स बचा सकते हैं।
JayCe

@JayCe को कुछ और बाइट्स मिले!
ग्यूसेप

1
@JDL हाँ, qलेकिन अभी भी एक अच्छा विचार के बारे में एक शर्म की बात है! उपयोग करने NAसे कम अच्छा है {}क्योंकि मैं वास्तव में यहां की लंबाई के बारे में परवाह करता हूं (और मैं वास्तव में कैश से तत्वों को पॉप नहीं कर रहा हूं)।
ग्यूसेप

5

हास्केल, 61 58 बाइट्स

n!a|let(a:b)#c|elem a c=b#c|1<2=1+b#take n(a:c);_#_=0=a#[]

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

n!a|      =a#[]     -- take input 'n' and a list 'a'
                    -- and call # with the initial list and an empty cache
 let                -- bind function '#':
  (a:b)#c           -- if there's at least one element 'a' left in the list
     |elem a c=b#c  --  and it's in the cache, go on with the same cache
                    --  and the remainder of the list
     |1<2=          -- else (i.e. cache miss)
          1+        --  add one to the recursive call of
       b#           --  the remainder of the list and 
       take n(a:c)  --  the first n elements of 'a' prepended to the cach
 _#_=0              -- if there's no element in the list, return 0

संपादित करें: -3 बाइट्स @ लियन के लिए धन्यवाद।


5

05AB1E , 17 16 बाइट्स

)svDyå_i¼y¸ìI£]¾

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

व्याख्या

)                   # wrap the stack in a list
 sv                 # for each item y in input list
   D                # duplicate current list
    yå_i            # if y is not contained in the current list
        ¼           # increment counter
         y¸ì        # prepend y to the current list
            I£      # keep the first input elements
              ]¾    # end loop and push counter

@ नमि: धन्यवाद! बाइट की बचत करते समय निर्धारित :)
Emigna

5

कोटलिन , 82 69 बाइट्स

{a,n->a.fold(List(0){0}){c,v->if(v!in c.takeLast(n))c+v else c}.size}

इनपुट के रूप में लेता है IntArray, कि ठेठ List<Int>(जो एक समस्या नहीं होनी चाहिए।) यह "कैश इतिहास का निर्माण और इसकी लंबाई की गणना" के दृष्टिकोण का उपयोग करता है।

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

व्याख्या

{ a, n ->                         // lambda where a is accesses and n is cache size
    a.fold(List(0){0}) { c, v ->  // fold on empty list
        if(v !in c.takeLast(n))   // if resource is not in last n cache inserts
            c + v                 // insert to cache list
        else
            c                     // return cache as is
    }.size                        // length of cache list is number of inserts
}

एक खाली सूची बनाना

कोटलिन के पास संग्रह शाब्दिक नहीं हैं, लेकिन नए संग्रह बनाने के लिए इसके कुछ कार्य हैं।

खाली बनाने का उचित तरीका List<Int>बस है:

List<Int>()

लेकिन यह छोटा है अगर हम आकार का दुरुपयोग करते हैं और इनिशियलाइज़र ऐसा करने का तर्क देता है:

List(0){0}
List(0)       // List of size 0
       { 0 }  // with generator returning 0

क्योंकि जनरेटर लैम्ब्डा 0 लौटाता है, कोटलिन इस सूची के प्रकार को संक्रमित करता है List<Int>, और 0 के आकार का अर्थ है कि यह सूची खाली है।



4

जावा 8, 96 बाइट्स

एक कैम्ब्र्ड लैम्बडा कैची साइज़ ( int) और एक्सेस लिस्ट (म्यूटेबल java.util.List<Integer>) ले रहा है और वापस आ रहा है int

s->a->{int w=0,m=0,i;for(int r:a)m+=(i=a.indexOf(r))<w&i<s?0:s<1?1:1+0*a.set(w++%s,r);return m;}

यह ऑनलाइन की कोशिश करो

Ungolfed

यह पहले (अप करने के लिए) का उपयोग करता है s कैश के लिए इनपुट सूची में स्लॉट ।

s ->
    a -> {
        int
            w = 0,
            m = 0,
            i
        ;
        for (int r : a)
            m +=
                (i = a.indexOf(r)) < w & i < s ?
                    0
                    s < 1 ?
                        1
                        : 1 + 0*a.set(w++ % s, r)
            ;
        return m;
    }

स्वीकृतियाँ

  • बगिम्मी धन्यवाद निमि के लिए

4

पायथ ,  १६ १५ १ 18 १४  13 बाइट्स

इसहाक के लिए 1 बाइट का धन्यवाद सहेजा गया

luaW-H>QGGHEY

परीक्षण सूट!

यह चुनौती पाइथ के बहुत अनुकूल है u संरचना के ।

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

luaW-H>QGGHEY     Full program. Q = the cache length, E = the list.
 u         E      Reduce E with G = current value and H = corresponding element
            Y     With starting value Y, which is preinitialised to [] (empty list).
   W              Conditional application. If...
    -H            ... Filtering H on absence of...
      >QG         ... The last Q elements of G... 
                  ... Yields a truthy value (that is, H is not in G[-Q:]), then...
  a      GH       ... Append H to G.
                  ... Otherwise, return G unchanged (do not append H at all).
l                  Get the length of the result.

aW-H>QGGH?}H<GQG+HG1 से धड़कता है
isaacg

@isaacg धन्यवाद! शुरू में मेरे पास था +G*]H!}H>QG, लेकिन जब मैंने इसे गोल्फ किया तो मैंने वास्तव में सोचा नहीं था W... अच्छा!
श्री एक्सकोडर

वास्तव में क्या करता uहै?
डायलन

@dylnan uintial value ऑपरेटर के साथ एक कमी है। जैसे जेली काƒ
श्री एक्सकोडर

3

वोल्फ्राम भाषा (गणितज्ञ) , 60 59 बाइट्स

Tr[k={};n=#;k~Take~UpTo@n~FreeQ~#&&k~PrependTo~#&/@#2;1^k]&

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

पैटर्न-मिलान, 60 बाइट्स का उपयोग करना

Length[#2//.{p___,a_,q___,a_,r___}/;Tr[1^{q}]<#:>{p,a,q,r}]&

मैं वास्तव में इसे बेहतर पसंद करता हूं, लेकिन यह 1 बाइट लंबा है ...

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


2

जाप, 16 बाइट्स

;£A¯V øX ªAiXÃAl

कोशिश करो


व्याख्या

                     :Implicit input of array U and integer V
 £                   :Map over each X in U
; A                  :  Initially the empty array
   ¯V                :  Slice to the Vth element
      øX             :  Contains X?
         ª           :  Logical OR
          AiX        :  Prepend X to A
             Ã       :End map
              Al     :Length of A

1

K4 , 42 40 बाइट्स

समाधान:

{*1+/1_{r,,(y;x#z,y)r:~z in y:*|y}[x]\y}

उदाहरण:

q)k)f:{*1+/1_{r,,(y;x#z,y)r:~z in y:*|y}[x]\y}
q)f[0;1 2 3 4 1 2 3 4]
8
q)f[2;0 0 0 0 0 0 0]
1
q)f[3;3 2 1 0 3 2 4 3 2 1 0 4]
9
q)f[4;3 2 1 0 3 2 4 3 2 1 0 4]
10

स्पष्टीकरण:

आंतरिक फ़ंक्शन के लिए, y कैश है, z अनुरोध है और x कैश आकार है।

{*1+/1_{r,,(y;x#z,y)r:~z in y:*|y}[x]\y} / the solution
{                                      } / lambda taking 2 args
       {                         }       / lambda taking 3 args
                                  [x]\y  / iterate over lambda with each y
                              *|y        / last (reverse, first) y
                            y:           / assign to y
                       z in              / is z in y?
                      ~                  / not 
                    r:                   / assign result to r (true=1,false=0)
           ( ;     )                     / 2-element list
                z,y                      / join request to cache
              x#                         / take x from cache (limit size)
            y                            / (else) return cache unchanged
          ,                              / enlist this result
        r,                               / join with r
     1_                                  / drop the first result
  1+/                                    / sum up (starting from 1)
 *                                       / take the first result

टिप्पणियाँ:

शायद यह सब करने का एक अच्छा तरीका है, लेकिन यह पहला तरीका है जो दिमाग में आया।

फ़ंक्शन को 36 बाइट्स के लिए इस तरह चलाया जा सकता है :

q)k)*1+/1_{r,,(y;x#z,y)r:~z in y:*|y}[4]\3 2 1 0 3 2 4 3 2 1 0 4
10

वैकल्पिक - राज्य को संग्रहीत करने के लिए एक वैश्विक चर का उपयोग करना (बहुत K- जैसा नहीं), 42 बाइट्स :

{m::0;(){$[z in y;y;[m+:1;x#z,y]]}[x]\y;m}

1

ब्रेन-फ्लैक , 172 बाइट्स

(([{}]<>)<{({}(()))}{}>)<>([]){{}<>((({})<{({}()<<>(({})<({}<>({}<>))>)<>>)}{}>)<<>(({})([{}]<>{<>(){[()](<{}>)}{}<><({}()<<>({}<>)>)>}{})){(<{}{}>)}{}>)<>([])}{}<>({}[]<>)

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

# Initialize cache with n -1s (represented as 1s)
(([{}]<>)<{({}(()))}{}>)<>

# For each number in input
([]){{}

    # Keep n on third stack
    <>((({})<

        # For last n cache entries, compute difference between entry and new value
        {({}()<<>(({})<({}<>({}<>))>)<>>)}{}

    >)<

        # Get negation of current entry and...
        <>(({})([{}]<>

            {

                # Count cache hits (total will be 1 or 0)
                <>(){[()](<{}>)}{}

                # while moving entries back to right stack
                <><({}()<<>({}<>)>)>

            }{}

        ))

        # If cache hit, don't add to cache
        {(<{}{}>)}{}

    >)

<>([])}{}

# Compute cache history length minus cache size (to account for the initial -1s)
<>({}[]<>)

1

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

Ṗɼṛ;ɼe®Uḣ⁴¤C$¡€ṛLɼ

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

पहले तर्क के रूप में सूची लेता है और दूसरे तर्क के रूप में कैश क्षमता।

Ṗɼṛ;ɼe®Uḣ⁴¤C$¡€ṛLɼ
 ɼ                 Apply to the register:
Ṗ                  Pop. This initializes the register to the empty list.
  ṛ                Right argument. Yields the list of addresses.
              €    For each element in the list
             ¡     If{
     e                 the element is in
          ¤            nilad{
      ®                      the register
       U                     reversed
        ḣ                    first...
         ⁴                   (cache depth) number of elements
                             }
           C           Complement. 1 <-> 0. Easier to type this than "not".
            $          Combines everything up to `e` into a monad
                      }
                    Then{
    ɼ                    Apply to the register and store the result
   ;                     Append the element
                        }
                ṛ   Right argument:
                  ɼ Apply to the register:
                 L  Length

1

रूबी , 43 40 बाइट्स

->s,a,*r{a.count{|*x|r!=r=(r|x).pop(s)}}

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

3 बाइट्स शेविंग के लिए धन्यवाद histocrat।


1
अच्छा जवाब! आप तर्क सूची के भाग के रूप में r को प्रारंभ करके एक युगल बाइट्स को बचा सकते हैं: ->s,a,*rजो बोनस सुविधा भी प्रदान करता है कि कॉलर अतिरिक्त तर्क पास करके कैश को प्राइम कर सकता है :)
histocrat

ओह, और इसी तरह xएक सरणी में डालने के लिए :.count{|*x|
histocrat


0

सी (जीसीसी) , 156 बाइट्स

s,n,m,i,j;f(x,_)int*_;{int c[x];n=m=0;for(i=0;i<x;++i)c[i]=-1;for(i=s=0;_[i]>=0;++i,s=0){for(j=0;j<x;++j)s|=(c[j]==_[i]);if(!s){c[n++]=_[i];m++;n%=x;}}x=m;}

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

विवरण:

s,n,m,i,j;                       // Variable declaration
f(x,_)int*_;{                    // F takes X (the cache size) and _ (-1-terminated data)
    int c[x];                    // declare the cache
    n=m=0;                       // next queue insert pos = 0, misses = 0
    for(i=0;i<x;++i)c[i]=-1;     // initialize the cache to -1 (invalid data)
    for(i=s=0;_[i]>=0;++i,s=0){  // for each datum in _ (resetting s to 0 each time)
        for(j=0;j<x;++j)         // for each datum in cache
            s|=(c[j]==_[i]);     // set s if item found
        if(!s){                  // if no item found
            c[n++]=_[i];         // add it to the cache at position n
            m++;                 // add a mis
            n%=x;                // move to next n position (with n++)
        }} x=m;}                 // 'return' m by assigning to first argument

सुझाएँ wmemset(c,-1,x)बजाय n=m=0;for(i=0;i<x;++i)c[i]=-1, n=m=i=s=0बजाय i=s=0, for(j=x;j--;)के बजाय for(j=0;j<x;++j), और s||(c[n++]=_[i],m++,n%=x);के बजायif(!s){c[n++]=_[i];m++;n%=x;}
ceilingcat




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