Швидкий, дешевий і хороший - виберіть будь-які два


43

Як програмісти, ми всі знаємо приказку: "Ви можете мати це швидко і добре, але це не буде дешево, ви можете його дешево і добре, але це не буде швидко, або ви можете швидко і дешево , але це не буде добре ".

Для цього завдання ви реалізуєте уявний інструмент налаштування для своїх спеціальних служб програмування. Вам слід надати набір із трьох прапорців із заголовком "ВИБРАТИ БУДЬ-ЯК ДВОЙ":

SELECT ANY TWO  
☐ FAST  
☐ CHEAP  
☐ GOOD

Після вибору двох елементів третій елемент повинен бути відключений. Якщо скасувати вибір одного з двох вибраних елементів, всі параметри потрібно знову активувати. По-іншому, якщо вибрано нуль або один елемент, усі все ще ввімкнено, але якщо вибрано два елементи, третій повинен бути відключений.

Не допускаються спеціальні елементи керування. Прапорці повинні бути стандартним прапором вашою мовою на вибір. Наприклад, не використовуйте елемент "CheckBoxList", якщо у вас є його мова. Я думаю, що більшість записів буде HTML / jQuery, але це не правило. Це кодовий гольф, шукаючи найкоротший запис.

ПЕРЕМОЖИТИ ТАКІ БОЛЬШЕ

Я розбию його на категорії. Є кілька чітких переможців:

jQuery: nderscore, Mr. Tenacity Під 100b, якщо ви виключаєте текстові "ресурси". Почесна згадка також має бути присвячена Метту за введення концепцій jQuery, від яких багато брали натхнення.

Dyalog APL: marinus, він же містер Unicode. Як ви вводите всі ці речі? Я бачу, чому ви хочете писати короткі програми.

PHP: SuperScript Я вважаю, що це найкоротший запис, який фактично вимикає, а не скасовує вибір третього варіанту, після суворої інтерпретації правил.


Чи можу я просто зробити так, що одночасно можна вибрати лише двох? Отже, що вибір третього де-вибирає один з інших? Чи, можливо, додати кнопку прийняття, яка буде сірою, якщо вибрано 3 варіанти?
Джастін

7
@Quincunx - Оскільки не існує евристики (поза розумом читання), яка могла б вирішити, яку відмінити, це збентежить користувача ... тому мені доведеться сказати "ні", тому що ми не хочемо першого враження про наші сервісні програмні послуги є поганими. ;)
Брюс Пірсон

Це питання мене зацікавило в tkinter Python 3, тому я зараз намагаюся дізнатися це. IMO, найкращий спосіб вивчити графічний інтерфейс - методом проб і помилок. Я спробував це: ideone.com/YHLZIQ . Результат: швидке відкриття нових графічних інтерфейсів. Мені довелося відкрити менеджера завдань, щоб закрити їх. :-). Зображення (число скоро піднялося до 340: i.stack.imgur.com/c9wQi.png )
Джастін

Конкурс на преміювання повинен бути ще одним питанням, оскільки немає об'єктивного первинного критерію виграшу чи будь-якого опису «бонусу». У ньому сказано, що код повинен бути "... елегантним та гнучким ..." та "... лаконічним і чітким ...", що проти коду-гольфу . VTC як незрозуміло, про що ви питаєте. Будь ласка, не радикально змінюйте питання довгий час після їх запитання.
користувач80551

1
@BrucePierson Власне, є. Ми могли зняти прапорець із найстарішим вибраним прапором. Однак код для цього буде набагато більше, ніж потрібний вам код.
Джастін

Відповіді:


23

Javascript ( ES5 ) з jQuery - 143 ( демонстрація )

Я змінив рішення Метта і переграв його настільки далеко, наскільки я думаю, що це може піти:

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

Javascript ( ES5 ) без jQuery - 185 175 ( демонстрація )

Використання jQuery - це такий спосіб обману, тому ось без нього рішення:

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

Якщо нам дозволено перешкоджати користувачеві перевіряти 3-е поле, а не фактично вимикати поле, ми можемо зробити його ще коротшим:

З jQuery - 126 123 ( демонстрація )

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

Без jQuery - 150 147 ( демонстрація )

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

Класно. Використання .join- це хороший трюк!
Роббі Віксиз

