Rapide, bon marché et bon - Choisissez deux personnes

43

En tant que programmeurs, nous connaissons tous le dicton suivant: "Vous pouvez l’avoir vite et bien, mais ce ne sera pas bon marché, vous pourrez l’avoir bon ou bon marché, mais ce ne sera pas rapide, ou vous pourrez l’avoir vite et pas cher. , mais ce ne sera pas bon. "

Pour ce défi, vous implémentez un outil de configuration imaginaire pour vos services de programmation personnalisés. Vous devez rendre un ensemble de trois cases à cocher, avec un en-tête "SÉLECTIONNER LES DEUX":

SELECT ANY TWO  
☐ FAST  
☐ CHEAP  
☐ GOOD

Une fois que deux éléments ont été sélectionnés, le troisième élément doit être désactivé. Lors de la désélection de l'un des deux éléments sélectionnés, toutes les options doivent à nouveau être activées. En d'autres termes, si zéro ou un élément est sélectionné, tous sont toujours activés, mais si deux éléments sont sélectionnés, le troisième doit être désactivé.

Pas de contrôles spéciaux autorisés. Les cases à cocher doivent être les cases à cocher standard dans la langue de votre choix. Par exemple, n'utilisez pas un contrôle "CheckBoxList", si votre langue en a un. J'imagine que la plupart des entrées seront HTML / jQuery, mais ce n'est pas une règle. C'est le code golf, à la recherche de l'entrée la plus courte.

GAGNANTS JUSQU'A PRÉS

Je vais le diviser en catégories. Il y a des gagnants clairs:

jQuery: nderscore, M. Tenacity Moins de 100b lorsque vous excluez le texte "ressources". Une mention honorable devrait également être adressée à Matt pour avoir présenté les concepts jQuery dont beaucoup se sont inspirés.

Dyalog APL: marinus, alias Mr. Unicode Comment tapez-vous toutes ces choses? Je peux voir pourquoi vous voudriez écrire des programmes courts.

PHP: SuperScript Je crois que c'est l'entrée la plus courte qui désactive plutôt que de désélectionner la troisième option, en suivant l'interprétation la plus stricte des règles.

Bruce Pierson
la source
Puis-je simplement faire en sorte que deux personnes seulement puissent être sélectionnées à la fois? Alors que la sélection du troisième désélectionne l’un des autres? Ou peut-être ajouter un bouton d'acceptation qui devient grisé si 3 options sont sélectionnées?
Justin
7
@Quincunx - Puisqu'il n'y a pas d'heuristique (en dehors de la lecture de pensées) qui puisse décider lequel désélectionner, cela confondrait l'utilisateur ... alors je vais devoir dire non, car nous ne voulons pas la première impression de nos services logiciels personnalisés pour être un mauvais. ;)
Bruce Pierson
Cette question m'a intéressé au tkinter de Python 3, alors j'essaie de l'apprendre maintenant. OMI, la meilleure façon d'apprendre l'interface graphique est par essais et erreurs. J'ai essayé ceci: ideone.com/YHLZIQ . Résultat: ouverture rapide de nouvelles interfaces graphiques. J'ai dû ouvrir un gestionnaire de tâches pour les fermer. :-) Image (le nombre a bientôt grimpé à 340: i.stack.imgur.com/c9wQi.png )
Justin
Le concours de bonus devrait être une autre question car il n’existe pas de critère objectif objectif de gain ni de description du "bonus". Il a dit que le code devrait être "... élégant et flexible ..." et "... concis et clair ...", ce qui va à l'encontre du code-golf . VTC comme peu clair ce que vous demandez. S'il vous plaît, ne changez pas radicalement les questions longtemps après leur demande.
user80551
1
@BrucePierson En fait, il y a. Nous pourrions désélectionner la case la plus ancienne sélectionnée. Cependant, le code correspondant serait bien plus que le code requis.
Justin

Réponses:

23

Javascript ( ES5 ) avec jQuery - 143 ( démo )

