Задача такова: Надо соединить 3 кнопки, 3 лампочки и 1звонок так, чтобы при нажатии кнопки1 ( Кн1 ) загарается лампочка1 ( Л1 ) и звенит звонок, при нажатии Кн2 загарается Л2 и звенит звонок, и при нажатии Кн3 загарается Л3 и звени звонок.
Главная загвостка в том, что Лампочки(в последовательности) и звонок должны работать в полную силу. Напряжение 220В Кнопки с самовозвратом, 4 контактные (2 контакта на вкл состояние, и 2 на выкл) Нельзя добавлять ничего лишнего(т.е конденсаторы, рэле, сопротивление и таму подобное)
Это всё будет ставится якобы в камуналке
Lapp
12.12.2008 8:37
Ко всем, кто находит удовольствие в решении чисто программистских задач, просьба - дочитать этот мессадж до конца .
Цитата(Иваныч @ 30.11.2008 19:12)
Это всё будет ставится якобы в камуналке
Н-да.. Первой моей реакцией на эту тему было, ессно, перенести ее в Физику. Но потом я подумал, что возможно, что нужно не просто представить решение, а сделать способ нахождения такой схемы - то есть, программу . И еще я подумал, что прога-то будет несложная. Ну, я и написал ее. А потом, счастливо улыбаясь, запустил...
И тут я понял, что мне не увидеть результатов. По крайней мере - живым . Способ не включал в себя никаких научных достижений, а был основан на полном переборе вариантов, и оценка времени его выполнения скромно зашкаливала за сотни лет (очень грубая оценка).. И тогда я бросил эту задачу, и даже не стал писать ответ в тему.
Но потом она снова попалась мне на глаза, и я понял, что мне не уйти от нее . И я решил пооптимизировать.. Возможностей для этого оказалось достаточно. И через некоторое время я смог получить ответ в упрощенном варианте (квартира с двумя жильцами ). Интересно, что программа нашла не то решение, которое я придумал своим мозгом (без помощи электроники). Вот это решение, найденное моим лаптопом меньше, чем за минуту (проу прощения за качество камеры в моем телефоне):
Ниже привожу саму программу. Написана на Obect Pascal, хотя это не очень существенно (никаких виртуальных методов). Приглашаю всех желающих приложить руку к ее оптимизации. Комментарии включены самые ограниченные, но я опишу подробно, если кто-то проявит интерес (и если сами не разберетесь ). Если кто-то предложит другой метод - более эффективный - ваще будет здорово . Но в любом случае постарайтесь не ограничиваться словами.. Критика также принимается в любом (приличном) виде. Желаю успеха!
uses CRT;
var n: integer; // Суммарное число контактов всех элементов t: integer; // Номер следующего соединения при сборке
type tVolt= (None,v1,v2); // Напряжение: не подано, v1, v2 tPin= array[1..255] of byte; // Массив выводов
tElement= object mp: integer; // Число выводов Pin: ^tPin; // Выводы procedure Clear; // Отсоединение от всех шин procedure Connect(p,b: byte); // Параметры: вывод, шина function Connected: string; // Возвращает строку номеров шин по пинам constructor Create(ip: integer); end;
// Устройство с двумя выводами (лампа, звонок) tDevice= object(tElement) function Active: boolean; // Возвращает true, если на приборе есть полное напряжение constructor Create; end;
// Переключатель с двумя парами контактов tSwitch= object(tElement) Pos: byte; // Состояние переключателя: 0, 1 procedure Connect(p,b:byte); constructor Create; end;
// Источник (батарея или розетка) tPower= object(tElement) // Напряжение на выводах Volt: array[1..2]of tVolt; procedure Connect(p,b: byte); constructor Create; end;
var Bus: array[1..255]of tVolt; // Массив шин (соединительных проводов) Shorting: boolean; // Индицирует состояние короткого замыкания в схеме
procedure tElement.Clear; var i: byte; begin for i:=1 to mp do Pin^[i]:=0 end;
procedure tElement.Connect(p,b: byte); begin if p<=mp then Pin^[p]:=b; Inc(t); end;
function tElement.Connected: string; var i: integer; s,t: string; begin s:=''; for i:=1 to mp do begin Str(Pin^[i]:5,t); s:=s+t; end; Connected:=s end;
constructor tElement.Create(ip: integer); var i: integer; begin mp:=ip; Inc(n,mp); GetMem(Pin,mp); for i:=1 to mp do Pin^[i]:=0; end;
constructor tDevice.Create; begin tElement.Create(2); end;
function tDevice.Active: boolean; begin Active:=(Pin^[1]>0)and(Pin^[2]>0)and(Bus[Pin^[1]]<>None)and(Bus[Pin^[2]]<>None)and(Bus[Pin^[1]]<>Bus[Pin^[2]]) end;
constructor tSwitch.Create; begin tElement.Create(4); end;
procedure tSwitch.Connect(p,b:byte); var i:byte; begin tElement.Connect(p,b); case p of 1,2: i:=Pin^[3-p]; 3,4: i:=Pin^[7-p] end; if Pos=(p-1)div 2 then begin if i>0 then if Bus[b]=None then Bus[b]:=Bus[i] else if Bus[i]=None then Bus[i]:=Bus[b] else Shorting:=Shorting or(Bus[b]<>Bus[i]); end end;
constructor tPower.Create; begin tElement.Create(2); Volt[1]:=v1; Volt[2]:=v2 end;
procedure tPower.Connect(p,b: byte); begin tElement.Connect(p,b); if Bus[b]=None then Bus[b]:=Volt[p] else Shorting:=Bus[b]<>Volt[p] end;
const nn=100; // Максимально возможное суммарное число контактов всех элементов m= 2; // Число ламп (равно числу переключателей)
procedure Show; var i: integer; begin for i:=1 to n do Write(c[i]:3); WriteLn end;
// Перебор всех возможных комбинаций подключений procedure Next; var i,j: integer; b: boolean; begin repeat b:=false; repeat i:=0; repeat Inc(i); if c[i]=k then c[i]:=1 else Inc(c[i]) until (c[i]<>1)or(i=n); if Odd(i) and(c[i]=c[i+1]) then for j:=1 to i-1 do c[j]:=k else b:=true until b; for j:=1 to (i-1)div 2*2 do if Odd(j) then c[j]:=2; j:=0; for i:=1 to n do if c[i]=k then begin Inc(j); if j=2 then break end until j>1 end;
var s: string; i,j,p,a,t0: byte; h: char; Debug: boolean;
begin Debug:=true; Power.Create; for i:=1 to m do begin Lamp[i].Create; Switch[i].Create; end; Bell.Create; Power.Connect(1,2); Power.Connect(2,1); k:=2; repeat Inc(k); WriteLn('Buses: ',k); // Начальная конфигурация соединений c[1]:=k; c[2]:=1; c[3]:=k; for i:=3 to n do c[i]:=i mod 2+1; // Основной цикл перебора repeat if Debug or KeyPressed then begin h:=ReadKey; if h=#13 then Debug:=not Debug; Show end; // Разборка схемы for i:=1 to m do Lamp[i].Clear; Bell.Clear; // Сборка схемы (лампы и звонок) t:=1; for i:=1 to m do begin Lamp[i].Connect(1,c[t]); Lamp[i].Connect(2,c[t]); end; Bell.Connect(1,c[t]); Bell.Connect(2,c[t]); t0:=t; Shorting:=false; Correct:=true; // Цикл по состояниям кнопок (0 - ничего не нажато) for a:=0 to m do if not Shorting then begin for i:=3 to k do Bus[i]:=None; for i:=1 to m do if i=a then Switch[i].Pos:=1 else Switch[i].Pos:=0; for i:=1 to m do Switch[i].Clear; for j:=1 to m do begin t:=t0; for i:=1 to m do {if not Shorting then} begin Switch[i].Connect(1,c[t]); Switch[i].Connect(2,c[t]); Switch[i].Connect(3,c[t]); Switch[i].Connect(4,c[t]); end end; Correct:=Correct and not Shorting; // Проверка работы схемы for i:=1 to m do Correct:=Correct and (Lamp[i].Active=(a=i)); Correct:=Correct and (Bell.Active=(a>0)) end; if not Correct then Next; until Correct or (c[n-1]=3) or (h=#27) until Correct or (h=#27); if Correct then begin Show; WriteLn('Power: ',Power.Connected); for j:=1 to m do begin WriteLn('Lamp',j,': ',Lamp[j].Connected); WriteLn('Switch',j,': ',Switch[j].Connected); end; WriteLn('Bell: ',Bell.Connected) end else WriteLn('Interrupted') end.
P.S. Время, может, не самое подходящее - типа сессия близко, но - who cares?
P.P.S. А не такая и мелкая, как мне казалось - рука устала елозить мышой, пока метил ее..
xds
12.12.2008 17:55
Мое решение (интуитивное). Подходит для любого количества жильцов.
Хочу отметить, что в условии не оговорено ни одного из следующих условий: 1. Возможности функционирования схемы при нажатии нескольких кнопок одновременно. 2. Сотношения между напряжением в сети и номинальными напряжениями лампочек и звонка. Предлагаю схему: Три цепочки из лампочки и последовательно соединенного с ней звонка включены в параллель. Вся эта конструкция последовательно соединена со звонком. При этом, естественно, номинальные токи лампочки и звонка должны быть равны, а напряжение в сети - сумме их номинальных напряжений. Режим одновременного нажатия на кнопки схема не предусматривает так же, как и оба варианта, опубликованные ранее. Достоинства схемы: 1. Легкость обобщения на произвольное количество лампочек и кнопок. 2. В конструкции допустимо использование "стандартных" кнопок, т.е. имеющих лишь одну пару контактов на замыкание (без размыкающих контактов). Схема не лишена недостатков, в частности, перегрузка звонка в нештатном режиме работы (при замыкании нескольких кнопок одновременно). Но мне это кажется меньшим недостатком, чем то, что опережение замыкания перед размыканием (в штатном режиме) ведет к КЗ.
Lapp
13.12.2008 4:35
Узнаю "раннего" andriano, готового спорить до бесконечности из-за никому неинтересных деталей..
Цитата(andriano @ 12.12.2008 23:35)
Хочу отметить, что в условии не оговорено ни одного из следующих условий: 1. Возможности функционирования схемы при нажатии нескольких кнопок одновременно. 2. Сотношения между напряжением в сети и номинальными напряжениями лампочек и звонка.
... а также стандарты на изоляцию проводов, типы ламп и девичья фамилия бабушек жильцов.. Хорошо, я оговорю. 1. Одновременное нажатие кнопок запрещено и грозит выплатой полной стоимости оборудования (даже в случае его сохранности), плюс штраф в размере 2.71828 минимальных зарплат. 2. Номинальное значение напряжения ламп и звонка в точности равно напряжению в сети. И добавлю от себя (по просьбе электрика Васи) еще один пункт: 3.14. ПАЛЬЦЫ В РИЗЕТКИ НЕСУВАТЬ!!!!!
Цитата(andriano @ 12.12.2008 23:35)
Предлагаю схему: Три цепочки из лампочки и последовательно соединенного с ней звонка включены в параллель. Вся эта конструкция последовательно соединена со звонком. При этом, естественно, номинальные токи лампочки и звонка должны быть равны, а напряжение в сети - сумме их номинальных напряжений. Режим одновременного нажатия на кнопки схема не предусматривает так же, как и оба варианта, опубликованные ранее.
Ты лучше нарисуй, хотя мне уже не нравятся слово "последовательно" и подозреваемая мной множественность звонков..
Цитата(andriano @ 12.12.2008 23:35)
Достоинства схемы: 1. Легкость обобщения на произвольное количество лампочек и кнопок.
Схема xds делает это с блеском.
Цитата(andriano @ 12.12.2008 23:35)
2. В конструкции допустимо использование "стандартных" кнопок, т.е. имеющих лишь одну пару контактов на замыкание (без размыкающих контактов).
... ибо контакты на размыкание безумно дороги в производстве, что особенно существенно при гигантских масштабах нашего Проекта..
Цитата(andriano @ 12.12.2008 23:35)
Схема не лишена недостатков, в частности, перегрузка звонка в нештатном режиме работы (при замыкании нескольких кнопок одновременно). Но мне это кажется меньшим недостатком, чем то, что опережение замыкания перед размыканием (в штатном режиме) ведет к КЗ.
Если таковые (двойные) кнопки выпускаются производством, они должны быть сертифицированы и гарантированы от подобных нештатных ситуаций.
Ладно, хватит шутить - andriano, ты правда не видишь, что задача имеет чисто академический характер? Решение привел xds, решение правильное и т.д. и т.п.. Но!
Но мне очень жаль, что никто из ответивших не понял меня.. Задача провисела тут несколько дней, и ни у кого не появилось мысли ее решить. Стоило же мне сказать, что задача в этом разделе может нести в себе другой смысл - как тут же появились желающие пофлудить физикой в паскалевском разделе..
Моя программа - не Бог весть какое чудо, но она все же вносит некоторое разнообразие в бесконечные "расставить сторки по.." Она решает только эту конкретную задачу, причем за непозволительно большое время, но все же дает некоторое понятие о неких других задачах, которые могут решаться программным способом. Я надеялся на дискуссию именно по программированию, а не по физике (когда я начал решать ее программно, я как бы заблокировал себе мысли об обычном решении). Что ж, не вышло.. Наверное, надо действительно перенести тему в Физику, а свой пост опубликовать отдельно в FAQ - хотя, я не назвал бы этот вопрос часто задаваемым.. я подумаю. Чего и вам желаю..
Take it easy!
andriano
13.12.2008 15:37
Цитата(Lapp @ 13.12.2008 0:35)
Узнаю "раннего" andriano, готового спорить до бесконечности из-за никому неинтересных деталей.. ... Но мне очень жаль, что никто из ответивших не понял меня.. ... Задача провисела тут несколько дней, и ни у кого не появилось мысли ее решить. ... Я надеялся на дискуссию ...
Вопрос о том, кто именно готов обсуждать никому не интересные детали, конечно, интересен, но ответ на него, на мой взгляд, не столь однозначен.
Я честно попытался прочитать программу, но, увы, не преуспел в этом. Виной этому: 1. Во-первых - моя лень. 2. Во-вторых - то, что стиль написания несколько отличается от того, к которому я привык:
var n: integer; // Суммарное число контактов всех элементов
Я бы не стал называть глобальную переменную однобуквенным идентификатором, но это в данном случае неважно, по крайней мере. на данном этапе еще не помешало погиманию, а вот это:
t: integer; // Номер следующего соединения при сборке
я действительно не могу понять. Из 4-х слов понимаю смысл только первого. Что такое соединение? Каким образом они нумеруются? (хотя бы в пределах одной схемы или в процессе перебора по разным вариантам схем) Что такое сборка?
type tVolt= (None,v1,v2); // Напряжение: не подано, v1, v2
Правильно ли я перевел на "свой" язык?
type tVolt= (None, LoV, HiV); // Напряжение на контакте: не подключен, низкий уровень, высокий уровень
tPin= array[1..255] of byte; // Массив выводов
Как соотносятся между собой выводы и контакты? Что означает каждое из 255 вариантов значения вывода?
constructor Create(ip: integer);
Что обозначает входная переменная?
Pos: byte; // Состояние переключателя: 0, 1
Почему переменная, принимающая только два значения, имеет тип byte, а не boolean? И какой цифре соответствует состояние "замкнуто", а какой "разомкнуто"? (интуитивно кажется 1 и 0 соответственно, но хотелось бы знать наверняка)
И, на мой взгляд, в программе катастрофически не хватает комментариев: мне представляется, что КАЖДЫЙ заголовок процедуры или функции должен сопровождать описанием ее назначения, а также описанием каждого из параметров. Общая доля комментариев в коде, если не ошибаюсь, должно составлять около 30%.
Прошу понять меня правильно: я не высказываю претензий к автору, я пытаюсь объяснить, почему я не стал разбираться в этой программе. (т.к. автор высказывает претензии ко мне - почему не прочитал и не разобрался?)
-Владимир-
18.07.2016 13:20
Схема не будет работать. При включении любой из кнопок, гореть будут все лампочки так как питание будет проходить через лампочки.
-Ваня-
7.09.2019 2:42
Цитата(xds @ 12.12.2008 17:55)
Мое решение (интуитивное). Подходит для любого количества жильцов.
Валерий. Очень интересно! Это схему задачу я решал в 1973 году на Дальнем Востоке. Просидел над ней целый месяц. В конце концов решил её и на этом принципе мы построили много схем по управлению компрессорами. Тогда не было ни компьютеров, не Pascal.
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.