https://foro.gambas-es.org/viewtopic.php?f=15&t=8006
-----------------------------------
Shell
Martes, 28 Abril 2020, 20:55

Problema Del Restaurante. Ejercicio
-----------------------------------
Buenas!.

Os propongo resolver un problema: 
Se trata de un restaurante que es el mejor haciendo "huevos" con "chorizos".   :-D 

Tenemos que averiguar [b]cuantos platos[/b] se pueden hacer si:

- Cada plato está formado por 2 huevos y 200g de chorizo.

A la función hay que pasarle  la cantidad de huevos y chorizos que tenemos en la despensa. 
Creando una función  resolver el problema.

[code linenumbers=false syntax=gambas]
Public Function numdeplatos(docenasdehuevo As Integer, kilosdechorizo As Float) As Integer
  
  
  
End
[/code]

He encontrado dos formas de hacerlo. Razonar la respuesta. :-)

Saludos


-----------------------------------
jguardon
Martes, 28 Abril 2020, 21:15

Re: Problema Del Restaurante. Ejercicio
-----------------------------------
Muevo el hilo a "Retos"

Saludos


-----------------------------------
Shell
Miercoles, 29 Abril 2020, 09:50

Re: Problema Del Restaurante. Ejercicio
-----------------------------------
Ups, no sabía que había un subforo para esto.  :oops: 

Aunque puedo verlo directamente al responder. Ahora ya sé que se encuentra en Aplicaciones/Fragmentos de Código.

Saludos


-----------------------------------
Shell
Lunes, 04 May 2020, 14:14

Re: Problema Del Restaurante. Ejercicio
-----------------------------------
Bueno!. :-D

Gran interés!. (Ocurre en todos los foros de programación).

El problema no es resolver el ejercicio, es usar la lógica para encontrar la mejor solución.
Y eso es lo más complicado. Y que se debe ejercer.

Forma que lo haríamos, paso a paso. Si tenemos una cantidad de ingredientes y sabemos que necesitamos,
podemos ir restando una y otra vez de los ingredientes disponibles y crear un plato, llegará un momento que no
podamos hacer más platos.

[code linenumbers=false syntax=gambas]
' Procedimiento habitual
Public Function numdeplatosv1(docenasdehuevo As Integer, kilosdechorizo As Float) As Integer

  Dim totalingrediente1 As Integer
  Dim totalingrediente2 As Float
  Dim totaldeplatos As Integer
  
  'Cantidad total de los ingredientes
  'Unidades
  totalingrediente1 += docenasdehuevo * 12
  'Gramos    
  totalingrediente2 += kilosdechorizo * 1000   
  
  'Se necesita para un plato:
  ' 2 huevos
  ' 200g de chorizo
  
  'Vamos eliminando de las existencias los ingredientes necesarios por cada plato
  Repeat
    totalingrediente1 -= HUEVOSPORPLATO
    totalingrediente2 -= CHORIZOPORPLATO
    totaldeplatos += 1
  Until totalingrediente1 < 2 Or totalingrediente2 < 200
  
  Return totaldeplatos
  
End
[/code]

Pero y si...decimos, si se nos acaba uno de los ingredientes necesario para un plato,
no tenemos por que continuar....esto resulta un poco más complejo de pensar la primera vez.

[code linenumbers=false syntax=gambas]
'Pocedimiento alternativo y más rápido
Public Function numdeplatosv2(docenasdehuevo As Integer, kilosdechorizo As Float) As Integer
  
  Dim totalingrediente1 As Integer
  Dim totalingrediente2 As Float
  
  'Cantidad total de los ingredientes
  'Unidades
  totalingrediente1 += docenasdehuevo * 12
  'Gramos    
  totalingrediente2 += kilosdechorizo * 1000   
  
  'Se necesita para un plato:
  ' 2 huevos
  ' 200g de chorizo
  
  'Si se acaba uno de los ingredientes ya no podemos hacer más plato
  'Devolvemos la cantidad de platos máximos que se admite con un total de un ingredientes
  If totalingrediente1 / HUEVOSPORPLATO < totalingrediente2 / CHORIZOPORPLATO Then
    Return totalingrediente1 / HUEVOSPORPLATO
  Else 
    Return totalingrediente2 / CHORIZOPORPLATO
  Endif
  