J'ai modifié la solution de Matt et je l'ai mise au golf aussi loin que je le pense:

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

Javascript ( ES5 ) sans jQuery - 185 175 ( démo )

Utiliser jQuery est une sorte de tricherie, alors voici une solution sans:

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

Si nous sommes autorisés à empêcher l'utilisateur de cocher la 3ème case au lieu de désactiver le champ, nous pouvons le rendre encore plus court:

Avec jQuery - 126 123 ( démo )

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

Sans jQuery - 150 147 ( démo )

(d=document).write(["SELECT ANY TWO","FAST","GOOD","CHEAP"].join("<input type=checkbox onclick=this.checked*=!d.querySelectorAll(':checked')[2]>"))
Nderscore
la source
Cool. Utiliser .joinest un bon truc!
Robbie Wxyz
1
"SELECT ANY TWO0FAST0GOOD0CHEAP".replace(/0/g,est une autre façon de le faire avec la même longueur.
nderscore
juste pour être pointilleux, la version jQuery devrait utiliser prop, et non attr
Einacio
@Einacio votre souhait est ma commande!
nderscore
5
@Einacio Mais codegolf concerne les pires pratiques! : P
nderscore
29

JavaScript - 184 169 (avec 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: amélioré avec l’aide de @Daniel Lisik - https://codegolf.stackexchange.com/a/26805/16278

Mat
la source
5
Agréable! Pas assez de reps pour augmenter votre vote ... mais vous êtes embauché!
Bruce Pierson
2
Plus je regarde ça, plus j'apprends. L'intelligence de l'affectation de variable dans un sélecteur jQuery. Très sympa. Aussi, pourriez-vous expliquer ce que fait le "double coup" (!!)?
Bruce Pierson
1
Le bang simple, force une valeur booléenne, et double va évidemment l'inverser. undefinedcontraint à vrai. Cela et l’affectation des variables sont probablement les seules petites astuces réellement utilisées.
Matt
Votre code peut être réduit à 179 caractères, comme ceci: 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
nom-complet-manquant
12

Dyalog APL (sous Windows) (169)

Ceci est une fonction statique, pour la tester si vous ne connaissez pas APL, tapez-la )ed Cet collez-la dans la fenêtre d'édition, puis exécutez-la 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}

Les nouveaux morceaux d'APL ont des mots-clés longs . Je bat encore HTML cependant.

Explication:

  • 'R'⎕WC'Form' 'Select any two',2/⊂S←2/20: créer un formulaire Ravec titre Sélectionnez deux , taille et position 20 20. Stocke également 20 20dans S.
  • 1 21 41{... }¨'Fast' 'Cheap' 'Good': pour chacune de ces paires de données (nom et coordonnée y, qui sont les seules variables qui diffèrent entre les cases à cocher:
    • ('R.',⊃⍵)⎕WC'Button': créer un bouton Ravec la première lettre du nom,
    • ⍵(⍺1)S'Check': avec le bon argument comme titre, (left arg, 1)comme position, réutilisant Scomme taille et Checkcomme style,
    • ('Event' 'Select' 'F'), qui appelle la fonction Florsque vous cliquez dessus.
  • B←R.(F C G): utiliser Bcomme abréviation pour les trois cases que nous avons créées
  • F←{... }: définit la fonction de rappel comme:
    • X←B.State: obtenir l'état pour chaque case à cocher et les stocker dans X,
    • X∨2≠+/X: somme X, si elle n'est pas égale à deux, toutes les cases à cocher doivent être actives, si elle est égale à deux, seules les cases à cocher cochées doivent être actives
    • B.Active←: activer ou désactiver les cases à cocher

Résultat:

capture d'écran

marinus
la source
Excellente explication, merci!
Bruce Pierson
11

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

Je pensais que Python devait être plus court que Java. Voici la "preuve" ( EDIT: maintenant c'est vraiment plus court ):

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

Pour ceux d'entre vous qui sont curieux de savoir ce que l' execexpression exécute réellement, elle exécute ceci (c'est ce que le remplacement fait à la chaîne. Des nouvelles lignes ont été ajoutées pour la lisibilité):

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

Ceci utilise la même logique que ma réponse Java: désélectionnez la case si plus de 2 cases sont cochées. Unf Heureusement, malheureusement, j'ai dépensé plus moins, plus d'octets pour le faire.

entrez la description de l'image ici

EDITS:

  1. ajustement massif du code à utiliser exec, économisant un énorme octet!
  2. basculé en python 2 pour compresser deux octets de exec(suppression des parenthèses).
  3. plus de golf. Inclut la modification range(3)de 0,1,2l'indentation et la modification pour avoir une couche d'onglets. Je \t\tne sais pas si cela fonctionnerait au lieu de \t__( _est le caractère espace). Enfin atteint ma plus longue réponse en Java.
  4. utilisé remplacer truc
  5. a utilisé la suggestion de Bakiru et a joué au golf un peu plus. En fait fait plus court que Java! Mais maintenant, la réponse de Java a plus joué au golf, donc c'est encore plus long. :-(
  6. utilisé amélioré remplacer truc .
  7. changé un !=pour un -.
Justin
la source
Approche intéressante. +1
cjfaure
Je peux tricher avec le mode turbo sur mon clavier. Tout d'abord, je coche deux cases. Deuxièmement, j'utilise l'onglet pour mettre en évidence le troisième. Maintenant, je tiens la barre d'espace en mode turbo pendant quelques secondes. Parfois, cela coche la troisième case!
Kernigh
@kernigh, je pense que c'est parce que mon code parvient au point où il sait que la zone a été basculée, mais le code n'a pas atteint le point où il est à nouveau basculé. Donc, si vous basculez la case à ce moment-là (pour désactiver), mon code mettra une coche dessus.
Justin
1
Vous pouvez éviter le bloc indenté commençant à l' if p[i]aide d' un au andlieu d'un if: if p[i]:s>1 and B[i].toggle();s+=1.
Bakuriu
@ kernigh j'avais tort; remplacer B[i].toggle()par B[i].deselect()ne change rien. Je ne sais pas pourquoi c'est ainsi. C'est peut-être une faille avectkinter
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]
]

C'est le dialecte Rebol 3 View (r3-gui). Screendump ci-dessous à partir d'Ubuntu Linux:

exemple de vue 3 rebol

Mise à jour - Merci à Earl & Graham de Rebol SO Chatroom pour avoir rasé 22 caractères du code - http://chat.stackoverflow.com/transcript/message/16345039#16345039

draegtun
la source
C'est une réponse invalide, car la troisième est désactivée mais également cochée, ce qui signifie que les 3 sont cochées, corrigez-la.
ST3
2
@ ST3 - Vous avez tort, j'ai bien peur. La case à cocher "BON" n'est pas cochée ou en fait désactivée (mon code parcourt simplement la troisième case cochée désactivée). Voici comment Rebol 3 affiche une case non cochée (par défaut).
mardi
1
@ ST3 et al - Voici un lien indiquant l'aspect de la case à cocher par défaut que j'ai décrit ci-dessus (la 1ère image ne montre aucune case cochée, la 2ème ne contient
draegtun
Eh bien ... je regarde dans l'écran d'impression que vous avez ajouté et je vois les trois cases à cocher cochées, une seule ne peut pas être décochée.
ST3
3
@ ST3 - Une case à cocher grisée ne fait que Rebol 3 View, une façon de montrer que c'est une case à cocher qui peut être cochée. La coche devient verte lorsqu'elle est cochée et redevient grise lorsqu'elle n'est pas cochée. Ce sont les valeurs par défaut. Dans l'image ci-dessus, vous pouvez voir que "BON" est le focus de l'entrée (flou bleu) car il est "cliqué" mais il reste gris et non vert (donc non coché).
mardi
10

Java, 421 ... 369 351 octets

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 ... parce que Java. Plus beau 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();
    }
}

Exemple d'exécution (différentes tailles de la fenêtre, la première est au démarrage):

entrez la description de l'image ici
entrez la description de l'image ici
entrez la description de l'image ici

Les cases à cocher sont disposées horizontalement; c'est permis . Il en faudrait beaucoup plus pour l'aligner correctement. De plus, je désactive en décochant la case quand on clique dessus , et non en le rendant impossible.

EDITS:

  1. 3 octets enregistrés en faisant s'étendre la classe principale Checkbox.
  2. relisez Lambda Expressions et réalisez que le nom du type est inutile. Prenez ce python!
  3. converti une whileboucle en boucle foreach (merci Lee ); pourquoi je n'y avais pas pensé avant?
  4. 18 octets enregistrés en utilisant une classe anonyme et un initalizer d’instance pour Frameet Panel.
Justin
la source
Aucune restriction sur l'alignement (donc je suppose que Matt pourrait réduire le sien de 5 caractères). Accessoires pour un programme complet en cours d'exécution ... mais je ne vois pas que la troisième option est désactivée.
Bruce Pierson
@BrucePierson Il est désactivé. Il ne peut pas être cliqué. Si on clique dessus, rien ne se passe.
Justin
2
Ah, je pense que je vois. Vous êtes immédiatement en train de "déverrouiller" l'état coché sans le désactiver? Ce serait acceptable.
Bruce Pierson
@BrucePierson C'est vrai. Pour désactiver réellement, je devrais changer if(x>2)((Checkbox)e.getSource()).setState(1<0);àif(x>2){Checkbox b=(Checkbox)e.getSource();b.setState(1<0);b.setEnabled(1<0);}
Justin
1
@BrucePierson Chaque fois que vous pensez, cela a l'air amusant quand il s'agit d'utiliser une représentation de caractère graphique, recherchez Unicode. Alternativement, pour des raisons de design graphique, utilisez User Experience SE : i.stack.imgur.com/xFkzy.png
Justin
7

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

Parce que pourquoi pas

Étonnamment, à ce jour, nous sommes plus courts que Python, et le C # non bogué, et à égalité avec Java!

Crédits à EveBird pour l'avoir réduit de 561 à 481.

Et une fois de plus, EveBird le réduit de 481 à 433!

Pris quelques coups avec un lambda connect

Jusqu'à 389 avec les initialiseurs C ++ 11

Et 373 sans la classe séparée

Suppression de quelques espaces - 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();}

