elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: AIO elhacker.NET 2021 Compilación herramientas análisis y desinfección malware


  Mostrar Mensajes
Páginas: 1 ... 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 [63] 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 ... 102
621  Programación / Programación C/C++ / Re: Ayuda con el scanf n el for en: 18 Mayo 2019, 02:07 am
Supongo que estás empezando por tu duda y que por tanto no usas memoria dinámica. Entonces puedes hacer lo siguiente:
Código
  1. #define MAX_SIZE 100 // creamos un array/vector de capacidad maxima = 100
  2.  
  3. int main(){
  4.    float notas[MAX_SIZE]; // creamos un array de 100 elementos
  5.    int num_notas; // cantidad de notas que vamos a introducir. Tiene que ser menor o igual que el MAX_SIZE
  6.    float promedio = 0; // promedio de las notas
  7.  
  8.    printf("Introduce el numero de notas que vas a almacenar: ");
  9.    scanf("%d", &num_notas);
  10.  
  11.    for(int i = 0; i < num_notas; ++i){
  12.        printf("Introduce la nota %d: ", i+1);
  13.        scanf("%f", &notas[i]);
  14.    }
  15.  
  16.    // si queremos calcular el promedio...
  17.    for(int i = 0; i < num_notas; ++i)
  18.        promedio += notas[i];
  19.    promedio /= num_notas;
  20. }
Así ya tienes todas tus notas guardadas en un array. Cuando lo vayas a recorrer recuerda recorrerlo hasta <num_notas>, no hasta <MAX_SIZE> ya que desde la posición notas[num_notas] hasta notas[MAX_SIZE-1] tendrás basura.

Si lo quieres solo para el promedio. Puedes hacerlo más simple.
Código
  1. int num_notas; // numero de notas que vamos a introducir
  2. float nota; // guarda la nota actual
  3. float promedio = 0; // acumula la suma de las notas y al final guarda el promedio
  4. // preguntas la cantidad de notas a introducir
  5. for(int i = 0; i < num_notas; ++i){
  6.    printf("Introduce la nota %d: ", i+1);
  7.    scanf("%f", &nota);
  8.    promedio += nota; // equivalente a promedio = promedio + nota
  9. }
  10. promedio /= num_notas; // equivalente a promedio = promedio / num_notas

Citar
Tambien deberias agregar una variable que cuente las veces que se repite el cuerpo del for, no seria correcto usar la "i" en este caso por que siempre quedaria con 1+ de las veces que se repitio el cuerpo del for, a menos que le decrementes uno,una vez que termine el for.
Ya lo tiene agregado eso. En su caso es <vm> (aunque un nombre como <num_notas> es más específico)...
622  Programación / Programación C/C++ / Re: Un programa con varias funciones y sin entradas en: 17 Mayo 2019, 22:33 pm
EDITO: Se ha corregido el pseudocódigo para ver si un número es primo <return true> por <return false> y <return numero == 2> por <return numero >= 2>.

Citar
me equivoqué al expresarla, no quería decir una potencia de dos, sino una potencia de base 2.
Creo que sigue sin ser eso :xD. Creo que lo que quieres decir no es "una potencia de base 2 elevada a un número primo, menos 1, da como resultado otro número primo" sino que los números primos de Mersenne son los números primos que resultan de elevar un 2 a una potencia prima y restarle 1. Pero no todos cumplen tu suposición como he mostrado antes por ejemplo con el 11.

Citar
Luego en la función EsPrimo, he quitado los else como me dijiste, ya que es cierto lo que dices, no había caído. Y he aunque he añadido otro if con el 7 sigue sin ser correcta porque siempre me dará error al escribir múltiplos de los números primos, como es el caso del 11, 13... así que no tengo ni idea de como hacerlo, ya que de la forma que dice storing Manolo si que sé, pero en el ejercicio me piden que lo averigüe sin contar los divisores... ayuda!!
En lugar de empezar dividiendo por 1 (que siempre va a ser divisible) y terminar dividiendo por el propio número (que siempre va a ser divisible) y comprobar que para que sea primo se tiene que poder dividir exactamente por 2. Reduce las iteraciones innecesarias. Si el 1 siempre es divisible y el propio número también haz:
Código:
para i := 2 hasta numero-1
    si numero % i == 0
        return false
    fin si
