// tag::solution_variant[]
/// Appends tiles to solution until no more tile is found
///
/// Works in two directions, depending on argument `fwd`
///
/// If solution length is larger than `w`, next tiles are checked against neighbor in row above
/// if `fwd` is `true` or row below if `fwd` is false.
///
/// If neighbor from other row matches and direct neighbor does not match, new row is assumed. The
/// function does not check that each row actually has `width` elements, which should be the case
/// for a well formed problem.
:solution_variant[]
Appends tiles to solution until no more tile is found

Works in two directions, depending on argument `fwd`



If neighbor from other row matches and direct neighbor does not match, new row is assumed. The
function does not check that each row actually has `width` elements, which should be the case
for a well formed problem.
: solution_variant [] Appends tiles to solution until no more tile is found Works in two directions depending on argument ` fwd ` If neighbor from other row matches and direct neighbor does not match new row is assumed . The function does not check that each row actually has ` width ` elements which should be the case for a well formed problem .
fn append(solution: &mut VecDeque<(Tile, usize)>, tiles: &mut Vec<Tile>, w: usize, fwd: bool) {
    // determine search directions
    let (s_n, s_o) = if fwd { (1, 2) } else { (3, 0) };
    while !tiles.is_empty() {
        // neighbor and other row elements
        let ((tile_n, t_n), other) = if fwd {
            (solution.back().unwrap(), solution.iter().rev().skip(w - 1).next())
        } else {
            (solution.front().unwrap(), solution.iter().skip(w - 1).next())
        };
        // find matching tile with transformation
        // there are three cases when an element matches
        // a) neighbor matches, there is no other -> add in first row
        // b) neighbor and other match with same transformation -> add in same row
        // c) neighbor does not match, other matches -> add in next row
        match tiles.iter().enumerate()
            .filter_map(|(pos, tile)| match (
                tile_n.matches(tile, *t_n, s_n),
                other.map(|(tile_o, t_o)| tile_o.matches(tile, *t_o, s_o)).flatten()
            ) {
                (Some(ta), None) if other.is_none() => Some((pos, ta)),
                (Some(ta), Some(tb)) if ta == tb => Some((pos, ta)),
                (None, Some(tb)) => Some((pos, tb)),
                _ => None,
            }).next().map(|(pos, t)| (tiles.remove(pos), t))
        {
            Some(value) if fwd => solution.push_back(value),
            Some(value) => solution.push_front(value),
            _ => break,
        }
    }
}
fn append ( solution : & mut VecDeque < ( Tile , usize ) > , tiles : & mut Vec < Tile > , w : usize , fwd : bool ) { // determine search directions let ( s_n , s_o ) = if fwd { ( 1 , 2 ) } else { ( 3 , 0 ) } ; while ! tiles . is_empty ( ) { // neighbor and other row elements let ( ( tile_n , t_n ) , other ) = if fwd { ( solution . back ( ) . unwrap ( ) , solution . iter ( ) . rev ( ) . skip ( w - 1 ) . next ( ) ) } else { ( solution . front ( ) . unwrap ( ) , solution . iter ( ) . skip ( w - 1 ) . next ( ) ) } ; // find matching tile with transformation // there are three cases when an element matches // a) neighbor matches, there is no other -> add in first row // b) neighbor and other match with same transformation -> add in same row // c) neighbor does not match, other matches -> add in next row match tiles . iter ( ) . enumerate ( ) . filter_map ( | ( pos , tile ) | match ( tile_n . matches ( tile , * t_n , s_n ) , other . map ( | ( tile_o , t_o ) | tile_o . matches ( tile , * t_o , s_o ) ) . flatten ( ) ) { ( Some ( ta ) , None ) if other . is_none ( ) => Some ( ( pos , ta ) ) , ( Some ( ta ) , Some ( tb ) ) if ta == tb => Some ( ( pos , ta ) ) , ( None , Some ( tb ) ) => Some ( ( pos , tb ) ) , _ => None , } ) . next ( ) . map ( | ( pos , t ) | ( tiles . remove ( pos ) , t ) ) { Some ( value ) if fwd => solution . push_back ( value ) , Some ( value ) => solution . push_front ( value ) , _ => break , } } }
tag::solution_variant[]
Appends tiles to solution until no more tile is found
tag :: solution_variant [] Appends tiles to solution until no more tile is found
solution
&mut VecDeque<(Tile, usize)>
tiles
&mut Vec<Tile>
w
usize
fwd
bool