Задача такова: Надо соединить 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;
beginfor i:=1to mp do Pin^[i]:=0end;
procedure tElement.Connect(p,b: byte);
beginif p<=mp then Pin^[p]:=b;
Inc(t);
end;
function tElement.Connected: string;
var
i: integer;
s,t: string;
begin
s:='';
for i:=1to mp dobegin
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:=1to 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 of1,2: i:=Pin^[3-p];
3,4: i:=Pin^[7-p]
end;
if Pos=(p-1)div2thenbeginif i>0thenif Bus[b]=None then Bus[b]:=Bus[i]
elseif Bus[i]=None then Bus[i]:=Bus[b]
else Shorting:=Shorting or(Bus[b]<>Bus[i]);
endend;
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; // Число ламп (равно числу переключателей)
var
Lamp: array[1..m]of tDevice;
Switch: array[1..m]of tSwitch;
Bell: tDevice;
Power: tPower;
Sw: tSwitch;
c: array[1..nn]of integer;
Correct: boolean;
k: integer;
procedure Show;
var
i: integer;
beginfor i:=1to n do Write(c[i]:3);
WriteLn
end;
// Перебор всех возможных комбинаций подключений
procedure Next;
var
i,j: integer;
b: boolean;
beginrepeat
b:=false;
repeat
i:=0;
repeat
Inc(i);
if c[i]=k then c[i]:=1else Inc(c[i])
until (c[i]<>1)or(i=n);
if Odd(i) and(c[i]=c[i+1]) thenfor j:=1to i-1do c[j]:=k else b:=true
until b;
for j:=1to (i-1)div2*2doif Odd(j) then c[j]:=2;
j:=0;
for i:=1to n doif c[i]=k thenbegin
Inc(j);
if j=2then break
enduntil j>1end;
var
s: string;
i,j,p,a,t0: byte;
h: char;
Debug: boolean;
begin
Debug:=true;
Power.Create;
for i:=1to m dobegin
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:=3to n do c[i]:=i mod2+1;
// Основной цикл перебора
repeatif Debug or KeyPressed thenbegin
h:=ReadKey;
if h=#13then Debug:=not Debug;
Show
end;
// Разборка схемы
for i:=1to m do Lamp[i].Clear;
Bell.Clear;
// Сборка схемы (лампы и звонок)
t:=1;
for i:=1to m dobegin
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:=0to m doifnot Shorting thenbeginfor i:=3to k do Bus[i]:=None;
for i:=1to m doif i=a then Switch[i].Pos:=1else Switch[i].Pos:=0;
for i:=1to m do Switch[i].Clear;
for j:=1to m dobegin
t:=t0;
for i:=1to 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]);
endend;
Correct:=Correct andnot Shorting;
// Проверка работы схемы
for i:=1to m do Correct:=Correct and (Lamp[i].Active=(a=i));
Correct:=Correct and (Bell.Active=(a>0))
end;
ifnot Correct then Next;
until Correct or (c[n-1]=3) or (h=#27)
until Correct or (h=#27);
if Correct thenbegin
Show;
WriteLn('Power: ',Power.Connected);
for j:=1to m dobegin
WriteLn('Lamp',j,': ',Lamp[j].Connected);
WriteLn('Switch',j,': ',Switch[j].Connected);
end;
WriteLn('Bell: ',Bell.Connected)
endelse 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.
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.