1
"SELECT ANY TWO0FAST0GOOD0CHEAP".replace(/0/g,це ще один спосіб зробити це в результаті однакової довжини.
nderscore

просто вибагливий, версія jquery повинна використовувати prop, а не attr
Einacio

@Einacio ваше бажання - це моя команда!
nderscore

5
@Einacio Але codegolf - це про найгірші практики! : P
nderscore

29

JavaScript - 184 169 (з 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: покращено за допомогою @Daniel Lisik - https://codegolf.stackexchange.com/a/26805/16278


5
Приємно! Не вистачає представника, щоб підняти ... але ви найняті!
Брюс Пірсон

2
Чим більше я дивлюся на це, тим більше я вчуся. Розумність призначення змінної всередині селектора jQuery. Дуже круто. Також ви могли б пояснити, що робить "подвійний удар" (!!)?
Брюс Пірсон

1
Одиничний удар, примушує булеве значення, а подвійний, очевидно, це переверне. undefinedпримушування до істинного. Це та призначення змінної - це, мабуть, єдині маленькі хитрощі, які реально використовуються.
Метт

Ваш код може бути скорочений до 179 символів, таких як: 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
відображення-ім’я-відсутнє


12

Dyalog APL (для Windows) (169)

Це статична функція, щоб перевірити її, якщо ви не знаєте APL, введіть )ed Cі вставте це у вікно редагування, а потім запустіть 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}

Новіші біти APL мають довгі ключові слова. Я все ще перемагаю HTML.

Пояснення:

  • 'R'⎕WC'Form' 'Select any two',2/⊂S←2/20: створити форму Rз заголовком Виберіть будь-які два та розмір та позицію 20 20. Також магазини 20 20в S.
  • 1 21 41{... }¨'Fast' 'Cheap' 'Good': для кожної з цих пар даних (ім'я та координата у, які є єдиними змінними, які відрізняються між прапорцями:
    • ('R.',⊃⍵)⎕WC'Button': створіть кнопку Rз першою літерою імені,
    • ⍵(⍺1)S'Check': з правильним аргументом як заголовок, (left arg, 1)як позиція, повторне використання Sяк розміру, так і Checkстилю,
    • ('Event' 'Select' 'F'), яка викликає функцію Fпри натисканні.
  • B←R.(F C G): використовувати Bяк абревіатуру для трьох створених нами прапорів
  • F←{... }: визначити функцію зворотного дзвінка як:
    • X←B.State: отримайте стан для кожного прапорця і зберігайте їх X,
    • X∨2≠+/X: сума X, якщо це не дорівнює двом, усі прапорці повинні бути активними, якщо вона дорівнює двом, лише активовані прапорці повинні бути активними
    • B.Active←: включити або вимкнути прапорці

Результат:

скріншот


Чудове пояснення, дякую!
Брюс Пірсон

11

Python 3 2, 454 434 ... 393 392 байт

Я думав, Python повинен бути коротшим, ніж Java. Ось "доказ" ( EDIT: тепер він справді коротший ):

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

Тим, хто цікавиться тим, що execнасправді виконує вираз, він виконує це (саме це робить заміна для рядка. Нові рядки додаються для читабельності):

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

Для цього використовується та ж логіка, що і моя відповідь на Java: зніміть прапорець, якщо це призведе до встановлення більше двох прапорців. Unf На щастя, на жаль, я витратив на це більше менше байтів.

введіть тут опис зображення

ЗМІНИ:

  1. масове коригування коду для використання exec, економлячи колосальні 1 байт!
  2. перейшов на python 2, щоб видавити два байти з exec(видалення дужок).
  3. більше гольфу. Включає в себе зміни range(3)в 0,1,2і зміни відступів мати один шар вкладок. Не впевнений, чи \t\tпрацював би замість \t__( _символом пробілу). Нарешті дійшов до найдовшого моєї відповіді на Java.
  4. використаний трюк заміни
  5. використовував пропозицію Бакіру та ще кілька гравців у гольф. Насправді зробив його коротшим, ніж Java! Але тепер відповідь на Java отримала більше гольфу, тому це знову довше. :-(
  6. використаний покращений трюк заміни .
  7. змінив а !=на а -.

Цікавий підхід. +1
cjfaure

Я можу обдурити турбо-режим на моїй клавіатурі. Спочатку я перевіряю два поля. По-друге, я використовую Tab для виділення третього. Тепер я тримаю пробіл у турбо режимі на кілька секунд. Іноді це перевіряє третє поле!
kernigh

@kernigh Я вважаю, що це тому, що мій код потрапляє до того моменту, коли він знає, що поле змінено, але код не досяг тієї точки, де він перемикає поле. Тож якщо ви переключите прапорець у цей час (вимкнено), мій код поставить на ньому галочку.
Джастін

1
Ви можете уникнути відступу блоку , починаючи з if p[i]використовуючи andзамість if: if p[i]:s>1 and B[i].toggle();s+=1.
Бакуріу

@kernigh я помилився; заміна B[i].toggle()на B[i].deselect()нічого не змінює. Я поняття не маю, чому це так. Можливо, це вада зtkinter
Джастін

10

Ребол, 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]]