Sorte de non-golfée:

#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

Jacob Hacker
la source
1
+1 pour le "pourquoi pas" auto-flagellant :)
Bruce Pierson
Peut améliorer un peu plus: remplacer QWidget mpar QDialog met m.show();a.exec()avec m.exec().
Toby Speight
6

CoffeeScript - 167, 154

Port CoffeeScript de la réponse de @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]

Un peu non-golfé:

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 .

Tony Ellis
la source
5

PHP, Javascript, jQuery - 135b

J'admirais la réponse de @ nderscore, mais j'ai ensuite décidé de le copier et de le remplacer par un.

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

En gros, j'ai remplacé son .joinastuce par du prétraitement PHP Hypertext.

Robbie Wxyz
la source
Si vous considérez que 27 octets sont nécessaires pour le texte "ressources" dans le programme, cela devient très proche d'un programme 100b. Bien joué!
Bruce Pierson
1
Je ne suis pas vraiment un golfeur PHP, mais j'ai coupé quelques octets pour vous: (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 octets

J'utilise les mêmes widgets Tk que la réponse Python 3 de Quincunx.

Ce programme enfreint les règles car il a une liste de cases à cocher . (Les règles disaient: "N'utilisez pas de liste de cases à cocher.") Oui, il as'agit d'un tableau de 3 objets TkCheckButton, et je crois qu'un tableau est une liste. Ma défense est de ne pas utiliser de liste de cases à cocher existante, mais d'utiliser les cases à cocher standard et de créer ma propre liste.

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

