Menutupi Skyline dengan sapuan kuas


43

Diberikan daftar tinggi bilangan bulat langit-langit non-negatif, jawab berapa banyak sapuan kuas horisontal 1 unit tinggi yang tidak terputus yang diperlukan untuk menutupinya.

[1,3,2,1,2,1,5,3,3,4,2], divisualisasikan sebagai:

      5    
      5  4 
 3    5334 
 32 2 53342
13212153342

membutuhkan sembilan sapuan kuas:

      1    
      2  3 
 4    5555 
 66 7 88888
99999999999

Contohnya

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

[5,8]8

[1,1,1,1]1

[]0

[0,0]0

[2]2

[2,0,2]4

[10,9,8,9]11


Untuk pengguna rep tinggi yang tertarik: Berdasarkan ini sesuai ini .
Adám

2
Jadi, semua sapuan kuas bersifat horizontal?
tsh

1
@ tsh Poin bagus. Ditambahkan.
Adám

Itu bukan codegolf, tapi saya punya pertanyaan ini untuk tes kode wawancara sekitar setahun yang lalu.
luizfzs

Jawaban:


35

JavaScript (Node.js) , 38 byte

a=>a.map(v=>(n+=v>p&&v-p,p=v),p=n=0)|n

Cobalah online!

Cukup algoritma serakah yang memindai dari kiri ke kanan, hanya menggambar garis jika diperlukan, dan menggambarnya selama mungkin.

Terima kasih Arnauld, simpan 2 3 byte


@Arnauld tangkapan yang bagus. benar-benar lupa.
tsh

Bagaimana Anda menyadari ini?
Adám

@ Adám Tidak ada yang ajaib. Pertama kali saya membaca pertanyaan saya bingung dengan cara mencari sampai saya menyadari semua garis hanya horisontal. Dan formula ini baru saja muncul di benak saya secara alami ....
tsh

4
sihir sepertinya kata yang pas untuk menggambarkan proses itu.
Adám

1
Meskipun ini adalah asal dari algoritma yang sekarang banyak digunakan, dijelaskan di sini .
Adám

28

05AB1E ,  8 7  5 byte

Disimpan 2 byte berkat @Adnan

0š¥þO

Cobalah online!

Bagaimana?

Ini menggunakan algoritma yang pertama kali ditemukan oleh @tsh . Jika Anda menyukai jawaban ini, pastikan untuk membatalkan jawaban mereka juga!

Setiap kali gedung pencakar langit lebih rendah dari atau setinggi yang sebelumnya, itu dapat dicat 'gratis' hanya dengan memperpanjang sapuan kuas.

Misalnya, mengecat gedung pencakar langit B dan C pada gambar di bawah ini tidak ada biaya.

Di sisi lain, kita perlu 2 sapuan kuas baru untuk mengecat gedung pencakar langit E , tidak peduli apakah itu akan digunakan kembali setelah itu atau tidak.

bangunan

Untuk gedung pencakar langit pertama, kita selalu membutuhkan sapuan kuas sebanyak lantai.

Mengubah ini menjadi matematika:

S=h0+i=1nmax(hihi1,0)

Jika kita menambahkan ke daftar, ini dapat disederhanakan menjadi:0

S=i=1nmax(hihi1,0)

Berkomentar

0š¥þO     # expects a list of non-negative integers  e.g. [10, 9, 8, 9]
0š        # prepend 0 to the list                    -->  [0, 10, 9, 8, 9]
  ¥       # compute deltas                           -->  [10, -1, -1, 1]
   þ      # keep only values made of decimal digits
          # (i.e. without a minus sign)              -->  ["10", "1"]
    O     # sum                                      -->  11

Saya pikir 0š¥ʒd}Omenghemat satu byte.
Tn. Xcoder

@ Don'tbeax-tripledot Saya sedang mengedit jawaban saya tepat ketika saya melihat komentar Anda;)
Arnauld

4
Penjelasan yang indah.
Adám

1
Mengganti ʒd}dengan þharus menghemat dua byte.
Adnan

@ Adnan Ah, bagus. Terima kasih!
Arnauld

7

Python 3 , 37 byte

