Szybko, tanio i dobrze - wybierz dowolne dwa


43

Jako programiści wszyscy znamy powiedzenie: „Możesz mieć to szybko i dobrze, ale nie będzie tanie, możesz mieć tanie i dobre, ale nie będzie szybkie, lub możesz mieć szybkie i tanie , ale nie będzie dobrze ”.

Aby sprostać temu wyzwaniu, wdrażasz wymyślone narzędzie konfiguracyjne dla niestandardowych usług programistycznych. Powinieneś wyrenderować zestaw trzech pól wyboru z nagłówkiem „WYBIERZ DOWOLNE DWA”:

SELECT ANY TWO  
☐ FAST  
☐ CHEAP  
☐ GOOD

Po wybraniu dwóch elementów trzeci element musi zostać wyłączony. Po odznaczeniu jednego z dwóch wybranych elementów wszystkie opcje muszą być ponownie włączone. Innymi słowy, jeśli wybrano zero lub jeden element, wszystkie są nadal włączone, ale jeśli wybrane są dwa elementy, trzeci musi być wyłączony.

Żadne specjalne kontrole nie są dozwolone. Pola wyboru powinny być standardowymi polami wyboru w wybranym języku. Na przykład nie używaj kontrolki „CheckBoxList”, jeśli Twój język ją ma. Wyobrażam sobie, że większość wpisów będzie HTML / jQuery, ale to nie jest reguła. To jest golf golfowy, szukający najkrótszego wpisu.

ZWYCIĘZCY DALEKO

Podzielę to na kategorie. Istnieje kilka wyraźnych zwycięzców:

jQuery: nderscore, Mr. Tenacity Under 100b, jeśli wykluczysz tekst „zasoby”. Wyróżnienie należy również podziękować Mattowi za wprowadzenie koncepcji jQuery, z których wielu czerpało inspirację.

Dyalog APL: marinus, alias Mr. Unicode Jak wpisujesz te wszystkie rzeczy? Rozumiem, dlaczego chcesz pisać krótkie programy.

PHP: SuperScript Uważam, że jest to najkrótszy wpis, który faktycznie wyłącza, a nie wyłącza trzecią opcję, zgodnie z najściślejszą interpretacją reguł.


Czy mogę to zrobić tak, aby jednocześnie można było wybrać tylko dwa? Czy wybranie trzeciego usuwa zaznaczenie jednego z pozostałych? A może dodać przycisk akceptacji, który zostanie wyszarzony, jeśli zostaną wybrane 3 opcje?
Justin

7
@Quincunx - Ponieważ nie ma heurystyki (poza czytaniem w myślach), która mogłaby zdecydować, który z nich usunąć, wprowadziłby to w błąd użytkownika ... więc muszę powiedzieć nie, ponieważ nie chcemy pierwszego wrażenia nasze niestandardowe usługi oprogramowania są złe. ;)
Bruce Pierson

To pytanie zainteresowało mnie tkinter Pythona 3, więc próbuję się tego teraz nauczyć. IMO, najlepszym sposobem na naukę GUI jest metoda prób i błędów. Próbowałem tego: ideone.com/YHLZIQ . Wynik: szybkie otwarcie nowych GUI. Musiałem otworzyć menedżera zadań, aby je zamknąć. :-). Zdjęcie (liczba wkrótce wzrosła do 340: i.stack.imgur.com/c9wQi.png )
Justin

Konkurs premiowy powinien być kolejnym pytaniem, ponieważ nie ma obiektywnego podstawowego kryterium wygranej ani żadnego opisu „bonusu”. Mówił, że kod powinien być „… elegancki i elastyczny ...” oraz „… zwięzły i przejrzysty ...”, co jest sprzeczne z golfem . VTC jako niejasne o co pytasz. Nie zmieniaj radykalnie pytań długo po ich zadaniu.
user80551

1
@BrucePierson Tak naprawdę jest. Możemy odznaczyć najstarsze zaznaczone pole wyboru. Jednak kod tego byłby znacznie większy niż wymagany kod.
Justin

Odpowiedzi:


23

JavaScript ( ES5 ) z jQuery - 143 ( Demo )

