ค้นหาความจุของวัตถุที่พิมพ์แบบ 2D


23

ในโลกสมมติ 2 มิติชุดคำสั่งการพิมพ์ 2D สำหรับวัตถุสามารถแสดงได้ด้วยรายการจำนวนเต็มดังนี้:

1 4 2 1 1 2 5 3 4

แต่ละตัวเลขแสดงถึงความสูงของวัตถุ ณ จุดนั้น รายการด้านบนแปลเป็นวัตถุต่อไปนี้เมื่อพิมพ์:

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

จากนั้นเราเติมน้ำให้มากที่สุดเท่าที่ทำได้

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

เรากำหนดความจุของวัตถุให้เป็นหน่วยของน้ำที่วัตถุสามารถเก็บได้เมื่อเต็มอย่างสมบูรณ์ ในกรณีนี้ 11.

พูดอย่างเคร่งครัดหน่วยของน้ำ ( ~) สามารถมีอยู่ในสถานที่หากและถ้ามันถูกล้อมรอบด้วยสองบล็อกของแข็ง ( #) ในแถวเดียวกัน

ท้าทาย

รับรายการจำนวนเต็มบวกเป็นอินพุต (ในรูปแบบใด ๆ ) และส่งออกความจุของวัตถุที่พิมพ์เมื่อใช้รายการตามคำแนะนำ

คุณสามารถสมมติว่ารายการมีองค์ประกอบอย่างน้อยหนึ่งองค์ประกอบและองค์ประกอบทั้งหมดอยู่ระหว่าง 1 ถึง 255

กรณีทดสอบ

+-----------------+--------+
|      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 |
+-----------------+--------+

คำตอบ:


15

Haskell, 54 ไบต์

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

การแสดงออกscanl1 max lและการscanr1 max lคำนวณค่าสูงสุดในการอ่านรายการไปข้างหน้าและข้างหลังคือโปรไฟล์ของน้ำและที่ดินถ้าน้ำไหลไปในทิศทางเดียว

orig:

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

ซ้าย:

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

ขวา:

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

จากนั้นโปรไฟล์ของภาพรวมคือค่าต่ำสุดซึ่งสอดคล้องกับตำแหน่งที่น้ำไม่รั่วไหลทั้งสองทิศทาง

จำนวนขั้นต่ำ:

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

ในที่สุดปริมาณน้ำคือผลรวมของรายการนี้ซึ่งมีทั้งน้ำและที่ดินลบด้วยผลรวมของรายการดั้งเดิมซึ่งมีเพียงที่ดิน


9

เยลลี่ 10 ไบต์

U»\U«»\S_S

ในขณะที่ APL ต้องการวงเล็บหลายอันและสัญลักษณ์สองตัวอักษร J อัลกอริทึมนั้นสวยงามใน Jelly

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

ลองมันนี่


4

MATL , 14

คำตอบ Matlab ของฉันแปลเป็น MATL อัลกอริทึมของ xnor

Y>GPY>P2$X<G-s

คำอธิบาย

Y>: cummax()(ผลักถูกป้อนโดยปริยายบนสแต็ก)

G: อินพุตพุช (อีกครั้ง)

P: flip()

Y>: cummax()

P: flip()

2$X<: min([],[])(ขั้นต่ำสองข้อโต้แย้ง)

G: อินพุตพุช (อีกครั้ง)

-: -

s: sum()


MATLL เป็นภาษาทดแทนของ Matlab หรือไม่ คุณสามารถให้ลิงค์ในส่วนหัวได้หรือไม่?
Addison Crump

1
@FlagAsSpam ฉันคิดว่ามันเป็นมากกว่านั้น: esolangs.org/wiki/MATL
Martin Ender

@ MartinBüttner pseudocode สำหรับสิ่งนี้จะเหมือนกับ pseudocode ของ Matlab หรือไม่ ฉันสงสัยว่ามันเป็นเรื่องการแปลโดยตรงหรือไม่
Addison Crump

1
@FlagAsSpam MATL เป็นแบบสแต็กดังนั้นมันจึงไม่ใช่การแทนที่ธรรมดา
Martin Ender

ใช่มันเป็นการแปลโดยตรง MATLเป็นแบบสแต็ค (สัญกรณ์ขัดกลับ) ที่มีชวเลขหนึ่งถึงสามอักขระสำหรับผู้ปฏิบัติงานและฟังก์ชันของMATLAB ดู [ github.com/lmendo/MATL/blob/master/doc/MATL_spec.pdf]
Rainer P.

3

Dyalog APL ขนาด 17 ไบต์

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

นี่คือรถไฟขบวนเดียวที่นำอาร์เรย์เข้าทางด้านขวา

อัลกอริทึมนั้นค่อนข้างเหมือนกับ xnor แม้ว่าฉันจะพบว่ามันเป็นอิสระ มันสแกนหาค่าสูงสุดในทั้งสองทิศทาง (ย้อนกลับโดยการย้อนกลับอาร์เรย์การสแกนและการย้อนกลับอีกครั้ง) และค้นหาเวกเตอร์ขั้นต่ำเหล่านั้น จากนั้นมันจะลบอาร์เรย์และผลรวมต้นฉบับ

วิธีอื่นในการทำเช่นนี้ก็คือการแบ่งอาร์เรย์ในแต่ละตำแหน่ง แต่นั่นก็นานกว่า

ลองมันนี่


1
ฉันมาที่นี่เพื่อเขียน :-) เมื่อเราได้รับคู่ (aka ใต้) ผู้ประกอบการคุณสามารถบันทึก 3 +/⊢-⍨⌈\⌊⌈\⍢⌽ไบต์ด้วย
Adám