BON MARCHÉ et BON vérifié, mais FAST désactivé

J'ai testé avec Ruby 2.1.0 et Tk 8.5.15.

  • o[c]est un prédicat à tester si le bouton cocher cest sélectionné. Avec ou par défaut, c.variable.valueis '0'ou '1', la comparaison de chaînes n'est vraie que si '1'>'0'. EDIT: J'ai sauvegardé 1 octet (219 à 218) en changeant '0'à ?0. En Ruby, ?0est une constante de caractère.
  • a.count(&o) utilise le prédicat pour compter les cases à cocher sélectionnées.
  • Lorsque l'utilisateur bascule un bouton à cocher, la commande appelle a.mapen boucle pour tous les boutons, les rendant :normalou :disabled.
Kernigh
la source
1
Très bien. Aucune règle ici rupture - Je faisais référence à une liste case à cocher contrôle qui peut arriver à faire partie du cadre linguistique. Je pense que toutes les réponses jusqu’à présent utilisent une carte ou un sélecteur, c’est donc tout à fait légitime.
Bruce Pierson
5

Merci à Rotem et Johnbot pour l'aide au golf!

C # 343 334

Celui-ci utilise la même "astuce" que la réponse Java de Quincunx - les cases à cocher ne sont pas réellement désactivées; ils ne vous permettent tout simplement pas de vérifier si cette vérification fait 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);}}