Zmodyfikowałem rozwiązanie Matta i grałem w golfa tak daleko, jak mi się wydaje:

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

JavaScript ( ES5 ) bez jQuery - 185 175 ( Demo )

Korzystanie z jQuery jest rodzajem oszustwa, więc oto rozwiązanie bez niego:

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

Jeśli wolno nam uniemożliwić użytkownikowi zaznaczenie trzeciego pola zamiast faktycznego wyłączenia pola, możemy go skrócić:

Z jQuery - 126 123 ( Demo )

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

Bez jQuery - 150 147 ( Demo )

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

Chłodny. Używanie .jointo dobra sztuczka!
Robbie Wxyz

1
"SELECT ANY TWO0FAST0GOOD0CHEAP".replace(/0/g,jest innym sposobem na osiągnięcie tego samego efektu.
nderscore

po prostu wybredny, wersja jquery powinna używać prop, a nie attr
Einacio

@Einacio twoje życzenie jest dla mnie rozkazem!
nderscore

5
@Einacio Ale codegolf dotyczy najgorszych praktyk! : P
nderscore

29

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

EDYCJA: ulepszona dzięki pomocy @Daniel Lisik - https://codegolf.stackexchange.com/a/26805/16278


5
Miły! Za mało przedstawicieli, aby głosować ... ale jesteś zatrudniony!
Bruce Pierson

2
Im dłużej na to patrzę, tym więcej się uczę. Sprytność przypisania zmiennych w selektorze jQuery. Bardzo fajny. Czy mógłbyś także wyjaśnić, co robi „podwójny huk” (!!)?
Bruce Pierson

1
Pojedynczy huk wymusza wartość logiczną, a podwójne oczywiście to odwróci. undefinedprzymusza do prawdy. To i zmienne przypisanie to prawdopodobnie jedyne naprawdę małe sztuczki.
Matt

Twój kod można zmniejszyć do 179 znaków, takich jak: 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
nazwy wyświetlanej


12

Dyalog APL (w systemie Windows) (169)

Jest to funkcja statyczna. Aby ją przetestować, jeśli nie znasz APL, wpisz ją )ed Ci wklej w oknie edycji, a następnie uruchom 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}

Nowsze bity APL mają długie słowa kluczowe. Nadal jednak pokonuję HTML.