End
[/code]

Fijaros que el condicional comprueba dos ingredientes..Pero y si ahora le queremos 
añadir "patatas fritas!" al plato, ahora serian más ingredientes...esa condición no nos valdría..


Y si...usamos otras cosas....

Saludos


-----------------------------------
Shell
Lunes, 04 May 2020, 14:22

Re: Problema Del Restaurante. Ejercicio
-----------------------------------
Pues la última parte.

No he usado una interfaz gráfica. Quedaría mejor..pero eso es lo de menos, o quizás..no. :-D

Apliquemos ahora programación orientada a o objeto. Usamos dos clases.
Ingrediente:

[code linenumbers=false syntax=gambas]
Private hnombre As String
Private hunidades As Integer

Property Read nombre As String
Property unidades As Integer


Public Sub _new($nombre As String, $unidades As Integer)
  
  hnombre = $nombre
  hunidades = $unidades
  
End

Private Function nombre_Read() As String
  
  Return hnombre  
  
End

Private Function unidades_Read() As Integer
  
  Return hunidades  
  
End

Private Sub unidades_Write(Value As Integer)
  
  hunidades = Value    
  
End

Public Sub addIngrediente(cantidad As Float)
  
  hunidades += cantidad   
  
End
[/code]

Plato:

[code linenumbers=false syntax=gambas]
Private hnombredelplato As String
Property nombredelplato As String

Private hingredientesparaplato As Collection
Property Read ingredientesparaplato As Collection

Public Sub _new(nomdeplato As String, ...)
  
  Dim ingredientenecesario As Ingrediente
  Dim nomingrediente As Ingrediente   
  
  hnombredelplato = nomdeplato
  hingredientesparaplato = New Collection 
  
  For Each nomingrediente In Param    
    ingredientenecesario = New Ingrediente(nomingrediente.nombre, nomingrediente.unidades)
    hingredientesparaplato.Add(ingredientenecesario, ingredientenecesario.nombre) 
  Next
  
End

Private Function nombredelplato_Read() As String
  
  Return hnombredelplato
  
End

Private Sub nombredelplato_Write(Value As String)
  
  hnombredelplato = Value 
  
End

'Probablemente se pueda abreviar
Public Function TotalDePlatos(existencias As Ingrediente[]) As Integer
  
  Dim totaldeplatosposiblesconingrediente As Integer  
  Dim ingredienteconmenosexistencias As Ingrediente      
  Dim i As Integer  
   
  ingredienteconmenosexistencias = existencias[0]
  totaldeplatosposiblesconingrediente = ingredienteconmenosexistencias.unidades / hingredientesparaplato[ingredienteconmenosexistencias.nombre].unidades  
  
  For i = 1 To existencias.Count - 1
      If totaldeplatosposiblesconingrediente < existencias[i].unidades / hingredientesparaplato[ingredienteconmenosexistencias.nombre].unidades Then
        ingredienteconmenosexistencias = existencias[i]
      Endif
  Next
    
  Return ingredienteconmenosexistencias.unidades / hingredientesparaplato[ingredienteconmenosexistencias.nombre].unidades
  
End

Private Function ingredientesparaplato_Read() As Collection
  
  Return hingredientesparaplato
  
End
[/code]

Y el bloque principal:

[code linenumbers=false syntax=gambas]
Public Sub Main()
  
  Dim platohuevoconchorizos As Plato
  
  'Los ingredientes que necesitamos
  Dim ingredientenecesario1 As Ingrediente  
  Dim ingredientenecesario2 As Ingrediente
  
  'Los que vamos a tener que comprar
  Dim existenciasdeingrediente1 As Ingrediente
  Dim existenciasdeingrediente2 As Ingrediente
  
  'Todo los ingredientes que voy a tener del mismo plato
  Dim existenciastotales As New Ingrediente[]
  
  'Ingredientes para hacer un plato de huevos con chorizos  
  ingredientenecesario1 = New Ingrediente("huevos", 2)
  ingredientenecesario2 = New Ingrediente("chorizos", 200) 
  
  'Vamos al mercado a comprar los ingredientes...:-D 
  
  existenciasdeingrediente1 = New Ingrediente(ingredientenecesario1.nombre, 0)  
  existenciasdeingrediente1.addIngrediente(36)
  
  existenciasdeingrediente2 = New Ingrediente(ingredientenecesario2.nombre, 0)
  existenciasdeingrediente2.addIngrediente(1000)
  
  ' Y los añadimos a la despensa 
  existenciastotales.Add(existenciasdeingrediente1)
  existenciastotales.Add(existenciasdeingrediente2)
  
  'Leemos la receta y le añadimos los ingredientes que necesita
  platohuevoconchorizos = New Plato("Huevos con chorizos", ingredientenecesario1, ingredientenecesario2)
  
  'Con los que tenemos en la despensa podemos hacer:
  Print Subst("Platos que se pueden preparar: &1", platohuevoconchorizos.TotalDePlatos(existenciastotales)) 
  
End
[/code]

Como habréis visto he usado unidades, no kg en la mayoría de los problemas. La solución es la misma.

Ahora se le añade una GUI y quedará mejor. Pero para la lógica no se necesitan florituras.
Si para los ojos y atraer usuarios.. 

Saludos


-----------------------------------
Shell
Lunes, 04 May 2020, 14:26

Re: Problema Del Restaurante. Ejercicio
-----------------------------------
¿ Sabéis que cuando nos acostumbramos a la programación por procedimientos cometemos errores a la hora de crear el mismo programa en POO ?.

Visto eso. Mejor comenzar directamente por POO..  :-D 

Dice un dicho.  "La programación por procedimientos a la hora de depurarla es como llevar encima un calamar gigante y no puedes evitar que algún tentáculo 
te de en toda la cara."

Saludos


-----------------------------------
tercoIDE
Lunes, 04 May 2020, 14:45

Re: Problema Del Restaurante. Ejercicio
-----------------------------------
una vez que uno comprende POO, pasa a un plano superlativo en programacion

se transforma en Jedi


-----------------------------------
Shell
Lunes, 04 May 2020, 15:11

Re: Problema Del Restaurante. Ejercicio
-----------------------------------
tercoIDE:

[quote]
una vez que uno comprende POO, pasa a un plano superlativo en programacion

se transforma en Jedi
[/quote]

 :lol:

Bueno, pero no quita que nos podamos equivocar también... :wink: 
En ese caso la localización se simplifica más.

Saludos


-----------------------------------
Shell
Lunes, 04 May 2020, 15:13

Re: Problema Del Restaurante. Ejercicio
-----------------------------------
Añado los ordinogramas. 

Básico:

 [img]https://foro.gambas-es.org/files/images/768/procedimentob_sico.png[/img] 

Mejor depurado:

 [img]https://foro.gambas-es.org/files/images/768/procedimientomejorusado.png[/img] 

Código en PseInt:

[quote]
Algoritmo Restaurante
	Escribir numdeplatosv1(3, 1);
	Escribir numdeplatosv2(3, 1);
FinAlgoritmo

Funcion platos <- numdeplatosv1(docenasdehuevo, kilosdechorizo)
	Definir platos Como Entero;
	docenasdehuevo <- docenasdehuevo * 12;
	kilosdechorizo <- kilosdechorizo * 1000;
	platos <- 0;
	Repetir			
		docenasdehuevo<-docenasdehuevo - 2;
		kilosdechorizo<-kilosdechorizo - 200;
		platos<-platos + 1;
	Hasta Que (docenasdehuevo<2 o kilosdechorizo<200)
	
FinFuncion		

Funcion platos <- numdeplatosv2(docenasdehuevo , kilosdechorizo)
	Definir n1 Como Entero;
	Definir n2 Como Real;
	Definir platos Como Entero;
	n1 <- (docenasdehuevo * 12) / 2 ;
	n2 <- (kilosdechorizo * 1000) / 200;
	
	si n1 < n2 Entonces
		// Devolver n1
		platos <- n1;
	sino
		// Devolver n2
		platos <- n2;		
	FinSi
FinFuncion
[/quote]

Saludos