fin para
return numero >= 2
Este pseudocódigo te sirve para una función que indica si el número es primo sin contar los divisores y teniendo en cuenta que el 2 es el primer primo.

La formula que está en main es la que saqué de wikipedia. Tenia un problema con los resultados que no coincidian, concretamente a partir del 3 numero primo que me daba 9 y en wikipedia me salia que era 31 cambie mi función Potencia por pow en el main para ver si implementara mal la funcion y todos los resultados coincidian, primos y perfectos. Entonces arreglé mi función Potencia y los resultados eran los mismos que con pow.
Respecto a esto, tenemos el desarrollo de la wikipedia: https://es.wikipedia.org/wiki/N%C3%BAmero_perfecto en la sección de "Son Números Triangulares".
Según lo que me dices de que tus resultados son los mismos, tenemos la siguiente tabla:
Código:
NP: Numeros primos
NPX: Numeros primos generadores de los numeros primos de Mersenne
NPerfecto: Numeros perfectos usando los NP
NPerfectoX: Numeros perfectos usando los NPx
NPerfectoO: Numeros perfectos originales

NP  NPX    NPerfecto                              NPerfectoX = NPerfectoO
2     2         6                                             6
3     3         28                                           28
5     5         496                                         496
7     7         8128                                       8128
11   13       2096128                                 33550306
13   17       33550306                               8589869056
17   19       8589869056                           137438691328
19   31       137438691328                       2305843008139952128
23   61       35184367894528                   2658455991569831744654692615953842176
29   89       144115187807420420           191561942608236107294793378084303638130997321548169216
623  Programación / Programación C/C++ / Re: Un programa con varias funciones y sin entradas en: 17 Mayo 2019, 10:25 am
Dejando a un lado las respuestas que no llevan a nada productivo pero que puedo resumir en "enseñar malas prácticas a alguien que está empezando genera otra persona que enseñará malas prácticas a otros que estén empezando".
Citar
Por lo que entendí de la formula en wikipedia, cualquier numero primo al que se le aplique la formula pasa a ser automáticamente un numero primo de Mersenne sin necesidad de nada mas. De no ser así con volver a llamar a la función EsPrimo ya estaría el problema solucionado. Pero consulte la salida de los valores de la variable que almacena los numeros primos de Mersenne y coincidian con los que encontre en google. Estás seguro de que son incorrectos? Porque también comprobé los 10 numeros perfectos en google y eran los mismos que me da la salida de mi programa.
Los números primos de Mersenne son números que se calculan con la fórmula M(p) = 2^p-1 donde p es primo y M(p) también lo es. Si cogemos p = 11, tenemos M(11) = 2047 = 23 * 89, por lo que p sí es primo pero M(p), no. No había comprobado lo del número perfecto pero lo hacemos ahora. 2047 * 2^10 = 2096128 que se encuentra entre el tercer número perfecto (8128) y el cuarto (33550336), por lo que no es un número perfecto... al menos en donde yo he comprobado esos resultados que no digo que sea una página 100% fiable pero una de las dos, la tuya o la mía, es incorrecta.

624  Programación / Programación C/C++ / Re: Un programa con varias funciones y sin entradas en: 17 Mayo 2019, 08:55 am
Vaia coñazo de trabajos os mandan hacer. No tengo ni zorra de mates, pero es solo seguir las pautas del ejercicio y preguntarle las formulas a wikipedia. Haciendo estos ejercicios no aprendes nada. Buscate un libro teorico de C++. Te recomiendo Apress Learn C++ Game Development 2014. Cuando lo acabes pasate por la web https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list y pilla el libro de 1000 hojas que es el asco teorico más grande. Ve haciendo programas que se te ocurran mientras vas asimilando conceptos.

