Jadikan aku manajer jendela!

14

Saya benci kode mengasapi!

Jadi saya memutuskan untuk mengganti sistem Windows 7 saya dengan versi golf. Namun, saya tahu itu tidak mudah, jadi mari kita membangun prototipe terlebih dahulu. Ini akan mengambil daftar windows dari pengguna dan menunjukkannya menggunakan tampilan pseudo-grafis pada output standar.

Misalnya: input pengguna:

0,0,15,10
15,10,20,15
10,13,15,15
9,1,16,3
17,5,20,7
11,2,17,4
15,4,19,6
13,3,18,5

Keluaran Code Golf® Window Manager ™:

┌──────────────┐
│ :::::::: ┌─────┴┐
│ :::::::: │: ┌────┴┐
│ :::::::: └─┤: ┌───┴┐
│ :::::::::: └─┤ :::: ├┐
│ :::::::::::: └─┬──┘├┐
│ :::::::::::::: ├─┬─┘│
│ :::::::::::::: │ └──┘
│ :::::::::::::: │
│ :::::::::::::: │
└──────────────────
               │ :::: │
               │ :::: │
          ┌────┤ :::: │
          │ :::: │ :::: │
          └────┴────┘

Memasukkan:

  • Diambil dari input standar (atau, jika sistem Anda tidak memiliki stdin, metode apa pun yang dapat memberikan beberapa jalur input)
  • Setiap baris berisi 4 angka, dibatasi oleh koma - koordinat jendela
  • Dua angka pertama: sudut kiri atas; dua angka terakhir: sudut kanan bawah
  • Menggunakan x,ynotasi

Keluaran:

  • Tulis ke output standar (atau, jika sistem Anda tidak memiliki stdout, apa pun yang menampilkan teks monospace)
  • Gunakan karakter menggambar kotak tunggal dari Kode 437 untuk menggambar batas jendela
  • Windows yang ditentukan kemudian dalam input mengaburkan yang ditentukan sebelumnya
  • Isi jendela dengan karakter titik dua: :
  • Ruang depan dan belakang tidak apa-apa, asalkan tidak merusak perataan jendela

Catatan:

  • Resolusi maksimum yang ingin saya dukung: 76 (horizontal) oleh 57 (vertikal)
  • Tidak perlu mendukung input yang buruk
  • Jumlah jendela maksimum: 255 (jika Anda membutuhkan batas)
  • cmdShell Windows 7 saya menampilkan codepage 437 karakter secara default; jika ada yang punya cara untuk melakukannya di linux (menggunakan xtermatau apa pun), tolong jelaskan di sini

Untuk referensi, kode karakter adalah:

┌da   ─c4   ┬c2   ┐bf

│b3   :3a   │b3   │b3

├c3   ─c4   ┼c5   ┤b4

└c0   ─c4   ┴c1   ┘d9

Total: 12 karakter berbeda.

anatolyg
sumber
Perhatikan bahwa Anda dapat menampilkan jendela cantik di halaman ini jika Anda menempelkan kode berikut di bilah alamat browser:javascript:$('pre').css('line-height','1em')
Michael M.
Saya mendapatkan tampilan yang benar di gnome-terminal dengan mengikuti instruksi pada stackoverflow.com/questions/5509829/…
brm

Jawaban:

3

Python, 397 karakter

#coding:437
import os
J=range
M=[[0]*76 for _ in J(57)]
for A,C,B,D in[map(int,q.split(','))for q in os.read(0,9999).split('\n')]:
 for x in J(A+1,B):
    for y in J(C+1,D):M[C][A]|=5;M[C][B]|=6;M[D][A]|=9;M[D][B]|=10;M[C][x]|=3;M[D][x]|=3;M[y][A]|=12;M[y][B]|=12;M[y][x]=16;M[y][x-1]&=~1;M[y][x+1]&=~2;M[y-1][x]&=~4;M[y+1][x]&=~8
C=" rl─d┌┐┬u└┘┴│├┤┼:"
for l in M:print''.join((C+C[1:])[m]for m in l)

Ubah C="...ke C=u"...dan itu akan dicetak dalam unicode saja! Mungkin sulit untuk mendapatkan file untuk disimpan dengan benar karena halaman kode 437 karakter tidak lolos (baris komentar 'coding' pertama diperlukan).