lambda a:sum(a)-sum(map(min,a[1:],a))

Cobalah online!

-5 byte dengan beralih ke Python 3, terima kasih kepada Sarien


Python 2 , 47 43 42 byte

lambda a:sum(a)-sum(map(min,a[1:],a[:-1]))

Cobalah online!

Alt:

lambda a:sum(a)-sum(map(min,zip(a[1:],a)))

Cobalah online!


Dalam Python 3 Anda dapat membuang [: -1], menghemat 5 byte.
Sarien

@Sarien Terima kasih: D, saya tidak tahu peta berbeda dalam python 2 dan 3
TFeld

7

Haskell , 32 byte

(0%)
p%(h:t)=max(h-p)0+h%t
p%_=0

Cobalah online!

Peningkatan pada solusi Lynn yang melacak elemen sebelumnya palih-alih melihat elemen berikutnya. Hal ini membuat kasing dasar dan panggilan rekursif menjadi lebih pendek sebagai ganti kebutuhan untuk memanggil (0%).

max(h-p)0bisa max h p-pdengan panjang yang sama.



5

K (oK) , 12 7 byte

-5 byte terima kasih kepada ngn!

Sebuah k (oK) pelabuhan solusi 05AB1E Arnauld (dan solusi JavaScript TSH ini):

+/0|-':

Cobalah online!

J , 15 byte

Port AJ dari solusi 05AB1E Arnauld (dan solusi JavaScript tsh):

1#.0>./2-~/\0,]

Cobalah online!

Solusi naif saya:

J , 27 byte

1#.2(1 0-:])\0,@|:@,~1$~"0]

Cobalah online!


2
oK: setiap prior ( ':) menggunakan elemen identitas implisit ( 0untuk -) sebelum daftar, jadi 0,tidak perlu. Anda dapat menghilangkan { x}untuk membuatnya komposisi:+/0|-':
ngn

@ ngn Terima kasih! Rupanya saya sudah lupa ini:Some primitive verbs result in a different special-cased initial value: +, *, - and & are provided with 0, 1, 0 or the first element of the sequence, respectively
Galen Ivanov

5

Haskell , 34 32 byte

2 byte dipangkas oleh Lynn

g x=sum$max 0<$>zipWith(-)x(0:x)

Cobalah online!

Jadi untuk memulai kita sudah zipWith(-). Ini mengambil dua daftar dan menghasilkan daftar baru dari perbedaan berpasangan mereka. Kami kemudian menggabungkannya dengan xdan (0:x). (0:)adalah fungsi yang menambahkan nol di bagian depan daftar dan dengan menggabungkannya dengan zipWith(-)kita mendapatkan perbedaan antara elemen berturut-turut dari daftar itu dengan nol di depan. Lalu kita mengubah semua yang negatif menjadi nol dengan (max 0<$>). Ini membuat daftar baru di mana setiap elemen adalah jumlah pukulan baru yang harus dimulai di setiap menara. Untuk mendapatkan total, kami hanya menjumlahkannya dengan sum.


2
g x=sum$max 0<$>zipWith(-)x(0:x)adalah 32 byte :)
Lynn

Sebagaimana adanyasum.zipWith((max 0.).(-))<*>(0:)
Lynn

@ Lynn Yang kedua Anda akan membutuhkan tanda kurung tambahan karena .memiliki prioritas lebih tinggi daripada <*>.
Wheat Wizard

3

Japt , 8 byte

-2 byte dari @Shaggy

mîT Õ¸¸è

Penjelasan

mîT Õ¸¸è      Full program. Implicit input U
                e.g. U = [2,0,2]
mîT             Map each item X and repeat T(0) X times
                     U = ["00","","00"]
    Õ           Transpose rows with columns
                     U = ["0 0","0 0"]
     ¸¸         Join using space and then split in space
                     U = ["0","0","0","0"]
        è       Return the count of the truthy values

Cobalah online!


8 byte:mîT Õ¸¸è
Shaggy

1
Bagus penggunaan A.y()'s padding, by the way.
Shaggy

3

MATL , 8 byte

0whd3Y%s

Cobalah online!

