Rápido, barato e bom - escolha dois

43

Como programadores, todos conhecemos o ditado: "Você pode obtê-lo rápido e bom, mas não será barato, você pode obtê-lo barato e bom, mas não será rápido, ou você pode obtê-lo rápido e barato , mas não será bom. "

Para esse desafio, você está implementando uma ferramenta de configuração imaginária para seus serviços de programação personalizados. Você deve renderizar um conjunto de três caixas de seleção, com o cabeçalho "SELECIONAR QUALQUER DOIS":

SELECT ANY TWO  
☐ FAST  
☐ CHEAP  
☐ GOOD

Após a seleção de dois itens, o terceiro item deve ser desativado. Ao desmarcar um dos dois itens selecionados, todas as opções devem ser novamente ativadas. Em outras palavras, se zero ou um item for selecionado, todos ainda estarão ativados, mas se dois itens forem selecionados, o terceiro deverá ser desativado.

Não são permitidos controles especiais. As caixas de seleção devem ser a caixa de seleção padrão no seu idioma de escolha. Por exemplo, não use um controle "CheckBoxList", se o seu idioma tiver um. Estou imaginando que a maioria das entradas será HTML / jQuery, mas isso não é uma regra. Este é o código de golfe, procurando a entrada mais curta.

VENCEDORES ATÉ AGORA

Vou dividir em categorias. Existem alguns vencedores claros:

jQuery: nderscore, Sr. Tenacidade Abaixo de 100b quando você exclui o texto "recursos". Menção honrosa também deve ser dada a Matt por apresentar os conceitos do jQuery dos quais muitos se inspiraram.

Dyalog APL: marinus, também conhecido como Sr. Unicode Como você digita todas essas coisas? Eu posso ver por que você gostaria de escrever programas curtos.

PHP: SuperScript Eu acredito que essa é a entrada mais curta que realmente desativa, em vez de desmarcar a terceira opção, seguindo a interpretação mais estrita das regras.

Bruce Pierson
fonte
Posso apenas fazer com que apenas dois possam ser selecionados de cada vez? Para que selecionar o terceiro desmarque um dos outros? Ou talvez adicione um botão de aceitação que fica acinzentado se 3 opções estiverem selecionadas?
Justin
7
@Quincunx - Como não há heurística (fora da leitura da mente) que possa decidir qual desmarcar, isso confundiria o usuário ... então vou ter que dizer não, porque não queremos a primeira impressão de nossos serviços de software personalizados para serem ruins. ;)
Bruce Pierson
Esta questão me interessou no tkinter do Python 3, então estou tentando aprender isso agora. Na IMO, a melhor maneira de aprender a GUI é por tentativa e erro. Eu tentei o seguinte: ideone.com/YHLZIQ . Resultado: abertura rápida de novas GUIs. Eu tive que abrir o gerenciador de tarefas para fechá-las. :-). Imagem (o número logo subiu para 340: i.stack.imgur.com/c9wQi.png )
Justin
O concurso de bônus deve ser outra questão, pois não há critério objetivo de vitória primário ou qualquer descrição do "bônus". Disse que o código deveria ser "... elegante e flexível ..." e "... conciso e claro ...", o que é contra o código-golfe . VTC como claro o que você está perguntando. Por favor, não mude radicalmente as perguntas depois que elas forem feitas.
User80551
1
@BrucePierson Na verdade, existe. Podemos desmarcar a caixa de seleção selecionada mais antiga. No entanto, o código para isso seria muito mais do que o código necessário.
8137 Justin

Respostas:

23

Javascript ( ES5 ) com jQuery - 143 ( Demo )

Eu modifiquei solução de Matt e golfed-lo, tanto para baixo como eu acho que ele pode ir:

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

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

Usar o jQuery é meio trapaceiro, então aqui está uma solução sem ele:

(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 for permitido impedir o usuário de marcar a terceira caixa em vez de realmente desabilitar o campo, podemos torná-lo ainda mais curto:

Com jQuery - 126 123 ( Demo )

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

Sem jQuery - 150 147 ( Demo )

(d=document).write(["SELECT ANY TWO","FAST","GOOD","CHEAP"].join("<input type=checkbox onclick=this.checked*=!d.querySelectorAll(':checked')[2]>"))
nderscore
fonte
Legal. Usar .joiné um bom truque!
Robbie Wxyz
1
"SELECT ANY TWO0FAST0GOOD0CHEAP".replace(/0/g,é outra maneira de fazer isso, resultando no mesmo comprimento.
Ndscore # 8/14
apenas a ser exigente, a versão jQuery deve usar prop, não attr
Einacio
@Einacio seu desejo é meu comando!
Ndscore # 8/14
5
@Einacio Mas o codegolf é sobre as piores práticas! : P
nderscore
29

JavaScript - 184 169 (com 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: aprimorado com a ajuda de @Daniel Lisik - https://codegolf.stackexchange.com/a/26805/16278

Matt
fonte
5
Agradável! Representante insuficiente para votar ... mas você foi contratado!
Bruce Pierson
2
Quanto mais eu olho para isso, mais eu estou aprendendo. A inteligência da atribuição de variável dentro de um seletor jQuery. Muito legal. Além disso, você poderia explicar o que o "double bang" (!!) está fazendo?
Bruce Pierson
1
O golpe simples, coage um valor booleano, e o duplo obviamente inverterá isso. undefinedcoage para verdadeiro. Isso e a atribuição de variáveis ​​são provavelmente os únicos pequenos truques realmente usados.
Matt
Seu código pode ser reduzido para 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 (no Windows) (169)

Esta é uma função estática; para testá-la se você não conhece o APL, digite )ed Ce cole na janela de edição e execute 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}

Os bits mais recentes do APL têm palavras-chave longas . Eu ainda bato HTML embora.

Explicação:

  • 'R'⎕WC'Form' 'Select any two',2/⊂S←2/20: crie um formulário R, com o título Selecione dois, tamanho e posição 20 20. Também armazena 20 20em S.
  • 1 21 41{... }¨'Fast' 'Cheap' 'Good': para cada um desses pares de dados (nome e coordenada y, que são as únicas variáveis ​​que diferem entre as caixas de seleção:
    • ('R.',⊃⍵)⎕WC'Button': crie um botão Rcom a primeira letra do nome,
    • ⍵(⍺1)S'Check': com o argumento correto como o título, (left arg, 1)como posição, reutilizando Scomo tamanho e Checkestilo,
    • ('Event' 'Select' 'F'), que chama a função Fquando clicado.
  • B←R.(F C G): use Bcomo abreviação para as três caixas de seleção que criamos
  • F←{... }: define a função de retorno de chamada como:
    • X←B.State: obtenha o estado de cada caixa de seleção e armazene-os X,
    • X∨2≠+/X: soma X, se não for igual a duas, todas as caixas de seleção devem estar ativas, se for igual a duas apenas caixas de seleção marcadas devem estar ativas
    • B.Active←: ativar ou desativar as caixas de seleção

Resultado:

captura de tela

marinus
fonte
Ótima explicação, obrigado!
Bruce Pierson
11

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

Eu pensei, Python deve ser mais curto que Java. Aqui está a "prova" ( EDIT: agora é realmente mais curta ):

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 aqueles que estão curiosos sobre o que a execexpressão realmente executa, ela executa isso (é o que as substituições fazem na sequência. Novas linhas adicionadas para facilitar a leitura):

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

Isso usa a mesma lógica da minha resposta Java: desmarque a caixa de seleção se faz com que mais de 2 caixas de seleção sejam selecionadas. Unf Felizmente Infelizmente, eu passei mais menos mais bytes fazendo isso.

insira a descrição da imagem aqui

EDITAR% S:

  1. ajuste maciço de código a ser usado exec, economizando 1 byte!
  2. mudou para python 2 para execextrair dois bytes do (removendo parênteses).
  3. mais golfe. Inclui mudando range(3)para 0,1,2e mudando o recuo para ter uma camada de abas. Não tenho certeza se \t\tfuncionaria em vez de \t__( _é o caractere de espaço). Finalmente chegou ao mais longo que minha resposta Java já foi.
  4. truque de substituição usado
  5. usou a sugestão de Bakiru e jogou golfe um pouco mais. Na verdade, ficou mais curto que o Java! Mas agora, a resposta do Java foi mais aplicada, então isso é novamente mais longo. :-(
  6. usado truque de substituição aprimorado .
  7. mudou a !=para a -.
Justin
fonte
Abordagem interessante. +1
cjfaure
Eu posso trapacear com o modo turbo no meu teclado. Primeiro, eu checo duas caixas. Segundo, eu uso o Tab para destacar o terceiro. Agora eu mantenho a barra de espaço no modo turbo por alguns segundos. Às vezes, isso verifica a terceira caixa!
kernigh
@ kernigh Eu acredito que é porque meu código chega ao ponto em que sabe que a caixa foi alternada, mas o código não atingiu o ponto em que re-alterna a caixa. Portanto, se você alternar a caixa nesse momento (para desativada), meu código colocará uma marca de seleção.
Justin
1
Você pode evitar o bloco recuado começando com if p[i]usando um andem vez de um if: if p[i]:s>1 and B[i].toggle();s+=1.
Bakuriu
@ kernigh eu estava errado; substituir B[i].toggle()por B[i].deselect()não muda nada. Não tenho ideia do porquê disso. Talvez seja uma falha comtkinter
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]
]

Este é o dialeto Rebol 3 View (r3-gui). Screendump abaixo do Ubuntu Linux:

exemplo de exibição rebol 3

Atualização - Agradecimentos a Earl & Graham, da Rebol SO Chatroom, por barbear 22 caracteres do código - http://chat.stackoverflow.com/transcript/message/16345039#16345039

draegtun
fonte
É uma resposta inválida, pois o terceiro está desativado, mas também marcado, o que significa que todos os três estão marcados, portanto, corrija-o.
ST3
2
@ ST3 - Você está incorreto, eu tenho medo. A caixa de seleção "BOM" não está marcada ou desativada (meu código simplesmente apaga a terceira caixa marcada como DESLIGADA). É assim que a exibição do Rebol 3 mostra uma caixa desmarcada (por padrão).
Draegtun
1
@ ST3 et al. - Aqui está um link que mostra a aparência padrão das caixas de seleção que descrevi acima (a primeira imagem não mostra caixas de seleção clicadas, a segunda apenas "BOM") - plus.google.com/u/0/104216037702741908932/posts/Z2EbuQX67aq
draegtun
Bem ... Eu olho para a tela de impressão que você adicionou e vejo as três caixas de seleção marcadas, apenas apenas uma não pode ser desmarcada.
ST3
3
@ ST3 - Uma caixa de seleção acinzentada é apenas uma maneira do Rebol 3 View de mostrar que é uma caixa de seleção que pode ser marcada. O visto fica verde quando marcado e volta para cinza quando desmarcado. Estes são os padrões. Na imagem na resposta acima, você pode ver "BOM" como o foco de entrada (desfoque azul) porque está sendo "clicado", mas permanece cinza e não verde (portanto, não 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 aparência melhor:

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

Exemplo de execução (diferentes tamanhos da janela, o primeiro é na inicialização):

insira a descrição da imagem aqui
insira a descrição da imagem aqui
insira a descrição da imagem aqui

As caixas de seleção são organizadas horizontalmente; isso é permitido . Levaria muito mais para alinhá-lo corretamente. Além disso, estou desativando desmarcando a caixa quando ela é clicada , e não impossibilitando a clicagem.

EDITAR% S:

  1. salvou 3 bytes, estendendo a classe principal Checkbox.
  2. releia as expressões lambda e percebeu que o nome do tipo era desnecessário. Tome esse Python!
  3. converteu um whileloop em um loop foreach (obrigado Lee ); por que eu não pensei nisso antes?
  4. economizou 18 bytes usando uma classe anônima e um initalizador de instância para Framee Panel.
Justin
fonte
Nenhuma restrição no alinhamento (então, suponho que Matt possa reduzir o dele em 5 caracteres). Adereços para um programa em execução completo ... mas não vejo que a terceira opção esteja desabilitada.
Bruce Pierson
@BrucePierson Está desativado. Não pode ser clicado. Se for clicado, nada acontece.
826 Justin
2
Ah, acho que estou vendo. Você está "desmarcando" imediatamente o estado verificado sem desativar? Isso seria aceitável.
Bruce Pierson
@BrucePierson Isso mesmo. Para realmente desabilitar, eu precisaria mudar if(x>2)((Checkbox)e.getSource()).setState(1<0);para #if(x>2){Checkbox b=(Checkbox)e.getSource();b.setState(1<0);b.setEnabled(1<0);}
Justin
1
@BrucePierson Sempre que você pensa, isso parece engraçado quando se trata de usar uma representação de caracteres de alguma coisa gráfica, procure unicode. Alternativamente, para o projeto de coisas gráficas, voltar-se para User Experience SE : i.stack.imgur.com/xFkzy.png
Justin
7

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

Porque porque não?

Surpreendentemente, a partir de agora somos mais curtos que o Python, e o C # que não é buggy, e empatamos com o Java!

Créditos ao EveBird por reduzi-lo de 561 para 481.

E mais uma vez, o EveBird reduz de 481 para 433!

Tirou alguns com uma conexão lambda

Até 389 com inicializadores C ++ 11

E 373 sem a classe separada

Removidos alguns espaços - 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 não golfe:

#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
fonte
1
+1 para a auto-flagelando "por que não" :)
Bruce Pierson
Pode melhorar um pouco mais: substitua QWidget mpor QDialog me m.show();a.exec()com m.exec().
perfil completo de Toby Speight
6

CoffeeScript - 167154

Porta CoffeeScript da resposta 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]

