Schnell, günstig und gut - wählen Sie zwei


43

Als Programmierer kennen wir alle das Sprichwort: "Sie können es schnell und gut haben, aber es wird nicht billig sein, Sie können es billig und gut haben, aber es wird nicht schnell sein, oder Sie können es schnell und billig haben , aber es wird nicht gut sein. "

Für diese Herausforderung implementieren Sie ein imaginäres Konfigurationstool für Ihre benutzerdefinierten Programmierdienste. Sie sollten drei Kontrollkästchen mit der Überschrift "SELECT ANY TWO" rendern:

SELECT ANY TWO  
☐ FAST  
☐ CHEAP  
☐ GOOD

Sobald zwei Elemente ausgewählt wurden, muss das dritte Element deaktiviert werden. Wenn Sie eines der beiden ausgewählten Elemente abwählen, müssen alle Optionen erneut aktiviert werden. Anders ausgedrückt, wenn null oder ein Element ausgewählt ist, sind alle weiterhin aktiviert. Wenn jedoch zwei Elemente ausgewählt sind, muss das dritte deaktiviert werden.

Keine speziellen Kontrollen erlaubt. Die Kontrollkästchen sollten das Standardkontrollkästchen in der Sprache Ihrer Wahl sein. Verwenden Sie beispielsweise kein "CheckBoxList" -Steuerelement, wenn Ihre Sprache eines hat. Ich stelle mir vor, dass die meisten Einträge HTML / jQuery sein werden, aber das ist keine Regel. Dies ist Code Golf, der nach dem kürzesten Eintrag sucht.

GEWINNER BISHER

Ich werde es in Kategorien aufteilen. Es gibt einige klare Gewinner:

jQuery: nderscore, Mr. Tenacity Under 100b, wenn Sie Text "Ressourcen" ausschließen. Lobende Erwähnung sollte auch Matt für die Einführung der jQuery-Konzepte zuteil werden, von denen sich viele inspirieren ließen.

Dyalog APL: Marinus , auch bekannt als Mr. Unicode Wie schreibt man all diese Dinge? Ich kann verstehen, warum Sie kurze Programme schreiben möchten.

PHP: SuperScript Ich glaube, dies ist der kürzeste Eintrag, der die dritte Option deaktiviert, anstatt sie abzuwählen. Dabei wird die strengste Interpretation der Regeln befolgt.


Kann ich es einfach so machen, dass nur zwei gleichzeitig ausgewählt werden können? Wenn Sie also den dritten auswählen, wird einer der anderen abgewählt? Oder fügen Sie eine Schaltfläche zum Akzeptieren hinzu, die ausgegraut wird, wenn 3 Optionen ausgewählt sind?
Justin

7
@Quincunx - Da es keine Heuristik (außerhalb des Gedankenlesens) gibt, die entscheiden könnte, welche abgewählt werden soll, würde dies den Benutzer verwirren ... also muss ich nein sagen, da wir nicht den ersten Eindruck von haben wollen unsere kundenspezifischen Softwaredienste sind schlecht. ;)
Bruce Pierson

Diese Frage hat mich am tkinter von Python 3 interessiert, also versuche ich das jetzt zu lernen. IMO ist der beste Weg, um GUI zu lernen, durch Ausprobieren. Ich habe es versucht: ideone.com/YHLZIQ . Ergebnis: schnelles Öffnen neuer GUIs. Ich musste den Task-Manager öffnen, um sie zu schließen. :-). Bild (die Zahl stieg bald auf 340: i.stack.imgur.com/c9wQi.png )
Justin

Der Bonuswettbewerb sollte eine andere Frage sein, da es kein objektives primäres Gewinnkriterium oder eine Beschreibung des "Bonus" gibt. Es hieß, Code sollte "... elegant und flexibel sein ..." und "... prägnant und klar ...", was gegen Code-Golf ist . VTC als unklar, was Sie fragen. Bitte ändern Sie die Fragen nicht lange, nachdem Sie sie gestellt haben.
user80551

1
@ BrucePierson Eigentlich gibt es. Wir könnten das älteste ausgewählte Kontrollkästchen deaktivieren. Der Code dafür wäre jedoch viel mehr als der Code, den Sie benötigen.
Justin

Antworten:


23

Javascript ( ES5 ) mit jQuery - 143 ( Demo )

Ich habe Matts Lösung modifiziert und es so weit wie möglich ausprobiert:

$("*").html(["SELECT ANY TWO","FAST","GOOD","CHEAP"].join("<input type=checkbox onclick=(a=$('input:not(:checked)')).prop('disabled',!a[1])>"))

Javascript ( ES5 ) ohne jQuery - 185 175 ( Demo )

Die Verwendung von jQuery ist eine Art Betrug. Hier ist eine Lösung ohne jQuery:

(d=document).write(["SELECT ANY TWO","FAST","GOOD","CHEAP"].join("<input type=checkbox onclick='for(b in a=d.querySelectorAll(\"input:not(:checked)\"))a[b].disabled=!a[1]'>"))

Wenn wir den Benutzer daran hindern dürfen, das dritte Kontrollkästchen zu aktivieren, anstatt das Feld tatsächlich zu deaktivieren, können wir es noch kürzer machen:

Mit jQuery - 126 123 ( Demo )

$("*").html(["SELECT ANY TWO","FAST","GOOD","CHEAP"].join("<input type=checkbox onclick=this.checked*=!$(':checked')[2]>"))

Ohne jQuery - 150 147 ( Demo )

(d=document).write(["SELECT ANY TWO","FAST","GOOD","CHEAP"].join("<input type=checkbox onclick=this.checked*=!d.querySelectorAll(':checked')[2]>"))

Cool. Verwenden .joinist ein guter Trick!
Robbie Wxyz

