Rápido, barato y bueno: elija dos

43

Como programadores, todos conocemos el dicho: "Puedes tenerlo rápido y bien, pero no será barato, puedes tenerlo barato y bueno, pero no será rápido, o puedes tenerlo rápido y barato , pero no será bueno ".

Para este desafío, está implementando una herramienta de configuración imaginaria para sus servicios de programación personalizados. Debe representar un conjunto de tres casillas de verificación, con el título "SELECCIONE CUALQUIERA DOS":

SELECT ANY TWO  
☐ FAST  
☐ CHEAP  
☐ GOOD

Una vez que se han seleccionado dos elementos, el tercer elemento debe deshabilitarse. Al anular la selección de uno de los dos elementos seleccionados, todas las opciones deben volver a habilitarse. Dicho de otra manera, si se seleccionan cero o un elemento, todos están habilitados, pero si se seleccionan dos elementos, el tercero debe desactivarse.

No se permiten controles especiales. Las casillas de verificación deben ser la casilla de verificación estándar en su idioma de elección. Por ejemplo, no use un control "CheckBoxList", si su idioma tiene uno. Me imagino que la mayoría de las entradas serán HTML / jQuery, pero eso no es una regla. Este es el código de golf, buscando la entrada más corta.

GANADORES HASTA AHORA

Lo dividiré en categorías. Hay algunos ganadores claros:

jQuery: nderscore, Mr. Tenacity Under 100b cuando excluye "recursos" de texto. Mención de honor también debe ir a Matt por presentar los conceptos jQuery de los que muchos se inspiraron.

Dyalog APL: marinus, también conocido como Mr. Unicode ¿Cómo se escriben todas esas cosas? Puedo ver por qué querrías escribir programas cortos.

PHP: SuperScript Creo que esta es la entrada más corta que en realidad desactiva en lugar de deseleccionar la tercera opción, siguiendo la interpretación más estricta de las reglas.

Bruce Pierson
fuente
¿Puedo hacer que solo se puedan seleccionar dos a la vez? ¿De modo que seleccionar el tercero anula la selección de uno de los otros? ¿O tal vez agregue un botón de aceptación que se atenúa si se seleccionan 3 opciones?
Justin
77
@Quincunx: dado que no hay heurística (fuera de la lectura de la mente) que pueda decidir cuál anular, esto confundiría al usuario ... así que tendré que decir que no, porque no queremos la primera impresión de nuestros servicios de software personalizados son malos. ;)
Bruce Pierson
Esta pregunta me interesó en el tkinter de Python 3, así que estoy tratando de aprender eso ahora. En mi opinión, la mejor manera de aprender GUI es por prueba y error. Intenté esto: ideone.com/YHLZIQ . Resultado: apertura rápida de nuevas GUI. Tuve que abrir el administrador de tareas para cerrarlos. :-). Imagen (el número pronto subió a 340: i.stack.imgur.com/c9wQi.png )
Justin
El concurso de bonificación debería ser otra cuestión, ya que no existe un criterio objetivo primario ganador ni ninguna descripción del "bonus". Decía que el código debería ser "... elegante y flexible ..." y "... conciso y claro ...", lo que va en contra del código-golf . VTC como no está claro lo que está preguntando. Por favor, no cambie radicalmente las preguntas mucho después de que se hagan.
user80551
1
@BrucePierson En realidad, lo hay. Podríamos anular la selección de la casilla de verificación seleccionada más antigua. Sin embargo, el código para eso sería mucho más que el código que necesita.
Justin

Respuestas:

23

Javascript ( ES5 ) con jQuery - 143 ( Demo )

He modificado solución de Matt y Jugamos al golf es tan abajo como creo que puede ir:

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

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

Usar jQuery es una especie de trampa, así que aquí hay una solución sin ella:

(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 se nos permite evitar que el usuario marque la tercera casilla en lugar de deshabilitar el campo, podemos hacerlo aún más corto:

Con jQuery - 126 123 ( Demo )

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

Sin jQuery - 150 147 ( Demostración )

(d=document).write(["SELECT ANY TWO","FAST","GOOD","CHEAP"].join("<input type=checkbox onclick=this.checked*=!d.querySelectorAll(':checked')[2]>"))
nderscore
fuente
Guay. ¡Usar .joines un buen truco!
Robbie Wxyz
1
"SELECT ANY TWO0FAST0GOOD0CHEAP".replace(/0/g,Es otra forma de hacerlo resultando en la misma longitud.
nderscore
solo siendo exigente, la versión de jquery debería usar prop, no attr
Einacio
@Einacio tu deseo es mi comando!
nderscore
55
@Einacio ¡Pero codegolf trata de las peores prácticas! : 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/

EDITAR: mejorado con la ayuda de @Daniel Lisik - https://codegolf.stackexchange.com/a/26805/16278

Mate
fuente
55
¡Agradable! No hay suficiente representante para votar ... ¡pero estás contratado!
Bruce Pierson
2
Cuanto más miro esto, más aprendo. La inteligencia de la asignación de variables dentro de un selector jQuery. Muy genial. Además, ¿podría explicar qué está haciendo el "doble golpe" (!!)?
Bruce Pierson
1
La explosión simple, coacciona un valor booleano, y el doble obviamente lo invertirá. undefinedcoacciona a la verdad. Eso y la asignación variable son probablemente los únicos pequeños trucos utilizados realmente.
Matt
Su código puede reducirse a 179 caracteres como este: 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 (en Windows) (169)

Esta es una función estática, para probarla si no conoce APL, escriba )ed Cy pegue esto en la ventana de edición, luego ejecútelo 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}

Los bits más nuevos de APL tienen palabras clave largas . Aunque todavía vencí a HTML.

Explicación:

  • 'R'⎕WC'Form' 'Select any two',2/⊂S←2/20: cree un formulario R, con título Seleccione dos y cualquier tamaño y posición 20 20. También tiendas 20 20en S.
  • 1 21 41{... }¨'Fast' 'Cheap' 'Good': para cada uno de estos pares de datos (nombre y coordenada y, que son las únicas variables que difieren entre las casillas de verificación:
    • ('R.',⊃⍵)⎕WC'Button': crea un botón Rcon la primera letra del nombre,
    • ⍵(⍺1)S'Check': con el argumento correcto como título, (left arg, 1)como posición, reutilizando Scomo tamaño y Checkestilo,
    • ('Event' 'Select' 'F'), que llama a la función Fcuando se hace clic.
  • B←R.(F C G): utilícelo Bcomo abreviatura de las tres casillas de verificación que creamos
  • F←{... }: define la función de devolución de llamada como:
    • X←B.State: obtenga el estado de cada casilla de verificación y guárdelos X,
    • X∨2≠+/X: suma X, si esto no es igual a dos, todas las casillas de verificación deben estar activas, si es igual a dos, solo las casillas de verificación deben estar activas
    • B.Active←: habilitar o deshabilitar las casillas de verificación

Resultado:

captura de pantalla

marinus
fuente
Gran explicación, gracias!
Bruce Pierson
11

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

Pensé, Python debe ser más corto que Java. Aquí está la "prueba" ( EDITAR: ahora realmente es más corta ):

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

Para aquellos de ustedes que tengan curiosidad sobre lo que la execexpresión realmente ejecuta, ejecuta esto (esto es lo que hacen los reemplazos en la cadena. Se agregaron nuevas líneas para facilitar la lectura):

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

Esto utiliza la misma lógica que mi respuesta Java: desmarque la casilla de verificación si hace que se seleccionen más de 2 casillas de verificación. UNF Afortunadamente Por desgracia, pasé más menos más bytes hacer esto.

ingrese la descripción de la imagen aquí

EDICIONES:

  1. ajuste masivo de código para usar exec, ¡ahorrando la friolera de 1 byte!
  2. cambió a python 2 para exprimir dos bytes de exec(eliminar paréntesis).
  3. Más golf. Incluye cambiando range(3)a 0,1,2y el cambio de la indentación para tener una capa de pestañas. No estoy seguro de si \t\tfuncionaría en lugar de \t__( _es el carácter de espacio). Finalmente llegué a la respuesta Java más larga que he tenido.
  4. usado reemplazar truco
  5. se utiliza la sugerencia de Bakiru y golfed un poco más. En realidad lo hizo más corto que Java! Pero ahora, la respuesta de Java se jugó más, así que esto es nuevamente más largo. :-(
  6. truco de reemplazo mejorado utilizado .
  7. cambiado a !=por a -.
Justin
fuente
Enfoque interesante +1
cjfaure
Puedo hacer trampa con el modo turbo en mi teclado. Primero, marco dos casillas. En segundo lugar, uso Tab para resaltar el tercero. Ahora mantengo la barra espaciadora en modo turbo durante unos segundos. ¡A veces, esto marca la tercera casilla!
kernigh
@kernigh Creo que eso se debe a que mi código llega al punto en que sabe que la caja se ha activado, pero el código no ha llegado al punto en que vuelve a activar la caja. Entonces, si activa la casilla en ese momento (apagado), mi código pondrá una marca de verificación en él.
Justin
1
Puede evitar el bloque sangrado con if p[i]el uso de un andlugar de una if: if p[i]:s>1 and B[i].toggle();s+=1.
Bakuriu
@kernigh me equivoqué; reemplazar B[i].toggle()con B[i].deselect()no cambia nada. No tengo idea de por qué esto es así. Tal vez sea un defecto contkinter
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]]