Um pouco não-destruído:

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

PHP, Javascript, jQuery - 135b

Eu estava admirando a resposta de @ nderscore, mas então decidi copiá-lo e colocá-lo em uma lista.

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

Basicamente, substituí o .jointruque dele por algum pré-processamento de hipertexto PHP.

Robbie Wxyz
fonte
Quando você considera que 27 bytes são necessários para o texto "recursos" no programa, isso está ficando muito próximo a um programa 100b. Bem feito!
Bruce Pierson
1
Eu não sou muito de um jogador de golfe PHP, mas eu picado alguns bytes fora para você: (128)SELECT ANY TWO<?=($m="<input type=checkbox onclick=(a=$('input:not(:checked)')).prop('disabled',!a[1])>").FAST.$m.GOOD.$m.CHEAP;
nderscore
5

Ruby, 219 218 bytes

Eu uso os mesmos widgets Tk da resposta Python 3 de Quincunx.

Este programa quebra as regras porque possui uma lista de caixas de seleção . (As regras diziam: "Não use uma lista de caixas de seleção".) Sim, aé uma matriz de 3 objetos TkCheckButton e acredito que uma matriz seja uma lista. Minha defesa é que eu não usei nenhuma lista de caixas de seleção existente, mas usei as caixas de seleção padrão e fiz minha própria 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 e BOM marcado, mas RÁPIDO desativado