Wyjaśnienie:

  • 'R'⎕WC'Form' 'Select any two',2/⊂S←2/20: utwórz formularz R, z tytułem Wybierz dowolne dwa oraz rozmiar i pozycję 20 20. Przechowuje również 20 20w S.
  • 1 21 41{... }¨'Fast' 'Cheap' 'Good': dla każdej z tych par danych (nazwa i współrzędna y, które są jedynymi zmiennymi, które różnią się między polami wyboru:
    • ('R.',⊃⍵)⎕WC'Button': utwórz przycisk Rz pierwszą literą nazwy,
    • ⍵(⍺1)S'Check': z odpowiednim argumentem jako tytułem, (left arg, 1)pozycją, ponownym użyciem Sjako rozmiar i Checkstyl,
    • ('Event' 'Select' 'F'), który wywołuje funkcję Fpo kliknięciu.
  • B←R.(F C G): użyj Bjako skrótu trzech utworzonych przez nas pól wyboru
  • F←{... }: zdefiniuj funkcję oddzwaniania jako:
    • X←B.State: uzyskaj stan dla każdego pola wyboru i zapisz je X,
    • X∨2≠+/X: suma X, jeśli to nie jest równe dwa, wszystkie pola wyboru muszą być aktywne, jeśli jest równe dwa, tylko zaznaczone pola wyboru muszą być aktywne
    • B.Active←: włącz lub wyłącz pola wyboru

Wynik:

zrzut ekranu


Świetne wyjaśnienie, dzięki!
Bruce Pierson

11

Python 3 2, 454 434 ... 393 392 bajtów

Pomyślałem, że Python musi być krótszy niż Java. Oto „dowód” ( EDYCJA: teraz naprawdę jest krótszy ):

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

Dla tych z Was, którzy są ciekawi, co execfaktycznie wykonuje wyrażenie, wykonuje to (tak właśnie zastępują ciąg znaków. Dodano nowe znaki dla czytelności):

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

Wykorzystuje to tę samą logikę, co moja odpowiedź Java: odznacz pole wyboru, jeśli powoduje zaznaczenie więcej niż 2 pól wyboru. Unf szczęście Niestety, spędziłem więcej mniej więcej bajtów to robi.

wprowadź opis zdjęcia tutaj

EDYCJE:

  1. ogromne dostosowanie kodu do użycia exec, oszczędzając aż 1 bajt!
  2. przełączono na python 2, aby wycisnąć dwa bajty z exec(usuwanie nawiasów).
  3. więcej golfa. Zawiera zmienia range(3)się 0,1,2i zmieniając wcięcie mieć jedną warstwę zakładkach. Nie jestem pewien, czy \t\tzadziała zamiast \t__( _jest spacją). W końcu dotarłem do najdłuższej z moich odpowiedzi w języku Java.
  4. używana sztuczka zastępująca
  5. skorzystał z sugestii Bakiru i jeszcze trochę grał w golfa. W rzeczywistości sprawił, że był krótszy niż Java! Ale teraz odpowiedź na Javę zyskała na grze w golfa, więc to znowu jest dłuższe. :-(
  6. zastosowano ulepszoną sztuczkę wymiany .
  7. zmieniono !=na a -.

Ciekawe podejście +1
cjfaure

Mogę oszukiwać w trybie turbo na klawiaturze. Najpierw zaznaczam dwa pola. Po drugie, używam Tab, aby podświetlić trzeci. Teraz trzymam spację w trybie turbo przez kilka sekund. Czasami sprawdza to trzecie pole!
kernigh

@kernigh Uważam, że dzieje się tak, ponieważ mój kod dochodzi do momentu, w którym wie, że skrzynka została przełączona, ale kod nie osiągnął punktu, w którym ponownie przełącza skrzynkę. Więc jeśli przełączysz pole w tym czasie (aby wyłączyć), mój kod doda na nim znacznik wyboru.
Justin

1
Można uniknąć wcięty blok zaczynające się if p[i]stosując andzamiast if: if p[i]:s>1 and B[i].toggle();s+=1.
Bakuriu

@kernigh się myliłem; zastępując B[i].toggle()z B[i].deselect()niczego nie zmienia. Nie mam pojęcia, dlaczego tak jest. Być może jest to wada ztkinter
Justinem

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

Nie golfowany:

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

To jest dialekt Rebol 3 View (r3-gui). Screendump poniżej z Ubuntu Linux:

przykład widoku zbrojenia 3

Aktualizacja - dzięki Earl & Graham z Rebol SO Chatroom za golenie 22 znaków kodu - http://chat.stackoverflow.com/transcript/message/16345039#16345039


To nieprawidłowa odpowiedź, ponieważ trzecia jest wyłączona, ale również zaznaczona, co oznacza, że ​​wszystkie 3 są zaznaczone, więc proszę to naprawić.
ST3

2
@ ST3 - Obawiam się, że się mylisz. Pole „DOBRE” nie jest zaznaczone lub w rzeczywistości wyłączone (mój kod po prostu zaznacza trzecie pole jako WYŁĄCZONE). W ten sposób widok Rebol 3 pokazuje niezaznaczone pole (domyślnie).
draegtun

1
@ ST3 i in. - Oto link pokazujący domyślny wygląd pola wyboru, który opisałem powyżej (1. zdjęcie pokazuje brak
zaznaczonych pól

Cóż ... Patrzę na ekran, który dodałeś i widzę wszystkie trzy pola wyboru zaznaczone, tylko jednego nie można odznaczyć.
ST3

3
@ ST3 - Wyszarzone pole wyboru to tylko Rebol 3 Zobacz sposób pokazania, że ​​jest to pole wyboru, które można zaznaczyć. Zaznaczenie zmienia kolor na zielony po zaznaczeniu, a zmienia się z powrotem w szary po odznaczeniu. To są wartości domyślne. Na obrazku w odpowiedzi powyżej widać, że „DOBRY” jako fokus wejściowy (niebieskie rozmycie), ponieważ jest „kliknięty”, ale pozostaje szary, a nie zielony (więc nie zaznaczony).
draegtun

10

Java, 421 ... 369 351 bajtów

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 ... ponieważ Java. Ładniej wyglądający kod:

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

Uruchomienie przykładowe (różne rozmiary okna, pierwsze uruchomienie):

wprowadź opis zdjęcia tutaj
wprowadź opis zdjęcia tutaj
wprowadź opis zdjęcia tutaj

Pola wyboru są ułożone poziomo; to jest dozwolone . Prawidłowe wyrównanie wymagałoby znacznie więcej. Ponadto wyłączam , odznaczając pole po kliknięciu , a nie uniemożliwiając kliknięcie.

EDYCJE:

  1. zapisano 3 bajty, rozszerzając klasę główną Checkbox.
  2. ponownie przeczytaj wyrażenia Lambda i zdałem sobie sprawę, że nazwa typu jest niepotrzebna. Weź tego Pythona!
  3. przekształcił whilepętlę w pętlę foreach (dzięki Lee ); dlaczego wcześniej o tym nie myślałem?
  4. zapisano 18 bajtów, używając anonimowej klasy i inicjatora instancji zarówno dla, jak Framei Panel.

Brak ograniczeń w wyrównaniu (więc przypuszczam, że Matt mógłby zmniejszyć swój o 5 znaków). Rekwizyty dla kompletnie działającego programu ... ale nie widzę, aby trzecia opcja była wyłączona.
Bruce Pierson

@BrucePierson To jest wyłączone. Nie można go kliknąć. Po kliknięciu nic się nie dzieje.
Justin

2
Ach, myślę, że rozumiem. Natychmiast „wyłączasz” sprawdzony stan bez wyłączania? To byłoby do przyjęcia.
Bruce Pierson

@BrucePierson Zgadza się. Aby faktycznie wyłączyć, musiałbym zmienić if(x>2)((Checkbox)e.getSource()).setState(1<0);naif(x>2){Checkbox b=(Checkbox)e.getSource();b.setState(1<0);b.setEnabled(1<0);}
Justin

1
@BrucePierson Ilekroć myślisz, wygląda to zabawnie, gdy ma to związek z używaniem reprezentacji graficznej jakiegoś elementu graficznego, poszukaj Unicode. Alternatywnie, jeśli chodzi o projektowanie graficzne, przejdź do User Experience SE : i.stack.imgur.com/xFkzy.png
Justin

7

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

Bo czemu nie.

Szokujące jest to, że na dzień dzisiejszy jesteśmy niżsi od Pythona i bezbłędnego C # i związany z Javą!

Podziękowania dla EveBird za zmniejszenie go z 561 do 481.

I jeszcze raz EveBird skraca go z 481 do 433!

Wziąłem kilka z połączeniem lambda

Do 389 z inicjalizatorami C ++ 11

I 373 bez osobnej klasy

Usunięto kilka spacji - 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();}

Rodzaj gry w golfa:

#include<QtWidgets>

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

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

GFC


1
+1 za samozwańcze „dlaczego nie” :)
Bruce Pierson

Może poprawić nieco bardziej zamienić QWidget mz QDialog mi m.show();a.exec()z m.exec().
Toby Speight,

6

CoffeeScript - 167, 154

Port CoffeeScript w odpowiedzi @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]