Безголівки:

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

Це діалект Rebol 3 View (r3-gui). Нижче на екрані від Ubuntu Linux:

Приклад rebol 3 view

Оновлення - Завдяки Earl & Graham з Rebol SO Chatroom за гоління 22 символів коду - http://chat.stackoverflow.com/transcript/message/16345039#16345039


Це неправдива відповідь, оскільки третій відключений, але також перевірений, це означає, що всі 3 перевірені, тому, будь ласка, виправте це.
ST3

2
@ ST3 - Ви невірні, боюся. Поле "ДОБРЕ" не встановлено або фактично вимкнено (мій код просто натискає на третій прапорець вимкнено). Ось таким чином у перегляді Rebol 3 відображається галочка (за замовчуванням).
draegtun

1
@ ST3 та ін. - Ось посилання, що відображає прапорець за замовчуванням, який я описав вище (1-е зображення показує, що
кнопки

Ну ... Я дивлюся на доданий вами екран друку, і я бачу, що всі три прапорці встановлені, лише одну не можна зняти.
ST3

3
@ ST3 - прапорець із сірим кольором - це просто Rebol 3 Переглянути спосіб показу, що це прапорець, який можна встановити. При відмітці галочка стає зеленою та повертається у сіру, якщо вона не встановлена. Це за замовчуванням. На зображенні у відповіді вище ви бачите, що "ДОБРИЙ" як фокус на вході (синє розмиття), оскільки його "натискають", але він залишається сірим, а не зеленим (тому не перевіряється).
draegtun

10

Java, 421 ... 369 351 байт

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 ... тому що Java. Приємніше виглядає код:

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

Виконання зразка (різні розміри вікна, перший - при запуску):

введіть тут опис зображення
введіть тут опис зображення
введіть тут опис зображення

Прапорці розташовані горизонтально; це дозволено . Щоб її вирівняти, знадобиться набагато більше. Також я відключаю, знімаючи прапорець біля цього пункту , а не роблячи неможливим його натискання.

ЗМІНИ:

  1. збережено 3 байти, зробивши основний клас розширенням Checkbox.
  2. перечитав вирази лямбда та зрозумів, що ім'я типу непотрібне. Візьміть того пітона!
  3. перетворив whileцикл у цикл foreach (спасибі Лі ); чому я не думав про це раніше?
  4. збережено 18 байт, використовуючи анонімний клас та ініталізатор екземплярів як для, так Frameі для Panel.

Ніяких обмежень на вирівнювання (тому, я думаю, Метт міг зменшити його на 5 символів). Реквізити для повної запущеної програми ... але я не бачу, що третій варіант вимкнено.
Брюс Пірсон

@BrucePierson Це вимкнено. Це не можна натиснути. Якщо його натиснути, нічого не станеться.
Джастін

2
Ах, я думаю, що бачу. Ви негайно "скасовуєте" перевірений стан, не відключаючи його? Це було б прийнятно.
Брюс Пірсон

@BrucePierson Правильно. Щоб насправді відключити, я повинен був би перейти if(x>2)((Checkbox)e.getSource()).setState(1<0);наif(x>2){Checkbox b=(Checkbox)e.getSource();b.setState(1<0);b.setEnabled(1<0);}
Джастін

1
@BrucePierson Кожного разу, коли ти думаєш, це виглядає смішно, коли це стосується використання символьної репрезентації якоїсь графічної речі, шукай unicode. Крім того, для речей із графічним дизайном зверніться до користувальницького досвіду SE : i.stack.imgur.com/xFkzy.png
Джастін

7

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

Бо чому ні.

Шокуюче, що зараз ми коротші, ніж Python, і не-баггі C #, і пов'язані з Java!

Кредити EveBird за скорочення її з 561 до 481.

І ще раз EveBird скорочує його з 481 до 433!

Взяв декілька за допомогою лямбда-з'єднання

До 389 з ініціалізаторами C ++ 11

І 373 без окремого класу

Видалено кілька пробілів - 369

Гольф:

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

Сорт Un-Golfed:

#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 за самогубчасте "чому б і ні" :)
Брюс Пірсон

Можна покращити трохи більше: замінити QWidget mна QDialog mі m.show();a.exec()на m.exec().
Toby Speight

6

CoffeeScript - 167, 154

Порт CoffeeScript відповіді @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]