1
"SELECT ANY TWO0FAST0GOOD0CHEAP".replace(/0/g,ist eine andere Möglichkeit, dies zu tun, was zu derselben Länge führt.
nderscore

nur wählerisch sein, sollte die jquery version prop verwenden, nicht attr
Einacio

@Einacio dein Wunsch ist mein Befehl!
nderscore

5
@Einacio Aber bei Codegolf geht es um schlechteste Praktiken! : P
nderscore

29

JavaScript - 184 169 (mit jQuery)

b="input",a="<input type=checkbox>",c=":checked";$("body").html("SELECT ANY TWO"+a+"FAST"+a+"GOOD"+a+"CHEAP").click(function(){$(b).not(c).attr("disabled",!!$(b+c)[1])})

http://jsfiddle.net/L33JK/16/

BEARBEITEN: Verbessert mit Hilfe von @Daniel Lisik - https://codegolf.stackexchange.com/a/26805/16278


5
Nett! Nicht genug Repräsentanten, um zu stimmen ... aber du bist angeheuert!
Bruce Pierson

2
Je mehr ich mir das anschaue, desto mehr lerne ich. Die Übersichtlichkeit der Variablenzuweisung in einem jQuery-Selektor. Sehr cool. Könnten Sie auch erklären, was der "Doppelknall" (!!) tut?
Bruce Pierson

1
Der Einfachknall erzwingt einen Booleschen Wert und das Doppelte wird dies offensichtlich umkehren. undefinedzwingt zu wahr. Das und die Variablenbelegung sind wahrscheinlich die einzigen kleinen Tricks, die wirklich angewendet werden.
Matt

Ihr Code kann auf 179 Zeichen wie a="<input type='checkbox'>",b="input",c=":checked",$("body").html("SELECT ANY TWO"+a+"FAST"+a+"GOOD"+a+"CHEAP").change(function(){$(b+":not("+c+")").attr("disabled",!!$(b+c)[1])}) folgt
Anzeigename-fehlt


12

Dyalog APL (unter Windows) (169)

Dies ist eine statische Funktion, um zu testen, ob Sie APL nicht kennen. Geben Sie diese ein )ed Cund fügen Sie sie in das Bearbeitungsfenster ein C. Führen Sie sie dann aus .

C
'R'⎕WC'Form' 'Select any two',2/⊂S←2/20
1 21 41{('R.',⊃⍵)⎕WC'Button'⍵(⍺1)S'Check'('Event' 'Select' 'F')}¨'Fast' 'Cheap' 'Good'
B←R.(F C G)
F←{B.Active←X∨2≠+/X←B.State}

Neuere Teile von APL haben lange Schlüsselwörter. Trotzdem habe ich HTML geschlagen.

Erläuterung:

  • 'R'⎕WC'Form' 'Select any two',2/⊂S←2/20: ein Formular Rmit Titel erstellen Wählen Sie zwei beliebige und Größe und Position 20 20. Läden auch 20 20in S.
  • 1 21 41{... }¨'Fast' 'Cheap' 'Good': für jedes dieser Datenpaare (Name und y-Koordinate, die einzigen Variablen, die sich zwischen den Kontrollkästchen unterscheiden):
    • ('R.',⊃⍵)⎕WC'Button': erstelle eine Schaltfläche Rmit dem ersten Buchstaben des Namens,
    • ⍵(⍺1)S'Check': mit dem richtigen Argument als Titel, (left arg, 1)als Position, Wiederverwendung Sals Größe und Checkals Stil,
    • ('Event' 'Select' 'F'), der Fbeim Anklicken die Funktion aufruft .
  • B←R.(F C G): Verwenden Sie Bals Abkürzung für die drei von uns erstellten Kontrollkästchen
  • F←{... }: Definiere die Rückruffunktion als:
    • X←B.State: Status für jedes Kontrollkästchen abrufen und in speichern X,
    • X∨2≠+/X: Summe X, wenn dies nicht gleich zwei ist, müssen alle Kontrollkästchen aktiviert sein, wenn dies gleich zwei ist, müssen nur aktivierte Kontrollkästchen aktiviert sein
    • B.Active←: Aktivieren oder deaktivieren Sie die Kontrollkästchen

Ergebnis:

Bildschirmfoto


Tolle Erklärung, danke!
Bruce Pierson

11

Python 3 2, 454 434 ... 393 392 Bytes

Ich dachte, Python muss kürzer als Java sein. Hier ist der "Beweis" ( EDIT: jetzt ist es wirklich kürzer ):

from Tkinter import*
t=Tk()
r=str.replace
exec r(r(r(r('a@b@c@l=Label(t,text="SELECT ANY TWO");A`FAST|a);B`CHEAP|b);C`GOOD|c);l^A^B^C^','`','=Checkbutton(t,text="'),'|','",v='),'^','.pack();'),'@','=IntVar();')
def f(p,b,B,s):
 for i in 0,1,2:
    y=b[i].get()
    if p[i]-y:
     p[i]=y;s-=1
     if p[i]:s>0and B[i].toggle();s+=2
 t.after(1,f,p,b,B,s)
t.after(1,f,[0]*3,[a,b,c],[A,B,C],0)
t.mainloop()

Für diejenigen unter Ihnen, die neugierig sind, was der execAusdruck tatsächlich ausführt, führt er dies aus (dies ist das, was die Ersetzungen für den String tun. Zeilenumbrüche zur besseren Lesbarkeit hinzugefügt):

a=IntVar();
b=IntVar();
c=IntVar();
l=Label(t,text="SELECT ANY TWO");
A=Checkbutton(t,text="FAST",v=a);
B=Checkbutton(t,text="CHEAP",v=b);
C=Checkbutton(t,text="GOOD",v=c);
l.pack();
A.pack();
B.pack();
C.pack();

Dies verwendet dieselbe Logik wie meine Java-Antwort: Deaktivieren Sie das Kontrollkästchen, wenn dadurch mehr als 2 Kontrollkästchen aktiviert werden. Unf Zum Glück Leider verbrachte ich mehr weniger mehr Bytes dies zu tun.

Bildbeschreibung hier eingeben

