Rutas
/
Rust
Rust
/
Ejercicios
/
Juego embebido de bajo consumo
Juego embebido de bajo consumo

Juego embebido de bajo consumo

Ejercicio de aprendizaje

Introducción

Las tuplas son una forma ligera de agrupar un conjunto fijo de tipos de datos arbitrarios. Una tupla no tiene un nombre concreto; dar nombre a una estructura de datos la convierte en un struct. Los campos de una tupla no tienen nombres; se accede a ellos mediante desestructuración o por posición.

Sintaxis

Creación

Las tuplas siempre se crean con una expresión de tupla:

// pointless but legal
let unit = ();
// single element
let single_element = ("note the comma",);
// two element
let two_element = (123, "elements can be of differing types");

Las tuplas pueden tener un número arbitrario de elementos.

Acceso por desestructuración

Es posible acceder a los elementos de una tupla mediante desestructuración. Esto significa simplemente asignar nombres de variables a los elementos individuales de la tupla, consumiéndola.

let (elem1, _elem2) = two_element;
assert_eq!(elem1, 123);

Acceso por posición

También es posible acceder a los elementos de una tupla mediante un índice numérico posicional. La indexación, como siempre, empieza en 0.

let notation = single_element.0;
assert_eq!(notation, "note the comma");

Estructuras de tupla

También se te pedirá que trabajes con estructuras de tupla. Al igual que las estructuras normales, son tipos con nombre; a diferencia de las estructuras normales, tienen campos anónimos. Su sintaxis es muy similar a la sintaxis normal de las tuplas. Es legal usar tanto la desestructuración como el acceso por posición.

struct TupleStruct(u8, i32);
let my_tuple_struct = TupleStruct(123, -321);
let neg = my_tuple_struct.1;
let TupleStruct(byte, _) = my_tuple_struct;
assert_eq!(neg, -321);
assert_eq!(byte, 123);

Visibilidad de los campos

Todos los campos de las tuplas anónimas son siempre públicos. Sin embargo, los campos de las estructuras de tupla tienen visibilidad individual, que por defecto es privada, al igual que los campos de las estructuras estándar. Puedes hacer que los campos sean públicos con el modificador pub, igual que en una estructura estándar.

// fails due to private fields
mod tuple { pub struct TupleStruct(u8, i32); }
fn main() { let _my_tuple_struct = tuple::TupleStruct(123, -321); }
// succeeds: fields are public
mod tuple { pub struct TupleStruct(pub u8, pub i32); }
fn main() { let _my_tuple_struct = tuple::TupleStruct(123, -321); }

Instrucciones

Estás trabajando en un juego para un sistema embebido de bajo consumo y necesitas escribir varias funciones de utilidad que usarán otras partes del juego.

1. Calcula el cociente y el residuo de una división

El cociente es el resultado de una división.

fn divmod(dividend: i16, divisor: i16) -> (i16, i16)

Ejemplo:

assert_eq!(divmod(10, 3), (3, 1));

2. Elige los elementos en posiciones pares de un iterador

Esto te ayudará a habilitar una optimización del búfer de pantalla, te promete tu jefe.

Los iteradores son elementos que exponen los métodos definidos por el trait Iterator. Esa documentación es bastante extensa, porque ofrecen muchos métodos; estas son las propiedades más relevantes:

  • Un iterador es un flujo de elementos de longitud arbitraria
  • Tienen un método enumerate que devuelve una tupla (i, val) para cada valor
  • Tienen un método filter que usa un closure para determinar si se debe producir un elemento del iterador
  • Tienen un método map que usa un closure para modificar los elementos del iterador

Como tu función puede ejecutarse con cualquier tipo de iterador, usa impl para indicar que se trata de una instancia de trait en lugar de un elemento simple. Del mismo modo, la sintaxis <Item=T> solo significa que no importa qué tipo de elemento produzca el iterador; tu función puede producir los elementos pares de cualquier iterador.

fn evens<T>(iter: impl Iterator<Item=T>) -> impl Iterator<Item=T>

Ejemplos:

let mut even_ints = evens(0_u8..);
assert_eq!(even_ints.next(), Some(0));
assert_eq!(even_ints.next(), Some(2));
assert_eq!(even_ints.next(), Some(4));
assert_eq!(even_ints.next(), Some(6));
let mut evens_from_odds = evens(1_i16..);
assert_eq!(evens_from_odds.next(), Some(1));
assert_eq!(evens_from_odds.next(), Some(3));
assert_eq!(evens_from_odds.next(), Some(5));
assert_eq!(evens_from_odds.next(), Some(7));

3. Calcula la distancia Manhattan de una posición al origen

Para facilitar el mapeo, tienes un struct de tupla Position:

struct Position(i16, i16);

Necesitas implementar un método manhattan en Position que devuelva la distancia Manhattan de esa posición al origen (Position(0, 0)).

impl Position {
    fn manhattan(&self) -> i16
}

Ejemplo:

assert_eq!(Position(3, 4).manhattan(), 7);
Editar en GitHub El enlace se abre en una ventana o pestaña nueva
Rust Exercism

¿Listo para empezar Juego embebido de bajo consumo?

Regístrate en Exercism para aprender y dominar Rust con 99 ejercicios y mentoría humana real, todo gratis.