Veloce, economico e buono: scegli due qualsiasi


43

Come programmatori, sappiamo tutti il ​​detto: "Puoi averlo veloce e buono, ma non sarà economico, puoi averlo economico e buono, ma non sarà veloce, o puoi averlo veloce ed economico , ma non sarà buono. "

Per questa sfida, stai implementando uno strumento di configurazione immaginario per i tuoi servizi di programmazione personalizzati. Dovresti visualizzare un set di tre caselle di controllo, con un'intestazione di "SELEZIONA QUALSIASI DUE":

SELECT ANY TWO  
☐ FAST  
☐ CHEAP  
☐ GOOD

Dopo aver selezionato due elementi, il terzo elemento deve essere disabilitato. Dopo aver deselezionato uno dei due elementi selezionati, è necessario abilitare nuovamente tutte le opzioni. In altre parole, se sono selezionati zero o uno, tutti sono ancora abilitati, ma se sono selezionati due elementi, il terzo deve essere disabilitato.

Non sono ammessi controlli speciali. Le caselle di controllo dovrebbero essere la casella di controllo standard nella lingua prescelta. Ad esempio, non utilizzare un controllo "CheckBoxList", se la tua lingua ne ha uno. Immagino che la maggior parte delle voci saranno HTML / jQuery, ma questa non è una regola. Questo è il codice golf, cercando la voce più breve.

VINCITORI COSÌ LONTANO

Lo suddividerò in categorie. Ci sono alcuni chiari vincitori:

jQuery: nderscore, Mr. Tenacity Under 100b quando si escludono "risorse" di testo. Una menzione d'onore va anche a Matt per l'introduzione dei concetti jQuery da cui molti hanno preso ispirazione.

Dyalog APL: marinus, aka Mr. Unicode Come si scrivono tutte quelle cose? Vedo perché vorresti scrivere programmi brevi.

PHP: SuperScript Credo che questa sia la voce più breve che in realtà disabilita piuttosto che deselezionare la terza opzione, seguendo l'interpretazione più rigorosa delle regole.


Posso semplicemente farlo in modo che solo due possano essere selezionati alla volta? In modo che selezionando il terzo deselezioni uno degli altri? O forse aggiungi un pulsante di accettazione che diventa grigio se sono selezionate 3 opzioni?
Justin

7
@Quincunx - Dal momento che non esiste un'euristica (al di fuori della lettura della mente) che potrebbe decidere quale deselezionare, questo confonderebbe l'utente ... quindi dovrò dire di no, perché non vogliamo la prima impressione di i nostri servizi software personalizzati devono essere cattivi. ;)
Bruce Pierson

Questa domanda mi ha interessato nel tkinter di Python 3, quindi sto provando a impararlo ora. IMO, il modo migliore per imparare la GUI è provare ed errori. Ho provato questo: ideone.com/YHLZIQ . Risultato: rapida apertura di nuove GUI. Ho dovuto aprire il task manager per chiuderli. :-). Immagine (il numero è salito presto a 340: i.stack.imgur.com/c9wQi.png )
Justin

Il concorso bonus dovrebbe essere un'altra domanda in quanto non esiste un criterio di vincita primario oggettivo o una descrizione del "bonus". Ha detto che il codice dovrebbe essere "... elegante e flessibile ..." e "... conciso e chiaro ..." che è contro il code-golf . VTC non è chiaro cosa stai chiedendo. Per favore non cambiare radicalmente le domande molto tempo dopo che sono state poste.
user80551

1
@BrucePierson In realtà, c'è. Potremmo deselezionare la casella di controllo selezionata più vecchia. Tuttavia, il codice per questo sarebbe molto più del codice richiesto.
Giustino,

Risposte:


23

Javascript ( ES5 ) con jQuery - 143 ( Demo )

Ho modificato la soluzione di Matt e l'ho giocata fino a che penso che possa andare:

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

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

L'uso di jQuery è una specie di imbroglio, quindi ecco una soluzione senza di essa:

(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]'>"))

Se ci è permesso impedire all'utente di selezionare la terza casella invece di disabilitare effettivamente il campo, possiamo renderlo ancora più breve:

Con jQuery - 126 123 ( Demo )

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

Senza jQuery - 150 147 ( Demo )

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

Freddo. Usare .joinè un buon trucco!
Robbie Wxyz,