EDITS:

  1. Massive Anpassung des zu verwendenden Codes exec, wodurch satte 1 Byte eingespart werden!
  2. wechselte zu Python 2, um zwei Bytes aus dem exec(Entfernen von Klammern) zu quetschen .
  3. mehr Golfen. Umfasst range(3)das 0,1,2Ändern der Einrückung in und das Ändern der Einrückung, um eine Ebene mit Registerkarten zu erhalten. Unsicher, ob \t\tdas funktionieren würde \t__( _ist das Leerzeichen). Endlich die längste Java-Antwort, die ich je erhalten habe.
  4. benutzter Ersatztrick
  5. benutzte Bakirus Vorschlag und spielte noch mehr Golf. Eigentlich kürzer als Java! Aber jetzt hat die Java-Antwort mehr Golf gespielt, und das ist wieder länger. :-(
  6. benutzter verbesserter Ersatztrick .
  7. änderte a !=für a -.

Interessanter Ansatz. +1
cjfaure

Ich kann mit dem Turbo-Modus auf meiner Tastatur schummeln. Zuerst markiere ich zwei Kästchen. Zweitens benutze ich die Tabulatortaste, um die dritte hervorzuheben. Jetzt halte ich die Leertaste einige Sekunden lang im Turbomodus. Manchmal aktiviert dies das dritte Kästchen!
Kernigh

@kernigh Ich glaube, das liegt daran, dass mein Code an den Punkt gelangt, an dem er weiß, dass die Box umgeschaltet wurde, aber der Code nicht den Punkt erreicht hat, an dem er die Box umgeschaltet hat. Wenn Sie also das Kontrollkästchen in dieser Zeit ein- oder ausschalten, wird mein Code ein Häkchen darauf setzen.
Justin

1
Sie können die eingekerbten Block vermeiden , beginnend mit if p[i]Verwendung eines andanstelle eines if: if p[i]:s>1 and B[i].toggle();s+=1.
Bakuriu

@kernigh Ich habe mich geirrt; Ersetzen B[i].toggle()durch B[i].deselect()ändert nichts. Ich habe keine Ahnung warum das so ist. Vielleicht ist es ein Fehler mittkinter
Justin

10

Rebol, 219 197

load-gui p: func[p][p/state/value]x: func[v][if all[p a p b p c][set-face v false]] view [title"SELECT ANY TWO"a: check"FAST"on-action[x a]b: check"CHEAP"on-action[x b]c: check"GOOD"on-action[x c]]

Ungolfed:

load-gui    ;; this is temporary while r3-gui is in beta

p: func [p] [p/state/value]

x: func [v] [
    if all [p a p b p c] [set-face v false]
]

view [
    title "SELECT ANY TWO"
    a: check "FAST" on-action [x a]
    b: check "CHEAP" on-action [x b]
    c: check "GOOD" on-action [x c]
]

Dies ist der Rebol 3 View-Dialekt (r3-gui). Screendump unter Ubuntu Linux:

Beispiel für die Ansicht von Rebol 3

Update - Dank an Earl & Graham von Rebol SO Chatroom für das Rasieren von 22 Zeichen des Codes - http://chat.stackoverflow.com/transcript/message/16345039#16345039


Es ist eine ungültige Antwort, da die dritte deaktiviert, aber auch markiert ist, dh alle 3 markiert sind. Bitte korrigieren Sie sie.
ST3

2
@ ST3 - Du bist falsch, fürchte ich. Das Kontrollkästchen "GUT" ist nicht aktiviert oder deaktiviert (mein Code schaltet das dritte Kontrollkästchen einfach aus). Auf diese Weise zeigt die Rebol 3-Ansicht ein nicht angehaktes Kästchen (standardmäßig).
Draegtun

1
@ ST3 et al - Hier ist ein Link, der das oben beschriebene Aussehen der Standard-Checkbox zeigt (auf dem ersten Bild sind keine Checkboxen angeklickt, auf dem zweiten nur "GUT") - plus.google.com/u/0/104216037702741908932/posts/Z2EbuQX67aq
draegtun

Nun ... Ich schaue in den von Ihnen hinzugefügten Druckbildschirm und sehe, dass alle drei Kontrollkästchen aktiviert sind. Nur eines kann nicht deaktiviert werden.
ST3

3
@ ST3 - Ein ausgegrautes Kontrollkästchen ist nur ein Rebol 3 View-Weg, um zu zeigen, dass es sich um ein Kontrollkästchen handelt, das aktiviert werden kann. Das Häkchen wird grün, wenn es markiert ist, und grau, wenn es nicht markiert ist. Dies sind die Standardeinstellungen. In der Antwort oben sehen Sie "GUT" als Eingabefokus (blaue Unschärfe), da es "angeklickt" wird, aber grau und nicht grün bleibt (also nicht markiert).
draegtun

10

Java, 421 ... 369 351 Bytes

import java.awt.*;class F extends Checkbox{F(String s){super(s);}public static void main(String[]a){new Frame(){{add(new Panel(){{add(new Label("SELECT ANY TWO"));F[]c={new F("FAST"),new F("CHEAP"),new F("GOOD")};for(F b:c){add(b);b.addItemListener(e->{int x=0;for(F d:c)x+=d.getState()?1:0;if(x>2)((F)e.getSource()).setState(1<0);});}}});}}.show();}}

Java ... weil Java. Schöner aussehender Code:

import java.awt.*;

class F extends Checkbox {
    F(String s) {
        super(s);
    }

    public static void main(String[] a) {
        new Frame() {
            {
                add(new Panel() {
                    {
                        add(new Label("SELECT ANY TWO"));
                        F[] c = {new F("FAST"), new F("CHEAP"), new F("GOOD")};
                        for (F b: c) {
                            add(b);
                            b.addItemListener(e -> {
                                int x = 0;
                                for (F d: c) {
                                    x += d.getState() ? 1 : 0;
                                }
                                if (x > 2) ((F) e.getSource()).setState(1 < 0);
                            });
                        }
                    }
                });
            }
        }.show();
    }
}

Probelauf (verschiedene Größen des Fensters, zuerst beim Start):

Bildbeschreibung hier eingeben
Bildbeschreibung hier eingeben
Bildbeschreibung hier eingeben

Die Kontrollkästchen sind horizontal angeordnet. das ist erlaubt . Es würde viel mehr dauern, um es richtig auszurichten. Außerdem deaktiviere ich das Kontrollkästchen, indem ich es deaktiviere, wenn darauf geklickt wird , und mache es nicht unmöglich, darauf geklickt zu werden.

EDITS:

  1. 3 Bytes gespart, indem die Hauptklasse erweitert wird Checkbox.
  2. erneut lesen Lambda-Ausdrücke erneut und stellen Sie fest, dass der erforderlich ist . Nimm die Python!
  3. umgewandelt a while Schleife in eine foreach-Schleife (danke Lee ); warum habe ich vorher nicht daran gedacht?
  4. Durch Verwendung einer anonymen Klasse und eines Instanzinitalisierers für Frameund wurden 18 Byte gespart Panel.

Keine Einschränkung der Ausrichtung (also könnte Matt seine um 5 Zeichen reduzieren). Requisiten für ein vollständiges laufendes Programm ... aber ich sehe nicht, dass die dritte Option deaktiviert ist.
Bruce Pierson

@BrucePierson Es ist deaktiviert. Es kann nicht angeklickt werden. Wenn es angeklickt wird, passiert nichts.
Justin

2
Ah, ich glaube ich sehe. Sie können den aktivierten Status sofort "deaktivieren", ohne ihn zu deaktivieren? Das wäre akzeptabel.
Bruce Pierson

@ BrucePierson Das stimmt. Um es tatsächlich zu deaktivieren, müsste ich if(x>2)((Checkbox)e.getSource()).setState(1<0);aufif(x>2){Checkbox b=(Checkbox)e.getSource();b.setState(1<0);b.setEnabled(1<0);}
Justin

1
@BrucePierson Wann immer Sie denken, das sieht lustig aus, wenn es um die Verwendung einer Zeichendarstellung einer grafischen Sache geht, suchen Sie nach Unicode. Alternativ können Sie sich für grafische Gestaltungsaufgaben an User Experience SE wenden
Justin

7

C ++ 11 / Qt5.2 - 561 481 433 423 369

Weil warum nicht.

Erschreckenderweise sind wir ab sofort kürzer als Python und das nicht fehlerbehaftete C # und mit Java verbunden!

Dank an EveBird für die Kürzung von 561 auf 481.

Und noch einmal EveBird verkürzt es von 481 auf 433!

Nahm ein paar mit einem Lambda Connect

Bis auf 389 mit C ++ 11-Initialisierern

Und 373 ohne die eigene Klasse

Einige Leerzeichen entfernt - 369

Golf'd:

#include<QtWidgets>
#define C(x,y,z)z.setEnabled(x.isChecked()+y.isChecked()<2);
#define S(x)l.addWidget(&x);
#define X(x)S(x);x.connect(&x,&QCheckBox::clicked,[&](){C(g,f,c)C(g,c,f)C(f,c,g)});
int main(int n,char**v){QApplication a(n,v);QWidget m;QLabel t{"Select any two"};QCheckBox g{"Good"},f{"Fast"},c{"Cheap"};QVBoxLayout l(&m);S(t)X(g)X(f)X(c)m.show();a.exec();}

Art von Un-Golfed:

#include<QtWidgets>

#define C(x,y,z)z.setEnabled(x.isChecked()+y.isChecked()<2);
#define S(x)l.addWidget(&x);
#define X(x)S(x);connect(&x, &QCheckBox::clicked, [&](){C(g,f,c)C(g,c,f)C(f,c,g)});

int main(int n,char**v){ 
    QApplication a(n,v);
    QWidget m;
    QLabel t{"Select any two"};
    QCheckBox g{"Good"},f{"Fast"},c{"Cheap"};
    QVBoxLayout l(&m);
    S(t)X(g)X(f)X(c)m.show();
    a.exec();
}

GFC


1
+1 für das selbstgefällige "Warum nicht" :)
Bruce Pierson

