Concurso e Encontro Nacional de Programação em Lógica
CeNPL'2003
Universidade de Évora, Maio de 2003
Smoke
A Smokesoft é uma conhecida empresa de desenvolvimento de software, onde se usam as mais modernas ferramentas (incluindo a famosa distribuição Debian) e onde o controlo da produtividade é muito apertado.
Na Smokesoft trabalham muitos programadores, dos melhores que há. Todos partilham uma ampla sala, em regime de open-space. Infelizmente, há programadores que fumam e, felizmente, há programadores que não fumam. A convivência social não é problemática mas a produtividade ressente-se e a administração teve de actuar.
Por um lado, verificou-se que estando o ar poluído com fumo a produtividade dos não fumadores desce imediatamente. De facto, estudos científicos mostraram que a perda marginal de produtividade para um não fumador causada pelo fumo do x-ésimo cigarro fumado na sala é x LOC por dia. Explicando melhor: a produtividade dos programadores mede-se em “lines of codes”, LOC, por dia. Tome o caso do João, que não fuma. A sua produtividade nominal é 128 LOC/dia. No entanto, se um colega fumar um cigarro na sua presença, o João fica ligeiramente desconcentrado e já só conseguirá fazer 127 linhas nesse dia. Se forem fumados dois cigarros, já só conseguirá fazer 125 linhas, com 3 cigarros já só vai até 122, etc. Se fumarem para aí uns 20 cigarros, mais vale mandá-lo para casa, porque já não vai conseguir fazer nada que se aproveite.
Sendo assim, poderíamos pensar em proibir o fumo, mas isso seria uma má ideia, porque a produtividade dos programadores fumadores ressentir-se-ia. De facto, o ganho marginal de produtividade para um programador fumador pelo x-ésimo cigarro por ele fumado é 12 – x LOCs por dia. Veja o que se passa com a Isabel, grande fumadora. A sua produtividade nominal é 96 LOC/dia. No entanto, se fumar um cigarrito, a produtividade sobe para 107, se fumar 2, sobe para 117, se fumar 3, sobe para 126, etc. Se fumar mais do que 12, fica de tal maneira intoxicada que a produtividade começa a descer, e se fumar trinta e tal cigarros já não faz mais nada.
Perante isto, a administração tem de escolher a nova política de fumo no trabalho. Não se trata de apenas decidir qual é o número de cigarros que cada fumador pode fumar, porque é possível instalar um aparelho de reciclagem de ar que elimina uma percentagem do fumo, assim contribuindo para o bem-estar e produtividade dos não fumadores. O custo de operação dessa máquina é 1000 * x2 euros por dia (1000 vezes x ao quadrado), sendo x a percentagem do fumo eliminado. Por exemplo, eliminar 50% do fumo custa €250 por dia, eliminar 80% custa €640 por dia.
Qual é a política de fumo mais vantajosa para a empresa?
A sua tarefa é escrever um programa Prolog que, dados o número de programadores fumadores, o número de programadores não fumadores e o valor da linha de código em cêntimos, calcula o número de cigarros que cada fumador pode (e deve!) fumar, a percentagem de fumo que a máquina de reciclagem de ar deve extrair e o ganho de produtividade assim obtido truncado aos cêntimos, de maneira que o lucro da Smokesoft seja o maior possível.
No caso de haver várias soluções igualmente vantajosas, o seu programa deve escolher a que corresponda ao menor número de cigarros por fumador.
Esclarecimento: os não fumadores só são sensíveis ao fumo de cigarros “inteiros”. Por exemplo, se houver no ar o fumo de 10 cigarros e a máquina estiver a funcionar a 75%, os não fumadores só são incomodados pelo equivalente a 2 cigarros.
Outro esclarecimento: a máquina só pode funcionar em “modo inteiro”, isto é, a percentagem de fumo que consegue extrair é um número inteiro a dividir por 100. Para os efeitos deste problema, percentagem 17, por exemplo, significa 17%.
O seu programa deve conter um predicado smoke(S, N, L, C, R, P) que, quando chamado com S, N e L instanciados com números inteiros positivos representado o número de fumadores, o número de não fumadores e o valor de uma linha de código, devolve em C o número inteiro de cigarros que cada fumador deve fumar, em R o número inteiro que representa a percentagem de fumo que a máquina deve extrair do ar e em P o ganho de produtividade assim obtido.
Eis um exemplo de utilização do predicado smoke:
| ?- smoke(1, 1, 400, C, R, P).
C = 6;
R = 1;
C = 14390;
no
| ?- smoke(2, 0, 400, C, R, P).
C = 11;
R = 0;
C = 52800;
no
| ?- smoke(3, 1, 500, C, R, P).
C = 6;
R = 39;
C = 33790;
no
| ?- smoke(1, 5, 1000, C, R, P).
C = 4;
R = 26;
C = 16240;
no