ফিফোর ক্যাশে মিস করার সংখ্যা


35

এই চ্যালেঞ্জটি সত্যই সহজ (এবং আরও বেশি কঠিন সমস্যার পূর্ববর্তী!)।

রিসোর্স অ্যাক্সেসের একটি অ্যারে দেওয়া হয়েছে (কেবলমাত্র অণুগঠিত পূর্ণসংখ্যার দ্বারা চিহ্নিত করা হয়েছে) এবং একটি প্যারামিটার n, আমাদের ক্যাশে ক্ষমতা আছে ধরে নিয়েছে এবং যে ক্যাশে মিস করেছে তার সংখ্যাটি ফিরিয়ে দিন nএবং পূর্ণ হলে এটি ফার্স্ট-ইন-ফার্স্ট-আউট (ফিফো) ইজেকশন স্কিম ব্যবহার করে ।

উদাহরণ:

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?এখন কিছুক্ষণের জন্য শেষ বিবৃতিটির দিকে চেয়ে ছিলাম ... এবং কেবল লক্ষ্য করেছি, ক্যাশে ক্ষমতা বাড়ানো অগত্যা মিসের সংখ্যা হ্রাস করে না ?!
জংহওয়ান মিন

নিবন্ধন করুন আসলে, এটি কতটা খারাপ হতে পারে তা সীমাহীন।
orlp

আমরা কি আনারিতে আউটপুট দিতে পারি?
dylnan

9
বালির ব্যঙ্গাত্মক হিসাবে পরিচিত এবং ফিফোর ক্লাসিক উদাহরণ। অসঙ্গতি সীমাহীন হয়
ভার্চুয়ালফান

দুঃখিত, দুঃখিত।
orp

উত্তর:


11

জাভাস্ক্রিপ্ট (ES6), 55 বাইট

পদ্ধতি # 1: ক্যাশে ইনপুটটিকে ওভাররাইট করে

বাক্য গঠন সিনট্যাক্সে ইনপুট নেয় (cache_size)(list)

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

এটি অনলাইন চেষ্টা করুন!

কিভাবে?

আমরা ক্যাশে দিয়ে ইনপুট অ্যারে a [] ওভাররাইট করি , 0 এ শুরু করে আলাদা পয়েন্টার কে ব্যবহার করে ।

এক্স ক্যাশে আছে a.indexOf(x, k > n && k - n) < kকিনা তা পরীক্ষা করতে আমরা ব্যবহার করি ।

মূল অ্যারেটি indexOf()যেভাবে চলেছে তার চেয়ে ক্যাশে দ্রুত বাড়তে পারে না, সুতরাং প্রতিটি মান ক্যাশে উইন্ডোর অভ্যন্তরে বা তার বাইরে খুঁজে পাওয়ার গ্যারান্টিযুক্ত (অর্থাত কখনই -1 ফিরে আসবে না )।

সর্বাধিক (0, কে - এন) এবং কে - 1 (উভয় সীমা অন্তর্ভুক্ত) এর মধ্যে একটি সূচীতে যদি এটি পাওয়া যায় তবে একটি মান ক্যাশে থাকে , সেই ক্ষেত্রে আমরা একটি [সত্য] = এক্স করি । এটি কেবলমাত্র একটি [] এর পিছনে অন্তর্নিহিত সামগ্রীর সম্পত্তিকে প্রভাবিত করে তবে অ্যারে a [] পরিবর্তন করে না । অন্যথায়, আমরা একটি [কে ++] = এক্স করি

উদাহরণ

নীচে 2 এর[1, 1, 2, 3, 3, 2, 1, 4] ক্যাশে আকারের ইনপুটটির জন্য বিভিন্ন পদক্ষেপ রয়েছে :

  • গা bold় সীমানা: মানচিত্র () পয়েন্টার
  • বন্ধনী: ক্যাশে পয়েন্টার কে
  • কমলা: বর্তমান ক্যাশে উইন্ডো
  • হলুদ: মেয়াদোত্তীর্ণ ক্যাশে মান

পদ্ধতি # 1


জাভাস্ক্রিপ্ট (ES6), 57 বাইট

পদ্ধতি # 2: ইনপুট শেষে ক্যাশে সংযুক্ত করা হয়