1
"SELECT ANY TWO0FAST0GOOD0CHEAP".replace(/0/g,è un altro modo per farlo con la stessa lunghezza.
nderscore,

essendo pignolo, la versione jquery dovrebbe usare prop, non attr
Einacio

@Einacio il tuo desiderio è il mio comando!
nderscore,

5
@Einacio Ma codegolf parla delle peggiori pratiche! : P
nderscore,

29

JavaScript - 184 169 (con 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/

EDIT: migliorato con l'aiuto di @Daniel Lisik - https://codegolf.stackexchange.com/a/26805/16278


5
Bello! Non abbastanza rappresentante per il voto ... ma sei assunto!
Bruce Pierson,

2
Più guardo questo, più sto imparando. L'intelligenza dell'assegnazione delle variabili all'interno di un selettore jQuery. Molto bello. Inoltre, potresti spiegare cosa sta facendo il "double bang" (!!)?
Bruce Pierson,

1
Il singolo bang costringe un valore booleano e il doppio ovviamente lo invertirà. undefinedcostringe al vero. Quello e l'assegnazione delle variabili sono probabilmente gli unici piccoli trucchi usati davvero.
Matt,

Il tuo codice può essere ridotto a 179 caratteri in questo modo: 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])}) jsfiddle.net/L33JK/15
display-name-is-missing


12

Dyalog APL (su Windows) (169)

Questa è una funzione statica, per testarla se non conosci l'APL, digita )ed Ce incolla questo nella finestra di modifica, quindi esegui C.

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}

I bit più recenti di APL hanno parole chiave lunghe . Ho comunque battuto HTML.

Spiegazione:

  • 'R'⎕WC'Form' 'Select any two',2/⊂S←2/20: crea un modulo R, con titolo Seleziona due e dimensione e posizione 20 20. Memorizza anche 20 20in S.
  • 1 21 41{... }¨'Fast' 'Cheap' 'Good': per ciascuna di queste coppie di dati (nome e coordinata y, che sono le uniche variabili che differiscono tra le caselle di controllo:
    • ('R.',⊃⍵)⎕WC'Button': crea un pulsante all'interno Rcon la prima lettera del nome,
    • ⍵(⍺1)S'Check': con l'argomento giusto come titolo, (left arg, 1)posizione, riutilizzo Scome dimensione e Checkstile,
    • ('Event' 'Select' 'F'), che chiama la funzione Fquando si fa clic.
  • B←R.(F C G): usa Bcome abbreviazione le tre caselle che abbiamo creato
  • F←{... }: definisce la funzione di callback come:
    • X←B.State: ottieni lo stato per ogni casella di controllo e memorizzalo in X,
    • X∨2≠+/X: somma X, se questo non è uguale a due tutte le caselle di controllo devono essere attive, se è uguale a due solo caselle di controllo devono essere attive
    • B.Active←: abilita o disabilita le caselle di controllo

Risultato:

screenshot


Grande spiegazione, grazie!
Bruce Pierson,

11

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

Ho pensato, Python deve essere più corto di Java. Ecco la "prova" ( EDIT: ora è davvero più breve ):

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

Per quelli di voi curiosi di execsapere cosa esegue effettivamente l' espressione, esegue questo (questo è ciò che i rimpiazzi fanno alla stringa. Newline aggiunte per la leggibilità):

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

Questo utilizza la stessa logica della mia risposta Java: deseleziona la casella di controllo se provoca la selezione di più di 2 caselle di controllo. Unf Fortunatamente Purtroppo, ho trascorso più meno più byte fare questo.

enter image description here

Modifiche:

  1. massiccia regolazione del codice da utilizzare exec, risparmiando un enorme 1 byte!
  2. passato a Python 2 per comprimere due byte dalla exec(rimozione delle parentesi).
  3. più golf. Include cambiare range(3)per 0,1,2e cambiando il rientro di avere uno strato di schede. Non so se \t\tfunzionerebbe invece di \t__( _è il carattere spaziale). Finalmente raggiunsi la risposta più lunga che la mia Java fosse mai stata.
  4. usato per sostituire il trucco
  5. ha usato il suggerimento di Bakiru e ha giocato ancora a golf. In realtà lo ha reso più corto di Java! Ma ora, la risposta di Java è stata giocata di più, quindi questo è ancora più lungo. :-(
  6. usato un trucco di sostituzione migliorato .
  7. cambiato a !=per a -.

Approccio interessante +1
cjfaure

Posso imbrogliare con la modalità turbo sulla mia tastiera. Innanzitutto, seleziono due caselle. In secondo luogo, utilizzo Tab per evidenziare il terzo. Ora tengo la barra spaziatrice in modalità turbo per alcuni secondi. A volte, questo controlla la terza casella!
kernigh,

@kernigh Credo che ciò sia dovuto al fatto che il mio codice arriva al punto in cui sa che la casella è stata attivata, ma il codice non ha raggiunto il punto in cui viene riattivata la casella. Quindi, se tocchi la casella in quel momento (su off), il mio codice metterà un segno di spunta su di essa.
Justin

1
È possibile evitare il blocco rientrato a cominciare if p[i]con un andinvece di un if: if p[i]:s>1 and B[i].toggle();s+=1.
Bakuriu,

@kernigh mi sbagliavo; la sostituzione B[i].toggle()con B[i].deselect()non cambia nulla. Non ho idea del perché sia ​​così. Forse è un difettotkinter
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]
]

