Bộ đệm chống tràn


23

Lý lịch

Các lập trình viên ngày nay dường như không thể giữ bộ đệm của họ thẳng! Một nguồn lỗi phổ biến là cố gắng sử dụng một chỉ mục mảng quá lớn cho bộ đệm. Nhiệm vụ của bạn là thực hiện một bộ đệm trong đó các chỉ số lớn được giảm xuống kích thước mà bộ đệm có thể xử lý. Bởi vì tôi quyết định chính xác những gì tốt nhất cho mọi người, bạn sẽ triển khai bộ đệm này theo thông số kỹ thuật chính xác của tôi.

Tổng quan

Bạn có một bộ đệm chỉ chèn tăng kích thước khi các phần tử được thêm vào nó. Bộ đệm được lập chỉ mục bằng không, và cũng được lập chỉ mục modulo kích thước hiện tại của nó. Quy tắc đặc biệt cho thử thách này là:

  • Để chèn một mục tại index i có nghĩa là để tính toán j , j = i % buffer.length()và chèn mục mới sau khi thứ j mục trong danh sách.

Trường hợp đặc biệt duy nhất là nếu bộ đệm trống, vì modulo số học không hoạt động. Do đó, nếu bộ đệm hiện đang trống, mục mới sẽ là chỉ số 0 .

Nếu bộ đệm chỉ có một mục, thì bạn luôn chèn sau mục thứ 0 . Đây chỉ là một ví dụ của trường hợp chung.

Nếu bộ đệm chứa 6 mục: [4, 9, 14, 8, 5, 2]và bạn được yêu cầu chèn một mục mới 10vào chỉ mục 15 , bạn tìm thấy mục đó 15 % 6 == 3, sau đó chèn mục mới 10vào sau 8mục 3 , cung cấp bộ đệm kết quả là [4, 9, 14, 8, 10, 5, 2]

Vấn đề

Viết hàm hoặc chương trình nhận trong danh sách các số nguyên dương có thứ tự và các chỉ số nguyên dương để chèn chúng.

Bắt đầu với một bộ đệm trống và thêm các số nguyên được chỉ định vào bộ đệm tại các chỉ số tương ứng.

Xuất ra danh sách các số nguyên có trong bộ đệm sau khi tất cả các lần chèn được chỉ định đã được thực hiện.

Đây là một thử thách chơi gôn, vì vậy mã ngắn nhất sẽ thắng.

Hướng dẫn đầu vào

Bạn có thể lấy danh sách đầu vào tuy nhiên bạn thấy phù hợp. Ví dụ:

  • Danh sách các cặp: [ [1,1], [2,4], [3,9], [4,16], [5,25]...]
  • Danh sách mục và danh sách chỉ mục: [1, 2, 3, 4, 5...], [1, 4, 9, 16, 25]
  • Làm phẳng: [1, 1, 2, 4, 3, 9, 4, 16, 5, 25 ...]
  • v.v.

Bạn có thể giả sử đầu vào luôn chứa ít nhất một mục và chỉ mục tương ứng.

Các trường hợp thử nghiệm

Trường hợp hình vuông từ trên cao:

[(1, 1), (2, 4), (3, 9), (4, 16), (5, 25), (6, 36), (7, 49), (8, 64)] -> [1, 2, 8, 7, 6, 5, 4, 3]

Tôi đã tạo ngẫu nhiên những thứ này:

[(11, 9), (13, 14)] -> [11, 13]
[(1, 18), (11, 7), (3, 35), (16, 22)] -> [1, 11, 16, 3]
[(3, 16), (16, 37), (0, 28), (18, 24)] -> [3, 18, 0, 16]
[(7, 26), (8, 20), (11, 39), (1, 23), (17, 27)] -> [7, 8, 11, 1, 17]
[(15, 35), (17, 7), (16, 15), (1, 13), (2, 6), (11, 34)] -> [15, 17, 1, 2, 16, 11]
[(2, 13), (1, 20), (16, 25), (8, 21), (5, 2), (16, 37), (3, 0)] -> [2, 3, 8, 1, 16, 5, 16]
[(6, 20), (15, 15), (12, 26), (10, 27), (17, 13), (7, 18), (4, 16)] -> [6, 10, 17, 12, 7, 4, 15]
[(18, 9), (5, 34), (15, 4), (12, 29), (2, 5), (7, 0), (7, 10), (16, 38)] -> [18, 7, 15, 2, 16, 5, 7, 12]
[(0, 12), (12, 0), (4, 16), (15, 12), (6, 28), (8, 10), (11, 24), (0, 25)] -> [0, 11, 8, 6, 15, 0, 4, 12]
[(6, 12), (14, 13), (10, 33), (11, 35), (1, 3), (0, 28), (15, 27), (8, 10), (1, 2)] -> [6, 14, 10, 1, 11, 8, 15, 0, 1]
[(2, 29), (19, 30), (18, 17), (13, 3), (0, 21), (19, 19), (11, 13), (12, 31), (3, 25)] -> [2, 13, 3, 11, 0, 12, 19, 18, 19]

