Tìm công suất của các đối tượng in 2D


23

Trong một thế giới 2D hư cấu, một tập hợp các hướng dẫn in 2D cho một đối tượng có thể được biểu diễn bằng một danh sách các số nguyên như sau:

1 4 2 1 1 2 5 3 4

Mỗi số đại diện cho chiều cao của đối tượng tại điểm cụ thể đó. Danh sách trên dịch sang đối tượng sau khi được in:

      #
 #    # #
 #    ###
 ##  ####
#########

Sau đó chúng tôi đổ đầy nó với lượng nước nhiều nhất có thể, dẫn đến điều này:

      #
 #~~~~#~#
 #~~~~###
 ##~~####
#########

Chúng tôi xác định công suất của đối tượng là đơn vị nước mà đối tượng có thể giữ khi hoàn toàn đầy đủ; trong trường hợp này, 11.

Nói một cách chính xác, một đơn vị nước ( ~) có thể tồn tại ở một vị trí khi và chỉ khi nó được bao quanh bởi hai khối rắn ( #) trong cùng một hàng.

Thử thách

Lấy danh sách các số nguyên dương làm đầu vào (ở bất kỳ định dạng nào) và xuất dung lượng của đối tượng được in khi danh sách được sử dụng làm hướng dẫn.

Bạn có thể giả sử danh sách chứa ít nhất một phần tử và tất cả các phần tử nằm trong khoảng từ 1 đến 255.

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

+-----------------+--------+
|      Input      | Output |
+-----------------+--------+
| 1               |      0 |
| 1 3 255 1       |      0 |
| 6 2 1 1 2 6     |     18 |
| 2 1 3 1 5 1 7 1 |      7 |
| 2 1 3 1 7 1 7 1 |      9 |
| 5 2 1 3 1 2 5   |     16 |
| 80 80 67 71     |      4 |
+-----------------+--------+

Câu trả lời:


15

Haskell, 54 byte

f l=(sum$zipWith min(scanl1 max l)$scanr1 max l)-sum l

Các biểu thức scanl1 max lscanr1 max ltính toán tối đa chạy của danh sách đọc tiến và lùi, tức là hồ sơ của nước cộng với đất nếu nước sẽ chảy theo một hướng.

Nguồn gốc:

      #
 #    # #
 #    ###
 ##  ####
#########

Trái:

      #~~
 #~~~~#~#
 #~~~~###
 ##~~####
#########

Đúng:

~~~~~~#
~#~~~~#~#
~#~~~~###
~##~~####
#########

Sau đó, hồ sơ của bức tranh tổng thể là tối thiểu trong số này, tương ứng với nơi nước không bị rò rỉ theo hướng nào.

Tối thiểu:

      #
 #~~~~#~#
 #~~~~###
 ##~~####
#########

Cuối cùng, lượng nước là tổng của danh sách này, chứa cả nước và đất, trừ đi tổng của danh sách ban đầu, chỉ chứa đất.


9

Thạch, 10 byte

U»\U«»\S_S

Trong khi APL yêu cầu nhiều dấu ngoặc đơn và ký hiệu hai ký tự J, thuật toán này rất đẹp trong Jelly.

     »\          Scan maximums left to right
U»\U             Scan maximums right to left
    «            Vectorized minimum
       S_S       Sum, subtract sum of input.

Hãy thử nó ở đây .


4

TOÁN , 14

Câu trả lời Matlab của tôi được dịch sang MATL. thuật toán của xnor.

Y>GPY>P2$X<G-s

Giải trình

Y>: cummax()(đầu vào được đẩy ngầm vào ngăn xếp)

G: đẩy đầu vào (một lần nữa)

P: flip()

Y>: cummax()

P: flip()

2$X<: min([],[])(tối thiểu hai đối số)

G: đẩy đầu vào (một lần nữa)

-: -

s: sum()


MATL có phải là ngôn ngữ thay thế của Matlab không? Bạn có thể cung cấp một liên kết trong tiêu đề?
Addison Crump

1
@FlagAsSpam Tôi nghĩ rằng nó còn hơn thế một chút: esolangs.org/wiki/MATL
Martin Ender

@ MartinBüttner Mã giả cho điều này có giống với mã giả Matlab không? Tôi tự hỏi nếu nó là một điều dịch trực tiếp, chứ không phải là dựa trên điều.
Addison Crump

1
@FlagAsSpam MATL dựa trên stack, vì vậy đây chắc chắn không phải là sự thay thế đơn giản.
Martin Ender

Vâng, đó là một bản dịch trực tiếp. MATL là dựa trên ngăn xếp (ký hiệu đánh bóng ngược) với các tốc ký từ một đến ba ký tự cho các toán tử và hàm MATLAB . Xem [ github.com/lmendo/MATL/blob/master/doc/MATL_spec.pdf] .
Rainer P.

3

APL Dyalog, 17 byte

+/⊢-⍨⌈\⌊⌽∘(⌈\⌽)

Đây là một tàu đơn trị lấy mảng đầu vào bên phải.

Thuật toán này khá giống với xnor, mặc dù tôi thấy nó độc lập. Nó quét tối đa theo cả hai hướng (ngược lại bằng cách đảo ngược mảng, quét và đảo ngược lại) và tìm thấy mức tối thiểu được vector hóa của các hướng đó. Sau đó, nó trừ mảng ban đầu và tổng.

Cách khác để làm điều này là phân chia mảng tại mỗi vị trí, nhưng lâu hơn.

Hãy thử nó ở đây .


1
Chính xác là tôi đến đây để viết. :-) Khi chúng tôi nhận được toán tử kép (còn gọi là), bạn có thể lưu 3 byte với +/⊢-⍨⌈\⌊⌈\⍢⌽.
Adám