Kann ein bisschen mehr verbessern: ersetzen QWidget mmit QDialog mund m.show();a.exec()mit m.exec().
Toby Speight

6

CoffeeScript - 167154

CoffeeScript-Port der Antwort von @Matt .

b="input";a="<input type=checkbox>";c=":checked";$("body").html("SELECT ANY TWO#{a}FAST#{a}GOOD#{a}CHEAP").click ->$(b).not(c).attr "disabled",!!$(b+c)[1]

Etwas ungolfed:

b = "input"
a = "<input type=checkbox>"
c = ":checked"

$( "body" ).html( "SELECT ANY TWO#{a}FAST#{a}GOOD#{a}CHEAP" ).click ->
    $( b ).not( c ).attr "disabled", !!$( b + c )[1]

JSFiddle .


5

PHP, Javascript, jQuery - 135b

Ich habe die Antwort von @ nderscore bewundert, aber dann habe ich beschlossen, ihn zu kopieren und auszuspielen.

<?echo"SELECT ANY TWO".($m="<input type=checkbox onclick=(a=$('input:not(:checked)')).prop('disabled',!a[1])>")."FAST$m GOOD$m CHEAP"?>

Grundsätzlich habe ich seinen .joinTrick durch eine PHP Hypertext Preprocessing ersetzt.


Wenn Sie bedenken, dass 27 Byte für den Text "resources" im Programm erforderlich sind, kommt dies einem 100b-Programm sehr nahe. Gut gemacht!
Bruce Pierson

1
Ich bin kein großer PHP-Golfer, aber ich habe ein paar Bytes für Sie abgeschnitten: (128)SELECT ANY TWO<?=($m="<input type=checkbox onclick=(a=$('input:not(:checked)')).prop('disabled',!a[1])>").FAST.$m.GOOD.$m.CHEAP;
nderscore

5

Ruby, 219 218 Bytes

Ich verwende die gleichen Tk-Widgets wie die Python 3-Antwort von Quincunx.

Dieses Programm verstößt gegen die Regeln, da es eine Kontrollkästchenliste enthält . (Die Regeln besagten: "Keine Kontrollkästchenliste verwenden.") Ja, es ahandelt sich um ein Array mit 3 TkCheckButton-Objekten, und ich glaube, dass ein Array eine Liste ist. Zu meiner Verteidigung habe ich keine vorhandene Kontrollkästchenliste verwendet, sondern die Standardkontrollkästchen verwendet und eine eigene Liste erstellt.

require'tk'
o=->(c){c.variable.value>?0}
TkLabel.new{text'SELECT ANY TWO'
pack}
a=%w[FAST CHEAP GOOD].map{|t|TkCheckButton.new{text t
command{a.map{|c|c.state a.count(&o)<2||o[c]?:normal: :disabled}}
pack}}
Tk.mainloop

GÜNSTIG und GUT geprüft, aber SCHNELL deaktiviert