Дещо незворушний:

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

Я захоплювався відповіддю @ nderscore, але потім вирішив скопіювати його і передати його.

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

В основному я замінив його .joinхитрість на деяку попередню обробку гіпертексту PHP.


Якщо ви вважаєте, що для текстових "ресурсів" в програмі потрібно 27 байт, це дуже наближається до програми 100b. Молодці!
Брюс Пірсон

1
Я не дуже гольфіст на PHP, але я нарізав вам кілька байтів: (128)SELECT ANY TWO<?=($m="<input type=checkbox onclick=(a=$('input:not(:checked)')).prop('disabled',!a[1])>").FAST.$m.GOOD.$m.CHEAP;
nderscore

5

Рубі, 219 218 байт

Я використовую ті самі віджети Tk, що і відповідь Python 3 Quincunx.

Ця програма порушує правила, оскільки в ній є список прапорців . (У правилах сказано: "Не використовуйте список прапорців.") Так, aце масив із 3 об'єктів TkCheckButton, і я вважаю, що масив - це список. Мій захист полягає в тому, що я не використовував жодного наявного списку прапорів, але я використав стандартні прапорці і склав власний список.

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

CHEAP і ДОБРО перевірено, але ШВИДКО відключено

Я тестував Ruby 2.1.0 і Tk 8.5.15.

  • o[c]- це предикат для перевірки, якщо cвибрана кнопка галочки . Якщо рядки за замовчуванням c.variable.valueє , є '0'або '1', тож порівняння рядків істинне лише тоді, якщо '1'>'0'. EDIT: Я зберег 1 байт (219 до 218), змінивши '0'на ?0. У Рубі ?0- константа символів.
  • a.count(&o) використовує присудок для підрахунку вибраних кнопок.
  • Коли користувач перемикає кнопку перевірки, команда викликає a.mapцикл для всіх кнопок, роблячи їх :normalабо :disabled.

1
Дуже добре. Немає порушення правил тут - я не мав в виду список прапорців контролю , що може трапитися , щоб бути частиною структури мови. Я вважаю, що всі відповіді поки що використовують якусь карту або селектор, тому це абсолютно законно.
Брюс Пірсон

5

Дякуємо Ротему та Джонботу за допомогу в гольфі!

С # 343 334

Цей використовується той самий "чіт", що і відповідь Java на Quincunx - прапорці фактично не вимкнені; вони просто не дозволяють вам перевіряти їх, якщо цей чек становить 3.

using System.Windows.Forms;using System.Linq;class P:Form{static void Main(){P p=new P();p.Text="SELECT ANY TWO";int y=0;var a=new CheckBox[3];foreach(var n in "FAST CHEAP GOOD".Split()){var c=new CheckBox();a[y]=c;c.Top=y++*50;c.Text=n;c.Validating+=(s,e)=>{if(a.Count(b=>b.Checked)>1)e.Cancel=true;};p.Controls.Add(c);}Application.Run(p);}}

Існує також незначна помилка, яку ви не можете закрити вікно після вибору третього прапорець, якщо ви не знімете його, оскільки перевірка не пройде. Але це , тож кого це хвилює? ;)

C # 403 397 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)=>{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);}}

Знімок екрана

Ніби не гольф:

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
Не вдалося if(a.Count(b=>b.Checked)==2)e.Cancel=true;переписати як e.Cancel=a.Count(b=>b.Checked)==2;?
Ротем

@Rotem Так, так, це могло б. Я німий. І є аналогічна оптимізація для іншої. Дякую!
Боб

Зачекайте, ні, для іншого немає. Е, все-таки врятували кілька символів.
Боб

