Che một đường chân trời bằng nét cọ


43

Đưa ra một danh sách chiều cao đường chân trời nguyên không âm, trả lời có bao nhiêu nét cọ ngang cao 1 đơn vị không bị gián đoạn là cần thiết để che nó.

[1,3,2,1,2,1,5,3,3,4,2], được hình dung như:

      5    
      5  4 
 3    5334 
 32 2 53342
13212153342

cần chín nét cọ:

      1    
      2  3 
 4    5555 
 66 7 88888
99999999999

Ví dụ

[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


Đối với người dùng cao cấp quan tâm: Dựa trên điều này theo điều này .
Adám

2
Vì vậy, tất cả các nét cọ là ngang?
tsh

1
@tsh Điểm tốt. Thêm.
Adám

Đó không phải là codegolf, nhưng tôi đã có câu hỏi này cho một bài kiểm tra mã phỏng vấn khoảng một năm trước.
luizfzs

Câu trả lời:


35

JavaScript (Node.js) , 38 byte

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

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

Đơn giản chỉ là một thuật toán tham lam quét từ trái sang phải, chỉ vẽ các đường nếu cần và vẽ nó càng lâu càng tốt.

Cảm ơn Arnauld, lưu 2 3 byte


@Arnauld bắt đẹp. hoàn toàn quên nó
tsh

Làm thế nào bạn nhận ra điều này?
Adám

@ Adám Không có gì kỳ diệu. Lần đầu tiên tôi đọc câu hỏi tôi đã bối rối bởi cách tìm kiếm cho đến khi tôi nhận ra tất cả các dòng chỉ nằm ngang. Và sau đó, công thức này xuất hiện trong tâm trí tôi một cách tự nhiên ....
tsh

4
ma thuật có vẻ như là một từ phù hợp để mô tả quá trình đó.
Adám

1
Trong khi đây là nguồn gốc của thuật toán hiện đang được sử dụng rộng rãi, nó được giải thích ở đây .
Adám

28

05AB1E ,  8 7  5 byte

Đã lưu 2 byte nhờ @Adnan

0š¥þO

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

Làm sao?

Đây là sử dụng thuật toán lần đầu tiên được tìm thấy bởi @tsh . Nếu bạn thích câu trả lời này, hãy đảm bảo nâng cao câu trả lời của họ !

Mỗi lần một tòa nhà chọc trời thấp hơn hoặc cao như trước, nó có thể được vẽ 'miễn phí' bằng cách mở rộng các nét vẽ.

Chẳng hạn, vẽ các tòa nhà chọc trời và trong hình dưới đây không tốn kém gì.BC

Mặt khác, chúng ta cần 2 nét vẽ mới để vẽ tòa nhà chọc trời , bất kể chúng có được sử dụng lại sau đó hay không.E

các tòa nhà

Đối với tòa nhà chọc trời đầu tiên, chúng ta luôn cần nhiều nét vẽ như có các tầng trong đó.

Biến điều này thành toán học:

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

Nếu chúng tôi thêm vào danh sách, điều này có thể được đơn giản hóa thành:0

S=i=1nmax(hihi1,0)

Đã bình luận

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

Tôi nghĩ 0š¥ʒd}Ogiúp bạn tiết kiệm một byte.
Ông Xcoder

@ Don'tbeax-tripledot Tôi đã chỉnh sửa câu trả lời của mình chính xác khi tôi thấy bình luận của bạn;)
Arnauld

4
Giải thích đẹp.
Adám

1
Thay thế ʒd}bằng þsẽ giúp bạn tiết kiệm hai byte.
Ad Nam

@Ad Nam ơi, đẹp quá. Cảm ơn!
Arnauld

7

Python 3 , 37 byte

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

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

-5 byte bằng cách chuyển sang Python 3, nhờ Sarien


Python 2 , 47 43 42 byte

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

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

Alt:

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

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


Trong Python 3, bạn có thể bỏ [: -1], tiết kiệm 5 byte.
Sarien

@Sarien Cảm ơn: D, tôi không biết bản đồ là khác nhau ở python 2 và 3
TFeld

7

Haskell , 32 byte

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

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

Một cải tiến về giải pháp của Lynn theo dõi phần tử trước pthay vì nhìn vào phần tử tiếp theo. Điều này làm cho trường hợp cơ sở và cuộc gọi đệ quy ngắn hơn để đổi lấy việc cần phải gọi (0%).

max(h-p)0có thể max h p-pcho cùng một chiều dài.



5

K (oK) , 12 7 byte

-5 byte nhờ ngn!

Một k (OK) cảng giải pháp 05AB1E Arnauld (và giải pháp JavaScript tsh của):

+/0|-':

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

J , 15 byte

Cổng AJ của giải pháp 05AB1E của Arnauld (và giải pháp JavaScript của tsh):

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

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

Giải pháp ngây thơ của tôi:

J , 27 byte

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

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