Ich habe mit Ruby 2.1.0 und Tk 8.5.15 getestet.

  • o[c]ist ein Prädikat zum Testen, ob die Check-Schaltfläche causgewählt ist. Bei den Standardzeichenfolgen c.variable.valueist '0'oder '1', der Zeichenfolgenvergleich ist also nur wahr, wenn '1'>'0'. BEARBEITEN: Ich habe 1 Byte (219 bis 218) gespart, indem ich zu geändert '0'habe ?0. In Ruby ?0ist eine Zeichenkonstante.
  • a.count(&o) Verwendet das Prädikat, um die ausgewählten Kontrollkästchen zu zählen.
  • Wenn der Benutzer eine Check-Schaltfläche umschaltet, ruft der Befehl eine a.mapSchleife für alle Schaltflächen auf und macht sie zu :normaloder :disabled.

1
Sehr gut. Hier wurde keine Regel verletzt - ich bezog mich auf ein Kontrollkästchen-Listensteuerelement , das möglicherweise Teil des Sprachrahmens ist. Ich glaube, dass alle Antworten bisher auf einer Karte oder einem Selektor basieren. Das ist also absolut legitim.
Bruce Pierson

5

Vielen Dank an Rotem und Johnbot für die Golfhilfe!

C # 343 334

Dieser verwendet den gleichen "Cheat" wie die Java-Antwort von Quincunx - die Kontrollkästchen sind eigentlich nicht deaktiviert. sie erlauben dir einfach nicht, sie zu überprüfen, wenn diese Prüfung 3 ergibt.

using System.Windows.Forms;using System.Linq;class P:Form{static void Main(){P p=new P();p.Text="SELECT ANY TWO";int y=0;var a=new CheckBox[3];foreach(var n in "FAST CHEAP GOOD".Split()){var c=new CheckBox();a[y]=c;c.Top=y++*50;c.Text=n;c.Validating+=(s,e)=>{if(a.Count(b=>b.Checked)>1)e.Cancel=true;};p.Controls.Add(c);}Application.Run(p);}}

Es gibt auch einen kleinen Fehler, bei dem Sie das Fenster nach dem Aktivieren des dritten Kontrollkästchens nicht schließen können, es sei denn, Sie deaktivieren eines, da die Validierung nicht bestanden wird. Aber das ist , also wen interessiert das? ;)

C # 403 397 374

Dies ist eine richtige Option, mit der das dritte Kontrollkästchen deaktiviert wird.

using System.Windows.Forms;using System.Linq;class P:CheckBox{static void Main(){var p=new Form{Text="SELECT ANY TWO"};P[]a=null;a="FAST CHEAP GOOD".Split().Select((x,i)=>{var c=new P{Top=i*50,Text=x};c.Click+=(s,e)=>{a.First(b=>!b.Checked).Enabled=a.Count(b=>b.Checked)>1?1<0:a.All(b=>b.Enabled=0<1);};p.Controls.Add(c);return c;}).ToArray();Application.Run(p);}}

Bildschirmfoto

Ein bisschen ungolfed:

using System.Windows.Forms;
using System.Linq;

class P:Form
{
    static void Main()
    {
        P p = new P();
        p.Text = "SELECT ANY TWO";
        int y = 0;
        var a = new CheckBox[3];
        foreach (var n in "FAST CHEAP GOOD".Split())
        {
            var c = new CheckBox(); a[y] = c; c.Top = y++ * 50; c.Text = n; c.Click += (s, e) =>
            {
                if (a.Count(b => b.Checked) == 2)
                {
                    a.First(b => !b.Checked).Enabled = false;
                }
                else
                {
                    foreach (var b in a) b.Enabled = true;
                }
            };
            p.Controls.Add(c);
        }
        Application.Run(p);
    }
}

1
Konnte nicht if(a.Count(b=>b.Checked)==2)e.Cancel=true;umgeschrieben werden als e.Cancel=a.Count(b=>b.Checked)==2;?
Rotem

@Rotem Ja, das könnte es. Ich bin dumm. Und für den anderen gibt es eine ähnliche Optimierung. Vielen Dank!
Bob

Warten Sie, nein, es gibt keine für die andere. Eh, noch ein paar Zeichen gespart.
Bob

1
Wenn Sie die Vererbung auf CheckBox umstellen, Objektinitialisierer verwenden und Linq ein wenig missbrauchen, können Sie die richtige auf 374 bringen:using System.Windows.Forms;using System.Linq;class P:CheckBox{static void Main(){var p=new Form{Text="SELECT ANY TWO"};P[]a=null;a="FAST CHEAP GOOD".Split().Select((x,i)=>{var c=new P{Top=i*50,Text=x};c.Click+=(s,e)=>{if(a.Count(b=>b.Checked)>1){a.First(b=>!b.Checked).Enabled=1<0;}else a.All(b=>b.Enabled=0<1);};p.Controls.Add(c);return c;}).ToArray();Application.Run(p);}}
Johnbot

1
364 wenn Sie den bedingten Operator anstelle der if-Anweisung verwenden. Ersetzen if(a.Count(b=>b.Checked)>1){a.First(b=>!b.Ch‌​ecked).Enabled=1<0;}else a.All(b=>b.Enabled=0<1);durcha.First(b=>!b.Checked).Enabled=a.Count(b=>b.Checked)>1?1<0:a.All(b=>b.Enabled=0<1);
Johnbot

5

AngularJS - 214

<input type=checkbox ng-model=fast ng-disabled=cheap&&good>FAST</input>
<input type=checkbox ng-model=cheap ng-disabled=fast&&good>CHEAP</input>
<input type=checkbox ng-model=good ng-disabled=fast&&cheap>GOOD</input>

Ich habe das bei JSFiddle ausprobiert, aber ohne Erfolg . Können Sie ein funktionierendes Beispiel liefern?
Squeamish Ossifrage


Sie haben "ng-app" nicht erwähnt. Aktivieren Sie in meinem Beispiel <head>.
user12345

1
Ah, OK :-) Sie können ein bisschen Golf spielen, indem Sie die Anführungszeichen und zusätzlichen Zeilenumbrüche entfernen.
zimperlich ossifrage

4

JavaScript (mit jQuery) - 224 , 222 , 210 , 205 , 178

a="<input type=checkbox>",c=":checked",e="input",f="disabled",d=$("body").html("SELECT ANY TWO"+a+" FAST"+a+"CHEAP"+a+"GOOD").click(function(){$(e).not(c).attr(f,$(e+c).length>1)})

Dank eines Kommentars von brilliant @Matt habe ich den Code um 27 Zeichen reduziert.