Nieco golfisty:

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

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

JSFiddle .


5

PHP, JavaScript, jQuery - 135b

Podziwiałem odpowiedź @ nderscore, ale potem postanowiłem go skopiować i poprawić.

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

Zasadniczo zamieniłem jego .joinsztuczkę na wstępne przetwarzanie hipertekstowe PHP.


Jeśli weźmiesz pod uwagę, że na tekst „zasoby” w programie potrzeba 27 bajtów, zbliża się to bardzo do programu 100b. Dobra robota!
Bruce Pierson

1
Nie jestem wielkim golfistą PHP, ale SELECT ANY TWO<?=($m="<input type=checkbox onclick=(a=$('input:not(:checked)')).prop('disabled',!a[1])>").FAST.$m.GOOD.$m.CHEAP;
odciąłem

5

Rubinowy, 219 218 bajtów

Używam tych samych widżetów Tk, co odpowiedź Quhonunx na Python 3 .

Ten program łamie reguły, ponieważ ma listę pól wyboru . (Reguły mówiły: „Nie używaj listy pól wyboru”). Tak, ajest tablicą 3 obiektów TkCheckButton i uważam, że tablica jest listą. Moja obrona polega na tym, że nie użyłem żadnej istniejącej listy pól wyboru, ale użyłem standardowych pól wyboru i utworzyłem własną listę.

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