Sin golf:

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

Este es el dialecto Rebol 3 View (r3-gui). Screendump a continuación de Ubuntu Linux:

ejemplo de vista de rebol 3

Actualización : gracias a Earl & Graham de Rebol SO Chatroom por afeitar 22 caracteres del código: http://chat.stackoverflow.com/transcript/message/16345039#16345039

draegtun
fuente
Es una respuesta no válida, ya que el tercero está deshabilitado pero también está marcado, eso significa que los 3 están marcados, así que corríjalo.
ST3
2
@ ST3 - Me temo que estás incorrecto. La casilla de verificación "BUENA" no está marcada o de hecho deshabilitada (mi código simplemente apaga la tercera casilla marcada como DESACTIVADA). Así es como la vista Rebol 3 muestra una casilla sin marcar (por defecto).
draegtun
1
@ ST3 et al - Aquí hay un enlace que muestra el aspecto de casilla de verificación predeterminado que describí anteriormente (la primera imagen no muestra casillas de verificación presionadas, la segunda simplemente "BUENA") - plus.google.com/u/0/104216037702741908932/posts/Z2EbuQX67aq
draegtun
Bueno ... Miro la pantalla de impresión que agregaste y veo las tres casillas marcadas, solo una no se puede desmarcar.
ST3
3
@ ST3: una casilla de verificación atenuada es solo Rebol 3 Ver la forma de mostrar que es una casilla de verificación que se puede marcar. La marca se vuelve verde cuando está marcada y vuelve a gris cuando no está marcada. Estos son los valores predeterminados. En la imagen de la respuesta anterior, puede ver que "BUENO" es el foco de entrada (desenfoque azul) porque se está "haciendo clic" pero permanece gris y no verde (por lo tanto, no está marcado).
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 ... porque Java. Código de aspecto más agradable:

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

Ejecución de muestra (diferentes tamaños de la ventana, primero está en el inicio):

ingrese la descripción de la imagen aquí
ingrese la descripción de la imagen aquí
ingrese la descripción de la imagen aquí

Las casillas de verificación están dispuestas horizontalmente; Esto está permitido . Se necesitaría mucho más para alinearlo correctamente. Además, estoy deshabilitando desmarcando la casilla cuando se hace clic , no haciendo imposible que se haga clic.

EDICIONES:

  1. ahorró 3 bytes al extender la clase principal Checkbox.
  2. volví a leer las expresiones de Lambda y me di cuenta de que el nombre del tipo era innecesario. ¡Toma esa Python!
  3. convirtió un whilebucle en un bucle foreach (gracias Lee ); ¿Por qué no pensé en eso antes?
  4. ahorró 18 bytes mediante el uso de una clase anónima y un inicializador de instancias para ambos Framey Panel.
Justin
fuente
No hay restricción en la alineación (así que supongo que Matt podría reducir la suya en 5 caracteres). Accesorios para un programa completo en ejecución ... pero no veo que la tercera opción esté desactivada.
Bruce Pierson
@BrucePierson Está deshabilitado. No se puede hacer clic. Si se hace clic, no pasa nada.
Justin
2
Ah, creo que ya veo. ¿Inmediatamente está "desarmando" el estado marcado sin deshabilitar? Eso sería aceptable.
Bruce Pierson
@BrucePierson Eso es correcto. Para deshabilitar realmente, tendría que cambiar if(x>2)((Checkbox)e.getSource()).setState(1<0);aif(x>2){Checkbox b=(Checkbox)e.getSource();b.setState(1<0);b.setEnabled(1<0);}
Justin
1
@BrucePierson Siempre que pienses, esto se ve divertido cuando tiene que ver con el uso de una representación de caracteres de alguna cosa gráfica, busca unicode. Alternativamente, para cosas de diseño gráfico, diríjase a User Experience SE : i.stack.imgur.com/xFkzy.png
Justin
7

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