Triển khai tham chiếu Python3

def f(inputs):
    # `inputs` is a list of pairs
    buff = []
    for item, index in inputs:
        if len(buff) == 0:
            buff.insert(0, item)
        else:
            insert_after = index % len(buff)
            buff.insert(insert_after+1, item)
    return buff

Đầu vào có thể được thực hiện ngược lại?
FlipTack

Vâng tôi nghĩ rằng đầu vào có thể ít nhiều linh hoạt như bạn muốn.
turbulencetoo

Câu trả lời:


4

MATL , 24 22 byte

"N?@2)yn\Q:&)@1)wv}@1)

Đầu vào là một ma trận (với ;dấu phân cách hàng) chứa các giá trị ở hàng đầu tiên và các chỉ số trong hàng thứ hai.

Đầu ra là một mảng cột, được hiển thị dưới dạng số được phân tách bằng dòng mới.

Hãy thử trực tuyến! Hoặc xác minh tất cả các trường hợp kiểm tra , với mỗi kết quả được hiển thị trên một dòng.

Giải trình

"          % Input matrix (implicit). For each column 
  N        %   Number of elements in the stack
  ?        %   If nonzero (true for all iterations but the first)
    @2)    %     Push second element of current column: new index
    yn     %     Duplicate current buffer; push its number of elements
    \      %     Modulo
    Q      %     Add 1
    :&)    %     Split buffer at that point. This gives two pieces, one
           %     of which may be empty
    @1)    %     Push first element of current column: new value
    wv     %     Swap; concatenate all stack. This places the new value
           %     between the two pieces of the buffer
  }        %   Else (this is executed only in the first iteration)
    @1)    %     Push first element of current column: new value
           %   End (implicit)
           % End (implicit)
           % Display (implicit)

8

Perl, 37 byte

35 byte mã + 2 byte cho -lpcờ.

splice@F,1+<>%(@F||1),0,$_}{$_="@F"

Hãy thử trực tuyến!

Việc thực hiện khá đơn giản, splicechèn vào mảng @Ftại chỉ mục 1+<>%(@F||1)(lưu ý @F||1xử lý trường hợp mảng bị trống).

Chỉ một vài từ về niềng răng (dường như) chưa từng có }{(vì tôi đã có một nhận xét về nó và tôi nghĩ nó khá kỳ lạ đối với những người không biết Perl), và đó là một mẹo khá phổ biến trong môn đánh gôn Perl:
-pcờ bao quanh mã với (đại khái) while(<>){ CODE } continue { print }, ( continueđược thực hiện sau mỗi lần lặp). Vì vậy, với những người chưa từng có }{ , tôi đổi mã của mình thành while(<>) { CODE}{ } continue { print }. Vì vậy, nó tạo ra một khối trống ngay sau mã của tôi (nhưng đó không phải là vấn đề) và chỉ continueđược thực hiện một lần, sau khi while(tức là khi tất cả các đầu vào đã được đọc).


3
Điều đó }{đang khiến tôi phát điên ...
ETHproductions 17/1/2017

@ETHproductions Tôi đã quen với nó nhưng tôi thích thể hiện điều đó với người khác, họ luôn nghĩ có gì đó không ổn! :) (nhược điểm là gây rối với vết lõm emacs của tôi ..)
Dada

1
Điều đó làm }{tôi nhớ đến ảo ảnh này
Luis Mendo

Vâng, tôi đã làm. :-)
Dennis