JSFiddle


Sparen Sie etwa 25, indem Sie Ihre Bedingung $(e+c).length>1in die Zuweisung als solche verschieben, $(e).not(c).attr(f,$(e+c).length>1)da Sie nur den Booleschen Wert selbst ändern.
Matt

1
Hat es geschafft, mit einer Mischung aus deiner und meiner auf 169 zu kommen. Der !!Zwang und ein bisschen mehr Golf mit dem nicht zugewiesenen Körper zu d. a="<input type=checkbox>",c=":checked",e="input";$("body").html("SELECT ANY TWO"+a+"FAST"+a+"CHEAP"+a+"GOOD").click(function(){$(e).not(c).attr("disabled",!!$(e+c)[1])})
Matt

4

Mathematica

Eine Code-Golf-Version, wie von David vorgeschlagen, 255 Zeichen :

h = Checkbox;
i = Dynamic;
j = Enabled;
t = True;
i[
 If[Total@Boole@{a, b, c} == 2,
  {d, e, f} = {a, b, c},
  {d, e, f} = {t, t, t}
  ];
 Row@{
   "SELECT ANY TWO",
   h[i@a, j -> d], "FAST",
   h[i@b, j -> e], "CHEAP",
   h[i@c, j -> f], "GOOD"
   }
 ]

Sie können einige Zeichen mit speichern h=Checkbox;i=Dynamic;j=Enabled.
DavidC

@DavidCarraher Danke, ich kann mir vorstellen, diese Technik auch in Zukunft für andere Code-Golf-Fragen zu verwenden.

1
Es müssen nicht beide Versionen enthalten sein. Und vergessen Sie nicht, hdie Zeichenanzahl in der Überschrift zu verwenden und anzupassen.
DavidC

4

mIRC-Skript ( 727 719 Byte)

Ich habe diese Sprache bis zu einem betrunkenen Gespräch letzte Nacht vergessen.

alias select_two {
  dialog -m s2 s2
}

dialog s2 {
  title "Select any two:"
  size -1 -1 200 100
  check "Fast",1, 5 10 170 25
  check "Cheap",2, 5 30 170 25
  check "Good",3, 5 50 170 25 
}

on *:dialog:s2:sclick:*: {
  if ($did(s2, $did).state = 1) {
    if ($did = 1) {
      if ($did(s2, 2).state = 1) { did -b s2 3 }
      if ($did(s2, 3).state = 1) { did -b s2 2 }
    }
    if ($did = 2) {
      if ($did(s2, 1).state = 1) { did -b s2 3 }
      if ($did(s2, 3).state = 1) { did -b s2 1 }
    }
    if ($did = 3) {
      if ($did(s2, 1).state = 1) { did -b s2 2 }
      if ($did(s2, 2).state = 1) { did -b s2 1 }
    }
  }
  if ($did(s2, $did).state = 0) {
    did -e s2 1
    did -e s2 2
    did -e s2 3
  }
}

Mehr sollte in dieser Sprache codiert werden! Aber es muss eine Möglichkeit geben, dies zu einem echten Chaos zu machen, damit es so gut wie Perl wird.

Edit: habe festgestellt, dass meine Python-Ismen durchgesickert sind und konnte den Code um 8 Bytes reduzieren!


Haha, ich mag das Intro zu diesem. Es ist ein bisschen wortreich - könnte es das Bier sein, das spricht? = c)
Bruce Pierson

3

C #, 335 333 326 320 308

Basierend auf Bobs Answer verwendet meins weniger Zeichen als sein (335 v 342), aber ich verstehe möglicherweise nicht ganz, wie man das zählt.

using System.Linq;using System.Windows.Forms;class P:Form{static void Main(){new P();}P(){Text="SELECT ANY TWO";var a="FAST CHEAP GOOD".Split().Select(r=>new CheckBox{Text=r,Top=r[0]%9*20}).ToList();a.All(r=>{r.Validating+=(b,c)=>c.Cancel=a.Count(z=>z.Checked)>1;Controls.Add(r);return 1>0;});ShowDialog();}}

Ungolfed

using System.Linq;
using System.Windows.Forms;

class P : Form
{
    static void Main()
    {
        new P();
    }

    P()
    {
        Text = "SELECT ANY TWO";

        var a = "FAST CHEAP GOOD".Split().Select(r => new CheckBox
        {
            Text = r,
            Top = r[0] % 9 * 20
        }).ToList();

        //loops, I dont need no stinking loops
        a.All(r => { r.Validating += (b, c) => c.Cancel = a.Count(z => z.Checked) > 1; Controls.Add(r); return 1 > 0; });
        ShowDialog();
    }
}

Großartige Nutzung von anon-Funktionen und Linq hier, besonders wie das Select.
Bruce Pierson

Sie können ein paar mehr Zeichen speichern , indem das Ersetzen ==2mit einem >1, und das truemit einem 1>0. Sie können auch ein Allanstelle von Whereund verwenden Last. ToListist auch kürzer als ToArray.
Bob

@ Bob Guter Anruf, weiß nicht, wie ich All () verpasst habe, und als Bonus erweist sich mit All, dass Sie es nicht materialisieren müssen, um noch mehr zu sparen
iamkrillin

3

Groovy - 357 221 217 Zeichen

Ich habe die Lösung von Quincunx mit SwingBuilder auf Groovy 2.2.1 portiert (und noch grooviger gemacht):

c=[];new groovy.swing.SwingBuilder().frame(){panel(){label("SELECT ANY TWO");f={if(c.count{it.isSelected()}>2)it.source.setSelected(1<0)};["FAST","CHEAP","GOOD"].each{c<<checkBox(label:it,itemStateChanged:f)}}}.show()

Ungolfed:

c=[]
new groovy.swing.SwingBuilder().frame() {
    panel() {
        label("SELECT ANY TWO")
        f = { if (c.count{it.isSelected()} > 2) it.source.setSelected(1<0) }
        ["FAST","CHEAP","GOOD"].each { c << checkBox(label: it, itemStateChanged: f) }
    }
}.show()

3

QML - 369 315 254 251 248 Bytes

