|  | @@ -2,6 +2,7 @@
 | 
	
		
			
				|  |  |  use crate::group::*;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  use std::collections::HashSet;
 | 
	
		
			
				|  |  | +use std::string::String;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  /// Width of the sudoku board.
 | 
	
		
			
				|  |  |  const WIDTH: u8 = 9;
 | 
	
	
		
			
				|  | @@ -67,15 +68,17 @@ impl Sudoku {
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    pub fn load_from(&mut self, s: &str) {
 | 
	
		
			
				|  |  | +    /// Load puzzle from a string.
 | 
	
		
			
				|  |  | +    /// Note, we load from (top,left), to (bottom,left) by columns.
 | 
	
		
			
				|  |  | +    pub fn load_from_tld(&mut self, start_ch: char, blank: char, s: &str) {
 | 
	
		
			
				|  |  |          self.clear();
 | 
	
		
			
				|  |  |          let mut x: u8 = 0;
 | 
	
		
			
				|  |  |          let mut y: u8 = 0;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          for ch in s.chars() {
 | 
	
		
			
				|  |  | -            if ch >= 'b' {
 | 
	
		
			
				|  |  | -                self.set(x, y, ch as u8 - 'a' as u8);
 | 
	
		
			
				|  |  | -                // self.board[pos(x, y) as usize] = ch as u8 - 'a' as u8;
 | 
	
		
			
				|  |  | -            };
 | 
	
		
			
				|  |  | +            if ch != blank {
 | 
	
		
			
				|  |  | +                self.set(x,y, (ch as u8-start_ch as u8) +1);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  |              y += 1;
 | 
	
		
			
				|  |  |              if y >= WIDTH {
 | 
	
		
			
				|  |  |                  y = 0;
 | 
	
	
		
			
				|  | @@ -84,6 +87,55 @@ impl Sudoku {
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    /// Load puzzle from a string.
 | 
	
		
			
				|  |  | +    /// This loads from (top,left) to (top,right), by rows.
 | 
	
		
			
				|  |  | +    pub fn load_from_tlr(&mut self, start_ch: char, blank: char, s: &str) {
 | 
	
		
			
				|  |  | +        self.clear();
 | 
	
		
			
				|  |  | +        let mut i: u8 = 0;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        for ch in s.chars() {
 | 
	
		
			
				|  |  | +            if ch != blank {
 | 
	
		
			
				|  |  | +                self.set(xy(i).0, xy(i).1, (ch as u8-start_ch as u8) +1);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            i += 1;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    pub fn save_to_tld(&self, mut start_ch:char, blank: char) -> String {
 | 
	
		
			
				|  |  | +        let mut result = String::new();
 | 
	
		
			
				|  |  | +        result.reserve(MAX_SIZE as usize);
 | 
	
		
			
				|  |  | +        start_ch = (start_ch as u8 -1) as char;
 | 
	
		
			
				|  |  | +        let mut x:u8 = 0;
 | 
	
		
			
				|  |  | +        let mut y:u8 = 0;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        for i in 0..MAX_SIZE {
 | 
	
		
			
				|  |  | +            if self.board[pos(x,y) as usize] == 0 {
 | 
	
		
			
				|  |  | +                result.push(blank);
 | 
	
		
			
				|  |  | +            } else {
 | 
	
		
			
				|  |  | +                result.push((start_ch as u8 + self.board[i as usize]) as char);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            y += 1;
 | 
	
		
			
				|  |  | +            if y >= WIDTH {
 | 
	
		
			
				|  |  | +                y = 0;
 | 
	
		
			
				|  |  | +                x +=1;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        result
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    pub fn save_to_tlr(&self, mut start_ch:char, blank: char) -> String {
 | 
	
		
			
				|  |  | +        let mut result = String::new();
 | 
	
		
			
				|  |  | +        result.reserve(MAX_SIZE as usize);
 | 
	
		
			
				|  |  | +        start_ch = (start_ch as u8 -1) as char;
 | 
	
		
			
				|  |  | +        for i in 0..MAX_SIZE {
 | 
	
		
			
				|  |  | +            if self.board[i as usize] == 0 {
 | 
	
		
			
				|  |  | +                result.push(blank);
 | 
	
		
			
				|  |  | +            } else {
 | 
	
		
			
				|  |  | +                result.push((start_ch as u8 + self.board[i as usize]) as char);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        result
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  |      pub fn set(&mut self, x: u8, y: u8, value: u8) {
 | 
	
		
			
				|  |  |          self.board[pos(x, y) as usize] = value;
 | 
	
		
			
				|  |  |          // Ok, update the possible
 |