1
Якщо ви переключите спадщину на CheckBox, використовуйте ініціалізатори об'єктів і трохи зловживайте Linq, ви зможете отримати відповідний до 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, якщо ви використовуєте умовний оператор замість оператора if. Замінити if(a.Count(b=>b.Checked)>1){a.First(b=>!b.Ch‌​ecked).Enabled=1<0;}else a.All(b=>b.Enabled=0<1);зa.First(b=>!b.Checked).Enabled=a.Count(b=>b.Checked)>1?1<0:a.All(b=>b.Enabled=0<1);
Johnbot

5

КутовийJS - 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>

Я спробував це в JSFiddle, але без жодного успіху . Чи можете ви надати робочий приклад?
кричуча костінь


Ви не згадали про "ng-app". Перевірте <head> у моєму прикладі.
користувач12345

1
Ага, гаразд :-) Ви можете трохи пограти в гольф , видаливши лапки та додаткові розриви рядків.
писклива косточка

4

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

Завдяки коментарю від блискучого @Matt я зменшив код на 27 символів.

JSFiddle


Збережіть 25 або більше, перемістивши свій стан $(e+c).length>1у завдання як таке: $(e).not(c).attr(f,$(e+c).length>1)оскільки ви змінюєте лише булевий.
Метт

1
Вдалося зменшити її до 169, використовуючи мікс вашого і мого. !!Примус і трохи більше грати в гольф з не призначаючи тіло р 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])})
Метт

4

Математика

Більш кодова версія для гольфу, як запропонував Девід, 255 символів :

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

Ви можете зберегти деякі символи, використовуючи h=Checkbox;i=Dynamic;j=Enabled.
DavidC

@DavidCarraher Спасибі, я можу побачити, що я використовую цю техніку для інших питань гольфу з кодом і в майбутньому.

1
Не потрібно включати обидві версії. І не забудьте скористатися hта відрегулювати кількість своїх знаків у заголовку.
DavidC

4

сценарій mIRC ( 727 719 байт)

Забув про цю мову до п'яної розмови минулої ночі.

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

Більше слід закодувати на цій мові! Але повинен бути спосіб перетворити це в справжній безлад, щоб воно могло бути таким же хорошим, як Perl.

Редагувати: помітив, що мої Python-Isms просочуються і зміг зменшити код на 8 байт!


Ха-ха, мені подобається вступ до цього. Це свого роду багатослівне - чи може це пиво? = c)
Брюс Пірсон

3

C #, 335 333 326 320 308

На основі відповіді Бобса мій використовує менше символів, ніж його (335 v 342), але я не можу зрозуміти повністю, як це рахувати.

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

Безумовно

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

Тут чудово використовується функція anon та Linq, особливо як у Select.
Брюс Пірсон

Ви можете зберегти ще пару символів, замінивши на ==2а >1, а на trueа 1>0. Ви також можете використовувати Allзамість Whereі Last. ToListтакож коротше, ніж ToArray.
Боб

@Bob Добрий дзвінок, не знаю, як я пропустив All (), і як бонус виходить Все, що вам не доведеться це матеріалізувати, заощаджуючи ще більше
iamkrillin

3

Groovy - 357 221 217 символів

Я переніс рішення Quincunx для Groovy 2.2.1, використовуючи SwingBuilder (і зробивши його ще більш 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()

Безголівки:

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 байт

Тут йде версія QML (QtQuick 2.0) з урахуванням лише вмісту файлу .qml. Цей код вимагає принаймні Qt 5.1 для запуску. Це не велика справа, оскільки її величезна порівняно з іншими рішеннями ( 248 байт ), але це повнофункціональний кросплатформенний додаток (включені Android та iO)! : 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}}

Діалогове вікно горизонтальної компонування

Щоб запустити його, збережіть код у файлі .qml, встановіть Qt 5.1 та запустіть qmlscene.exe (або просто qmlscene на Linux), де буде показано діалогове вікно відкритого файлу. Виберіть файл .qml, до якого ви зберегли код, і подивіться приголомшливий результат! : D


3

k3 - 95