Eu testei com Ruby 2.1.0 e Tk 8.5.15.

  • o[c]é um predicado para testar se o botão de seleção cestá selecionado. Com as cadeias padrão, c.variable.valueé '0'ou '1', portanto, a comparação de cadeias só é verdadeira se '1'>'0'. EDIT: salvei 1 byte (219 para 218), alterando '0'para ?0. Em Ruby, ?0é uma constante de caractere.
  • a.count(&o) usa o predicado para contar os botões de seleção selecionados.
  • Quando o usuário alterna um botão de verificação, o comando chama um a.maploop para todos os botões, tornando-os :normalou :disabled.
Kernigh
fonte
1
Muito bom. Nenhuma regra quebrando aqui - Eu estava me referindo a uma lista caixa de seleção controle que pode acontecer de ser parte da estrutura da linguagem. Acredito que todas as respostas até agora usam algum tipo de mapa ou seletor, então isso é totalmente legítimo.
Bruce Pierson
5

Agradecemos a Rotem e Johnbot pela ajuda no golfe!

C # 343 334

Este usa o mesmo "truque" da resposta Java do Quincunx - as caixas de seleção não estão realmente desativadas; elas simplesmente não permitem que você as verifique se essa verificação for 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);}}

Há também um pequeno erro que você não pode fechar a janela depois de marcar a terceira caixa de seleção, a menos que você desmarque uma, porque a validação não será aprovada. Mas isso é , então quem se importa? ;)

C # 403 397 374

Essa é uma opção adequada que realmente desativa a terceira caixa de seleção.

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 tela