Questo è il dialetto Rebol 3 View (r3-gui). Screendump di seguito da Ubuntu Linux:

example of rebol 3 view

Aggiornamento - Grazie a Earl & Graham di Rebol SO Chatroom per aver rasato 22 caratteri del codice - http://chat.stackoverflow.com/transcript/message/16345039#16345039


È una risposta non valida, poiché il terzo è disabilitato ma anche controllato, ciò significa che tutti e 3 sono controllati, quindi per favore correggilo.
ST3,

2
@ ST3 - Hai torto, temo. La casella di controllo "BUONO" non è selezionata o in effetti disabilitata (il mio codice semplicemente sposta la terza casella su OFF). Ecco come la vista Rebol 3 mostra una casella non selezionata (per impostazione predefinita).
Draegtun,

1
@ ST3 et al. Ecco un link che mostra l'aspetto predefinito della casella di controllo che ho descritto sopra (la 1a immagine non mostra caselle di controllo cliccate, la seconda solo "BUONA") - plus.google.com/u/0/104216037702741908932/posts/Z2EbuQX67aq
draegtun

Bene ... guardo nella schermata di stampa che hai aggiunto e vedo tutte e tre le caselle di controllo selezionate, solo una non può essere deselezionata.
ST3,

3
@ ST3 - Una casella di controllo in grigio è solo il modo Rebol 3 View per mostrare che è una casella di controllo che può essere selezionata. Il segno di spunta diventa verde quando è selezionato e diventa grigio quando non è selezionato. Queste sono le impostazioni predefinite. Nell'immagine in risposta sopra puoi vedere quel "BUONO" come focus di input (sfocatura blu) perché è "cliccato" ma rimane grigio e non verde (quindi non selezionato).
Draegtun,

10

Java, 421 ... 369 351 byte

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 ... perché Java. Codice più bello:

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

Esempio di esecuzione (diversi dimensionamenti della finestra, il primo è all'avvio):

inserisci qui la descrizione dell'immagine
inserisci qui la descrizione dell'immagine
inserisci qui la descrizione dell'immagine

Le caselle di controllo sono disposte orizzontalmente; questo è permesso . Ci vorrebbe molto di più per allinearlo correttamente. Anche, sto disabilitando deselezionando la casella quando viene cliccato , non rendendo impossibile fare clic.

Modifiche:

  1. salvato 3 byte estendendo la classe principale Checkbox.
  2. rileggere Lambda Expressions e si rese conto che il nome del tipo non era necessario. Prendi quel Python!
  3. convertito un whileciclo in un ciclo foreach (grazie Lee ); perché non ci avevo pensato prima?
  4. salvato 18 byte utilizzando una classe anonima e un initalizer di istanza sia per Framee Panel.

Nessuna limitazione all'allineamento (quindi suppongo che Matt potrebbe ridurre il suo di 5 caratteri). Puntelli per un programma in esecuzione completo ... ma non vedo che la terza opzione è disabilitata.
Bruce Pierson,

@BrucePierson È disabilitato. Non è possibile fare clic. Se si fa clic, non succede nulla.
Giustino,

2
Ah, penso di vedere. Stai "azzerando" immediatamente lo stato controllato senza disabilitare? Sarebbe accettabile
Bruce Pierson,

@BrucePierson Esatto. Per disabilitare effettivamente, dovrei cambiare if(x>2)((Checkbox)e.getSource()).setState(1<0);inif(x>2){Checkbox b=(Checkbox)e.getSource();b.setState(1<0);b.setEnabled(1<0);}
Justin

1
@BrucePierson Ogni volta che pensi, questo sembra divertente quando ha a che fare con l'uso di una rappresentazione del personaggio di qualcosa di grafico, cerca unicode. In alternativa, per le cose di progettazione grafica, vai a User Experience SE : i.stack.imgur.com/xFkzy.png
Justin

7

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

Perché perché no.

Incredibilmente, a partire da ora siamo più corti di Python e del C # non buggy e legati a Java!

Crediti a EveBird per averlo ridotto da 561 a 481.

E ancora una volta EveBird lo accorcia da 481 a 433!

Ne ho prese alcune con una connessione lambda

Fino a 389 con inizializzatori C ++ 11

E 373 senza la classe separata

Rimossi alcuni spazi - 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();}