No hagas copia y pega que si tu profesor busca en google el codigo le saldra este post xD
Código
  1. #include <iostream>
  2. using namespace std;
  3.  
  4. unsigned long long Potencia (unsigned int Base, unsigned int Exponente)
  5. {
  6. unsigned long long potencia = 1;
  7. int i;
  8. if (Exponente==0) return 1; //Error.
  9. else
  10. {
  11. for(i=0;i<Exponente;++i)
  12. {
  13. potencia*=Base;
  14. }
  15. }
  16. return potencia;
  17. }
  18.  
  19. bool EsPrimo (unsigned long long Numero)
  20. {
  21. int Contador = 0;
  22. bool esPrimo = false;
  23. for (int i=1;i<(Numero+1); ++i)
  24. {
  25. if(Numero%i==0)
  26. {
  27. ++Contador;
  28. }
  29. }
  30. if(Contador!=2)
  31. {
  32. //Mete un cout por aqui de Numero si quieres para ver el numero que no es primo.
  33. return esPrimo;
  34. }
  35. else
  36. {
  37. esPrimo = true; //Mete un cout por aqui de Numero si quieres, para ver el numero que si es primo.
  38. return esPrimo;
  39. }
  40. }
  41.  
  42. int main()
  43. {
  44. unsigned int Numero = 1; //Numero a comprobar si es primo.
  45. unsigned int Contador = 1; //Contador para bucle do while.
  46. unsigned long long NumeroPrimoM;
  47. unsigned long long NumeroPerfecto;
  48. do {
  49.   if ( EsPrimo(Numero) ) //Funcion EsPrimo retorna true si el valor de Numero es primo.
  50.   {
  51.   NumeroPrimoM = Potencia(2,Numero) -1; //Formula para sacar primo de Mersenne.
  52. //Mete un cout aqui de NumeroPrimoM si quieres conocer a los primos de Mersenne.
  53.   NumeroPerfecto = (NumeroPrimoM*(NumeroPrimoM +1))/2; //Formula para sacar numero perfecto utilizando numero primo de Mersenne.
  54.   cout << Contador << " - Numero Perfecto: " << NumeroPerfecto << endl;
  55.   ++Contador; //Para el bucle while y seguir calculando hasta 10.
  56.   ++Numero;//Probemos si el siguiente numero es primo.
  57.     }
  58.  
  59.   else
  60.   {
  61.   ++Numero; //Si el valor en Numero no es primo, prueba el siguiente.
  62.   }
  63.  
  64. } while (Contador != 11);
  65. return 0;
  66. }
Si no entiendes algo pregunta.

O sea estos trabajos que te ayudan a pensar de forma lógica y a saber implementar las ideas que tienes en la cabeza son un coñazo y leerte un libro de 1000 páginas que ya adelantas ser "el asco teórico más grande" es mejor para alguien que está empezando?? Será buena idea si lo que quieres es que abandone la programación por parecerle "un coñazo".

En esa función <Potencia()> si tomas el caso de que exponente valga 0 de forma aislada (y no es un error eso) no tienes que inicializar <potencia> a 1 sino a <base> (es más puedes usar la propia variable base que no está pasada por referencia ni es constante para ahorrarte una variable y una iteración). Tal y como está implementado ahí, el bucle funciona también para el exponente 0 por lo que no es necesario tratarlo de forma aislada.

La función <esPrimo()> aparte de hacer iteraciones de más de forma innecesaria usa una variable para guardar true/false antes de retornar cuando se puede retornar el valor directamente. Y el <else> tampoco es necesario.

Ese programa no calcula los primos de Mersenne, calcula los números de Mersenne (no aseguras en ninguna parte que sean primos, es más, no lo son) por lo que los resultados no son correctos tampoco.

Y el uso correcto del <do while> es para bloques que deben ejecutarse una vez antes de comprobar la condición siempre, lo cual no es el caso. Para este caso por convención se emplea un <while>.

Al final los trabajos "coñazo" van a servir para ver los fallos que comete uno.
625  Programación / Programación C/C++ / Re: Sobrecarga de operador en: 17 Mayo 2019, 04:46 am
Bueno el problema principal como bien dices es que el operador < no está bien sobrecargado. Este operador pertenece a la clase, no es un operador externo a la clase que deba declararse como <friend>, es decir, sería así:
Código
  1. bool Usuario::operator<(const Usuario &otro)const{
  2.    return strncmp(this->nombre, otro.nombre, size) < 0;
  3. }