TANIE i DOBRY zaznaczone, ale SZYBKIE wyłączone

Testowałem z Ruby 2.1.0 i Tk 8.5.15.

  • o[c]jest predykatem do sprawdzenia, czy cwybrany jest przycisk wyboru. Przy domyślnych ciągach, c.variable.valuejest '0'lub '1', więc porównanie ciągów jest prawdziwe tylko wtedy, gdy '1'>'0'. EDYCJA: Zapisałem 1 bajt (219 do 218), zmieniając '0'na ?0. W Ruby ?0jest stałą postaci.
  • a.count(&o) używa predykatu, aby policzyć wybrane przyciski wyboru.
  • Gdy użytkownik przełącza przycisk wyboru, polecenie wywołuje a.mappętlę dla wszystkich przycisków, tworząc je :normallub :disabled.

1
Bardzo dobre. Tu nie ma łamania reguł - miałem na myśli formant listy pól wyboru, który może być częścią frameworka językowego. Uważam, że wszystkie dotychczasowe odpowiedzi wykorzystują jakąś mapę lub selektor, więc jest to całkowicie uzasadnione.
Bruce Pierson

5

Dzięki Rotem i Johnbot za pomoc w grze w golfa!

C # 343 334

Ten używa tego samego „oszukiwania” co odpowiedź Java Quincunx - pola wyboru nie są w rzeczywistości wyłączone; po prostu nie pozwalają ci ich sprawdzić, jeśli wynik ten wynosi 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);}}

Istnieje również drobny błąd, że nie można zamknąć okna po zaznaczeniu trzeciego pola wyboru, chyba że odznaczysz jedno, ponieważ sprawdzanie poprawności nie przejdzie. Ale to jest , więc kogo to obchodzi? ;)

C # 403 397 374

Jest to właściwy, który faktycznie wyłącza trzecie pole wyboru.

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

Zrzut ekranu

Trochę niepolakowanych:

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

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

1
Nie if(a.Count(b=>b.Checked)==2)e.Cancel=true;można przepisać jako e.Cancel=a.Count(b=>b.Checked)==2;?
Rotem,

@Rotem Tak, tak, może. Jestem głupi. I jest podobna optymalizacja dla drugiej. Dzięki!
Bob

Czekaj, nie, nie ma drugiego. Eh, wciąż zapisałem kilka znaków.
Bob

1
Jeśli przełączysz dziedziczenie na CheckBox, skorzystaj z inicjalizatorów obiektów i nadużywaj Linq, możesz uzyskać właściwy z 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, jeśli zamiast instrukcji if użyjesz operatora warunkowego. Wymienić if(a.Count(b=>b.Checked)>1){a.First(b=>!b.Ch‌​ecked).Enabled=1<0;}else a.All(b=>b.Enabled=0<1);za.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>

Próbowałem tego na JSFiddle, ale bez powodzenia . Czy możesz podać działający przykład?
piskliwy kostnica


Nie wspomniałeś o „ng-app”. Sprawdź <head> w moim przykładzie.
user12345

1
Ach, OK :-) Możesz trochę pograć w golfa, usuwając znaki cudzysłowu i dodatkowe łamanie linii.
piskliwy kostek

4

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

Dzięki komentarzowi genialnego @Matta zmniejszyłem kod o 27 znaków.

JSFiddle


Zaoszczędź 25 lub więcej, przenosząc swój warunek $(e+c).length>1do zadania jako takiego: $(e).not(c).attr(f,$(e+c).length>1)ponieważ zmieniasz tylko samą wartość logiczną.
Matt

1
Udało się sprowadzić go do 169, używając mieszanki twojej i mojej. !!Przymus i trochę więcej z golfa nie przypisując ciało do 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

Matematyka

Bardziej kodowana wersja, jak sugeruje David, 255 znaków :

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

