Tracks
/
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 datos de tipos arbitrarios. Una tupla no tiene un nombre particular; darle nombre a una estructura de datos la convierte en un struct. Los campos de una tupla no tienen nombre; 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 una cantidad arbitraria de elementos.

Acceso por desestructuración

Es posible acceder a los elementos de una tupla mediante desestructuración. Esto simplemente significa 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 posicional numérico. La indexación, como siempre, comienza en 0.

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

Structs de tupla

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

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 los structs de tupla tienen visibilidad individual, que por defecto es privada, igual que los campos de los structs estándar. Puedes hacer que los campos sean públicos con el modificador pub, justo como en un struct 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 dirigido a 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

Un 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

Tu jefe promete que esto te ayudará a habilitar una optimización del búfer de pantalla.

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 esto es una instancia de un trait en lugar de un elemento simple. De igual manera, la sintaxis <Item=T> solo significa que no importa qué tipo de elemento produzca el iterador; tu función puede producir los elementos en posición par 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 respecto al origen

Por comodidad para el mapeo, tienes una estructura de tupla Position:

struct Position(i16, i16);

Necesitas implementar un método manhattan en Position que devuelve la distancia Manhattan de esa posición respecto 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 una pestaña nuevas
Rust Exercism

¿Todo 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.