Hier ist die QML-Version (QtQuick 2.0), die nur den Inhalt der .qml-Datei enthält. Für diesen Code ist mindestens Qt 5.1 erforderlich. Keine große Sache im Vergleich zu anderen Lösungen ( 248 Byte ), aber eine plattformübergreifende Anwendung mit vollem Funktionsumfang (Android und iOS inbegriffen)! : D

    import QtQuick 2.0;import QtQuick.Controls 1.1;Row{Text{text:"SELECT ANY TWO"}CheckBox{id:a;text:"FAST";enabled:!b.checked|!c.checked}CheckBox{id:b;text:"CHEAP";enabled:!a.checked|!c.checked}CheckBox{id:c;text:"GOOD";enabled:!b.checked|!a.checked}}

Horizontaler Layout-Dialog

Um es auszuführen, speichern Sie den Code in einer .qml-Datei, installieren Sie Qt 5.1 und führen Sie qmlscene.exe (oder nur qmlscene unter Linux) aus. Daraufhin wird ein Dialogfeld mit geöffneten Dateien angezeigt. Wählen Sie die .qml-Datei, in der Sie den Code gespeichert haben, und sehen Sie das großartige Ergebnis! : D


3

k3 - 95

a[`FAST`CHEAP`GOOD]:0
a[.;`c]:`check
a..l:"SELECT ANY TWO"
a..t:"if[3=+/a[];.[_v;_i;:;0]]"
`show$`a

Code ist hier

Probelauf
(Quelle: nsl.com )


Zeile 1: ein Wörterbuch mit drei Variablen; Zeile 2: Jede Variable ist ein Häkchen. Zeile 3: beschriften Sie das Wörterbuch; Zeile 4: Wenn drei Variablen markiert wurden, setzen Sie die zuletzt markierte Variable auf 0 zurück. Zeile 5: Zeigt das Wörterbuch an.
Stevan Apter

Nett! Eine solche Tragödie k4 hat keine GUI ...
Mollmerx

k gewinnt (aber oh Ironie! 9 weitere Zeichen sind erforderlich, um zu posten!)
Stevan Apter

2

JavaScript / jQuery 237 234 229

Sehr ähnlicher Ansatz wie Matts Antwort , wenn auch etwas länger.

$(function(){var e="input ",t="disabled",n,r;$("body").html("SELECT ANY TWO|FAST|CHEAP|GOOD".replace(/\|/g,"<"+e+'type="checkbox">'));n=$(e);n.change(function(){n.removeAttr(t);r=$(":checked");if(r.length>1)n.not(r).attr(t,t)})})

2

JavaScript 209 (war 346)

Verkürzt: Danke für Kommentare.

function f(){var a=document.getElementsByClassName("x"),n=0,i=0;for(i in a){if(a[i].checked)n++;}if(n<2){for(i in a){a[i].disabled=false;}}else{for(i in a){i(false===a[i].checked){a[i].disabled=true;break;}}}}

Golf Funktion:

function f(a,b,c){
var x=document.getElementById(a);
var y=document.getElementById(b);
var z=document.getElementById(c);
var n=0,i=0;
var a=[x,y,z];
for(i in a)
{
if(a[i].checked) n++;
}
if(n<2)
{
for(i in a)
{
a[i].disabled=false;
}
}
else
{
for(i in a)
{
if(false===a[i].checked)
{
a[i].disabled=true;
break;
}
}
}
}

HTML-Formular: Stellt Eingaben bereit und ruft die Funktion auf. * Form verwendet jetzt class = x, um Eingaben zu gruppieren.

<form>
        SELECT ANY TWO<br>
        FAST <input id="a" type="checkbox" class="x" value="0" onchange="f()"><br>
        CHEAP <input id="b" type="checkbox" class="x" value="1" onchange="f()"><br>
        GOOD <input id="c" type="checkbox" class="x" value="2" onchange="f()"><br>
    </form>

Getestet mit NetBeans und Chrome.


Sie können die Funktion weiter varverbessern und auf 264 Zeichen reduzieren, indem Sie alle Ihre Zeichen zusammenfassen und unnötige Klammern und Leerzeichen (einschließlich Zeilenumbrüche) entfernen. Sie könnten wahrscheinlich kleiner werden, wenn Sie einen ES6-Lambda verwenden.
Tony Ellis

Abgesehen von etwas offensichtlicherem Golfspiel sollten Sie eine Klasse verwenden, um stattdessen alle Eingabeelemente mit einem Schlag in ein Array zu ziehen, getElementsByClassNamez. a=document.getElementsByClassName('q').
Matt

Ändern Sie die IDs zu nennen und sie rufen Sie einfach mit document.a, document.c, document.csie auch direkt in eine put []
Frieder

2

Groovy

Basiert auf der Java-Version, ist aber stark abgespeckt;)

Typen wurden durch 'def' ersetzt, Semikolons entfernt, durch << ersetzt, die 1 <0 durch 0 ersetzt, zum Erstellen der Kontrollkästchen gesammelt, der Elementevent-Typ entfernt, das Aktivieren des Kontrollkästchens entfernt und die Schleifen verbessert.

import java.awt.*
class F {
    def static main(a) {
        def f = new Frame()
        def p = new Panel()
        f << p
        p << new Label("SELECT ANY TWO")
        def c = ['FAST','CHECK','GOOD'].collect { new Checkbox(it) }
        c.each { b ->
            p << b
            b.addItemListener { e->
                int x = 0, i = 0
                3.times {
                    x += c[it].state ? 1 : 0
                }
                if (x > 2) {
                    e.source.state = 0                        
                }
            }
        }
        f.show()
    }
}

Groovy ist kein Java. Das bedeutet, dass all diese Verbesserungen nicht so viel zählen. Alles, was Sie entfernt haben, war in Java notwendig, aber nicht groovig.
Justin

1
Sie haben Recht, Groovy ist kein Java, deshalb heißt es Groovy. Ich bin nicht sicher, was Sie hier sagen wollen.
Erik Pragt

1

TCL 347

Zumindest schlägt es Python und Java.

set d .
proc a v {upvar f f c c g g d d $v x
if $x&&$f+$c+$g==2 {set d .$f$c$g
$d configure -state disabled} 
if !$x {$d configure -state normal}}
set z -variable
set y -command
set x checkbutton
label .l -text {SELECT ANY TWO}
$x .011 -text FAST $z f $y a\ f
$x .101 -text CHEAP $z c $y a\ c
$x .110 -text GOOD $z g $y a\ g
pack .l .011 .101 .110

Hinweis: Wenn Sie zunächst ein Kontrollkästchen aktivieren und es sofort deaktivieren, wird eine Fehlermeldung angezeigt. Sie können das Problem beheben, indem Sie 110es am Ende der ersten Zeile einfügen.

Ungolfed:

# Keep track of the last disabled button. Set it to something valid to start with.
set last .110

proc toggled name {
        # Access some globals
        upvar fast  fast
        upvar cheap cheap
        upvar good  good
        upvar last  last
        upvar $name value

        # Just toggled one on, check if exactly two are now on
        if {$value == 1 && ($fast + $cheap + $good) == 2} {
                set last .$fast$cheap$good
                $last configure -state disabled
        }
        # Just toggled one off. Re-enable disabled one.
        if {$value == 0} {
                $last configure -state normal
        }
}

label .label -text {SELECT ANY TWO}

checkbutton .011 -text FAST  -variable fast  -command {toggled fast}
checkbutton .101 -text CHEAP -variable cheap -command {toggled cheap}
checkbutton .110 -text GOOD  -variable good  -command {toggled good}

pack .label .011 .101 .110

1

Javascript + Knockout: ~ 250 Zeichen

a=function(i){return "<input type=checkbox data-bind='value: "+i+", checked: x, disable: x().length>=2 && x().indexOf(\""+i+"\")==-1'>"},document.body.innerHTML = "SELECT ANY TWO"+a(0)+"Fast"+a(1)+"Good"+a(2)+"Cheap"; ko.applyBindings({x:ko.observableArray([])})

0

AngularJS - 155 ( Demo )

SELECT ANY TWO :<i ng-init=t=[]><p ng-repeat="(i,v) in ['FAST','CHEAP','GOOD']"><input type=checkbox ng-disabled=t[(i+1)%3]&&t[(i+2)%3] ng-model=t[i]>{{v}}

Die ungolfed Version:

SELECT ANY TWO :
<i ng-init="checkedArray = []" /> <!-- A useless tag to initialize the array (which can't be done on the `input` tag, unfortunately) -->
<p ng-repeat="(key, value) in ['FAST', 'CHEAP', 'GOOD']">
    <input
        type="checkbox"
        ng-model="checkedArray[key]"
        ng-disabled="checkedArray[(key + 1) % 3] && checkedArray[(key + 2) % 3]"
    />
    {{value}}
</p>

0

Ruby with Shoes, 133 Zeichen

Shoes.app{para'SELECT ANY TWO'
$o=%w{FAST GOOD CHEAP}.map{|q|c=check{|c|$o[c]=!$o[c];$o.values.all?&&c.checked=p}
para q
[c,p]}.to_h}

Beispielausgabe:

Schuhfenster Screenshot


0

AppleScript, 194 190 Bytes (ziemlich sicher, dass das ein bisschen schummelt ...)

Es gibt zwei Probleme:

  • In AppleScript gibt es keine Kontrollkästchen, nur Listen.
  • Es gibt nur die Option, EINEN aus der Liste oder einen beliebigen Betrag auszuwählen.

Umstände:

  • Verwenden einer Endlosschleife mit einem Haltepunkt, um einen Ausgang zu erhalten, wenn 2 und nur 2 Elemente in der Liste ausgewählt sind.
  • Bestrafte mich mit einer display alertKomponente, die mir zusätzliche 30 Bytes Länge gibt.

Gründe, warum ich dies poste:

  • Es ist der Weg , dies in Applescript zu tun.
  • Der Code kann nicht mit drei ausgewählten Optionen vervollständigt werden, sodass die dritte Option durch Erweiterung deaktiviert wird .

Dies wird hauptsächlich veröffentlicht, um die Leistungsfähigkeit von AppleScript in der Aqua / GUI-Interaktion zu demonstrieren.

wiederholen
Wählen Sie aus der Liste {"FAST", "CHEAP", "GOOD"} mit der Eingabeaufforderung "CHOOSE ANY TWO" mit mehreren Auswahlmöglichkeiten
wenn die Anzahl der Elemente des Ergebnisses <= 2 ist
Wiederholung beenden
sonst
display alert "BITTE ZWEI PICKEN"
Ende
Ende

Hinrichtung gif

Wenn Sie der Meinung sind, dass dies zu unangebracht ist, bitten Sie mich, es zu löschen.


Das ist wild! Das ist die englischsprachigste Sprache, die ich je gesehen habe.
Bruce Pierson

Es ist wirklich schade, dass sie nicht so etwas wie "mit 2 Auswahlmöglichkeiten" oder so ähnlich haben.
Bruce Pierson

@BrucePierson Ja, AppleScript ist eine seltsame Sprache. ¯ \ _ (ツ) _ / ¯ Ich benutze es immer nur für kleine Dinge, es ist ziemlich schwierig, etwas wirklich damit anzufangen.
Addison Crump

Diese sind nicht angekreuzt, was diese Antwort von den Regeln "zu abweicht". Ich bitte Sie hiermit um Löschung.
pppery vor

0

FLTK, 303 Zeichen

decl{int c;}Function{}{}{Fl_Window{}{xywh {9 9 195 195}}{Fl_Pack{}{label{SELECT ANY TWO}}{Fl_Check_Button{}{callback{e(o);}label FAST}Fl_Check_Button{}{callback{e(o);}label GOOD}Fl_Check_Button{}{callback{e(o);}label CHEAP}}}}Function{e(Fl_Button*o)}{}{code{if((c+=o->value()*2-1)>2){o->value(0);c--;}}}

Ungolfed:

decl { int c; }

Function {} {} {
    Fl_Window {} {
        xywh {9 9 195 195}
    } {
        Fl_Pack {} {
            label {SELECT ANY TWO}
        } {
            Fl_Check_Button {} {
                callback { e(o); }
                label FAST
            }
            Fl_Check_Button {} {
                callback { e(o); }
                label GOOD
            }
            Fl_Check_Button {} {
                callback { e(o); }
                label CHEAP
            }
        }
    }
}

Function { e(Fl_Button* o) } {} {
    code {
        if ((c += o->value() * 2 - 1) > 2) {
            o->value(0);
            c--;
        }
    }
}

Beispielausgabe:

FLTK-Fenster-Screenshot

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.