a[`FAST`CHEAP`GOOD]:0
a[.;`c]:`check
a..l:"SELECT ANY TWO"
a..t:"if[3=+/a[];.[_v;_i;:;0]]"
`show$`a

код тут

зразок виконання
(джерело: nsl.com )


рядок 1: словник з трьома змінними; рядок 2: кожна змінна є контрольною кнопкою; рядок 3: позначте словник; рядок 4: якщо перевірені три змінні, відновіть останню перевірену змінну до 0; рядок 5: покажіть словник.
Стеван Аптер

Приємно! Така трагедія k4 не має GUI ...
mollmerx

k виграє (але о іронія! Для публікації потрібно ще 9 символів!)
Stevan Apter

2

JavaScript / jQuery 237 234 229

Дуже схожий підхід, як відповідь Метта , хоча трохи довше.

$(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 (було 346)

Скорочене: дякую за коментарі.

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

Гольф функція:

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

HTML-форма: забезпечує введення та виклик функції. * Форма тепер використовує class = x для групових входів.

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

Тестовано з NetBeans та Chrome.


Ви можете додатково пограти в гольф і зменшити його до 264 символів, консолідувавши всі свої vars, видаливши зайві дужки та пробіли (включаючи символи нового рядка). Можливо, ви могли б зменшити його, якщо використовувати лямбда ES6.
Тоні Елліс

Крім деяких більш очевидних гольфів, розгляньте можливість використання класу, щоб витягнути всі вхідні елементи в масив одним ударом, використовуючи getElementsByClassNameнапр. a=document.getElementsByClassName('q').
Метт

змінити ідентифікатори з ім'ям і просто називати їх document.a, document.c, document.cтакож помістити їх безпосередньо в []
Frieder

2

Groovy

На основі версії Java, але значно зменшена;)

Типи були замінені на 'def', крапки з комою вилучено, додано замінено на <<, 1 <0 замінено на 0, збір для створення прапорців, видалення itemevent типу, видалення кастингу, поліпшення циклів.

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 - не java. Це означає, що всі ці вдосконалення не так багато. Все, що ви зняли, було потрібно в java, але не groovy.
Джастін

1
Ви маєте рацію, Groovy - це не Java, тому її називають Groovy. Я не впевнений, що ти тут намагаєшся сказати.
Ерік Прагт

1

TCL 347

Принаймні це б'є Python та 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

Примітка: якщо ви почнете, встановивши один прапорець і негайно знявши його, ви отримаєте помилку. Ви можете виправити це, додавши 110в кінець першого рядка.

Безголівки:

# 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 + нокаут: ~ 250 символів

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 ( демонстрація )

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

Негольована версія:

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

Рубі з взуттям, 133 символи

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}

Вибірка зразка:

Скріншот вікна взуття


0

AppleScript, 194 190 байт (досить впевнений, що це трохи обман ...)

Існують дві проблеми:

  • У AppleScript немає прапорців, лише списки.
  • Є лише можливість вибрати ONE зі списку або БУДЬ-яку суму.

Окружність:

  • Використовуючи нескінченний цикл повторення з точкою розриву, щоб мати вихід, коли вибрано 2 та лише 2 пункти у списку.
  • Покарав себе display alertкомпонентом, який дає мені додаткові 30 байт довжини.

Обґрунтування того, що я розміщую це:

  • Це є способом зробити це в AppleScript.
  • Код не може доповнити обраними трьома параметрами, тому третій варіант відміняється шляхом розширення .

В основному розміщуйте це, щоб показати потужність AppleScript у взаємодії Aqua / GUI.

повторити
виберіть із списку {"Швидке", "ТЕХНІЧНЕ", "ДОБРЕ"} із запитом "ВИБОРІТЬ БУДЬ-ЯК ДВОЙ" із кількома дозволеними варіантами
якщо число елементів результату <= 2
вихід повторити
ще
індикація на дисплеї "БУДЬ ЛАСКА ДВОЙ"
кінець
кінець

виконання gif

Якщо ви вважаєте, що це занадто погано, прошу видалити.


Це дике! Це найбільш англійська мова, яку я коли-небудь бачив.
Брюс Пірсон

Це дуже погано, що у них немає чогось типу "з 2 необхідними виділеннями" або чогось у цьому напрямку.
Брюс Пірсон

@BrucePierson Так, AppleScript - дивна мова. ¯ \ _ (ツ) _ / ¯ я коли-небудь використовую його для дрібних речей, досить важко зробити з ним щось фактичне.
Аддісон Крамп

Вони не встановлені позначками, що робить цю відповідь "занадто відмежованою" від правил. Я прошу вас видалити.
pppery

0

FLTK, 303 символи

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

Безголівки:

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

Вибірка зразка:

Скріншот вікна FLTK

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.