5

ES6 (Javascript), 58,57,53, 50 byte

Chơi gôn

a=>a.map((e,i)=>b.splice(1+e[1]%i,0,e[0]),b=[])&&b

Lấy một mảng các cặp chỉ số-giá trị, làm đầu vào.

EDITS

  • Sử dụng &&để trả về giá trị, -1 byte
  • Đã xóa |0(vì mối nối rõ ràng có thể xử lý tốt NaN), -2 byte
  • Tạo b=[]một "đối số" thứ hai cho ánh xạ () , -2 byte (Thx @ETHproductions!)
  • Đã thay thế b.length bằng chỉ mục map () (i), -3 byte (Thx @Patrick Roberts!)

Kiểm tra

F=a=>a.map((e,i)=>b.splice(1+e[1]%i,0,e[0]),b=[])&&b

F([[11, 9], [13, 14]])
[ 11, 13 ]

F([[2, 29], [19, 30], [18, 17], [13, 3], [0, 21], [19, 19], [11, 13], [12, 31], [3, 25]])
[ 2, 13, 3, 11, 0, 12, 19, 18, 19 ]

1
Thật tuyệt, tôi nên thử những cách tiếp cận không đệ quy. Tôi nghĩ bạn có thể làma=>a.map(e=>...,b=[])&&b
ETHproductions

2
Bạn có thể trừ 3 byte bằng cách thay đổi e=>để (e,i)=>và sử dụng ithay vìb.length
Patrick Roberts

@PatrickRoberts Đó là một ý tưởng hay! Cảm ơn bạn !
zeppelin

5

Haskell , 70 69 byte

b!(x,i)|b==[]=[x]|j<-1+i`mod`length b=take j b++x:drop j b
foldl(!)[]

Hãy thử trực tuyến! Cách sử dụng : foldl(!)[] [(1,5),(2,4),(3,7)]. Đã lưu một byte nhờ @nimi!

Giải trình:

b!(x,i)                         -- b!(x,i) inserts x into list b at position i+1
 | b==[] = [x]                  -- if b is empty return the list with element x
 | j <- 1 + i `mod` length b    -- otherwise compute the overflow-save insertion index j
     = take j b ++ x : drop j b -- and return the first j elements of b + x + the rest of b
foldl(!)[]                      -- given a list [(1,2),(3,5),...], insert each element with function ! into the initially empty buffer

Giải pháp mà không tính toán mô đun: (90 byte)

f h t(x,-1)=h++x:t
f h[]p=f[]h p
f h(c:t)(x,i)=f(h++[c])t(x,i-1)
g((x,_):r)=foldl(f[])[x]r

Hãy thử trực tuyến!


j<-1+i`mod`length btiết kiệm một byte.
nimi

4

Python 2 , 64 62 58 56 byte

x=[]
for n,i in input():x[i%(len(x)or 1)+1:0]=n,
print x

Cảm ơn @xnor vì đã chơi golf 2 byte!

Hãy thử trực tuyến!


Bạn có thể làm (len(x)or 1)thay vì khởi tạo chiều dài?
xnor

Tìm kiếm một cách ngắn hơn. Cả hai len(x or[0])-~len(x[1:])cà vạt.
xnor

4

Python 2 , 62 60 byte

Lấy đầu vào là một danh sách các cặp, in kết quả. Chỉnh sửa: Bị ruồng bỏ bởi Dennis

b=[]
for x,y in input():b.insert(1+y%(len(b)or 1),x)
print b

Hãy thử trực tuyến!

Điều này khá đơn giản - lặp qua đầu vào, chèn các mục vào đúng vị trí và sau đó in kết quả. Quyết định chỉ mục nào để chèn vào được thực hiện với 1+y%(len(b)or 1). Đây là cách tiêu chuẩn để thực hiện lập chỉ mục mô-đun, với việc or 1xử lý trường hợp cạnh của danh sách trống.


3

JavaScript (ES6), 60 byte

f=([[q,r],...a],z=[])=>z.splice(r%z.length+1,0,q)+a?f(a,z):z

Kiểm tra đoạn


2

V , 38 40 35 byte