Sorta di non golfati:

#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 per il self-flagellating "why not" :)
Bruce Pierson,

Può migliorare un po 'di più: sostituisci QWidget mcon QDialog me m.show();a.exec()con m.exec().
Toby Speight,

6

CoffeeScript - 167, 154

Porta CoffeeScript della risposta di @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]

Abbastanza 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

Stavo ammirando la risposta di @ nderscore, ma poi ho deciso di copiarlo e risolverlo.

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

Fondamentalmente ho sostituito il suo .jointrucco con un po 'di pre-elaborazione PHP Hypertext.


Se si considera che sono necessari 27 byte per le "risorse" di testo nel programma, questo si avvicina molto a un programma 100b. Molto bene!
Bruce Pierson,

1
Non sono un gran giocatore di PHP, ma ho eliminato alcuni byte per te: (128)SELECT ANY TWO<?=($m="<input type=checkbox onclick=(a=$('input:not(:checked)')).prop('disabled',!a[1])>").FAST.$m.GOOD.$m.CHEAP;
nderscore,

5

Rubino, 219 218 byte

Uso gli stessi widget Tk della risposta Python 3 di Quincunx.

Questo programma infrange le regole perché ha un elenco di caselle di controllo . (Le regole dicevano "Non usare un elenco di caselle di controllo"). Sì, aè un array di 3 oggetti TkCheckButton e credo che un array sia un elenco. La mia difesa è che non ho usato nessun elenco di caselle di controllo esistente, ma ho usato le caselle di controllo standard e ho creato il mio elenco.

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

ECONOMICO e BUONO controllato, ma VELOCE disabilitato

Ho provato con Ruby 2.1.0 e Tk 8.5.15.

  • o[c]è un predicato da verificare se cè selezionato il pulsante di controllo . Con le stringhe predefinite, c.variable.valueè '0'o '1', quindi il confronto delle stringhe è vero solo se '1'>'0'. EDIT: ho salvato 1 byte (da 219 a 218) cambiando '0'in ?0. In Ruby, ?0è una costante del personaggio.
  • a.count(&o) usa il predicato per contare i pulsanti di controllo selezionati.
  • Quando l'utente attiva o disattiva un pulsante di spunta, il comando chiama a.mapin loop per tutti i pulsanti, rendendoli :normalo :disabled.

1
Molto bene. Nessuna regola violare qui - Mi riferivo a un controllo dell'elenco delle caselle di controllo che può capitare di far parte del framework linguistico. Credo che finora tutte le risposte utilizzino una sorta di mappa o selettore, quindi è del tutto legittimo.
Bruce Pierson,

5

Grazie a Rotem e Johnbot per l'aiuto del golf!

C # 343 334

Questo usa lo stesso "trucco" della risposta Java di Quincunx : le caselle di controllo non sono effettivamente disabilitate; semplicemente non ti permettono di controllarli se quel controllo fa 3.

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

C'è anche un bug minore che non è possibile chiudere la finestra dopo aver selezionato la terza casella di controllo a meno che non si deselezioni uno, perché la convalida non passerà. Ma questo è , quindi chi se ne frega? ;)

C # 403 397 374

Questo è proprio quello che disabilita effettivamente la terza casella di controllo.

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

Immagine dello schermo

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
Non è stato if(a.Count(b=>b.Checked)==2)e.Cancel=true;possibile riscriverlo e.Cancel=a.Count(b=>b.Checked)==2;?
Rotem,

@Rotem Sì, sì, potrebbe. Sono stupido E c'è un'ottimizzazione simile per l'altra. Grazie!
Bob,