Esa función compara el número de caracteres indicados en <size> de ambas cadenas y retorna un valor negativo si la primera es menor a la segunda, un valor positivo si la primera es mayor a la segunda y 0 si son iguales.

Además de eso la declaración de <usuario> la puedes hacer una única vez antes de empezar el bucle y luego ir cambiando el valor de <nombre> en cada iteración.

Además no tiene mucho sentido usar arrays dinámicos si siempre los creas de tamaño 16, porque entonces... hasta dónde comparas las cadenas?? Tienes dos opciones:
  • Crear un array estático muy grande donde guardar el nombre introducido por el usuario, calcular los caracteres útiles y entonces reservar memoria justo para esos caracteres.
  • Usar string que es la ventaja de C++ para trabajar con cadenas de caracteres. Si usas string tendrás que convertirlos a char* para usar las funciones típicas de las cadenas pero eso se puede hacer simplemente con <nombre_string.c_str()>

Aparte de eso, el <set> mejor que sea local en el <main> en lugar de global.
626  Programación / Programación C/C++ / Re: Pasar archivo de texto a un arreglo bidimensional en C en: 17 Mayo 2019, 02:57 am
Una cadena de texto <char*/char[]> es un arreglo unidimensional por lo que hacer un arreglo de cadenas de texto es un arreglo bidimensional. Tienes que imaginarlo como una matriz donde cada cadena se escribe en una fila y cada caracter en una columna.

Dicho esto para leer palabras de un fichero tienes la función <fgets()> en C. Esta función tiene la siguiente forma:
Código
  1. char *fgets(char *variable, int max_size, FILE *fichero)
El valor de retorno no importa mucho ya que retorna lo mismo que guarda en <variable>.

Donde <variable> es el arreglo en el que vas a guardar lo que lees, <max_size> la cantidad máxima de caracteres que va a leer la función y <fichero> pues el fichero de donde lo va a leer. La función lee hasta que encuentra un salto de línea o hasta llegar al máximo indicado (lo que antes ocurra). Con el segundo parámetro te aseguras de que no tienes problemas de memoria. Si usas un arreglo estático, usa el tamaño del arreglo como segundo parámetro de la función <fgets()>.
627  Programación / Programación C/C++ / Re: Importante bucle mientras en: 17 Mayo 2019, 02:46 am
Repites muchas veces el mismo código lo cual no es para nada eficiente. Tienes que pensar bien lo que quieres hacer antes de programar. Haz un esquema en un papel o algo por el estilo que te ayude a organizar la información.
Te dejo un ejemplo para que veas que se puede organizar mejor el código basándome en el primer código que publicaste. No está completo ya que lo que tienes bien te he puesto un comentario para que lo incluyas tú. Tampoco era plan de hacerlo todo. Espero que te sirva de ayuda porque no es algo que haga a menudo así que aprovéchalo.