Il y a aussi un bug mineur qui vous empêche de fermer la fenêtre après avoir coché la troisième case à moins d'en désélectionner une, car la validation ne passera pas. Mais c'est du , alors qui s'en soucie? ;)

C # 403 397 374

C’est un bon moyen qui désactive la troisième case à cocher.

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

Capture d'écran

Un peu non golfé:

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);
    }
}
Bob
la source
1
Ne pourrait pas if(a.Count(b=>b.Checked)==2)e.Cancel=true;être réécrit comme e.Cancel=a.Count(b=>b.Checked)==2;?
Rotem
@Rotem Oui, oui, c'est possible. Je suis stupide. Et il y a une optimisation similaire pour l'autre. Merci!
Bob
Attends, non, il n'y en a pas pour l'autre. Eh, encore sauvé quelques caractères.
Bob
1
Si vous passez l'héritage à CheckBox, utilisez les initialiseurs d'objet et abusez un peu de Linq, vous pouvez obtenir le nombre correct jusqu'à 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 si vous utilisez l'opérateur conditionnel à la place de l'instruction if. Remplacer if(a.Count(b=>b.Checked)>1){a.First(b=>!b.Ch‌​ecked).Enabled=1<0;}else a.All(b=>b.Enabled=0<1);para.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>
utilisateur12345
la source
J'ai essayé cela chez JSFiddle, mais sans succès . Pouvez-vous donner un exemple de travail?
ossifrage délirant
Vous n'avez pas mentionné "ng-app". Vérifiez <head> dans mon exemple.
user12345
1
Ah, OK :-) Vous pouvez jouer un peu en supprimant les guillemets et les sauts de ligne supplémentaires.
ossifrage délirant
4

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

Grâce à un commentaire de brillant @ Matt, j'ai réduit le code de 27 caractères.

JSFiddle

Le nom d'affichage est manquant
la source
Économisez environ 25% en déplaçant votre condition $(e+c).length>1dans l'affectation en tant que telle: $(e).not(c).attr(f,$(e+c).length>1)vous ne modifiez que le booléen lui-même.
Matt
1
Nous avons réussi à le réduire à 169 en utilisant un mélange de vôtre et de mien. La !!contrainte et un peu plus de golf avec ne pas assigner le corps à 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

Une version plus codée, suggérée par David, de 255 caractères :

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"
   }
 ]
Communauté
la source
Vous pouvez enregistrer certains caractères en utilisant h=Checkbox;i=Dynamic;j=Enabled.
DavidC
@DavidCarraher Merci, je peux me voir utiliser cette technique pour d'autres questions sur le golf dans le futur.
1
Pas besoin d'inclure les deux versions. Et n'oubliez pas d'utiliser het d'ajuster votre nombre de caractères dans l'en-tête.
DavidC
4