Meio 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);
    }
}
Prumo
fonte
1
Não foi if(a.Count(b=>b.Checked)==2)e.Cancel=true;possível reescrever como e.Cancel=a.Count(b=>b.Checked)==2;?
Rotem
@ Rotem Sim, sim, poderia. Eu sou estúpido. E há uma otimização semelhante para a outra. Obrigado!
Bob
Espere, não, não há para o outro. Ainda salvou alguns caracteres.
Bob
1
Se você alternar a herança para CheckBox, initializers uso de objetos e abusar Linq um pouco você pode obter o correto para baixo para 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 você usar o operador condicional no lugar da instrução if. Substitua if(a.Count(b=>b.Checked)>1){a.First(b=>!b.Ch‌​ecked).Enabled=1<0;}else a.All(b=>b.Enabled=0<1);pora.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
fonte
Eu tentei isso no JSFiddle, mas sem sucesso . Você pode fornecer um exemplo de trabalho?
Ossifrage melindroso
Você não mencionou "ng-app". Verifique <head> no meu exemplo.
User12345
1
Ah, OK :-) Você pode jogar um pouco mais , removendo as aspas e as quebras de linha extras.
Ossifrage melindroso
4

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

Graças a um comentário do brilhante @Matt, reduzi o código em 27 caracteres.

JSFiddle

o nome de exibição está ausente
fonte
Economize 25 ou mais movendo sua condição $(e+c).length>1para a atribuição como tal: $(e).not(c).attr(f,$(e+c).length>1)uma vez que você está apenas alterando o próprio booleano.
Matt
1
Conseguiu baixar para 169 usando uma mistura sua e minha. A !!coerção e um pouco de golfe extra sem atribuir 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

Mathematica

Uma versão mais codificada, como sugerida por 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"
   }
 ]
Comunidade
fonte
Você pode salvar alguns caracteres usando h=Checkbox;i=Dynamic;j=Enabled.
DavidC
@DavidCarraher Obrigado, posso me ver usando essa técnica para outras questões sobre código de golfe no futuro também.
1
Não há necessidade de incluir as duas versões. E não se esqueça de usar he ajustar sua contagem de caracteres no cabeçalho.
DavidC
4

script mIRC ( 727 719 bytes)

Esqueci esse idioma até uma conversa bêbada na noite passada.

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

Mais deve ser codificado neste idioma! Mas é preciso haver uma maneira de transformar isso em uma verdadeira bagunça, para que possa ser tão bom quanto o Perl.

Edit: notei que meus Python-isms estão vazando e foi capaz de reduzir o código em 8 bytes!

assustar
fonte
Haha, eu gosto da introdução a este. É meio detalhado - poderia ser a cerveja falando? = c)
Bruce Pierson
3

C #, 335 333 326 320 308

Baseado no Bobs Answer, o meu usa menos caracteres que o dele (335 v 342), mas talvez eu não entenda completamente como contar isso.

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
fonte
Grande uso de funções anon e Linq aqui, especialmente como o Select.
Bruce Pierson
Você pode salvar mais alguns caracteres substituindo o ==2por um >1e o truepor um 1>0. Você também pode usar um em Allvez de Wheree Last. ToListtambém é menor que ToArray.
Bob
@Bob Boa chamada, não sei como eu perdi Todos (), e como um bônus, acaba com tudo que você não tem que materializar-lo, poupando ainda mais
iamkrillin
3

Groovy - 357 221 217 caracteres

Eu tenho portado solução de Quincunx para Groovy 2.2.1, utilizando SwingBuilder (e tornou ainda mais 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
fonte
3

QML - 369 315 254 251 248 bytes

Aqui está a versão QML (QtQuick 2.0), considerando apenas o conteúdo do arquivo .qml. Este código requer pelo menos o Qt 5.1 para ser executado. Não é grande coisa como sua enorme em comparação com outras soluções ( 248 bytes ), mas é um aplicativo de plataforma cruzada com todos os recursos (Android e iOs incluído)! : 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}}

Diálogo de layout horizontal

Para executá-lo, salve o código em um arquivo .qml, instale o Qt 5.1 e execute qmlscene.exe (ou apenas qmlscene no linux), que mostrará uma caixa de diálogo de arquivo aberto. Escolha o arquivo .qml no qual você salvou o código e veja o resultado incrível! : D

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

código está aqui

amostra de execução
(fonte: nsl.com )

Stevan Apter
fonte
linha 1: um dicionário com três variáveis; linha 2: cada variável é um botão de verificação; linha 3: rotule o dicionário; linha 4: se três variáveis ​​foram verificadas, redefina a última variável verificada para 0; linha 5: mostra o dicionário.
precisa
Agradável! Tal k4 tragédia não tem GUI ...
mollmerx
vitórias k (mas oh ironia mais 9 caracteres são necessários, a fim de post!!)
Stevan Apter
2

