Caching yang Optimal


14

Anda akan diberikan urutan permintaan memori dan ukuran cache. Anda harus mengembalikan jumlah cache yang sesedikit mungkin dalam strategi penggantian cache apa pun.

Strategi optimal adalah algoritma Belady , yang dapat Anda gunakan jika Anda mau.


Sistem caching berfungsi sebagai berikut: Cache mulai kosong. Permintaan memori masuk. Jika permintaan meminta sepotong data dalam cache, semuanya baik-baik saja. Jika tidak, Anda mengalami kesalahan cache. Pada titik ini Anda dapat memasukkan data yang diminta ke dalam cache untuk digunakan di masa mendatang. Jika cache penuh dan Anda ingin memasukkan data baru, Anda harus mengusir data yang sebelumnya di cache. Anda mungkin tidak pernah memasukkan data yang bukan hanya di cache.

Tujuan Anda adalah untuk menemukan jumlah cache minimum yang mungkin untuk urutan permintaan memori dan ukuran cache yang diberikan.


Anda akan diberi ukuran cache, integer positif, dan urutan permintaan memori, yang merupakan daftar token. Token ini dapat berupa jenis token apa pun yang Anda suka, selama setidaknya 256 token yang berbeda dimungkinkan (byte baik-baik saja, bools tidak). Misalnya, int, string, daftar semuanya baik-baik saja. Minta klarifikasi jika perlu.


Kasus uji:

3
[5, 0, 1, 2, 0, 3, 1, 2, 5, 2]

6

Lihat wikipedia untuk kebijakan penggantian yang mencapainya.

2
[0, 1, 2, 0, 1, 0, 1]

3

Cukup hindari menambahkan 2ke cache.

3
[0, 1, 2, 1, 4, 3, 1, 0, 2, 3, 4, 5, 0, 2, 3, 4]

9

Salah satu cara untuk mencapai ini adalah dengan tidak pernah mengusir 0dan 2, dan mengusir 1sesegera mungkin setelah penggunaan terakhir.


Penilaian: Ini adalah kode golf. Bytes paling sedikit menang.


Bisakah kita berasumsi bahwa daftar berisi setidaknya 2 token?
Arnauld

@Arnauld saya akan mengatakan tidak, meskipun jika hanya ada 1 solusi, jawabannya tentu saja selalu 1.
isaacg

Jawaban:


4

JavaScript (ES6), 128 byte

Mengambil input sebagai (size)(list).

s=>a=>a.map((x,i)=>c.includes(x)?0:c[e++,[x,...c].map(m=(x,j)=>(k=[...a,x].indexOf(x,i+1))<m||(p=j,m=k)),i<s?i:p-1]=x,e=c=[])&&e

Cobalah online!

Berkomentar

Ini adalah implementasi dari algoritma Belady.

s => a =>                      // s = cache size; a[] = token list
  a.map((x, i) =>              // for each token x at position i in a[]:
    c.includes(x) ?            //   if x is currently stored in the cache:
      0                        //     do nothing
    :                          //   else:
      c[                       //     update the cache:
        e++,                   //       increment the number of errors (cache misses)
        [x, ...c]              //       we want to find which value among x and all current
                               //       cache values will be needed for the longest time in
                               //       the future (or not needed anymore at all)
        .map(m =               //       initialize m to a non-numeric value
                 (x, j) =>     //       for each x at position j in this array:
          ( k = [...a, x]      //         k = position of x in the array made of all values
            .indexOf(x, i + 1) //         of a[] followed by x, starting at i + 1
          ) < m                //         if it's greater than or equal to m, or m is
          || (p = j, m = k)    //         still non-numeric: set p to j and m to k
        ),                     //       end of inner map()
        i < s ?                //       if i is less than the cache size:
          i                    //         just fill the cache by using the next cache slot
        :                      //       else:
          p - 1                //         use the slot that was found above
                               //         special case: if p = 0, x was the best candidate
                               //         and we're going to store it at c[-1], which is
                               //         simply ignored (it will not trigger c.includes(x))
      ] = x,                   //     store x at this position
      e = c = []               //     start with e = [] (coerced to 0) and c = []
  ) && e                       // end of outer map; return e

4

Perl 5 , 193 byte

sub g{
  my($i,$m,$s,@a,%c)=(-1,0,@_);
  for(@a){
    $i++;
    next if $c{$_}++ || ++$m && keys%c <= $s;
    my($x,$d);
    for $k (sort keys %c){  #find which to delete, the one furtherst away
      my $n=0;
      ++$n && /^$k$/ && last for @a[$i+1..$#a];
      ($x,$d)=($n,$k) if $n>$x
    }
    delete $c{$d}
  }
  $m
}

Cobalah online!

print g(3,  5, 0, 1, 2, 0, 3, 1, 2, 5, 2),"\n";                     # 6
print g(2,  0, 1, 2, 0, 1, 0, 1),"\n";                              # 3
print g(3,  0, 1, 2, 1, 4, 3, 1, 0, 2, 3, 4, 5, 0, 2, 3, 4),"\n";   # 9

193 byte tanpa lekukan, baris baru, spasi, komentar:

sub g{my($i,$m,$s,@a,%c)=(-1,0,@_);for(@a){$i++;next if$c{$_}++||++$m&&keys%c<=$s;my($x,$d);for$k(sort keys%c){my$n=0;++$n&&/^$k$/&&last for@a[$i+1..$#a];($x,$d)=($n,$k)if$n>$x}delete$c{$d}}$m}


1

Haskell , 82 byte

f n|let(d:t)#c=1-sum[1|elem d c]+minimum[t#take n e|e<-scanr(:)(d:c)c];_#_=0=(#[])

Cobalah online!

Penjelasan

Bekerja dengan brute force: semua strategi cache dicoba dan hasil terbaik dikembalikan.

f n            Define a function f on argument n (cache size) and a list (implicit).
 |let(d:t)#c=  Define binary helper function #.
               Arguments are list with head d (current data) and tail t (remaining data), and list c (cache).
 1-            It returns 1 minus
 sum[1|        1 if
 elem d c]+    d is in the cache, plus
 minimum[      minimum of
 t#            recursive calls to # with list t
 take n e|     and cache being the first n values of e, where
 e<-           e is drawn from
 scanr(:)  c]  the prefixes of c
 (d:c)         with d and c tacked to the end.
 ;_#_=0        If the first list is empty, return 0.
 =(#[])        f then calls # with the list argument and empty cache.

0

Perl 6 , 146 byte

->\a,\b {$_=set();$!=0;for b.kv ->\i,\v {$_{v}&&next;++$!;vb[i^..*]||next;$_∖=.keys.max({(grep $_,:k,b[i^..*])[0]//Inf})if $_>=a;$_∪=v};$!}

Cobalah online!

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.