Możesz zapisać niektóre postacie, używając h=Checkbox;i=Dynamic;j=Enabled.
DavidC

@DavidCarraher Dzięki, widzę siebie używającego tej techniki w innych kwestiach związanych z golfem w przyszłości.

1
Nie trzeba dołączać obu wersji. I nie zapomnij użyć hi dostosować liczbę znaków w nagłówku.
DavidC

4

skrypt mIRC ( 727 719 bajtów)

Zapomniałem o tym języku do ostatniej pijanej rozmowy.

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

Więcej należy zakodować w tym języku! Ale musi istnieć sposób, aby zrobić z tego prawdziwy bałagan, aby mógł być tak dobry jak Perl.

Edycja: zauważyłem, że moje izumy Pythona przeciekają i byłem w stanie zmniejszyć kod o 8 bajtów!


Haha, podoba mi się wprowadzenie do tego. To jednak trochę gadatliwe - czy to może mówić piwo? = c)
Bruce Pierson

3

C #, 335 333 326 320 308

Opierając się na Bobs Answer, moja używa mniej znaków niż jego (335 v 342), ale może nie rozumiem w pełni, jak to policzyć.

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

Nie golfił

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

Świetne wykorzystanie funkcji anonowych i Linq tutaj, szczególnie takich jak Select.
Bruce Pierson

Możesz uratować jeszcze kilka postaci, zastępując litery ==2a >1, a trueliterą a 1>0. Możesz także użyć Allzamiast Wherei Last. ToListjest również krótszy niż ToArray.
Bob

@Bob Dobra rozmowa, nie wiem, jak tęskniłem za All (), a jako bonus okazuje się, że nie musisz tego zmaterializować, oszczędzając jeszcze więcej
iamkrillin

3

Groovy - 357 221 217 znaków

Przeniesiłem rozwiązanie Quincunx do Groovy 2.2.1, używając SwingBuilder (i uczyniłem go jeszcze bardziej 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()

Nie golfowany:

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

3

QML - 369 315 254 251 248 bajtów

Oto wersja QML (QtQuick 2.0), podana tylko zawartość pliku .qml. Ten kod wymaga przynajmniej Qt 5.1 do uruchomienia. Nie jest to wielka sprawa, ponieważ jest ogromna w porównaniu do innych rozwiązań ( 248 bajtów ), ale jest to w pełni funkcjonalna aplikacja wieloplatformowa (w tym Android i iOS)! :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}}

Okno dialogowe układu poziomego

Aby go uruchomić, zapisz kod w pliku .qml, zainstaluj Qt 5.1 i uruchom qmlscene.exe (lub po prostu qmlscene w systemie Linux), który wyświetli otwarte okno dialogowe pliku. Wybierz plik .qml, w którym zapisałeś kod, i zobacz niesamowity wynik! :RE


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

kod jest tutaj

próbny przebieg
(źródło: nsl.com )


wiersz 1: słownik z trzema zmiennymi; wiersz 2: każda zmienna jest przyciskiem kontrolnym; wiersz 3: oznacz słownik; wiersz 4: jeśli sprawdzono trzy zmienne, zresetuj ostatnią sprawdzoną zmienną na 0; wiersz 5: pokaż słownik.
Stevan Apter,

Miły! Taka tragedia k4 nie ma GUI ...
mollmerx,

k wygrywa (ale, o ironio! Aby opublikować post, potrzeba jeszcze 9 znaków!)
Stevan Apter

2

JavaScript / jQuery 237 234 229

Bardzo podobne podejście jak odpowiedź Matta , choć trochę dłużej.

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

2

JavaScript 209 (poprzednio 346)

Skrócony: dziękuję za komentarze.

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

Funkcja gry w golfa:

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

Formularz HTML: zapewnia dane wejściowe i wywołuje funkcję. * Formularz używa teraz class = x do grupowania danych wejściowych.

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

Testowane z NetBeans i Chrome.


Możesz dalej grać w golfa i zredukować ją do 264 znaków, konsolidując wszystkie swoje var, usuwając niepotrzebne nawiasy klamrowe i białe znaki (w tym znaki nowego wiersza). Prawdopodobnie możesz go zmniejszyć, jeśli używasz lambda ES6.
Tony Ellis