Aspetta, no, non c'è per l'altro. Eh, ho ancora salvato alcuni caratteri.
Bob,

1
Se si passa l'eredità a CheckBox, utilizzare inizializzatori di oggetti e abusare un po 'di Linq, è possibile ottenere quello corretto fino a 374: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 se si utilizza l'operatore condizionale al posto dell'istruzione if. Sostituisci if(a.Count(b=>b.Checked)>1){a.First(b=>!b.Ch‌​ecked).Enabled=1<0;}else a.All(b=>b.Enabled=0<1);cona.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>

L'ho provato su JSFiddle, ma senza successo . Potete fornire un esempio funzionante?
ossifrage schifoso


Non hai menzionato "ng-app". Controlla <head> nel mio esempio.
user12345

1
Ah, OK :-) Puoi ridurlo un po ' rimuovendo le virgolette e le interruzioni di riga extra.
ossifrage schifoso

4

JavaScript (con 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)})

Grazie a un commento del brillante @Matt ho ridotto il codice di 27 caratteri.

JSFiddle


Risparmia circa 25 spostando la tua condizione $(e+c).length>1nell'incarico in quanto tale: $(e).not(c).attr(f,$(e+c).length>1)poiché stai solo cambiando il booleano stesso.
Matt,

1
Riuscito a portarlo a 169 usando un tuo e il mio. La !!coercizione e un po 'di golf in più con non assegnare il corpo a 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

matematica

Una versione più codificata come suggerito da David, 255 caratteri :

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"
   }
 ]

Puoi salvare alcuni personaggi usando h=Checkbox;i=Dynamic;j=Enabled.
DavidC,

@DavidCarraher Grazie, posso vedermi usare questa tecnica anche per altre domande sul golf del codice in futuro.

1
Non è necessario includere entrambe le versioni. E non dimenticare di utilizzare he modificare il conteggio dei caratteri nell'intestazione.
DavidC,

4

script mIRC ( 727 719 byte)

Dimenticato questa lingua fino a una conversazione ubriaca ieri sera.

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

Altro dovrebbe essere codificato in questa lingua! Ma deve esserci un modo per trasformare questo in un vero casino in modo che possa essere buono come Perl.

Modifica: ho notato che i miei Python-isms perdono e sono stati in grado di ridurre il codice di 8 byte!


Haha, mi piace l'introduzione a questo. È un po 'prolisso - potrebbe essere la birra a parlare? = c)
Bruce Pierson,

3

C #, 335 333 326 320 308

Basato su Bobs Answer, il mio usa meno caratteri del suo (335 v 342), ma potrei non capire appieno come contarlo.

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

Grande uso delle funzioni anon e Linq qui, specialmente come Select.
Bruce Pierson,

Puoi salvare un altro paio di caratteri sostituendo ==2con a >1e truecon a 1>0. Puoi anche usare un Allinvece di Wheree Last. ToListè anche più breve di ToArray.
Bob,

@Bob Buona telefonata, non so come mi sono perso All () e, come bonus, si scopre con All che non devi materializzarlo, risparmiando ancora di più
iamkrillin

3

Groovy - 357 221 217 caratteri

Ho portato la soluzione di Quincunx su Groovy 2.2.1, usando SwingBuilder (e l'ho reso ancora più Groovier):

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 byte

Qui va la versione QML (QtQuick 2.0), dato solo il contenuto del file .qml. Questo codice richiede almeno Qt 5.1 per essere eseguito. Non è un grosso problema in quanto è enorme rispetto ad altre soluzioni ( 248 byte ), ma è un'applicazione multipiattaforma completa (Android e iO inclusi)! : 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}}

Finestra di dialogo layout orizzontale

Per eseguirlo, salva il codice in un file .qml, installa Qt 5.1 ed esegui qmlscene.exe (o semplicemente qmlscene su Linux), che mostrerà una finestra di dialogo di file aperta. Scegli il file .qml in cui hai salvato il codice e guarda il fantastico risultato! : 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

il codice è qui

esecuzione del campione
(fonte: nsl.com )


riga 1: un dizionario con tre variabili; riga 2: ogni variabile è un pulsante di spunta; riga 3: etichetta il dizionario; riga 4: se sono state verificate tre variabili, reimpostare l'ultima variabile su 0; riga 5: mostra il dizionario.
Stevan Apter,

Bello! Una tale tragedia k4 non ha GUI ...
mollmerx,

k vince (ma oh ironia! Sono necessari altri 9 caratteri per pubblicare!)
Stevan Apter

2

JavaScript / jQuery 237 234 229

Approccio molto simile alla risposta di Matt , anche se un po 'più a lungo.

$(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 (era 346)

Abbreviato: grazie per i commenti.

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;}}}}