1

MATLAB, 116 113 109 106 Bytes

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

สิ่งนี้ทำงานโดยการจัดเก็บจุดสูงทางด้านซ้ายและในขณะที่วนซ้ำผ่านแต่ละจุดถัดไปจะพบจุดสูงสุดไปทางขวา หากจุดปัจจุบันน้อยกว่าจุดสูงสุดทั้งสองจะเพิ่มส่วนต่างขั้นต่ำให้กับปริมาณสะสม

รหัสไม่ได้รับการตอบกลับ:

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

ครั้งแรกที่ฉันพยายามเล่นกอล์ฟอะไรก็ตาม MATLAB ดูจะไม่ดีที่สุดในการทำ ...


0

ES6, 101 ไบต์

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)

อีกพอร์ตของ @ xnor's alghorithm



0

Pip -l , 19 ไบต์

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

รับหมายเลขอินพุตเป็นอาร์กิวเมนต์บรรทัดคำสั่ง หรือเพิ่ม-rแฟล็กเพื่อใช้เป็นบรรทัด stdin: ลองออนไลน์!

คำอธิบาย

ซึ่งแตกต่างจากคำตอบอื่น ๆ ทั้งหมดใน Pip มันสั้นกว่าจริง ๆ ในการสร้าง (เวอร์ชั่นที่แก้ไขแล้ว) ASCII-art และนับหน่วยน้ำ

เราเริ่มด้วยgรายการข้อโต้แย้ง

[1 4 2 1 5 2 3]

0Xgผลิตรายการของสตริงของnศูนย์สำหรับแต่ละngใน

[0 0000 00 0 00000 00 000]

ZD1จากนั้นซิปสตริงเหล่านี้เข้าด้วยกันโดยใช้1เพื่อเติมช่องว่างใด ๆ ในรายการที่ซ้อนกันเป็นรูปสี่เหลี่ยมผืนผ้าผลลัพธ์:

[[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]]

STแปลงรายการนี้เป็นสตริง การ-lตั้งค่าสถานะระบุว่ารายการจะถูกจัดรูปแบบดังนี้: รายการที่ซ้อนกันทั้งหมดจะถูกรวมเข้าด้วยกันโดยไม่มีตัวคั่นและที่ระดับบนสุดตัวคั่นจะขึ้นบรรทัดใหม่ ดังนั้นเราจึงได้สาย multiline นี้ - โดยพื้นฐานแล้วแผนภาพของวัตถุ แต่กลับหัวกลับหาง:

0000000
1001000
1011010
1011011
1111011

จากนั้นเราจะได้พบกับการแข่งขันทั้งหมดของ `0.*0`regex สิ่งนี้ตรงกับผนังด้านนอกสุดทั้งสองและทุกสิ่งระหว่างพวกเขาในแต่ละบรรทัด

[0000000 001000 011010 0110]

Jรวมสายเหล่านี้เข้าด้วยกันเป็นสายใหญ่เส้นหนึ่งแล้ว$+บวกด้วยให้จำนวน1s - ซึ่งเท่ากับปริมาณน้ำที่วัตถุสามารถเก็บได้

6
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.