Pendekatannya adalah membangun peta secara bertahap menggunakan operator bit-wise. Versi yang kurang golf dengan komentar:

#coding:437
import os
J=range
# set up the field
# Each element is a bitfield. Flags are:
# 16 - inside a window?
# 8  - up
# 4  - down
# 2  - left
# 1  - right
M=[[0]*76 for _ in J(57)]
# for each window...
for A,C,B,D in[map(int,q.split(','))for q in os.read(0,9999).split('\n')]:
    # add the directions for the corners
    M[C][A]|=5;M[C][B]|=6;M[D][A]|=9;M[D][B]|=10
    # add the top and bottom edges
    for y in J(C+1,D):M[y][A]|=12;M[y][B]|=12
    # add the left and right edges
    for x in J(A+1,B):M[C][x]|=3;M[D][x]|=3 
    # deal with the middle
    for x in J(A+1,B):
       for y in J(C+1,D):
           # Clear the current spot by setting to inside a window
           M[y][x]=16
           # Remove the right direction from the left spot, top from the bottom, etc
           M[y][x-1]&=~1;M[y][x+1]&=~2;M[y-1][x]&=~4;M[y+1][x]&=~8
 # print it out
 C=u" rl─d┌┐┬u└┘┴│├┤┼:"
 for l in M:print''.join((C+C[1:])[m]for m in l)
Claudiu
sumber
6

JavaScript ES6 (FF ≥ 31.0), 404 karakter

w=s=>{a=[];for(i=0;i<57;)a[i++]=Array(76).fill(0);s.split('\n').map(e=>{r=e.split(',');a[x=r[1]][w=r[0]]|=5;a[x][y=r[2]]|=6;a[z=r[3]][w]|=9;a[z][y]|=10;for(i=x;++i<z;)a[i][w]|=12,a[i][w]&=14,a[i][y]|=12,a[i][y]&=13;for(i=w;++i<y;)a[x][i]|=3,a[x][i]&=11,a[z][i]|=3,a[z][i]&=7;for(i=x;++i<z;)for(j=w;++j<y;)a[i][j]=16});console.log(a.map(e=>e.map(t=>t==16?':':' xx─x┌┐┬x└┘┴│├┤┼'[t&15]).join('')).join('\n'))}

Tanpa ES6:

function w(s){a=[];for(i=0;i<57;i++){a[i]=[];for(j=0;j<76;j++)a[i][j]=0}s.split('\n').forEach(function(e){r=e.split(',');a[r[1]][r[0]]|=5;a[r[1]][r[2]]|=6;a[r[3]][r[0]]|=9;a[r[3]][r[2]]|=10;for(i=r[1];++i<r[3];)a[i][r[0]]|=12,a[i][r[0]]&=14,a[i][r[2]]|=12,a[i][r[2]]&=13;for(i=r[0];++i<r[2];)a[r[1]][i]|=3,a[r[1]][i]&=11,a[r[3]][i]|=3,a[r[3]][i]&=7;for(i=r[1];++i<r[3];)for(j=r[0];++j<r[2];)a[i][j]=16});console.log(a.map(function(e){return e.map(function(t){return t==16?':':' xx─x┌┐┬x└┘┴│├┤┼'[t&15]}).join('')}).join('\n'))}

w('0,0,15,10\n15,10,20,15\n10,13,15,15\n9,1,16,3\n17,5,20,7\n11,2,17,4\n15,4,19,6\n13,3,18,5'); menampilkan dengan benar contoh OP.

Tepi jendela dibuat menggunakan operator bitwise (Atas = 8, Bawah = 4, Kiri = 2, Kanan = 1).

Michael M.
sumber
Tidak diuji secara mendalam, tetapi tampaknya berfungsi baik dengan string literal, bukan array, dalam 548 karakter. (Diuji hanya di Firefox.)
manatwork
Anda dapat menyimpan banyak karakter dengan menggunakan ECMAScript 6: function w(s){...}menjadi w=(s)=>{...}(dan seperti bijak untuk semua fungsi literal lainnya). Dan tabel pencarian karakter mungkin bisa diganti dengan string dengan karakter yang sama.
Martin Ender
Hari ini, setelah Firefox 31.0 akan dirilis, Anda akan dapat menggunakannya Array.fill()untuk menginisialisasi ke "desktop".
manatwork
@Manatwork, saya mencoba dengan FF Aurora [].fill([].fill(0,0,76),0,57), sayang sekali tidak berhasil. Bisakah saya menulis lebih pendek dari new Array(57).fill(new Array(76).fill(0))?
Michael M.
Cobalah untuk melewatkan newoperator: Array(57).fill(Array(76).fill(0)).
manatwork
0

