1. Заголовок темы должен быть информативным. В противном случае тема удаляется ... 2. Все тексты программ должны помещаться в теги [code=pas] ... [/code]. 3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали! 4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора). 5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM! 6. Одна тема - один вопрос (задача) 7.Проверяйте программы перед тем, как разместить их на форуме!!! 8.Спрашивайте и отвечайте четко и по существу!!!
Задача по электротехнике, [советую заглянуть - Lapp :) ]
Задача такова: Надо соединить 3 кнопки, 3 лампочки и 1звонок так, чтобы при нажатии кнопки1 ( Кн1 ) загарается лампочка1 ( Л1 ) и звенит звонок, при нажатии Кн2 загарается Л2 и звенит звонок, и при нажатии Кн3 загарается Л3 и звени звонок.
Главная загвостка в том, что Лампочки(в последовательности) и звонок должны работать в полную силу. Напряжение 220В Кнопки с самовозвратом, 4 контактные (2 контакта на вкл состояние, и 2 на выкл) Нельзя добавлять ничего лишнего(т.е конденсаторы, рэле, сопротивление и таму подобное)
Ко всем, кто находит удовольствие в решении чисто программистских задач, просьба - дочитать этот мессадж до конца .
Цитата(Иваныч @ 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. А не такая и мелкая, как мне казалось - рука устала елозить мышой, пока метил ее..
--------------------
я - ветер, я северный холодный ветер я час расставанья, я год возвращенья домой