Funzione golfizzata:

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;
}
}
}
}

Modulo HTML: fornisce input e chiama la funzione. * Il modulo ora utilizza class = x per raggruppare gli input.

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

Testato con NetBeans e Chrome.


Puoi golf ulteriormente la funzione e ridurla a 264 caratteri consolidando tutte le tue vars, rimuovendo parentesi graffe e spazi bianchi non necessari (inclusi i caratteri di nuova riga). Probabilmente potresti ridurlo se usi un lambda ES6.
Tony Ellis,

A parte qualche golf più ovvio, considera invece l'uso di una classe per inserire tutti gli elementi di input in un array in un colpo solo, usando getElementsByClassNamead esempio a=document.getElementsByClassName('q').
Matt,

modificare gli ID per nome e basta chiamarli con document.a, document.c, document.canche metterli direttamente in un []
Frieder

2

Groovy

Basato sulla versione Java, ma molto ridotto;)

I tipi sono stati sostituiti da 'def', i punti e virgola sono stati rimossi, l'aggiunta è stata sostituita da <<, l'1 <0 è stata sostituita da 0, la raccolta per la creazione delle caselle di controllo, il tipo di elemento rimosso rimosso, il cast della casella di controllo rimosso, il loop migliorato.

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 non è java. Ciò significa che tutti questi miglioramenti non contano tanto. Tutto ciò che hai rimosso è stato necessario in java, ma non è groovy.
Giustino,

1
Hai ragione, Groovy non è Java, ecco perché si chiama Groovy. Non sono sicuro di cosa stai cercando di dire qui.
Erik Pragt,

1

TCL 347

Almeno batte Python e 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

Nota: se inizi selezionando una casella e deselezionandola immediatamente, verrà visualizzato un errore. Puoi aggiustarlo aggiungendo110 alla fine della prima riga.

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 caratteri

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

La versione ungolfed:

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

Rubino con scarpe, 133 caratteri

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}

Uscita campione:

Schermata della finestra delle scarpe


0

AppleScript, 194 190 byte (abbastanza sicuro che questo stia tradendo un po '...)

Esistono due problemi:

  • Non ci sono caselle di controllo in AppleScript, solo elenchi.
  • C'è solo l'opzione per selezionare UNO dall'elenco o QUALSIASI importo.

aggiramento:

  • Utilizzando un loop ripetuto infinito con un punto di interruzione per avere un'uscita quando sono selezionati 2 e solo 2 elementi nell'elenco.
  • Mi sono punito con un display alertcomponente che mi dà altri 30 byte di lunghezza.

Ragionamento dietro di me pubblicando questo:

  • Si è il modo per farlo in AppleScript.
  • Il codice non può essere completato con tre opzioni selezionate, quindi la terza opzione è deselezionata dall'estensione .

Pubblicando principalmente questo per mostrare la potenza di AppleScript nell'interazione Aqua / GUI.

ripetere
scegli dalla lista {"FAST", "ECONOMICO", "BUONO"} con prompt "SCEGLI QUALUNQUE DUE" con più selezioni consentite
se il numero di elementi del risultato <= 2
esci ripetizione
altro
visualizza avviso "SI PREGA DI SELEZIONARE DUE"
fine
fine

esecuzione gif

Se ritieni che questo sia troppo off, ti prego di chiedermi di eliminare.


Questo è selvaggio! Questa è la lingua più inglese che abbia mai visto.
Bruce Pierson,

È davvero un peccato che non abbiano qualcosa del tipo "con 2 selezioni richieste" o qualcosa del genere.
Bruce Pierson,

@BrucePierson Sì, AppleScript è un linguaggio strano. ¯ \ _ (ツ) _ / ¯ L'ho sempre usato solo per piccole cose, è piuttosto difficile fare qualcosa di reale con esso.
Addison Crump,

Non sono presenti caselle di controllo, rendendo questa risposta "troppo off" dalle regole. Ti chiedo di cancellare.
pepery

0

FLTK, 303 caratteri

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--;
        }
    }
}

Uscita campione:

Schermata della finestra FLTK

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.