Oprócz bardziej oczywistych gry w golfa, rozważ użycie klasy do przeciągnięcia wszystkich elementów wejściowych do tablicy za jednym razem, używając getElementsByClassNamenp. a=document.getElementsByClassName('q').
Matt

zmienić identyfikatory nazwy i po prostu do nich zadzwonić z document.a, document.c, document.crównież umieścić je bezpośrednio do A []
Frieder

2

Groovy

Oparty na wersji Java, ale znacznie wyszczuplony;)

Typy zostały zastąpione przez „def”, usunięte średniki, dodaj zastąpione przez <<, 1 <0 zastąpione przez 0, zbieraj do tworzenia pól wyboru, usuwaj inny typ przedmiotów, usuwaj rzucanie pola wyboru, ulepszaj pętle.

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

Groovy to nie java. Oznacza to, że wszystkie te ulepszenia nie liczą się tak bardzo. Wszystko, co usunąłeś, było konieczne w Javie, ale nie było fajne.
Justin

1
Masz rację, Groovy to nie Java, dlatego nazywa się Groovy. Nie jestem pewien, co próbujesz tu powiedzieć.
Erik Pragt

1

TCL 347

Przynajmniej wyprzedza Python i Javę.

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

Uwaga: jeśli zaczniesz od zaznaczenia jednego pola wyboru i natychmiastowego usunięcia zaznaczenia, pojawi się błąd. Możesz to naprawić, dodając 110na końcu pierwszego wiersza.

Nie golfowany:

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

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

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

label .label -text {SELECT ANY TWO}

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

pack .label .011 .101 .110

1

JavaScript + Knockout: ~ 250 znaków

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

0

AngularJS - 155 ( Demo )

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

Wersja bez golfa:

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

0

Rubin z butami, 133 znaków

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}

Przykładowe dane wyjściowe:

Zrzut ekranu okna obuwia


0

AppleScript, 194 190 bajtów (całkiem pewne, że to trochę oszukuje ...)

Istnieją dwa problemy:

  • W AppleScript nie ma żadnych pól wyboru, tylko listy.
  • Istnieje tylko opcja, aby wybrać JEDEN z listy lub DOWOLNĄ kwotę.

Obejścia:

  • Korzystanie z nieskończonej pętli powtarzania z punktem przerwania w celu uzyskania wyjścia, gdy wybrano 2 i tylko 2 elementy na liście.
  • Ukarałem się display alertkomponentem, który daje mi dodatkowe 30 bajtów długości.

Rozumowanie za mną, publikując to:

  • Jest to sposób na zrobienie tego w AppleScript.
  • Kod nie może zostać uzupełniony wybranymi trzema opcjami, więc trzecia opcja jest odznaczana przez rozszerzenie .

Głównie publikowanie tego, aby pokazać moc AppleScript w interakcji Aqua / GUI.

powtarzać
wybierz z listy {„SZYBKO”, „TANIO”, „DOBRY”} z pytaniem „WYBIERZ DOWOLNE DWA” z dozwolonym wyborem wielokrotnym
jeśli liczba pozycji wyniku <= 2
wyjdź powtórzyć
jeszcze
wyświetl alert „PROSZĘ WYBRAĆ DWA”
koniec
koniec

wykonanie gif

Jeśli uważasz, że to jest zbyt nieaktualne, poproś mnie o usunięcie.


To jest dzikie! To najbardziej angielski język, jaki kiedykolwiek widziałem.
Bruce Pierson,

Naprawdę szkoda, że ​​nie mają czegoś takiego jak „przy wymaganych 2 selekcjach” lub czegoś podobnego.
Bruce Pierson

@BrucePierson Tak, AppleScript to dziwny język. ¯ \ _ (ツ) _ / ¯ Używam go tylko do małych rzeczy, ciężko jest cokolwiek z tym zrobić.
Addison Crump,

Nie są zaznaczone, co powoduje, że ta odpowiedź jest „zbyt odległa” od reguł. Niniejszym proszę o usunięcie.
pppery

0

FLTK, 303 znaków

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

Nie golfowany:

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

Przykładowe dane wyjściowe:

Zrzut ekranu okna FLTK

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.