Algoritma @ Arnauld cukup banyak. Disimpan satu byte (terima kasih @LuisMendo) dengan melakukan casting uint64daripada memilih )entri positif.


3

Jelly , 5 byte

Port jawaban 05AB1E saya , yang mirip dengan jawaban JS @tsh .

ŻI0»S

Cobalah online!

Berkomentar

ŻI0»S    - main link, expecting a list of non-negative integers  e.g. [10, 9, 8, 9]
Ż        - prepend 0                                             -->  [0, 10, 9, 8, 9]
 I       - compute the deltas                                    -->  [10, -1, -1, 1]
  0»     - compute max(0, v) for each term v                     -->  [10, 0, 0, 1]
    S    - sum                                                   -->  11

3

Japt , 7 6 byte

änT fq

Cobalah

1 byte disimpan berkat Oliver.

änT xwT    :Implicit input of integer array
än         :Consecutive differences / Deltas
  T        :  After first prepending 0
    f      :Filter elements by
     q     :  Square root (The square root of a negative being NaN)
           :Implicitly reduce by addition and output


Bagus, @liver; tidak akan memikirkan itu.
Shaggy


2

Retina 0.8.2 , 21 byte

\d+
$*
(1+)(?=,\1)

1

Cobalah online! Tautan termasuk kasus uji. Penjelasan:

\d+
$*

Konversikan ke unary.

(1+)(?=,\1)

Hapus semua tumpang tindih dengan menara berikutnya, yang tidak memerlukan stroke baru.

1

Hitung goresan yang tersisa.


2

Common Lisp, 88 87 byte

(lambda(s)(let((o 0))(dolist(c s)(incf o(max 0 c))(mapl(lambda(y)(decf(car y)c))s))o))

non-minified

(lambda (skyline)
  (let ((output 0))
    (dolist (current-skyscraper-height skyline)
      (incf output (max 0 current-skyscraper-height))
      (mapl (lambda (skyscraper)
              (decf (car skyscraper) current-skyscraper-height))
            skyline))
    output)))

Menguji

Ketika satu menara dicat, dibutuhkan sejumlah sapuan kuas yang sama dengan tingginya. Sapuan kuas ini diterjemahkan ke semua yang berikut, yang ditunjukkan di sini dengan mengurangi ketinggian menara saat ini dari semua menara lainnya (dan itu sendiri, tapi itu tidak masalah). Jika menara berikut lebih pendek, maka akan didorong ke angka negatif, dan angka negatif ini kemudian akan dikurangi dari menara yang mengikuti (menunjukkan sapuan kuas yang tidak dapat diterjemahkan dari menara sebelumnya ke yang berikutnya). Ini sebenarnya hanya mengurangi jumlah dari semua ketinggian menara, termasuk yang sebelumnya, tetapi ini tidak masalah karena kita tidak melihat yang sebelumnya lagi.


Selamat datang di PPCG. Bisakah Anda memberikan tautan ke lingkungan pengujian online untuk kemudahan verifikasi?
Jonathan Frech

Ya, tentu saja. rextester.com/TKBU14782 Jawabannya akan segera diperbarui
Charlim

Sudah selesai dilakukan dengan baik. +1 untuk pos pertama yang bagus dan berfungsi. Selamat bermain golf.
Jonathan Frech

1

05AB1E , 13 10 byte

Z>Lε@γPO}O

Cobalah secara online atau verifikasi semua kasus uji .

Penjelasan:

Z            # Get the maximum of the (implicit) input-list
 >           # Increase it by 1 (if the list only contains 0s)
  L          # Create a list in the range [1, max]
   ε         # Map each value to:
    @        #  Check if this value is >= for each value in the (implicit) input
     γ       #  Split into chunks of adjacent equal digits
      P      #  Take the product of each inner list
       O     #  Take the sum
        }O   # And after the map: take the sum (which is output implicitly)

1

C # (Visual C # Interactive Compiler) dengan flag /u:System.Math, 47 byte

n=>n.Select((a,i)=>i<1?a:Max(a-n[i-1],0)).Sum()

Cobalah online!

Versi lama, dengan flag /u:System.Math, 63 byte