script mIRC ( 727 719 octets)

J'ai oublié cette langue jusqu'à une conversation ivre la nuit dernière.

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

Plus devrait être codé dans cette langue! Mais il doit y avoir un moyen de faire en sorte que cela devienne un véritable gâchis pour que ce soit aussi efficace que Perl.

Edit: remarqué que mes Python-isms fuyaient et était capable de réduire le code de 8 octets!

un monstre
la source
Haha, j'aime l'intro de celui-ci. C'est un peu bavard cependant - est-ce que ce serait la bière qui parle? = c)
Bruce Pierson
3

C #, 335 333 326 320 308

Basé sur Bobs Answer, le mien utilise moins de caractères que le sien (335 v 342), mais je ne comprendrais peut-être pas comment compter cela.

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();
    }
}
iamkrillin
la source
Excellente utilisation des fonctions anon et Linq ici, en particulier comme le Select.
Bruce Pierson
Vous pouvez enregistrer quelques caractères supplémentaires en remplaçant le ==2avec un >1, et le truepar un 1>0. Vous pouvez également utiliser un Allau lieu de Whereet Last. ToListest également plus court que ToArray.
Bob
@Bob Bon appel, je ne sais pas comment j'ai raté Tout (), et en bonus, il s'avère que vous n'avez pas besoin de le concrétiser, ce qui vous fait économiser encore plus
iamkrillin
3

Groovy - 357 221 217 caractères

J'ai porté la solution de Quincunx sur Groovy 2.2.1, en utilisant SwingBuilder (et je l’ai encore plus rendu en 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()
Michael Easter
la source
3

QML - 369 315 254 251 248 octets

Voici la version QML (QtQuick 2.0), étant donné le contenu du fichier .qml. Ce code nécessite au moins Qt 5.1 pour s'exécuter. Ce n'est pas bien grave, car son rapport est énorme par rapport à d'autres solutions ( 248 octets ), mais il s'agit d'une application multi-plateformes complète (Android et iOs inclus)! :RÉ

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

Dialogue de mise en page horizontale

Pour l'exécuter, enregistrez le code dans un fichier .qml, installez Qt 5.1 et exécutez qmlscene.exe (ou simplement qmlscene sur linux), ce qui affichera une boîte de dialogue de fichier ouverte. Choisissez le fichier .qml que vous avez enregistré le code et voyez le résultat génial! :RÉ

Eduard Sukharev
la source
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

le code est ici

échantillon échantillon
(source: nsl.com )

Stevan Apter
la source
ligne 1: un dictionnaire à trois variables; ligne 2: chaque variable est un bouton à cocher; ligne 3: étiquette le dictionnaire; ligne 4: si trois variables ont été vérifiées, réinitialisez la dernière variable contrôlée à 0; ligne 5: affiche le dictionnaire.
Stevan Apter
Agréable! Une telle tragédie k4 n'a pas d'interface graphique ...
mollmerx
k gagne (mais oh ironie! il faut encore 9 caractères pour pouvoir poster!)
Stevan Apter
2

JavaScript / jQuery 237 234 229

Approche très similaire à celle de Matt , bien qu’un peu plus longue.

$(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)})})
sshow
la source
2

JavaScript 209 (avant 346)

Raccourci: merci pour les commentaires.

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

Fonction golfée:

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

Formulaire HTML: fournit une entrée et appelle la fonction. * Le formulaire utilise maintenant class = x pour regrouper les entrées.

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

Testé avec NetBeans et Chrome.