Câu trả lời này bẻ cong định nghĩa của danh sách và thông thường không phải là ngôn ngữ bạn sử dụng để thao tác danh sách, nhưng tôi muốn sử dụng [count]/{regex}mà tôi đã thêm gần đây vào V. Đầu vào được lấy [index] [num] [index] [num] ...và trả về như thế nào [num] [num] [num].

Í ¨ä«© ½/¯ÜdÜ+òhea ±^
Hdd2xdG@"
X

Hãy thử trực tuyến!

Hexdump cho 2 ký tự ẩn:

00000000: cd20 a8e4 aba9 20bd 2faf dc64 dc2b f268  . .... ./..d.+.h
00000010: 6561 20b1 161b 5e0a 4864 6432 7864 4740  ea ...^.Hdd2xdG@
00000020: 220a 58                                  ".X

Giải trình

Mã lên đến dG@"định dạng tất cả các \d+ \d+cặp sao cho danh sách 1 2 3 4 5 6 sẽ kết thúc như

a 2^[^3/\d\+
hea 4^[^5/\d\+
hea 6^[^

và sau đó dG@"thực thi tất cả các mã đó dưới dạng mã V như sau:

a 2^[                 | insert " 2" and return to command mode
     ^                | LOOP: go to the first number
      3/\d\+          | find the 3rd number (0 indexed)
h                     | move one character left
 e                    | go to the end of the next word
  a 4^[               | append " 4" and return to command mode
       ^5/\d\+        | basically the same as LOOP on, just with different numbers

Chỉ cần nói, trạng thái không cạnh tranh chỉ dành cho ngôn ngữ hoặc tính năng ngôn ngữ mới hơn thách thức
Kritixi Lithos

À, cảm ơn bạn đã không biết điều đó. Tôi sẽ làm cho nó phù hợp
nmjcman101

2

PHP, 72 92 byte

for($b=[];++$i<$argc;)array_splice($b,$b?$argv[$i]%count($b)+1:0,0,$argv[++$i]);print_r($b);

lấy đầu vào làm phẳng từ các đối số dòng lệnh. Chạy với -nr.


Tôi khá chắc chắn câu trả lời này không hợp lệ: Tôi đã Fatal error: Uncaught DivisionByZeroError: Modulo by zerosửa, sửa nó, sau đó thử 1 1 1 2 1 3và lấy [1=>null]đầu ra thay vì[1,3,2]
user59178

Nó vẫn ghi đè j+1thay vì chèn sau j, không? 18 1 7 11 35 3 22 16=> [1,11,16]thay vì[1,11,16,3]
user59178

@ user59178: Ồ tôi đã bỏ lỡ inserttừ khóa. Cảm ơn; đã sửa.
Tít

2

Java 7, 125 124 byte

import java.util.*;List z(int[]a){List r=new Stack();for(int i=0,q=a.length/2;i<q;)r.add(i<1?0:a[i+q]%i+1,a[i++]);return r;}

Chấp nhận một danh sách phẳng các giá trị theo sau là các chỉ mục. Đối với trường hợp kiểm tra bình phương, đầu vào sẽ lànew int[] {1, 2, 3, 4, 5, 6, 7, 8, 1, 4, 9, 16, 25, 36, 49, 64}

Hãy thử trực tuyến!


1

Toán học, 62 byte

Fold[Insert[#,#2[[1]],Mod[Last@#2,Tr[1^#]]+2/.0/0->-1]&,{},#]&

Hàm thuần túy với đối số đầu tiên # dự kiến ​​là một danh sách các cặp. Bắt đầu với danh sách trống {}, để lại Folddanh sách đầu vào #với chức năng sau:

Insert[                                            Insert
       #,                                          into the first argument
         #2[[1]],                                  the first element of the second argument
                 Mod[                              at the position given by the modulus of
                     Last@#2,                      the second element of the second argument
                             Tr[1^#]               with respect to the length of the first argument
                                    ]+2            plus 2 (plus 1 to account for 1-indexing, plus 1 because we are inserting after that position)
                                       /.          then replace
                                         0/0       Indeterminate
                                            ->     with
                                              -1   negative 1
                                                ]& End of function


1

Clojure, 87 byte

#(reduce(fn[r[v i]](let[[b e](split-at(+(mod i(max(count r)1))1)r)](concat b[v]e)))[]%)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.