In the skyline problem, the user is provided with the coordinates of rectangular buildings that have varying widths and heights. The user is required to return a silhouette that traces the outlines of all the buildings. Note: A city's skyline is made up from the outer contour of the city's silhouette.
Given n rectangular buildings in a 2-dimensional city, computes the skyline of these buildings, eliminating hidden lines. The main task is to view buildings from a side and remove all sections that are not visible. 'left': is x coordinated of left side (or wall).
I'm just starting to learn J, so here goes my first attempt at golf:
103 62 49
46 characters
b =: 8 3 $ 1 11 5 2 6 7 3 13 9 12 7 16 14 3 25 19 18 22 23 13 29 24 4 28
,(,.{&s)I.s~:_1|.s=:0,~>./(1&{*{.<:[:i.{:)"1 b
1 11 3 13 9 0 12 7 16 3 19 18 22 3 23 13 29 0
although I'm sure someone who actually knows the language well could shorten this by quite a bit
An explanation of the code:
NB. list numbers up to right bound of the building ([: i. {:) 14 3 25 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 NB. compare to left bound of building and then multiply by height (1&{ * {. <: [: i. {:) 14 3 25 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 3 3 3 3 3 3 3 3 3 3 NB. apply to each row of b, note how shorter entries are padded with 0s (1&{ * {. <: [: i. {:)"1 b 0 11 11 11 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6 6 6 6 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ... NB. collapse to find max, add a 0 to the end for rotate later, assign to s ] s =: 0 ,~ >./ (1&{ * {. <: [: i. {:)"1 b 0 11 11 13 13 13 13 13 13 0 0 0 7 7 7 7 3 3 3 18 18 18 3 13 13 13 13 13 13 0 NB. rotate s right 1 and then compare to s to find where height changes s ~: _1 |. s 0 1 0 1 0 0 0 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 1 0 0 0 0 0 1 NB. find indices of all differences I. s ~: _1 |. s 1 3 9 12 16 19 22 23 29 NB. pair each index with the height of the building there (,. {&s) I. s ~: _1 |. s 1 11 3 13 9 0 ... NB. and finally flatten the list , (,. {&s) I. s ~: _1 |. s 1 11 3 13 9 0 12 7 16 3 19 18 22 3 23 13 29 0
Python, 89 characters, also using Triptych's 5001 cheat:
B=[[1,11,5],[2,6,7],[3,13,9],[12,7,16],[14,3,25],[19,18,22],[23,13,29],[24,4,28]]
x=o=0
while x<5001:
n=max([H for L,H,R in B if L<=x<R]+[0])
if n-o:print x,n,
o=n;x+=1
Replacing 5001
by max(map(max,B))+1
to allow (almost) arbitrarily large cities leaves 102 characters.
Revision History:
Python: 115 characters
Like the OP, I'm not including the declaration of the data, but I am counting whitespace.
D = [(1,11,5), (2,6,7), (3,13,9), (12,7,16),
(14,3,25), (19,18,22), (23,13,29), (24,4,28)]
P=[max([0]+[h for s,h,e in D if s<=x<e])for x in range(5001)]
for i,x in enumerate(P[1:]):
if x!=P[i]:print i+1,x,
Note that I am using the link provided by the OP as the exact definition of the problem. For instance, I cheat a bit by assuming there is not building coordinate over 5000, and that all coordinates are positive integers. The original post is not tightly constrained enough for this to be fun, in my opinion.
edit: thanks to John Pirie for the tip about collapsing the list construction into the printing for loop. How'd I miss that?!
edit: I changed range(1+max(zip(*D)[2]))
to range(5001)
after deciding the use the exact definition given in the original problem. The first version would handle buildings of arbitrary positive integers (assuming it all fit into memory).
edit: Realized I was overcomplicating things. Check my revisions.
BTW - I have a hunch there's a much more elegant, and possibly shorter, way to do this. Somebody beat me!
A 176 byte WinXP .COM executable:
vQoAgMYQjsKO2jPAM/+5AIDzq7QLzSE8/751AXQDvoQB6DkAi/noNACL2egvACn5A/87HXYCiR2D xwLi9eviM8mZ9/VSQQvAdfeI+rQCzSG3LFqAwjC0As0h4vbD/9Y8CnP6D7bI/9Y8CnPwtACR9+UD yOvxtAvNITz/dRO0CM0hLDDDtAHNITwadfW+kAHDM/Yz/7cgrTn4dA+L+I1E/tHo6Jr/i8folf8L 9nXozSA=
Base64 encoded, I used this site to encode it. Decode to a .com file. The program reads stdin until an EOF, which is a Ctrl-Z when reading from the console, and then outputs the result to stdout.
EDIT: The source code:
mov bp,10
add dh,10h
mov es,dx
mov ds,dx
xor ax,ax
xor di,di
mov cx,8000h
rep stosw
mov ah,0bh
int 21h
cmp al,255
mov si,offset l9
je l1
mov si,offset l11
l1:
call l7
mov di,cx
call l7
mov bx,cx
call l7
sub cx,di
add di,di
l2:
cmp bx,[di]
jbe l3
mov [di],bx
l3:
add di,2
loop l2
jmp l1
l4:
xor cx,cx
l5:
cwd
div bp
push dx
inc cx
or ax,ax
jnz l5
mov dl,bh
mov ah,2
int 21h
mov bh,44
l6:
pop dx
add dl,48
mov ah,2
int 21h
loop l6
ret
l7:
call si
cmp al,10
jae l7
db 0fh, 0b6h, 0c8h
l8:
call si
cmp al,10
jae ret
mov ah,0
xchg cx,ax
mul bp
add cx,ax
jmp l8
l9:
mov ah,0bh
int 21h
cmp al,255
jne l12
mov ah,8
int 21h
l10:
sub al,48
ret
l11:
mov ah,1
int 21h
cmp al,26
jne l10
mov si,offset l12
ret
l12:
xor si,si
xor di,di
mov bh,32
l13:
lodsw
cmp ax,di
je l14
mov di,ax
lea ax,[si-2]
shr ax,1
call l4
mov ax,di
call l4
l14:
or si,si
jne l13
int 20h
Compiled, as usual for me, using A86.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With