bacchusbeale
la source
Vous pouvez continuer à jouer à la fonction et la réduire à 264 caractères en consolidant tous vos vars, en supprimant les accolades et les espaces inutiles (y compris les caractères de nouvelle ligne). Vous pourriez probablement le réduire si vous utilisez un ES6 lambda.
Tony Ellis
En dehors de la pratique plus évidente du golf, envisagez d'utiliser une classe pour rassembler tous les éléments d'entrée dans un tableau en un hit, en utilisant getElementsByClassNamepar exemple. a=document.getElementsByClassName('q').
Matt
changer les ids de nommer et de les appeler avec document.a, document.c, document.cles mettre aussi directement dans un []
Frieder
2

Sensationnel

Basé sur la version Java, mais beaucoup allégé;)

Les types ont été remplacés par 'def', les points-virgules ont été supprimés, add a été remplacé par <<, le 1 <0 a été remplacé par 0, collectés pour la création des cases à cocher, a supprimé le type itemevent, supprimé en lançant la case à cocher, a amélioré les boucles.

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()
    }
}
Erik Pragt
la source
Groovy n'est pas java. Cela signifie que toutes ces améliorations ne comptent pas autant. Tout ce que vous avez supprimé était nécessaire en Java, mais pas groovy.
Justin
1
Tu as raison, Groovy n’est pas Java, c’est pourquoi on l’appelle Groovy. Je ne suis pas sûr de ce que vous essayez de dire ici.
Erik Pragt
1

TCL 347

Au moins, il bat Python et 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

Remarque: si vous commencez par cocher une case et la désélectionnez immédiatement, vous obtiendrez une erreur. Vous pouvez résoudre ce problème en ajoutant 110à la fin de la première ligne.

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
Kevin
la source
1

Javascript + Knockout: ~ 250 caractères

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([])})
Origineil
la source
0

AngularJS - 155 ( démo )

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 version non-golfée:

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>
Trou noir
la source
0

Rubis avec chaussures, 133 personnages

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}

Exemple de sortie:

Capture d'écran de la fenêtre chaussures

homme au travail
la source
0

AppleScript, 194 190 octets (à peu près sûr que c'est tricher un peu ...)

Deux problèmes existent:

  • AppleScript ne contient aucune case à cocher, mais uniquement des listes.
  • Il n’ya qu’une option pour sélectionner UN dans la liste ou TOUT montant.

Circonventions:

  • Utilisation d'une boucle de répétition infinie avec un point d'arrêt pour avoir une sortie lorsque 2 et seulement 2 éléments de la liste sont sélectionnés.
  • Je me suis puni avec un display alertcomposant qui me donne 30 octets de longueur supplémentaires.

Raisonnant derrière moi en affichant ceci:

  • Il est la façon de le faire en AppleScript.
  • Le code ne peut pas être complet avec trois options sélectionnées. La troisième option est donc désélectionnée par extension .

Publier principalement ceci pour montrer la puissance d'AppleScript dans les interactions Aqua / GUI.

répéter
choisir dans la liste {"RAPIDE", "BON MARCHÉ", "BON" "} avec invite" CHOISISSEZ LES DEUX "avec plusieurs sélections autorisées
si le nombre d'éléments du résultat <= 2
repetez la sortie
autre
Alerte d'affichage "PLEASE PICK TWO"
fin
fin

exécution gif

Si vous pensez que cela est trop compliqué, demandez-moi de le supprimer.

Addison Crump
la source
C'est sauvage! C'est la langue la plus anglaise que j'ai jamais vue.
Bruce Pierson
C'est vraiment dommage qu'ils n'aient pas quelque chose comme "avec 2 sélections requises" ou quelque chose du genre.
Bruce Pierson
@BrucePierson Ouais, AppleScript est un langage étrange. ¯ \ _ (ツ) _ / ¯ Je ne l'utilise que pour de petites choses, il est assez difficile d'obtenir quelque chose de réel avec.
Addison Crump
Celles-ci ne sont pas cochées, ce qui rend la réponse "trop ​​éloignée" des règles. Je vous demande par la présente de supprimer.
pppery
0

FLTK, 303 caractères

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

Exemple de sortie:

Capture d'écran de la fenêtre FLTK

homme au travail
la source