Debes ver qué cosas quieres guardar y cuales no hace falta; por ejemplo no es necesario guardar el precio antes del descuento y después (si fuera necesario pues entonces sí, creas una variable <precio_inicial> y otra <precio_final>). Si quieres mostrar cuántos clientes han elegido la opción 2 no tiene mucho sentido mostrarlo al terminar cada iteración porque en este caso si la opción es 2, los clientes que habrán elegido la opción 2 son todos <numero_clientes> y si la opción no es 2, entonces ninguno. Lo lógico desde mi punto de vista sería mostrar eso al terminar el programa (entonces en cada vuelta si la opción es 2, acumulamos los clientes que han elegido esa opción).
Código
  1. // creamos constantes globales para los precios ya que usar numeros sueltos que no se sabe lo que significa no es una buena practica
  2. const int PRECIO_1 = 250;
  3. const int PRECIO_2 = 255;
  4. const int PRECIO_3 = 350; // supongo esto ya que en el ultimo mensaje es 250 igual que precio1
  5.  
  6. // constantes para los descuentos
  7. const float DESCUENTO_1 = 0.15;
  8. const float DESCUENTO_3 = 0.25;
  9.  
  10. // constante para determinar el valor que se usa para finalizar el programa
  11. const int CLIENTES_EXIT = 9999;
  12.  
  13. int main(){
  14.    // creamos las variables que vamos a usar pensando bien en lo que necesitamos
  15.    int numero_clientes; // numero de clientes que van a "comprar" una de las opciones
  16.    int clientes_opcion2 = 0; // numero de clientes que eligen la opcion 2
  17.    int opcion_precio, opcion_pago; // opciones tanto de precio como de forma de pago
  18.    float precio, descuento; // precio de la compra (con decimales) y descuento aplicado
  19.  
  20.    // pides el numero de clientes
  21.    while(numero_clientes != CLIENTES_EXIT){
  22.        // pides las opciones
  23.  
  24.       // calculamos los precios segun el precio por cliente
  25.        if(opcion_precio == 1)
  26.            precio = numero_clientes * PRECIO_1;
  27.        else if(opcion_precio == 2)
  28.            precio = numero_clientes * PRECIO_2;
  29.        else
  30.            precio = numero_clientes * PRECIO_3;
  31.  
  32.        // calculamos lo necesario segun el metodo de pago
  33.        if(opcion_pago == 1)
  34.            descuento = precio * DESCUENTO_1;
  35.        else if(opcion_pago == 3)
  36.            descuento = precio * DESCUENTO_3;
  37.        else // si no es la opcion 1 ni 3, entonces es la 2 (suponiendo que solo se admiten esos 3 valores)
  38.            clientes_opcion2 += numero_clientes; // equivalente a clientes_opcion2 = clientes_opcion2 + numero_clientes
  39.  
  40.        // aplicamos el descuento
  41.        precio -= descuento; // equivalente a decir precio = precio - descuento
  42.  
  43.        // mostramos los resultados
  44.        printf("El importe final es: %.2f\n", precio); // mostramos el precio con 2 decimales
  45.        // muestras el descuento de la misma manera (CUIDADO: si la opcion de pago es 2 se mostrara el descuento de la repeticion anterior ya que no se actualiza)
  46.  
  47.        // pides numero de clientes nuevamente para repetir el programa
  48.    }
  49.    // llegamos aqui una vez que introducimos <numero_clientes = 9999>
  50.    printf("El numero de clientes que han elegido la opcion de pago 2 son: %d\n", clientes_opcion2);
  51. }

A la hora de pedir las opciones hay un problema. Que pasa si el usuario introduce opciones no válidas?? O qué pasa si el usuario introduce <numero_clientes = 10000>??
Bueno lo segundo es fácil. Cambiamos la condición del <while> por un (numero_clientes < CLIENTES_EXIT) y listo.
Lo primero se suele solucionar con lo que se conoce como filtro. Un filtro es un bucle que pide un valor al usuario y se repite mientras el valor no sea válido, o sea básicamente un filtro que solo deja pasar valores válidos. Esto se implementa con un <do while>. Te dejo un ejemplo de un filtro para que solo deje pasar números positivos y pares. Como tarea te queda adaptarlo a ti a tu problema...
Código
  1. int numero;
  2. do{ // hacer lo que hay dentro del bucle (pedir un valor)...
  3.    printf("Introduce un numero par y positivo: ");
  4.    scanf("%d", &numero);
  5. }   while(numero < 0 || numero % 2 != 0); // ... mientras el numero sea menor que 0 o sea impar
  6. // cuando un valor pase el filtro llegamos aqui y podemos asegurar que ese valor es positivo y par
  7. printf("El numero introducido es: %d\n", numero);
628  Programación / Programación C/C++ / Re: Un programa con varias funciones y sin entradas en: 17 Mayo 2019, 00:11 am
Lo primero, cuidado con esas suposiciones...
Citar
una potencia de 2 elevada a un número primo, menos uno, da como resultado otro número primo
Código:
potencia de 2 := 4
numero primo := 2
4² - 1 = 15 = 3*5 -> 15 no es primo

Siguiente problema. Esa función <esPrimo()>...
Código:
numero := 49
49 = 7² -> 49 no es primo
Segun la funcion: EsPrimo(49) = true
Es decir esa función no es correcta. Tienes que echarle un vistazo a ver si eres capaz de solucionarlo antes de que te diga cómo se hace.
Aparte y esto es más tontería, como son <return> no hacen falta los <else> ya que si se ejecuta un <return>, va a salir de la función y no sé ejecuta el resto:
Código
  1. if(x == a)
  2.    return 1;
  3. else if(x == b)
  4.    return 2;
  5. else
  6.    return 3;
  7.  
  8. // Se puede dejar en
  9. if(x == a) return 1;
  10. if(x == b) return 2;
  11. return 3;
