2B basılı nesnelerin kapasitesini bulun


23

Kurgusal bir 2D dünyasında, bir nesne için bir 2B yazdırma talimatı kümesi aşağıdaki gibi bir tamsayı listesiyle gösterilebilir:

1 4 2 1 1 2 5 3 4

Her sayı, o noktadaki nesnenin yüksekliğini temsil eder. Yukarıdaki liste, yazdırıldığında aşağıdaki nesneye çevirir:

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

Daha sonra elimizden geldiğince su ile doldurduk, sonuç olarak:

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

Nesnenin kapasitesini , tamamen dolu olduğunda nesnenin tutabileceği su birimleri olarak tanımlarız ; bu durumda, 11.

Açıkça konuşursak, bir yerde bir su birimi ( ~) aynı yerde iki katı blokla ( #) çevrelenmişse olabilir .

Meydan okuma

Giriş olarak pozitif tamsayıların bir listesini alın (herhangi bir biçimde) ve liste talimat olarak kullanıldığında yazdırılan nesnenin kapasitesini çıkartın.

Listenin en az bir öğe içerdiğini ve tüm öğelerin 1 ile 255 arasında olduğunu varsayabilirsiniz.

Test Kılıfları

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

Yanıtlar:


15

Haskell, 54 bayt

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

İfadeler scanl1 max lve scanr1 max llistenin maksimum akışını ileri ve geri okuma, yani suyun bir yöne akması durumunda suyun profili ve arsa hesabı.

Orig:

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

Ayrıldı:

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

Sağ:

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

Daha sonra, genel resmin profili, bunların en az olanıdır; bu, suyun herhangi bir yöne sızmadığı yere karşılık gelir.

En az:

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

Son olarak, su miktarı hem toprağı hem de karayı içeren bu listenin toplamı eksi, sadece kara içeren orijinal listenin toplamıdır.


9

Jöle, 10 bayt

U»\U«»\S_S

APL birden fazla parantez ve J iki karakterli semboller gerektirirken, algoritma Jelly'de çok güzel.

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

Burada dene .


4

MATL , 14

Matlab cevabım MATL'ye çevrildi. xnor'ın algoritması.

Y>GPY>P2$X<G-s

açıklama

Y>: cummax()(giriş yığına dolaylı olarak itilir)

G: itme girişi (tekrar)

P: flip()

Y>: cummax()

P: flip()

2$X<: min([],[])(minimum iki argüman)

G: itme girişi (tekrar)

-: -

s: sum()


MATL, Matlab'ın yerine geçecek bir dil midir? Başlıkta bir link verebilir misiniz?
Addison Crump,

1
@FlagAsSpam Sanırım bundan biraz daha fazlası: esolangs.org/wiki/MATL
Martin Ender

@ MartinBüttner Bunun için sözde kod Matlab sözde koduyla aynı mıdır? Acaba, bir şeye dayanmak yerine doğrudan bir çeviri olup olmadığını merak ediyorum.
Addison Crump,

1
@ FlagAsSpam MATL yığın tabanlıdır, bu nedenle kesinlikle basit bir oyuncu değişikliği değildir.
Martin Ender

Evet, doğrudan bir çeviri. MATL , MATLAB operatörleri ve işlevleri için bir ila üç karakter kısaltmasına sahip baca tabanlıdır (ters cila notasyonu) . Bakınız [ github.com/lmendo/MATL/blob/master/doc/MATL_spec.pdf] .
Rainer P.

3

Dyalog APL, 17 bayt

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

Bu sağdaki giriş dizisini alan bir monadik trendir.

Bağımsız bir şekilde bulmama rağmen, algoritma xnor'ınkilerle hemen hemen aynı. Her iki yönde de maksimum değeri tarar (diziyi ters çevirerek, tararken ve tekrar ters çevirerek geriye doğru) ve bunların minimumunu vectorized bulur. Sonra orijinal diziyi çıkarır ve toplar.

Bunu yapmanın diğer yolu, diziyi her yere bölmek olacaktır, ancak daha uzun.

Burada dene .


1
Aynen aynısını buraya yazmaya geldim. :-) Dual (aka under) operatörünü elde ettiğimizde, 3 bayt ile tasarruf edebilirsiniz +/⊢-⍨⌈\⌊⌈\⍢⌽.
Adám

2

Matlab, 47

Ayrıca xnor algoritmasını kullanarak.

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

1

MATLAB, 116 113 109 106 Bayt

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

Bu, en yüksek noktayı solda saklayarak çalışır ve her bir sonraki noktayı tekrarlarken, en yüksek noktayı sağa doğru bulur. Geçerli nokta, her iki yüksek noktadan daha küçükse, o zaman kümülatif hacme minimum farkı ekler.

Ungolfed kod:

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

İlk defa bir şeyi golf oynamaya çalıştım, MATLAB bunu yapacak en iyi şey gibi görünmüyor.


0

ES6, 101 bayt

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'ın algoritmasının başka bir limanı.



0

Pip -l , 19 bayt

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

Giriş numaralarını komut satırı argümanları olarak alır. Veya -rbayraklarını stdin çizgisi olarak almak için bayrak ekleyin : Çevrimiçi deneyin!

açıklama

Diğer tüm cevapların aksine, Pip'de ASCII sanatını inşa etmek (değiştirilmiş bir versiyon) yapmak ve su birimlerini saymak daha kısa sürdü.

gArgümanlar listesiyle başlıyoruz .

[1 4 2 1 5 2 3]

0Xgait dizeleri listesini üretir n her biri için sıfır n içinde g.

[0 0000 00 0 00000 00 000]

ZD1daha sonra 1ortaya çıkan dikdörtgen iç içe listesindeki boşlukları doldurmak için bu dizeleri birlikte sıkıştırın :

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

STbu listeyi bir dizeye dönüştürür. -lHer iç içe liste ayırıcı olmadan birlikte birleştirilir ve üst seviyede ayırıcı satır geçerli: listeler biçiminde olduğu bayrak belirtir izler. Bu yüzden bu çok satırlı dizgeyi elde ederiz - temelde nesnenin şeması, ancak baş aşağı:

0000000
1001000
1011010
1011011
1111011

Daha sonra regex'in tüm maçlarını buluruz `0.*0`. Bu, en dıştaki iki duvarı ve aralarındaki her çizgiyi her satırda eşleştirir.

[0000000 001000 011010 0110]

Jbu dizeleri bir büyük dizeye birleştirir ve toplar , nesnenin tutabileceği su miktarına eşit olan s $+sayısını verir 1.

6
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.