n=>n.Aggregate((0,0),(a,b)=>(a.Item1+Max(0,b-a.Item2),b)).Item1

Saya merasa solusi ini lebih elegan dari yang pertama. Itu pergi melalui array dengan tuple dua nilai sebagai nilai awal, mengambil nilai, dan menyimpan nilai sebelum itu di bagian kedua tuple.

Cobalah online!


1

Pyth, 8 byte

s>#0.++0

Namun port lain dari jawaban luar biasa @ tsh . Mengambil jumlah ( s) dari nilai positif ( >#0) dari delta (. +) Dari input dengan 0 prepended ( +0Q, trailing Q disimpulkan).

Coba online di sini , atau verifikasi semua uji sekaligus di sini .

Metode penggabungan string, 10 byte

Ini adalah solusi yang saya tulis sebelum menelusuri jawaban lainnya.

lcj.t+d*LN

Suite uji.

lcj.t+d*LNQ   Implicit: Q=eval(input()), b=<newline>, N=<quote mark>
              Trailing Q inferred
        L Q   Map each element of Q...
       * N    ... to N repeated that many times
     +b       Prepend a newline
   .t         Transpose, padding with spaces
  j           Join on newlines
 c            Split on whitespace
l             Take the length, implicit print

1

Clojure, 50 byte

#((reduce(fn[[s n]i][(+(max(- i n)0)s)i])[0 0]%)0)

Cobalah online! (Mengapa ini tidak mencetak apa-apa?)

#( ; begin anonymous function
    (reduce
        (fn [[s n] i] ; internal anonymous reducing function, destructures accumulator argument into a sum and the previous item
            [(+ (max (- i n) 0) s ; the sum part of the accumulator becomes the previous sum plus the larger of zero and the difference between the current number and the last one, which is how many new strokes need to be started at this point
            i]) ; ...and the previous item part becomes the current item
        [0 0] ; the initial value of the accumulator gives no strokes yet, and nothing for them to cover yet
        %) ; reduce over the argument to the function
    0) ; and get the sum element of the last value of the accumulator.

Selamat datang di PPCG! Saya tidak tahu apa-apa tentang Clojure, tetapi pencarian cepat menunjukkan bahwa Anda harus mengevaluasi malas untuk loop. Cobalah secara Online! (Kiat: Anda dapat menggunakan tombol tautan untuk memformat jawaban Anda secara otomatis). Semoga Anda tetap tinggal dan bersenang-senang!
Jo King

1

Java (JDK) , 57 byte

a->{int s=0,p=0;for(int x:a)s-=(x>p?p:x)-(p=x);return s;}

Cobalah online!

Port lain dari TSH 's Javascript jawabannya . Jadi, pastikan Anda telah memutakhirkannya.

Perhatikan bahwa saya menggunakan pengurangan bukannya penambahan karena memungkinkan saya untuk menulis (p=x)sebagai operan yang benar dalam pernyataan yang sama.


0

MATL , 15 14 13 byte

ts:<~"@Y'x]vs

Input adalah vektor kolom, menggunakan ;sebagai pemisah.

Cobalah online! Atau verifikasi semua kasus uji .

Penjelasan

t       % Implicit input: column vector. Duplicate
s       % Sum
:       % Range from 1 to that. Gives a row vector
<~      % Greater or equal? Element-wise with broadcast
"       % For each column
  @     %   Push current columnn
  Y'    %   Run-length encoding. Gives vector of values (0, 1) and vector of lengths
  x     %   Delete vector of lengths
]       % End
v       % Vertically concatenate. May give an empty array
s       % Sum. Implicit display

0

Perl 5, 21 byte

$\+=$_>$'&&$_-$';//}{

TIO

Bagaimana

  • -p+ }{+ $\trik
  • //cocok dengan string kosong sehingga untuk postmatch baris berikutnya $'akan berisi baris sebelumnya
  • $\+=$_>$'&&$_-$'untuk mengakumulasi perbedaan antara baris saat ini dan sebelumnya jika saat ini lebih besar dari sebelumnya, (bisa juga ditulis $\+=$_-$' if$_>$', tetapi perl tidak menguraikan $\+=$_-$'if$_>$'yang sama)


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.