2

Matlab, 47

Cũng sử dụng thuật toán của xnor.

@(x)sum(min(cummax(x),flip(cummax(flip(x))))-x)

1

MATLAB, 116 113 109 106 byte

n=input('');s=0;v=0;l=nnz(n);for i=1:l-1;a=n(i);w=min([s max(n(i+1:l))]);if a<w;v=v+w-a;else s=a;end;end;v

Điều này hoạt động bằng cách lưu trữ điểm cao bên trái và trong khi lặp qua từng điểm tiếp theo, tìm điểm cao nhất ở bên phải. Nếu điểm hiện tại nhỏ hơn cả điểm cao thì sẽ cộng chênh lệch tối thiểu vào khối lượng tích lũy.

Mã bị đánh cắp:

inputArray = input('');
leftHighPoint = inputArray(1);
volume = 0;
numPoints = nnz(inputArray);

for i = 1:numPoints-1
    currentPoint = inputArray(i); % Current value
    lowestHigh = min([max(inputArray(i+1:numPoints)) leftHighPoint]);

    if currentPoint < lowestHigh
        volume = volume + lowestHigh - currentPoint;
    else 
        leftHighPoint = currentPoint;
    end
end
volume

Lần đầu tiên tôi thử chơi golf, MATLAB dường như không phải là tốt nhất để làm điều đó trong ....


0

ES6, 101 byte

a=>(b=[],a.reduceRight((m,x,i)=>b[i]=m>x?m:x,0),r=m=0,a.map((x,i)=>r+=((m=x>m?x:m)<b[i]?m:b[i])-x),r)

Một cổng khác của alghorithm @ xnor.



0

Pip -l , 19 byte

$+J(ST0XgZD1`0.*0`)

Lấy số đầu vào làm đối số dòng lệnh. Hoặc, thêm -rcờ để lấy chúng làm dòng stdin: Hãy thử trực tuyến!

Giải trình

Không giống như tất cả các câu trả lời khác, trong Pip, nó thực sự ngắn hơn để xây dựng (một phiên bản sửa đổi) của nghệ thuật ASCII và đếm các đơn vị nước.

Chúng tôi bắt đầu với g, danh sách các đối số.

[1 4 2 1 5 2 3]

0Xgtạo ra một danh sách các chuỗi của n số không đối với mỗi n trong g.

[0 0000 00 0 00000 00 000]

ZD1sau đó nén các chuỗi này lại với nhau, sử dụng 1để điền vào bất kỳ khoảng trống nào trong danh sách lồng nhau hình chữ nhật:

[[0 0 0 0 0 0 0] [1 0 0 1 0 0 0] [1 0 1 1 0 1 0] [1 0 1 1 0 1 1] [1 1 1 1 0 1 1]]

STchuyển đổi danh sách này thành một chuỗi. Các -lquy định cụ thể cờ mà danh sách được định dạng như sau: mỗi danh sách lồng nhau được liên kết với nhau mà không có một dấu phân cách, và ở cấp cao nhất tách là dòng mới. Vì vậy, chúng ta có được chuỗi đa dòng này - về cơ bản, sơ đồ của đối tượng, nhưng lộn ngược:

0000000
1001000
1011010
1011011
1111011

Chúng tôi sau đó tìm thấy tất cả các trận đấu của regex `0.*0`. Điều này phù hợp với hai bức tường ngoài cùng và mọi thứ giữa chúng trên mỗi dòng.

[0000000 001000 011010 0110]

Jnối các chuỗi này lại với nhau thành một chuỗi lớn và tính $+tổng của nó, đưa ra số 1s - tương đương với lượng nước mà vật thể có thể giữ.

6
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.