JavaScript / jQuery 237 234 229

Abordagem muito semelhante à resposta de Matt , embora um pouco mais.

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

JavaScript 209 (eram 346)

Encurtado: obrigado por comentários.

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

Função Golfed:

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

Formulário HTML: fornece entrada e chama a função. * O formulário agora 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>

Testado com NetBeans e Chrome.

bacchusbeale
fonte
Você pode aprimorar ainda mais a função e reduzi-la a 264 caracteres consolidando todos os seus vars, removendo chaves e espaços em branco desnecessários (incluindo caracteres de nova linha). Você provavelmente poderia diminuir se usar um lambda ES6.
Tony Ellis
Além de um jogo de golfe mais óbvio, considere usar uma classe para puxar todos os elementos de entrada em uma matriz em uma ocorrência, usando, por getElementsByClassNameexemplo. a=document.getElementsByClassName('q').
Matt
altere os IDs para nomear e apenas chame-os com document.a, document.ce document.ctambém os coloque diretamente em []
frieder
2

Groovy

Com base na versão Java, mas muito reduzida;)

Os tipos foram substituídos por 'def', ponto-e-vírgula removido, add substituído por <<, o 1 <0 substituído por 0, coletado para criar as caixas de seleção, removeu o tipo de item do item, removeu a seleção da caixa de seleção e aprimorou os loops.

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
fonte
Groovy não é java. Isso significa que todas essas melhorias não contam tanto. Tudo o que você removeu foi necessário em java, mas não foi legal.
Justin
1
Você está certo, o Groovy não é Java, é por isso que se chama Groovy. Não tenho certeza do que você está tentando dizer aqui.
Erik Pragt
1

TCL 347

Pelo menos, supera 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 você começar marcando uma caixa de seleção e desmarcando-a imediatamente, receberá um erro. Você pode corrigi-lo adicionando 110ao final da primeira linha.

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

Javascript + Nocaute: ~ 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
fonte
0

AngularJS - 155 ( Demonstração )

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

A versão não destruída:

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>
Blackhole
fonte
0

Rubi com sapatos, 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}

Saída de amostra:

Captura de tela da janela de sapatos

homem a trabalhar
fonte
0

AppleScript, 194 190 bytes (com certeza isso está enganando um pouco ...)

Existem dois problemas:

  • Não há caixas de seleção no AppleScript, apenas listas.
  • Existe apenas a opção de selecionar UM da lista ou QUALQUER valor.

Circunstâncias:

  • Usando um loop de repetição infinito com um ponto de interrupção para sair quando 2 e apenas 2 itens da lista são selecionados.
  • Puni-me com um display alertcomponente que me dá um extra de 30 bytes de comprimento.

Raciocínio atrás de mim postando isso:

  • Ele é a maneira de fazer isso em AppleScript.
  • O código não pode ser concluído com três opções selecionadas; portanto, a terceira opção é desmarcada por extensão .

Poste isso principalmente para mostrar o poder do AppleScript na interação Aqua / GUI.

repetir
escolha na lista {"RÁPIDO", "BARATO", "BOM"} com o prompt "ESCOLHA QUALQUER DOIS", com várias seleções permitidas
se o número dos itens do resultado <= 2
sair repetir
outro
exibir alerta "POR FAVOR, ESCOLHA DOIS"
fim
fim

gif de execução

Se você acha que isso está muito errado, peça para excluir.

Addison Crump
fonte
Isso é selvagem! Essa é a língua mais parecida com o inglês que eu já vi.
Bruce Pierson
É realmente muito ruim que eles não tenham algo como "com 2 seleções necessárias" ou algo nesse sentido.
Bruce Pierson
@BrucePierson Sim, AppleScript é uma linguagem estranha. ¯ \ _ (ツ) _ / ¯ Eu só o uso para coisas pequenas, é muito difícil fazer algo real com ele.
Addison Crump
Eles não estão marcados, tornando esta resposta "muito fora" das regras. Peço que você exclua.
pppery 10/11
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--;}}}

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

Saída de amostra:

Captura de tela da janela FLTK

homem a trabalhar
fonte