Porque, porque no.

Sorprendentemente, a partir de ahora somos más bajos que Python, y el C # sin errores, ¡y atados con Java!

Créditos a EveBird por reducirlo de 561 a 481.

¡Y una vez más EveBird lo acorta de 481 a 433!

Tomó algunos con una conexión lambda

Hasta 389 con inicializadores C ++ 11

Y 373 sin la clase separada

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

Tipo de sin golf:

#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
fuente
1
+1 para el auto-flagelante "por qué no" :)
Bruce Pierson
Puede mejorar un poco más: reemplazar QWidget mcon QDialog my m.show();a.exec()con m.exec().
Toby Speight
6

CoffeeScript - 167154

Puerto CoffeeScript de la respuesta 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]

Algo no golfista:

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

PHP, Javascript, jQuery - 135b

Estaba admirando la respuesta de @ nderscore, pero luego decidí copiarlo y unirlo.

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

Básicamente, reemplacé su .jointruco con un preprocesamiento de hipertexto PHP.

Robbie Wxyz
fuente
Cuando considera que se requieren 27 bytes para el texto "recursos" en el programa, esto se está acercando mucho a un programa 100b. ¡Bien hecho!
Bruce Pierson
1
No soy un gran jugador de PHP, pero le corté algunos bytes: (128)SELECT ANY TWO<?=($m="<input type=checkbox onclick=(a=$('input:not(:checked)')).prop('disabled',!a[1])>").FAST.$m.GOOD.$m.CHEAP;
nderscore
5

Rubí, 219 218 bytes

Uso los mismos widgets Tk que la respuesta de Python 3 de Quincunx.

Este programa rompe las reglas porque tiene una lista de casillas de verificación . (Las reglas decían: "No use una lista de casillas de verificación"). Sí, aes una matriz de 3 objetos TkCheckButton, y creo que una matriz es una lista. Mi defensa es que no utilicé ninguna lista de casillas de verificación existente, pero utilicé las casillas de verificación estándar e hice mi propia lista.

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

BARATO y BUENO marcado, pero RÁPIDO deshabilitado

Probé con Ruby 2.1.0 y Tk 8.5.15.

  • o[c]es un predicado para probar si cse selecciona el botón de verificación . Con las cadenas predeterminadas, c.variable.valuees '0'o '1', por lo que la comparación de cadenas solo es verdadera si '1'>'0'. EDITAR: guardé 1 byte (219 a 218) cambiando '0'a ?0. En Ruby, ?0es un personaje constante.
  • a.count(&o) usa el predicado para contar los botones de verificación seleccionados.
  • Cuando el usuario alterna un botón de verificación, el comando llama a.mapal bucle para todos los botones, haciéndolos :normalo :disabled.
kernigh
fuente
1
Muy bien. No hay ninguna regla romper aquí - Me refería a una lista casilla de control que pueden pasar a ser parte de la estructura del lenguaje. Creo que todas las respuestas hasta ahora usan algún tipo de mapa o selector, por lo que esto es totalmente legítimo.
Bruce Pierson
5

¡Gracias a Rotem y Johnbot por la ayuda en el golf!

C # 343 334

Éste usa el mismo "truco" que la respuesta Java de Quincunx : las casillas de verificación no están realmente desactivadas; simplemente no le permiten verificarlos si ese cheque es 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);}}

También hay un error menor que no puede cerrar la ventana después de seleccionar la tercera casilla de verificación a menos que deseleccione uno, porque la validación no pasará. Pero esto es , entonces, ¿a quién le importa? ;)

C # 403 397 374

Esta es una correcta que deshabilita la tercera casilla de verificación.

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

Captura de pantalla

