Mach mich zum Fenstermanager!

14

Ich hasse Code Bloat!

Deshalb habe ich mich entschlossen, mein Windows 7-System durch eine Golfversion zu ersetzen. Ich weiß jedoch, dass es nicht einfach ist, also lassen Sie uns zuerst einen Prototyp erstellen. Es wird eine Liste von Fenstern vom Benutzer abgerufen und diese in einer pseudografischen Anzeige auf der Standardausgabe angezeigt.

Zum Beispiel: Benutzereingabe:

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

Der Code Golf® Window Manager ™ gibt Folgendes aus:

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

Eingang:

  • Entnommen aus der Standardeingabe (oder, falls Ihr System nicht über stdineine Methode verfügt, die mehrere Eingabezeilen bereitstellen kann)
  • Jede Zeile enthält 4 Zahlen, die durch Komma - Koordinaten eines Fensters getrennt sind
  • Die ersten beiden Zahlen: linke obere Ecke; Die letzten beiden Zahlen: untere rechte Ecke
  • Mit x,yNotation

Ausgabe:

  • Schreiben Sie es in die Standardausgabe (oder, falls Ihr System nicht über stdoutetwas verfügt , das monospaced Text anzeigt).
  • Verwenden Sie zum Zeichnen von Fenstergrenzen einzelne Box-Drawing-Zeichen aus Codepage 437
  • Windows, das später in der Eingabe angegeben wird, verdeckt die zuvor angegebenen
  • Füllen Sie die Fenster mit dem Doppelpunkt: :
  • Führende und nachfolgende Leerzeichen sind in Ordnung, sofern sie die Ausrichtung der Fenster nicht beeinträchtigen

Anmerkungen:

  • Maximale Auflösung, die ich unterstützen möchte: 76 (horizontal) mal 57 (vertikal)
  • Keine Notwendigkeit, schlechte Eingaben zu unterstützen
  • Maximale Anzahl von Fenstern: 255 (wenn Sie ein Limit benötigen)
  • Meine Windows 7- cmdShell zeigt standardmäßig Codepage mit 437 Zeichen an. Wenn jemand eine Möglichkeit hat, dies unter Linux zu tun (mit xtermoder was auch immer), beschreiben Sie dies bitte hier

Zu Referenzzwecken lauten die Zeichencodes:

┌da   ─c4   ┬c2   ┐bf

│b3   :3a   │b3   │b3

├c3   ─c4   ┼c5   ┤b4

└c0   ─c4   ┴c1   ┘d9

Insgesamt: 12 verschiedene Charaktere.

anatolyg
quelle
Beachten Sie, dass Sie auf dieser Seite hübsche Fenster anzeigen können, wenn Sie den folgenden Code in die Adressleiste des Browsers einfügen:javascript:$('pre').css('line-height','1em')
Michael M.
Ich habe die korrekte Anzeige im Gnome-Terminal erhalten, indem ich den Anweisungen auf stackoverflow.com/questions/5509829/…
brm

Antworten:

3

Python, 397 Zeichen

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

Wechseln Sie C="...zu C=u"...und es wird stattdessen in Unicode gedruckt! Es kann schwierig sein, die Datei ordnungsgemäß zu speichern, da die Codepage 437 nicht mit einem Escapezeichen versehen ist (die erste Kommentarzeile für die Codierung ist erforderlich).

Der Ansatz besteht darin, eine Karte inkrementell mit bitweisen Operatoren zu erstellen. Weniger Golf Version mit Kommentaren:

#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
quelle
6

JavaScript ES6 (FF ≥ 31.0), 404 Zeichen

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'))}

Ohne 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'); gibt das Beispiel des OP korrekt aus.

Die Kanten von Fenstern werden mit bitweisen Operatoren erstellt (Up = 8, Bottom = 4, Left = 2, Right = 1).

Michael M.
quelle
Nicht ausführlich getestet, aber mit String-Literal anstelle von Array in 548 Zeichen gut zu funktionieren. (Nur in Firefox getestet.)
Manatwork
Sie können eine Reihe von Zeichen speichern, indem Sie ECMAScript 6 verwenden: function w(s){...}wird w=(s)=>{...}(und dies gilt auch für alle anderen Funktionsliterale). Und die Zeichensuchtabelle kann wahrscheinlich durch eine Zeichenfolge mit denselben Zeichen ersetzt werden.
Martin Ender
Später heute, nach der Veröffentlichung von Firefox 31.0, können Sie Array.fill()mit "Desktop" initialisieren.
Manatwork
@manatwork, ich habe es mit FF Aurora versucht [].fill([].fill(0,0,76),0,57), schade, dass es nicht funktioniert. Kann ich kürzer schreiben als new Array(57).fill(new Array(76).fill(0))?
Michael M.
Versuchen Sie, die überspringen newOperatoren: Array(57).fill(Array(76).fill(0)).
Manatwork
0

Python, 672 Zeichen

Die weniger lesbare Version:

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

Ausgehend von der folgenden Version:

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
quelle