2
oK: mỗi trước ( ':) sử dụng một yếu tố nhận dạng ẩn ( 0for -) trước danh sách, do đó 0,không cần thiết. bạn có thể bỏ qua { x}để biến nó thành một tác phẩm:+/0|-':
ngn

@ngn Cảm ơn! Rõ ràng là tôi đã quên điều này: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 được cắt bởi Lynn

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

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

Vì vậy, để bắt đầu chúng ta có zipWith(-). Điều này có hai danh sách và tạo ra một danh sách mới về sự khác biệt theo cặp của họ. Chúng tôi sau đó kết hợp nó với x(0:x). (0:)là một hàm thêm số 0 vào trước danh sách và bằng cách kết hợp nó với zipWith(-)chúng ta sẽ có được sự khác biệt giữa các phần tử liên tiếp của danh sách đó với số 0 ở phía trước. Sau đó, chúng tôi biến tất cả những người tiêu cực về không (max 0<$>). Điều này tạo ra một danh sách mới trong đó mỗi phần tử là số nét mới phải được bắt đầu tại mỗi tháp. Để có được tổng số chúng tôi chỉ cần tổng hợp với sum.


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

Như làsum.zipWith((max 0.).(-))<*>(0:)
Lynn

@Lynn Cái thứ hai của bạn sẽ cần thêm dấu ngoặc đơn vì .ưu tiên cao hơn <*>.
Phù thủy lúa mì

3

Japt , 8 byte

-2 byte từ @Shaggy

mîT Õ¸¸è

Giải trình

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

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


8 byte:mîT Õ¸¸è
Shaggy

1
Nhân tiện, sử dụng tốt phần A.y()đệm.
Shaggy



3

Japt , 7 6 byte

änT fq

Thử nó

Lưu 1 byte nhờ 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


Đẹp một, @Oliver; sẽ không nghĩ về điều đó.
Xù xì


2

Võng mạc 0.8.2 , 21 byte

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

1

Hãy thử trực tuyến! Liên kết bao gồm các trường hợp thử nghiệm. Giải trình:

\d+
$*

Chuyển đổi sang unary.

(1+)(?=,\1)

Xóa tất cả các phần trùng lặp với tháp tiếp theo, không cần một nét mới.

1

Đếm các nét còn lại.


2

Lisp thường gặp, 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))

không khai thác

(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)))

Kiểm tra nó

Khi một tòa tháp được sơn, nó cần một số nét vẽ tương đương với chiều cao của nó. Các nét vẽ này dịch cho tất cả các kiểu sau, được chỉ ra ở đây bằng cách trừ chiều cao của tháp hiện tại khỏi tất cả các tháp khác (và chính nó, nhưng điều đó không thành vấn đề). Nếu một tháp sau ngắn hơn, thì nó sẽ bị đẩy sang số âm và số âm này sau đó sẽ bị trừ khỏi các tháp theo sau (biểu thị các nét vẽ không thể dịch từ tháp trước sang tháp tiếp theo). Nó thực sự chỉ trừ số từ tất cả các độ cao của tháp, bao gồm cả những cái trước đó, nhưng điều này không quan trọng bởi vì chúng ta không nhìn lại những cái trước đó.


Chào mừng đến với PPCG. Bạn có thể cung cấp một liên kết đến một môi trường thử nghiệm trực tuyến để dễ xác minh?
Jonathan Frech

Chắc chắn rồi. rextester.com/TKBU14782 Câu trả lời sẽ được cập nhật sớm
Charlim

Làm tốt. +1 cho một bài đăng tốt đẹp, làm việc đầu tiên. Chúc bạn chơi golf vui vẻ.
Jonathan Frech

1

05AB1E , 13 10 byte

Z>Lε@γPO}O

Hãy thử trực tuyến hoặc xác minh tất cả các trường hợp thử nghiệm .

Giải trình:

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 # (Trình biên dịch tương tác Visual C #) với cờ /u:System.Math, 47 byte

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

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

Phiên bản cũ, có cờ /u:System.Math, 63 byte

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

Tôi cảm thấy như giải pháp này là thanh lịch hơn so với giải pháp đầu tiên. Nó đi qua mảng với bộ dữ liệu hai giá trị làm giá trị bắt đầu, chọn giá trị và lưu trữ giá trị trước nó trong phần thứ hai của bộ dữ liệu.

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


1

Bình thường, 8 byte

s>#0.++0

Một cổng khác của câu trả lời tuyệt vời của @ tsh . Lấy tổng ( s) của các giá trị dương ( >#0) của deltas (. +) Của đầu vào với 0 được đặt trước ( +0Q, theo dõi Q được suy ra).

Dùng thử trực tuyến tại đây hoặc xác minh tất cả các trường hợp thử nghiệm cùng một lúc tại đây .

Phương thức nối chuỗi, 10 byte

Đây là giải pháp tôi đã viết trước khi duyệt các câu trả lời khác.

lcj.t+d*LN

Bộ thử nghiệm.

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)

Hãy thử trực tuyến! (Tại sao điều này không in bất cứ điều gì?)

#( ; 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.

Chào mừng đến với PPCG! Tôi không biết gì về Clojure, nhưng một tìm kiếm nhanh cho thấy bạn sẽ cần đánh giá vòng lặp lười biếng. Hãy thử trực tuyến! (Mẹo: bạn có thể sử dụng nút liên kết để tự động định dạng câu trả lời của mình). Hy vọng bạn dính xung quanh và có một số niềm vui!
Jo King


0

MATL , 15 14 13 byte

ts:<~"@Y'x]vs

Đầu vào là một vectơ cột, sử dụng ;như dấu phân cách.

Hãy thử trực tuyến! Hoặc xác minh tất cả các trường hợp thử nghiệm .

Giải trình

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

Làm sao

  • -p+ }{+ $\lừa
  • //khớp với chuỗi rỗng để cho postmatch dòng tiếp theo $'sẽ chứa dòng trước đó
  • $\+=$_>$'&&$_-$'để tích lũy sự khác biệt giữa dòng hiện tại và trước đó nếu hiện tại lớn hơn trước, (cũng có thể được viết $\+=$_-$' if$_>$', nhưng perl không phân tích $\+=$_-$'if$_>$'giống nhau)


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.