Un poco desanimado:

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);
    }
}
Mover
fuente
1
No se pudo if(a.Count(b=>b.Checked)==2)e.Cancel=true;reescribir como e.Cancel=a.Count(b=>b.Checked)==2;?
Rotem
@Rotem Sí, sí podría. Soy tonto. Y hay una optimización similar para el otro. ¡Gracias!
Bob
Espera, no, no hay para el otro. Eh, aún guardo algunos caracteres.
Bob
1
Si cambia la herencia a CheckBox, usa inicializadores de objetos y abusa un poco de Linq, puede obtener el correcto hasta 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 usa el operador condicional en lugar de la instrucción if. Reemplazar 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>
user12345
fuente
Probé esto en JSFiddle, pero sin ningún éxito . ¿Puedes dar un ejemplo de trabajo?
aprensivo ossifrage
No mencionaste "ng-app". Marque <head> en mi ejemplo.
user12345
1
Ah, está bien :-) Puede jugar un poco menos al eliminar las comillas y los saltos de línea adicionales.
aprensivo ossifrage
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)})

Gracias a un comentario del brillante @Matt reduje el código en 27 caracteres.

JSFiddle

falta el nombre para mostrar
fuente
Ahorre aproximadamente 25 moviendo su condición $(e+c).length>1a la tarea como tal: $(e).not(c).attr(f,$(e+c).length>1)ya que solo está cambiando el booleano.
Matt
1
Logré reducirlo a 169 usando una mezcla de la suya y la mía. La !!coerción y un poco de golf extra con no asignar cuerpo 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

Mathematica

Una versión más codificada como sugiere David, 255 caracteres :

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"
   }
 ]
Comunidad
fuente
Puede guardar algunos caracteres usando h=Checkbox;i=Dynamic;j=Enabled.
DavidC
@DavidCarraher Gracias, también puedo verme usando esa técnica para otra pregunta de golf de código en el futuro.
1
No es necesario incluir ambas versiones. Y no olvide usar hy ajustar su recuento de caracteres en el encabezado.
DavidC
4

script de mIRC ( 727 719 bytes)

Olvidé este idioma hasta una conversación borracha anoche.

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

¡Más debe codificarse en este idioma! Pero debe haber una manera de convertir esto en un verdadero desastre para que pueda ser tan bueno como Perl.

Editar: ¡noté que mis Python-isms se filtraban y pude reducir el código en 8 bytes!

afreak
fuente
Jaja, me gusta la introducción de este. Sin embargo, es algo detallado: ¿podría ser la cerveza hablando? = c)
Bruce Pierson
3

C #, 335 333 326 320 308

Basado en Bobs Answer, el mío usa menos caracteres que el suyo (335 v 342), pero es posible que no entienda completamente cómo contar esto.

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

Sin golf

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
fuente
Gran uso de las funciones anon y Linq aquí, especialmente como Select.
Bruce Pierson
Puede guardar un par de caracteres mediante la sustitución de la ==2de una >1, y la truede una 1>0. También puede usar un en Alllugar de Wherey Last. ToListTambién es más corto que ToArray.
Bob
@Bob Buena llamada, no sé cómo me perdí All () y, como beneficio adicional, resulta que no tienes que materializarlo, ahorrando aún más
iamkrillin
3

Groovy - 357 221 217 caracteres

Me he portado solución de QUINCUNCIO a Groovy 2.2.1, utilizando SwingBuilder (y lo hizo aún más groovy):

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

Sin golf:

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

QML - 369 315 254 251 248 bytes

Aquí va la versión QML (QtQuick 2.0), dado solo el contenido del archivo .qml. Este código requiere Qt 5.1 al menos para ejecutarse. ¡No es un gran problema ya que es enorme en comparación con otras soluciones ( 248 bytes ), pero es una aplicación multiplataforma con todas las funciones (Android e iOs incluidos)! :RE

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

Diálogo de diseño horizontal

Para ejecutarlo, guarde el código en un archivo .qml, instale Qt 5.1 y ejecute qmlscene.exe (o simplemente qmlscene en linux), que mostrará un diálogo de archivo abierto. ¡Elija el archivo .qml en el que ha guardado el código y vea el increíble resultado! :RE

Eduard Sukharev
fuente
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

el código está aquí

muestra de ejecución
(fuente: nsl.com )

Stevan Apter
fuente
línea 1: un diccionario con tres variables; línea 2: cada variable es un botón de verificación; línea 3: etiquetar el diccionario; línea 4: si se han verificado tres variables, restablezca la última variable verificada a 0; línea 5: muestra el diccionario.
Stevan Apter
¡Agradable! Tal tragedia k4 no tiene GUI ...
mollmerx
k gana (¡pero oh ironía! ¡Se requieren 9 caracteres más para publicar!)
Stevan Apter
2