Python, 672 karakter

Versi yang kurang mudah dibaca:

import sys
r=range
M=[0,0,0,191,0,196,218,194,0,217,179,180,192,193,195,197]
Z=[map(int,l.split(",")) for l in sys.stdin.readlines()]
S=[[[0]*5 for x in r(77) ] for y in r(58)]
for i in r(len(Z)):
 A,C,B,D=Z[i]
 for a,b,c in [(C,A,2),(C,A,3),(D,A,1),(D,A,2),(C,B,3),(C,B,4),(D,B,1),(D,B,4)]:S[a][b][c]=1
 for x in r(A+1,B):
  for a,b in [(C,2),(C,3),(C,4),(D,1),(D,2),(D,4)]:S[a][x][b]=(b+1)&1
 for y in r(C+1,D):
  for a,b in [(A,1),(A,2),(A,3),(B,1),(B,3),(B,4)]:S[y][a][b]=b&1
 for x in r(A+1,B):
  for y in r(C+1,D):S[y][x]=[i+1]+[0]*4
O=sys.stdout.write
for l in S:
 for k in l:
  c=' ';x=M[k[1]*8|k[2]*4|k[3]*2|k[4]]
  if k[0]:c=':'
  if x:c=chr(x) 
  O(c)
 O('\n')

Dimulai dari versi di bawah ini:

import sys

coords = [ tuple(map(int,l.strip().split(","))) for l in sys.stdin.readlines() ]

screen = [ [ [-1, [False,False,False,False]] for x in range(0, 77) ] for y in range(0, 58) ]

def mergeBorders(screen, w):
    x0,y0,x1,y1 = w
    screen[y0][x0][1][1] = True
    screen[y0][x0][1][2] = True
    screen[y1][x0][1][0] = True
    screen[y1][x0][1][1] = True
    screen[y0][x1][1][2] = True
    screen[y0][x1][1][3] = True
    screen[y1][x1][1][0] = True
    screen[y1][x1][1][3] = True

    for x in range(x0+1,x1):
        screen[y0][x][1][1] = True
        screen[y0][x][1][2] = False
        screen[y0][x][1][3] = True
        screen[y1][x][1][0] = False
        screen[y1][x][1][1] = True
        screen[y1][x][1][3] = True

    for y in range(y0+1,y1):
        screen[y][x0][1][0] = True
        screen[y][x0][1][1] = False
        screen[y][x0][1][2] = True
        screen[y][x1][1][0] = True
        screen[y][x1][1][2] = True
        screen[y][x1][1][3] = False

def paintInside(screen, w, wId):
    x0,y0,x1,y1 = w
    for x in range(x0+1,x1):
        for y in range(y0+1,y1):
            screen[y][x][0] = wId 
            screen[y][x][1] = [False, False, False, False]

for wId in range(len(coords)):
    w = coords[wId]
    mergeBorders(screen, w)
    paintInside(screen, w, wId)

borderMap = { (False, True, True, False): 0xda,
              (False, True, False, True): 0xc4,
              (False, True, True, True):  0xc2,
              (False, False, True, True): 0xbf,
              (True, False, True, False): 0xb3,
              (True, True, True, False):  0xc3,
              (True, True, True, True):   0xc5,
              (True, False, True, True):  0xb4,
              (True, True, False, False): 0xc0,
              (True, True, False, True):  0xc1,
              (True, False, False, True): 0xd9 }

def borderChar(c):
    return chr(borderMap[(c[0],c[1],c[2],c[3])])


for screenLine in screen:
    for contents in screenLine:
        c = ' '
        if True in contents[1]:
            c = borderChar(contents[1])
        elif contents[0] >= 0:
            c = ':'
        sys.stdout.write(c)
    sys.stdout.write('\n')
brm
sumber