বাক্য গঠন সিনট্যাক্সে ইনপুট নেয় (cache_size)(list)

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

এটি অনলাইন চেষ্টা করুন!

কিভাবে?

ইনপুট অ্যারে a [] অ-নেতিবাচক পূর্ণসংখ্যার সমন্বিত গ্যারান্টিযুক্ত হওয়ার কারণে, আমরা প্রতিটি মান x এর এক-পরিপূরক ~ x ব্যবহার করে একটি [] এর শেষে ক্যাশে নিরাপদে যুক্ত করতে পারি ।

আমরা শেষের n টি মানগুলির মধ্যে n x পাওয়া যায় n * ~a.indexOf(~x, -n)কিনা তা পরীক্ষা করতে ব্যবহার করি । যখনই এই পরীক্ষাটি ব্যর্থ হয়, আমরা যোগ ~ X করার একটি [] এবং শটটি সংখ্যা বাড়ায়

উদাহরণ

এই পদ্ধতিটি ব্যবহার করে উপরে নীচের মতো একই উদাহরণের জন্য বিভিন্ন পদক্ষেপ দেওয়া হল। ক্যাশে মানগুলি অ্যারের শেষে কেবল সংযুক্ত করা হয়, তাই কোনও স্পষ্ট ক্যাশে পয়েন্টার নেই।

পদ্ধতি # 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 বাইটের জন্য ovs এবং আরও 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,[]))
xnor

7

আর , 69 64 62 বাইট

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

এটি অনলাইন চেষ্টা করুন!

জ্যাকিকে কিছু উন্নতি করার পরামর্শ দেওয়ার জন্য এবং ডিজিএমএলকে অন্য এক দম্পতির জন্য ধন্যবাদ!


আমি +সামনে এর Fজন্য f(0,{})0 ফেরত দেওয়ার জন্য?
জয়সি

Fপ্রাক-ইনিশিয়ালাইজড রিটার্ন মান হিসাবে জায়েসি হ্যাঁ, টেন্ডেমের একটি ক্লাসিক গল্ফ ।
জিউসেপ

1
একটি ছোট উন্নতি । এছাড়াও যদি অ্যানারি আউটপুট গ্রহণ করা হয় তবে আপনি সম্ভবত কিছু বাইট সংরক্ষণ করতে পারেন।
জয়সি

@ জাসি আরও কিছু বাইট খুঁজে পেয়েছে!
জিউসেপ

1
@ জেডিএল হ্যাঁ, তবে এটি একটি লজ্জাজনক 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

05 এ বি 1 ই , 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

@ নিমি: ধন্যবাদ! বাইট সংরক্ষণের সময় ঠিক করা হয়েছে :)
এমিগানা

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

পাইথ ,  16 15 18 14  13 বাইট

Isaacg ধন্যবাদ 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

ধন্যবাদ! আমার শুরুতে ছিল +G*]H!}H>QG, কিন্তু যখন আমি এটি গল্ফ করলাম তখন আমি সত্যিই ভেবে দেখিনি W... চমৎকার!
মিঃ এক্সকোডার

ঠিক uকি করে?
dylnan

@ অল্লানন uহ'ল আন্তঃমূল্য অপারেটর সহ একটি হ্রাস। ƒ
জেলি'র

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 হ'ল অনুরোধ এবং এক্স ক্যাশের আকার।

{*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

বিকল্প - স্টোর স্টোরের জন্য একটি বৈশ্বিক পরিবর্তনশীল (খুব কে-এর মতো নয়) ব্যবহার করে, 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 বাইট শেভ করার জন্য হিস্টোক্র্যাট ধন্যবাদ।


1
চমৎকার উত্তর! আপনি আর্গুমেন্ট তালিকার অংশ হিসাবে আরম্ভ করে একটি দম্পতি বাইট সংরক্ষণ করতে পারেন: ->s,a,*rএটি বোনাস বৈশিষ্ট্যও সরবরাহ করে যা কলার অতিরিক্ত যুক্তি দিয়ে ক্যাশেটিকে প্রধান করতে পারে :)
হিস্টোক্র্যাট

ওহ, এবং একইভাবে xঅ্যারেতে কাস্ট করা:.count{|*x|
হিস্টোক্র্যাট


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




আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.