I'm trying to iterate through a 2d vector of Vec3, but I'm rather new to Rust and I'm not sure how. Here's what I got so far:
let vertList: Vec<Vec<Vec3>> = vec![vec![Vec3::new(0.,0.,0.);h as usize];w as usize];
for h in 0..vertList[?][?] {
for w in 0..vertList[?][?] {
//Some code for each pixel
}
}
For further context, I want to use this 2d vector for storing the color values of a screen, and I want to scan through all pixels.
You can use a for loop directly over a Vec’s elements, without involving a range of 0..len indices, using Vec::iter:
for row in vertList.iter() {
for pixel in row.iter() {
// …
}
}
(Alternatively, since &Vec can become an iterator directly and row here is a borrow of a Vec either way,)
for row in &vertList {
for pixel in row {
// …
}
}
And for completeness, the ranges you were looking for would end at vertList.len() and vertList[h].len() respectively.
Related
I have an OLS fitting function that returns an OMatrix. The return type should always be a one-dimensional vector of coefficients.
use std::f64::NAN;
use nalgebra::{DMatrix, Dynamic, MatrixSlice, OMatrix, RowVector};
fn ols(
x: MatrixSlice<f64, Dynamic, Dynamic>,
y: MatrixSlice<f64, Dynamic, Dynamic>,
) -> OMatrix<f64, Dynamic, Dynamic> {
(x.transpose() * x).pseudo_inverse(0.00001).unwrap() * x.transpose() * y
}
The output of ols will always have the same number of elements which is equal to the number of columns as the input x (I'm not sure how I can change the return signature to represent this, I'm new to rust).
The output of ols should then be copied to a single row of an output matrix out. I am trying to do this with the set_row function, but I get the error expected struct 'Const', found struct 'Dynamic'.
fn my_func(
x: &DMatrix<f64>, // data matrix
y: &DMatrix<f64>, // target matrix, actually a matrix with only 1 column
) -> DMatrix<f64> {
let nrows = x.shape().0;
let ncols = x.shape().1;
// initialize out matrix to all NAN's
let mut out = DMatrix::from_element(nrows, ncols, NAN);
let i: usize = 100;
let tmp_x: MatrixSlice<f64, Dynamic, Dynamic> = x.slice((i, 0), (50, ncols));
let tmp_y: MatrixSlice<f64, Dynamic, Dynamic> = y.slice((i, 0), (50, 1));
// the next two lines are where I need help
let ols_coefs = ols(tmp_x, tmp_y);
out.set_row(i, &ols_coefs); // error occurs here
return out;
}
I suspect I need to convert the type of the output of ols somehow, but I am not sure how.
I'm working through the Advent of Code 2015 problems in order to practise my Rust skills.
Here is the problem description:
Realizing the error of his ways, Santa has switched to a better model of determining whether a string is naughty or nice. None of the old rules apply, as they are all clearly ridiculous.
Now, a nice string is one with all of the following properties:
It contains a pair of any two letters that appears at least twice in the string without overlapping, like xyxy (xy) or aabcdefgaa (aa), but not like aaa (aa, but it overlaps).
It contains at least one letter which repeats with exactly one letter between them, like xyx, abcdefeghi (efe), or even aaa.
For example:
qjhvhtzxzqqjkmpb is nice because is has a pair that appears twice (qj) and a letter that repeats with exactly one letter between them (zxz).
xxyxx is nice because it has a pair that appears twice and a letter that repeats with one between, even though the letters used by each rule overlap.
uurcxstgmygtbstg is naughty because it has a pair (tg) but no repeat with a single letter between them.
ieodomkazucvgmuy is naughty because it has a repeating letter with one between (odo), but no pair that appears twice.
How many strings are nice under these new rules?
This is what I've managed to come up with so far:
pub fn part2(strings: &[String]) -> usize {
strings.iter().filter(|x| is_nice(x)).count()
/* for s in [
String::from("qjhvhtzxzqqjkmpb"),
String::from("xxyxx"),
String::from("uurcxstgmygtbstg"),
String::from("ieodomkazucvgmuy"),
String::from("aaa"),
]
.iter()
{
is_nice(s);
}
0 */
}
fn is_nice(s: &String) -> bool {
let repeat = has_repeat(s);
let pair = has_pair(s);
/* println!(
"s = {}: repeat = {}, pair = {}, nice = {}",
s,
repeat,
pair,
repeat && pair
); */
repeat && pair
}
fn has_repeat(s: &String) -> bool {
for (c1, c2) in s.chars().zip(s.chars().skip(2)) {
if c1 == c2 {
return true;
}
}
false
}
fn has_pair(s: &String) -> bool {
// Generate all possible pairs
let mut pairs = Vec::new();
for (c1, c2) in s.chars().zip(s.chars().skip(1)) {
pairs.push((c1, c2));
}
// Look for overlap
for (value1, value2) in pairs.iter().zip(pairs.iter().skip(1)) {
if value1 == value2 {
// Overlap has occurred
return false;
}
}
// Look for matching pair
for value in pairs.iter() {
if pairs.iter().filter(|x| *x == value).count() >= 2 {
//println!("Repeat pair: {:?}", value);
return true;
}
}
// No pair found
false
}
However despite getting the expected results for the commented-out test values, my result when running on the actual puzzle input does not compare with community verified regex-based implementations. I can't seem to see where the problem is despite having thoroughly tested each function with known test values.
I would rather not use regex if at all possible.
I think has_pairs has a bug:
In the word aaabbaa, we have overlapping aa (at the beginning aaa), but I think you are not allowed to return false right away, because there is another - non-overlapping - aa at the end of the word.
I'm trying to write code using conrod with a winit/glium backend. Conrod is an intermediate mode graphical user interface library for Rust while wininit provides an event model and glium the OpenGL bindings.
My code draws a grid of values onto a screen with a (row,col), i.e. "text1" at (0,0), "text2", (1,0), "text3" at (0,1) etc. where (row,col) is translated to an absolute (x,y) coordinate.
Basic flow is this:
For each value I want to render as text
Calculate the column / row of the value, i.e. (idx % num_cols, idx / num_cols)
Calculate an x and y from the column and row. i.e. (col * WIDTH, ROW * HEIGHT).
Create a widget::Text at (x, y) containing the value
The code that does this is shown below in a slightly simplified form. The entire file is online here.
This should be simple code to implement but when I run it, the text boxes are not drawn from x=0, y=0 but instead somewhere but not exactly offset from the centre of the view in both axes.
As far as I can tell this shouldn't happen because I am explicitly setting the absolute position and have confirmed the coordinates are correct. So I would expect them to render from the top left of the screen. I don't understand what causes the offset.
Any ideas?
The code that calculates position is this:
fn draw_ui(ui: &mut Ui, model: &mut UiModel) {
let ui = &mut ui.set_widgets();
// Canvas is the backdrop to the view
widget::Canvas::new()
.color(BACKGROUND_COLOUR)
.set(model.static_ids.canvas, ui);
// Create text widgets for each value
let state = model.session_state.read().unwrap();
// Create / update the widgets
if state.values.is_empty() {
// ... removed
} else {
let num_cols: usize = 2;
state.values.iter().enumerate().for_each(|(i, v)| {
// Create / update the cell and its state
let (node_id, value) = v;
if let Some(id) = model.value_ids.get(node_id) {
let (col, row) = (i % num_cols, i / num_cols);
let valid = value.is_valid();
let value = if let Some(ref value) = value.value {
value.to_string()
} else {
"None".to_string()
};
// Turn the value into a string to render it
let (x, y) = (col as f64 * (CELL_WIDTH + PADDING), row as f64 * (CELL_HEIGHT + PADDING));
value_widget(&value, valid, x, y, CELL_WIDTH, CELL_HEIGHT, model.static_ids.canvas)
.set(*id, ui);
}
});
}
}
fn value_widget(value: &str, valid: bool, x: f64, y: f64, w: f64, h: f64, canvas_id: conrod::widget::Id) -> widget::Text {
let color = if valid { GOOD_COLOUR } else { BAD_COLOUR };
widget::Text::new(value)
.x_y(x, y)
.w(w).h(h)
.color(color)
}
I think the 0,0 position is in the center of the window. The slight offset you are seeing comes from the text box position specifying the corner of the text box. To get something in the top left of the window you would want to do something like x_position - 0.5 * window_width + x_margin (similar for y).
I am writing a macro to parse some structured text into tuples, line by line. Most parts work now, but I am stuck at forming a tuple by extracting/converting Strings from a vector.
// Reading Tuple from a line
// Example : read_tuple( "1 ab 3".lines()
// ,(i32, String, i32))
// Expected : (1, "ab", 3)
// Note:: you can note use str
macro_rules! read_tuple {
(
$lines :ident , ( $( $t :ty ),* )
)
=> {{
let l = ($lines).next().unwrap();
let ws = l.trim().split(" ").collect::<Vec<_>>();
let s : ( $($t),* ) = (
// for w in ws {
// let p = w.parse().unwrap();
// ( p) ,
// }
ws[0].parse().unwrap(),
ws[1].parse().unwrap(),
//...
ws[2].parse().unwrap(),
// Or any way to automatically generate these statments?
);
s
}}
}
fn main() {
let mut _x = "1 ab 3".lines();
let a = read_tuple!( _x, (i32, String, i32));
print!("{:?}",a);
}
How can I iterate through ws and return the tuple within this macro?
You can try here
A tuple is a heterogeneous collection; each element may be of a different type. And in your example, they are of different types, so each parse method is needing to produce a different type. Therefore pure runtime iteration is right out; you do need all the ws[N].parse().unwrap() statements expanded.
Sadly there is not at present any way of writing out the current iteration of a $(…)* (though it could be simulated with a compiler plugin). There is, however, a way that one can get around that: blending run- and compile-time iteration. We use iterators to pull out the strings, and the macro iteration expansion (ensuring that $t is mentioned inside the $(…) so it knows what to repeat over) to produce the right number of the same lines. This also means we can avoid using an intermediate vector as we are using the iterator directly, so we win all round.
macro_rules! read_tuple {
(
$lines:ident, ($($t:ty),*)
) => {{
let l = $lines.next().unwrap();
let mut ws = l.trim().split(" ");
(
$(ws.next().unwrap().parse::<$t>().unwrap(),)*
)
}}
}
A minor thing to note is how I changed ),* to ,)*; this means that you will get (), (1,), (1, 2,), (1, 2, 3,), &c. instead of (), (1), (1, 2), (1, 2, 3)—the key difference being that a single-element tuple will work (though you’ll still sadly be writing read_tuple!(lines, (T))).
I am having a problem figuring out how to reference elements of a sub structure.
See: http://play.golang.org/p/pamS_ZY01s
Given something like following.... How do you reference data in the room struct? I have tried fmt.Println(*n.Homes[0].Rooms[0].Size), but that does not work.
Begin Code example
package main
import (
"fmt"
)
type Neighborhood struct {
Name string
Homes *[]Home
}
type Home struct {
Color string
Rooms *[]Room
}
type Room struct {
Size string
}
func main() {
var n Neighborhood
var h1 Home
var r1 Room
n.Name = "Mountain Village"
h1.Color = "Blue"
r1.Size = "200 sq feet"
// Initiaize Array of Homes
homeslice := make([]Home, 0)
n.Homes = &homeslice
roomslice := make([]Room, 0)
h1.Rooms = &roomslice
*h1.Rooms = append(*h1.Rooms, r1)
*n.Homes = append(*n.Homes, h1)
fmt.Println(n)
fmt.Println(*n.Homes)
}
First, *[]Home is really wasteful. A slice is a three worded struct under the hood, one of them being itself a pointer to an array. You are introducing a double indirection there. This article on data structures in Go is very useful.
Now, because of this indirection, you need to put the dereference operator * in every pointer-to-slice expression. Like this:
fmt.Println((*(*n.Homes)[0].Rooms)[0].Size)
But, really, just take out the pointers.