JavaScript / jQuery 237 234 229

Enfoque muy similar a la respuesta de Matt , aunque un poco más.

$(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
fuente
2

JavaScript 209 (antes 346)

Acortado: gracias por los comentarios.

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

Función de golf:

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

Forma HTML: proporciona entrada y llama a la función. * El formulario ahora usa class = x para agrupar entradas.

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

Probado con NetBeans y Chrome.

bacchusbeale
fuente
Puede desarrollar aún más la función y reducirla a 264 caracteres al consolidar todos sus varcorreos electrónicos, eliminando llaves y espacios en blanco innecesarios (incluidos los caracteres de nueva línea). Probablemente podría hacerlo más pequeño si usa un lambda ES6.
Tony Ellis
Además de algunos juegos de golf más obvios, considere usar una clase para extraer todos los elementos de entrada en una matriz en un solo golpe, usando getElementsByClassNameeg. a=document.getElementsByClassName('q').
Matt
cambiar los identificadores de nombre y sólo los llaman con document.a, document.c, document.ctambién ponerlos directamente en un []
Frieder
2

Maravilloso

Basado en la versión de Java, pero adelgazado mucho;)

Los tipos fueron reemplazados por 'def', los puntos y comas fueron removidos, agregar reemplazado por <<, el 1 <0 reemplazado por 0, recolectar para crear las casillas de verificación, eliminar el tipo de evento iterativo, eliminar la conversión de casillas de verificación, mejorar los bucles.

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
fuente
Groovy no es Java. Eso significa que todas esas mejoras no cuentan tanto. Todo lo que eliminó fue necesario en Java, pero no maravilloso.
Justin
1
Tienes razón, Groovy no es Java, por eso se llama Groovy. No estoy seguro de lo que estás tratando de decir aquí.
Erik Pragt
1

TCL 347

Al menos supera a Python y 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: si comienza seleccionando una casilla de verificación e inmediatamente deseleccionándola, recibirá un error. Puede solucionarlo agregando 110al final de la primera línea.

Sin golf:

# 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
fuente
1

Javascript + Knockout: ~ 250 caracteres

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
fuente
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 versión sin golf:

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>
Agujero negro
fuente
0

Ruby with Shoes, 133 caracteres.

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}

Salida de muestra:

Captura de pantalla de la ventana de zapatos

hombre trabajando
fuente
0

AppleScript, 194 190 Bytes (bastante seguro de que esto está engañando un poco ...)

Existen dos problemas:

  • No hay casillas de verificación en AppleScript, solo listas.
  • Solo existe la opción de seleccionar UNO de la lista o CUALQUIER cantidad.

Circunvenciones:

  • Usando un ciclo de repetición infinito con un punto de ruptura para tener una salida cuando se seleccionan 2, y solo 2, elementos en la lista.
  • Me castigé con un display alertcomponente que me da 30 bytes adicionales de longitud.

Razonamiento detrás de mí publicando esto:

  • Que es la manera de hacer esto en AppleScript.
  • El código no puede completarse con tres opciones seleccionadas, por lo que la tercera opción no está seleccionada por extensión .

Principalmente publicando esto para mostrar el poder de AppleScript en la interacción Aqua / GUI.

repetir
elija de la lista {"RÁPIDO", "BARATO", "BUENO"} con el mensaje "ELIJA CUALQUIERA DOS" con múltiples selecciones permitidas
si el número de elementos del resultado <= 2
salir repetir
más
muestra alerta "POR FAVOR, SELECCIONA DOS"
fin
fin

gif de ejecución

Si cree que esto está demasiado apagado, solicite que lo elimine.

Addison Crump
fuente
Esto es salvaje! Ese es el idioma más parecido al inglés que he visto.
Bruce Pierson el
Es realmente una pena que no tengan algo como "con 2 selecciones requeridas" o algo por el estilo.
Bruce Pierson
@BrucePierson Sí, AppleScript es un lenguaje extraño. ¯ \ _ (ツ) _ / ¯ Solo lo uso para cosas pequeñas, es bastante difícil hacer algo real con él.
Addison Crump
Estos no están marcados, lo que hace que esta respuesta esté "demasiado apagada" de las reglas. Por la presente le pido que elimine.
pppery
0

FLTK, 303 caracteres

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

Sin golf:

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

Salida de muestra:

Captura de pantalla de la ventana FLTK

hombre trabajando
fuente