Así queda más limpio y más simple al compilarlo.

Luego veamos la función <Potencia()>
Según el enunciado se te pide lo siguiente:
Citar
diseña, para ayudarte, una función 'Potencia' que eleve una base entera a una potencia entera y devuelva un 'unsigned long long' (¡no utilices la función 'pow'!).
Y tú creas esto:
Código
  1. // Cuidado que en el prototipo tienes un parametro y en la implementacion otro (unsigned int != unsigned long long)
  2. // Funcion que calcula la potencia indicada en el parametro de 2, es decir, 2^exponente
  3. unsigned long long Potencia(unsigned int exponente); // lo llamo exponente para que se entienda mejor
No has creado una función que eleve una base entera a una potencia entera. Has creado una función que eleva el 2 a una potencia NATURAL/entera positiva (0 incluido) (unsigned). Solo te lo comento para que veas la diferencia entre lo que te piden y lo que implementas. Lo suyo sería algo así:
Código
  1. unsigned long long Potencia2(int exponente); // dejar claro que esa funcion calcula potencias de 2
  2. unsigned long long Potencia(int base, int exponente); // lo que te pide el enunciado

Y después de todo esta parrafada, te comento lo que tienes que hacer. Los números perfectos se pueden obtener a partir de la fórmula que has comentado arriba aunque primero dejemos claro un par de notaciones para poder explicarte el ejercicio:
Código:
Pi := numero perfecto i
Mi(p) := numero de Mersenne i cuya formula es 2^p-1. Se suele representar como Mp, por ejemplo, M7 = 2⁷-1 = 127 pero te lo representare como M4(7), es decir, el 4º numero primo de Mersenne (que se calcula con p = 7)
Entonces tenemos que: Pi = Mi(p) * 2^p
Un número se considera de Mersenne si p es primo y 2^p-1 también es primo. Los 10 primeros p que cumplen esta condición son {2, 3, 5, 7, 13, 17, 19, 31, 61, 89} y los números de Mersenne que genera cada p son {3, 7, 31, 127, 8191, 131071, 524287, 2147483647, 2305843009213693951, 618970019…449562111} respectivamente (están en Wikipedia estos datos: https://es.wikipedia.org/wiki/N%C3%BAmero_primo_de_Mersenne)

Te pongo una forma de hacerlo para que tengas una idea
Código:
p := 2 // uso el mismo nombre que en las formulas anteriores
num_perfectos := 0
mientras num_perfectos < 10
    si esPrimo(p)
        numero_mersenne := Potencia(2,p)-1
        si esPrimo(numero_mersenne)
            numero_perfecto[num_perfecto] := numero_mersenne * Potencia(2, p-1)
            num_perfecto := num_perfecto + 1
        fin si
    fin si
    p := p + 1
fin mientras

Lo siento por el mensaje tan largo pero espero haberlo explicado todo con claridad. :-X
629  Programación / Programación C/C++ / Re: Rendondeo superior en: 16 Mayo 2019, 07:18 am
Existe la función <ceil()> de la librería <cmath> (en C++) o <math.h> (en C).
De todas formas puedes crear una función, simplemente suma una unidad al número original y luego trúncalo.
630  Programación / Programación C/C++ / Re: (Consulta) - Declaracion de punteros en Null en: 16 Mayo 2019, 04:45 am
Cuando creas un puntero, ese puntero guarda una dirección de memoria. Si el puntero no lo inicializas al crearlo, este apuntará a una dirección de memoria cualquiera que puedes ver pero no puedes usar porque no sabes a qué está apuntando. Se puede hacer que apunte a NULL para tener una referencia de que ese puntero no está en uso en ese momento.

Y ten cuidado con lo del arreglo... Un puntero no es un arreglo. Un puntero apunta al comienzo de un arreglo en el caso de que hayas reservado memoria o que sea un array estático, que no es el caso.
Páginas: 1 ... 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 [63] 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 ... 102
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines