<commit_before>//! module for finite automation.

use std::collections::HashSet;
use std::hash::Hash;

/// The rule that moves state from one to another.
///
/// `S` - the type parameter of state.
///
/// `T` - the type parameter of input symbol.
#[deriving(PartialEq, Eq, Hash)]
pub struct Rule<S, T> {
  pub state: S,
  pub symbol: Option<T>,
  pub next_state: S
}

impl<S: PartialEq, T: PartialEq> Rule<S, T> {
  /// determine whether the rule applies to the given state and symbol
  pub fn apply_to(&self, state: &S, symbol: &Option<T>) -> bool {
    self.state == *state && self.symbol == *symbol
  }
}

/// The transition relation in DFA,
/// containing all the rules needed by the DFA.
pub struct DFATransitions<S, T> {
  pub rules: HashSet<Rule<S, T>>
}

impl<S: Eq + Hash, T: Eq + Hash> DFATransitions<S, T> {
  /// get the next state for the given state and symbol
  pub fn next_state(&self, state: &S, symbol: &Option<T>) -> Option<&S> {
    self.rule_for(state, symbol).map(|rule| &rule.next_state)
  }

  fn rule_for(&self, state: &S, symbol: &Option<T>) -> Option<&Rule<S, T>> {
    self.rules.iter().find(|rule| { rule.apply_to(state, symbol) })
  }
}

/// A running dfa instance, constructed from a DFA model
pub struct DFA<'a, S: 'a, T: 'a> {
  state: S, // current state
  accept_states: &'a HashSet<S>, // set of accept states
  transitions: &'a DFATransitions<S, T>
}

impl<'a, S: Eq + Hash + Clone, T: Eq + Hash> DFA<'a, S, T> {
  pub fn accepted(&self) -> bool {
    self.accept_states.contains(&self.state)
  }

  pub fn read_symbol(&mut self, sym: &Option<T>) {
    self.state = self.transitions.next_state(&self.state, sym)
                                 .expect("unknown input symbol")
                                 .clone()
  }
}

/// DFA template that can generates dfa instance
pub struct DFAModel<S, T> {
  pub start_state: S,
  pub accept_states: HashSet<S>,
  pub transitions: DFATransitions<S, T>
}

impl<S: Clone + Eq + Hash, T: Eq + Hash> DFAModel<S, T> {
  /// determine whether the given symbols can be accepted by the model
  pub fn accept<I: Iterator<T>>(&self, mut iter: I) -> bool {
    let mut dfa = self.gen_dfa();
    for sym in iter {
      dfa.read_symbol(&Some(sym));
    }

    dfa.accepted()
  }

  /// generate a dfa instance
  fn gen_dfa(&self) -> DFA<S, T> {
    DFA {
      state: self.start_state.clone(),
      accept_states: &self.accept_states,
      transitions: &self.transitions
    }
  }
}

/// The transition relation in NFA,
/// containing all the rules needed by the NFA.
pub struct NFATransitions<S, T> {
  pub rules: HashSet<Rule<S, T>>
}

impl<S: Eq + Hash + Clone, T: Eq + Hash> NFATransitions<S, T> {

  pub fn next_states(&self, states: &HashSet<S>, symbol: &Option<T>) -> HashSet<S> {

    // TODO: find out why the flat_map thing cannot work.
    // states.iter().flat_map(|state| {
    //   // error goes here: borrowed value does not live long enough
    //   self.next_states_for(state, symbol).iter().map(|s| s.clone())
    // }).collect()

    let mut result = HashSet::new();
    for state in states.iter() {
      result.extend(self.next_states_for(state, symbol).iter().map(|s| s.clone()));
    }

    result
  }

  /// get the next state for the given state and symbol
  fn next_states_for(&self, state: &S, symbol: &Option<T>) -> HashSet<S> {
    self.rules.iter().filter_map(|rule| {
      if rule.apply_to(state, symbol) { Some(rule.next_state.clone()) } else { None }
    }).collect()
  }

  fn rules_for<'a>(&'a self, state: &S, symbol: &Option<T>) -> HashSet<&'a Rule<S, T>> {
    self.rules.iter()
              .filter(|rule| { rule.apply_to(state, symbol) })
              .collect()
  }
}

struct NFA<'a, S: 'a, T: 'a> {
  states: HashSet<S>,
  accept_states: &'a HashSet<S>,
  transitions: &'a NFATransitions<S, T>
}

impl<'a, S: Eq + Hash + Clone, T: Eq + Hash> NFA<'a, S, T> {
  pub fn read_symbol(&mut self, symbol: &Option<T>) {
    self.states = self.transitions.next_states(&self.states, symbol)
                                  .iter()
                                  .map(|state| { state.clone() }).collect()
  }

  pub fn accepted(&self) -> bool {
    !self.states.is_disjoint(self.accept_states)
  }
}

pub struct NFAModel<S, T> {
  pub start_state: S,
  pub accept_states: HashSet<S>,
  pub transitions: NFATransitions<S, T>
}

impl<S: Eq + Hash + Clone, T: Eq + Hash> NFAModel<S, T> {
  /// determine whether the given symbols can be accepted by the model
  pub fn accept<I: Iterator<T>>(&self, mut iter: I) -> bool {
    let mut dfa = self.gen_nfa();
    for sym in iter {
      dfa.read_symbol(&Some(sym));
    }

    dfa.accepted()
  }

  /// generate a nfa instance
  fn gen_nfa(&self) -> NFA<S, T> {
    let mut start_states = HashSet::new();
    start_states.insert(self.start_state.clone());
    NFA {
      states: start_states,
      accept_states: &self.accept_states,
      transitions: &self.transitions
    }
  }
}
<commit_msg>improve the flat_map things<commit_after>//! module for finite automation.

use std::collections::HashSet;
use std::hash::Hash;

/// The rule that moves state from one to another.
///
/// `S` - the type parameter of state.
///
/// `T` - the type parameter of input symbol.
#[deriving(PartialEq, Eq, Hash)]
pub struct Rule<S, T> {
  pub state: S,
  pub symbol: Option<T>,
  pub next_state: S
}

impl<S: PartialEq, T: PartialEq> Rule<S, T> {
  /// determine whether the rule applies to the given state and symbol
  pub fn apply_to(&self, state: &S, symbol: &Option<T>) -> bool {
    self.state == *state && self.symbol == *symbol
  }
}

/// The transition relation in DFA,
/// containing all the rules needed by the DFA.
pub struct DFATransitions<S, T> {
  pub rules: HashSet<Rule<S, T>>
}

impl<S: Eq + Hash, T: Eq + Hash> DFATransitions<S, T> {
  /// get the next state for the given state and symbol
  pub fn next_state(&self, state: &S, symbol: &Option<T>) -> Option<&S> {
    self.rule_for(state, symbol).map(|rule| &rule.next_state)
  }

  fn rule_for(&self, state: &S, symbol: &Option<T>) -> Option<&Rule<S, T>> {
    self.rules.iter().find(|rule| { rule.apply_to(state, symbol) })
  }
}

/// A running dfa instance, constructed from a DFA model
pub struct DFA<'a, S: 'a, T: 'a> {
  state: S, // current state
  accept_states: &'a HashSet<S>, // set of accept states
  transitions: &'a DFATransitions<S, T>
}

impl<'a, S: Eq + Hash + Clone, T: Eq + Hash> DFA<'a, S, T> {
  pub fn accepted(&self) -> bool {
    self.accept_states.contains(&self.state)
  }

  pub fn read_symbol(&mut self, sym: &Option<T>) {
    self.state = self.transitions.next_state(&self.state, sym)
                                 .expect("unknown input symbol")
                                 .clone()
  }
}

/// DFA template that can generates dfa instance
pub struct DFAModel<S, T> {
  pub start_state: S,
  pub accept_states: HashSet<S>,
  pub transitions: DFATransitions<S, T>
}

impl<S: Clone + Eq + Hash, T: Eq + Hash> DFAModel<S, T> {
  /// determine whether the given symbols can be accepted by the model
  pub fn accept<I: Iterator<T>>(&self, mut iter: I) -> bool {
    let mut dfa = self.gen_dfa();
    for sym in iter {
      dfa.read_symbol(&Some(sym));
    }

    dfa.accepted()
  }

  /// generate a dfa instance
  fn gen_dfa(&self) -> DFA<S, T> {
    DFA {
      state: self.start_state.clone(),
      accept_states: &self.accept_states,
      transitions: &self.transitions
    }
  }
}

/// The transition relation in NFA,
/// containing all the rules needed by the NFA.
pub struct NFATransitions<S, T> {
  pub rules: HashSet<Rule<S, T>>
}

impl<S: Eq + Hash + Clone, T: Eq + Hash> NFATransitions<S, T> {

  pub fn next_states(&self, states: &HashSet<S>, symbol: &Option<T>) -> HashSet<S> {
    states.iter().flat_map(|state| {
      // NOTE: use `move_iter` instead of `iter`
      self.next_states_for(state, symbol).move_iter()
    }).collect()
  }

  /// get the next state for the given state and symbol
  fn next_states_for(&self, state: &S, symbol: &Option<T>) -> HashSet<S> {
    self.rules.iter().filter_map(|rule| {
      if rule.apply_to(state, symbol) { Some(rule.next_state.clone()) } else { None }
    }).collect()
  }

  fn rules_for<'a>(&'a self, state: &S, symbol: &Option<T>) -> HashSet<&'a Rule<S, T>> {
    self.rules.iter()
              .filter(|rule| { rule.apply_to(state, symbol) })
              .collect()
  }
}

struct NFA<'a, S: 'a, T: 'a> {
  states: HashSet<S>,
  accept_states: &'a HashSet<S>,
  transitions: &'a NFATransitions<S, T>
}

impl<'a, S: Eq + Hash + Clone, T: Eq + Hash> NFA<'a, S, T> {
  pub fn read_symbol(&mut self, symbol: &Option<T>) {
    self.states = self.transitions.next_states(&self.states, symbol)
                                  .iter()
                                  .map(|state| { state.clone() }).collect()
  }

  pub fn accepted(&self) -> bool {
    !self.states.is_disjoint(self.accept_states)
  }
}

pub struct NFAModel<S, T> {
  pub start_state: S,
  pub accept_states: HashSet<S>,
  pub transitions: NFATransitions<S, T>
}

impl<S: Eq + Hash + Clone, T: Eq + Hash> NFAModel<S, T> {
  /// determine whether the given symbols can be accepted by the model
  pub fn accept<I: Iterator<T>>(&self, mut iter: I) -> bool {
    let mut dfa = self.gen_nfa();
    for sym in iter {
      dfa.read_symbol(&Some(sym));
    }

    dfa.accepted()
  }

  /// generate a nfa instance
  fn gen_nfa(&self) -> NFA<S, T> {
    let mut start_states = HashSet::new();
    start_states.insert(self.start_state.clone());
    NFA {
      states: start_states,
      accept_states: &self.accept_states,
      transitions: &self.transitions
    }
  }
}
<|endoftext|>


<commit_before>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use core::{mem};
use r_syscall::arch::{set_tls};
use base::prelude::*;
use cty::{tls_index};
use super::{Private};

pub use self::var::{mem_size};

#[path = "var1.rs"] mod var;

pub const DTVR_ALIGN: usize = 4;
pub const DTVR_SIZE: usize = 8;

#[repr(C)]
pub struct ArchPrivate {
    static_block: *mut u8,
}

pub unsafe fn place_tls(mut mem: *mut u8) -> (*mut Private, *mut u8) {
    let (private, tp, static_block) = var::place_tls(mem);
    (*private).arch.static_block = static_block;
    (private, tp)
}

pub unsafe fn set_tp(tls: *mut u8) -> Result {
    // XXX should only check this once at startup.
    let kuser_helper_version = *(0xffff0ffc as *const i32);
    assert!(kuser_helper_version > 0);

    // Not really sure how tls works on 32 bit arm. glibc simply uses this syscall while
    // musl only uses it on armv7.
    rv!(set_tls(tls))
}

pub unsafe fn get_tp() -> *mut u8 {
    // Documentation/arm/kernel_user_helpers.txt in the linux source tree.
    let kuser_get_tls = mem::cast::<_, extern fn() -> *mut u8>(0xffff0fe0);
    kuser_get_tls()
}

#[no_mangle]
pub unsafe extern fn __aeabi_read_tp(ti: *const tls_index) -> *mut u8 {
    let tp = get_tp();
    let private = var::get_private(tp);
    (*private).arch.static_block.add((*ti).ti_offset)
}
<commit_msg>fix tls on arm<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use core::{mem};
use r_syscall::arch::{set_tls};
use base::prelude::*;
use super::{Private};

pub use self::var::{mem_size};

#[path = "var1.rs"] mod var;

pub const DTVR_ALIGN: usize = 4;
pub const DTVR_SIZE: usize = 8;

#[repr(C)]
pub struct ArchPrivate {
}

pub unsafe fn place_tls(mem: *mut u8) -> (*mut Private, *mut u8) {
    let (private, tp, _) = var::place_tls(mem);
    (private, tp)
}

pub unsafe fn set_tp(tls: *mut u8) -> Result {
    // XXX should only check this once at startup.
    let kuser_helper_version = *(0xffff0ffc as *const i32);
    assert!(kuser_helper_version > 0);

    // Not really sure how tls works on 32 bit arm. glibc simply uses this syscall while
    // musl only uses it on armv7.
    rv!(set_tls(tls))
}

pub unsafe fn get_tp() -> *mut u8 {
    // Documentation/arm/kernel_user_helpers.txt in the linux source tree.
    let kuser_get_tls = mem::cast::<usize, extern fn() -> *mut u8>(0xffff0fe0);
    kuser_get_tls()
}

#[no_mangle]
pub unsafe extern fn __aeabi_read_tp() -> *mut u8 {
    get_tp()
}
<|endoftext|>


<commit_before>use std::convert::TryInto;
use std::io::{Cursor, Write};
use byteorder::WriteBytesExt;
use serde::ser::{Impossible, Serialize, Serializer, SerializeSeq, SerializeStruct, SerializeTuple};

use error::{Error, ResultE};
use super::osc_writer::OscWriter;
use super::pkt_type_decoder::{PktType, PktTypeDecoder};

pub struct PktSerializer<W: Write> {
    output: W,
}

/// After the State receives a serialize_seq call,
/// we return one of these. If the next data is a string, then it's the message
/// address & we're serializing a message.
/// If the next data is a sequence, we're serializing a bundle, and that sequence is
/// the (u32, u32) time tag.
pub struct PktContents<'a, W: Write + 'a> {
    output: &'a mut PktSerializer<W>,
    state: State,
}

pub enum State {
    UnknownType,
    Msg(MsgSerializer),
    Bundle(BundleSerializer),
}

/// Once we know we're serializing a message, we do so through this struct.
pub struct MsgSerializer {
    /// Address + typetag, merged into one field
    addr_typetag: Cursor<Vec<u8>>,
    /// Binary-formatted argument data
    args: Cursor<Vec<u8>>,
}

pub struct BundleSerializer {
    contents: Cursor<Vec<u8>>,
}

impl<W: Write> PktSerializer<W> {
    pub fn new(output: W) -> Self {
        Self{ output }
    }
}

impl<'a, W: Write> Serializer for &'a mut PktSerializer<W> {
    type Ok = ();
    type Error = Error;
    type SerializeSeq = PktContents<'a, W>;
    type SerializeTuple = Self::SerializeSeq;
    type SerializeStruct = Self::SerializeSeq;
    type SerializeTupleStruct = Impossible<Self::Ok, Error>;
    type SerializeTupleVariant = Impossible<Self::Ok, Error>;
    type SerializeMap = Impossible<Self::Ok, Error>;
    type SerializeStructVariant = Impossible<Self::Ok, Error>;

    default_ser!{bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char
        str bytes none some unit unit_struct unit_variant newtype_struct newtype_variant
        tuple_struct tuple_variant map struct_variant}
    fn serialize_seq(
        self,
        _size: Option<usize>
    ) -> ResultE<Self::SerializeSeq>
    {
        Ok(PktContents{ output: self, state: State::UnknownType })
    }
    fn serialize_seq_fixed_size(
        self,
        size: usize
    ) -> ResultE<Self::SerializeSeq>
    {
        self.serialize_seq(Some(size))
    }
    fn serialize_tuple(
        self,
        size: usize
    ) -> ResultE<Self::SerializeTuple>
    {
        self.serialize_seq(Some(size))
    }
    fn serialize_struct(
        self,
        _: &'static str,
        size: usize
    ) -> ResultE<Self::SerializeStruct>
    {
        self.serialize_seq(Some(size))
    }
}

impl<'a> Serializer for &'a mut MsgSerializer {
    type Ok = ();
    type Error = Error;
    type SerializeSeq = Impossible<Self::Ok, Error>;
    type SerializeTuple = Self::SerializeSeq;
    type SerializeStruct = Self::SerializeSeq;
    type SerializeTupleStruct = Impossible<Self::Ok, Error>;
    type SerializeTupleVariant = Impossible<Self::Ok, Error>;
    type SerializeMap = Impossible<Self::Ok, Error>;
    type SerializeStructVariant = Impossible<Self::Ok, Error>;

    fn serialize_i32(self, value: i32) -> ResultE<Self::Ok> {
        self.addr_typetag.write_i32_tag()?;
        Ok(self.args.osc_write_i32(value)?)
    }
    fn serialize_f32(self, value: f32) -> ResultE<Self::Ok> {
        self.addr_typetag.write_f32_tag()?;
        Ok(self.args.osc_write_f32(value)?)
    }
    fn serialize_str(self, value: &str) -> ResultE<Self::Ok> {
        self.addr_typetag.write_str_tag()?;
        Ok(self.args.osc_write_str(value)?)
    }
    fn serialize_bytes(self, value: &[u8]) -> ResultE<Self::Ok> {
        self.addr_typetag.write_blob_tag()?;
        Ok(self.args.osc_write_blob(value)?)
    }
    default_ser!{bool i8 i16 i64 u8 u16 u32 u64 f64 char
        none some unit unit_struct unit_variant newtype_struct newtype_variant
        seq seq_fixed_size tuple tuple_struct tuple_variant map struct struct_variant}
}

impl<'a, W: Write + 'a> SerializeSeq for PktContents<'a, W> {
    type Ok = ();
    type Error = Error;

    fn serialize_element<'b, T: ?Sized>(&'b mut self, value: &T) -> ResultE<()>
        where T: Serialize
    {
        match self.state {
            State::UnknownType => {
                // Determine the type of the packet.
                // If the first element is a string, then we become a message;
                //   will accept i32, f32, blob, str args.
                // If the first element we see is a timecode (seq of u32, u32),
                //   then we become a bundle.
                let mut decoder = PktTypeDecoder::new();
                value.serialize(&mut decoder)?;

                match decoder.pkt_type() {
                    PktType::Unknown => Err(Error::BadFormat),
                    PktType::Msg => {
                        let mut addr_typetag = decoder.data();
                        // Prepare to append type arguments in future calls
                        addr_typetag.write_u8(b',')?;
                        self.state = State::Msg(MsgSerializer{
                            addr_typetag,
                            args: Cursor::new(Vec::new()),
                        });
                        Ok(())
                    },
                    PktType::Bundle => {
                        self.state = State::Bundle(BundleSerializer{
                            contents: decoder.data(),
                        });
                        Ok(())
                    },
                }
            },
            State::Msg(ref mut msg) => {
                value.serialize(msg)
            },
            State::Bundle(ref mut bundle) => {
                // each bundle element is itself a packet.
                let mut ser = PktSerializer{ output: bundle.contents.by_ref() };
                value.serialize(&mut ser)
            },
        }
    }

    fn end(self) -> ResultE<()> {
        match self.state {
            // Packet has no contents!
            State::UnknownType => Err(Error::BadFormat),
            // Write the message header & data to the output
            State::Msg(msg) => {
                let typetag = msg.addr_typetag.into_inner();
                let args = msg.args.into_inner();
                let tag_pad = 4 - (typetag.len() % 4);
                let payload_size = typetag.len() + tag_pad + args.len();
                if payload_size % 4 != 0 {
                    // Sanity check; OSC requires packets to be a multiple of 4 bytes.
                    return Err(Error::BadFormat);
                }

                // Write the packet length
                self.output.output.osc_write_i32(payload_size.try_into()?)?;
                // Write the address and type tag
                self.output.output.write_all(&typetag)?;
                let zeros = b"\0\0\0\0";
                self.output.output.write_all(&zeros[..tag_pad])?;
                // Write the arguments
                Ok(self.output.output.write_all(&args)?)
            },
            // Write the bundle header & data to the output
            State::Bundle(bundle) => {
                let payload = bundle.contents.into_inner();
                // Add 8 because we have yet to write the #bundle address
                let payload_size = 8 + payload.len();
                if payload_size % 4 != 0 {
                    // Sanity check; OSC requires packets to be a multiple of 4 bytes.
                    return Err(Error::BadFormat);
                }
                // Write the packet length
                let output = &mut self.output.output;
                output.osc_write_i32(payload_size.try_into()?)?;
                // Write the packet payload
                output.osc_write_str("#bundle")?;
                Ok(output.write_all(&payload)?)
            }
        }
    }
}

impl<'a, W: Write + 'a> SerializeStruct for PktContents<'a, W> {
    type Ok = ();
    type Error = Error;

    fn serialize_field<T: ?Sized>(&mut self, _key: &'static str, value: &T) -> ResultE<()>
        where T: Serialize
    {
        SerializeSeq::serialize_element(self, value)
    }

    fn end(self) -> ResultE<()> {
        SerializeSeq::end(self)
    }
}

impl<'a, W: Write + 'a> SerializeTuple for PktContents<'a, W> {
    type Ok = ();
    type Error = Error;

    fn serialize_element<T: ?Sized>(&mut self, value: &T) -> ResultE<()>
        where T: Serialize
    {
        SerializeSeq::serialize_element(self, value)
    }

    fn end(self) -> ResultE<()> {
        SerializeSeq::end(self)
    }
}
<commit_msg>Visibility fixes<commit_after>use std::convert::TryInto;
use std::io::{Cursor, Write};
use byteorder::WriteBytesExt;
use serde::ser::{Impossible, Serialize, Serializer, SerializeSeq, SerializeStruct, SerializeTuple};

use error::{Error, ResultE};
use super::osc_writer::OscWriter;
use super::pkt_type_decoder::{PktType, PktTypeDecoder};

pub struct PktSerializer<W: Write> {
    output: W,
}

/// After the State receives a serialize_seq call,
/// we return one of these. If the next data is a string, then it's the message
/// address & we're serializing a message.
/// If the next data is a sequence, we're serializing a bundle, and that sequence is
/// the (u32, u32) time tag.
pub struct PktContents<'a, W: Write + 'a> {
    output: &'a mut PktSerializer<W>,
    state: State,
}

enum State {
    UnknownType,
    Msg(MsgSerializer),
    Bundle(BundleSerializer),
}

/// Once we know we're serializing a message, we do so through this struct.
struct MsgSerializer {
    /// Address + typetag, merged into one field
    addr_typetag: Cursor<Vec<u8>>,
    /// Binary-formatted argument data
    args: Cursor<Vec<u8>>,
}

struct BundleSerializer {
    contents: Cursor<Vec<u8>>,
}

impl<W: Write> PktSerializer<W> {
    pub fn new(output: W) -> Self {
        Self{ output }
    }
}

impl<'a, W: Write> Serializer for &'a mut PktSerializer<W> {
    type Ok = ();
    type Error = Error;
    type SerializeSeq = PktContents<'a, W>;
    type SerializeTuple = Self::SerializeSeq;
    type SerializeStruct = Self::SerializeSeq;
    type SerializeTupleStruct = Impossible<Self::Ok, Error>;
    type SerializeTupleVariant = Impossible<Self::Ok, Error>;
    type SerializeMap = Impossible<Self::Ok, Error>;
    type SerializeStructVariant = Impossible<Self::Ok, Error>;

    default_ser!{bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char
        str bytes none some unit unit_struct unit_variant newtype_struct newtype_variant
        tuple_struct tuple_variant map struct_variant}
    fn serialize_seq(
        self,
        _size: Option<usize>
    ) -> ResultE<Self::SerializeSeq>
    {
        Ok(PktContents{ output: self, state: State::UnknownType })
    }
    fn serialize_seq_fixed_size(
        self,
        size: usize
    ) -> ResultE<Self::SerializeSeq>
    {
        self.serialize_seq(Some(size))
    }
    fn serialize_tuple(
        self,
        size: usize
    ) -> ResultE<Self::SerializeTuple>
    {
        self.serialize_seq(Some(size))
    }
    fn serialize_struct(
        self,
        _: &'static str,
        size: usize
    ) -> ResultE<Self::SerializeStruct>
    {
        self.serialize_seq(Some(size))
    }
}

impl<'a> Serializer for &'a mut MsgSerializer {
    type Ok = ();
    type Error = Error;
    type SerializeSeq = Impossible<Self::Ok, Error>;
    type SerializeTuple = Self::SerializeSeq;
    type SerializeStruct = Self::SerializeSeq;
    type SerializeTupleStruct = Impossible<Self::Ok, Error>;
    type SerializeTupleVariant = Impossible<Self::Ok, Error>;
    type SerializeMap = Impossible<Self::Ok, Error>;
    type SerializeStructVariant = Impossible<Self::Ok, Error>;

    fn serialize_i32(self, value: i32) -> ResultE<Self::Ok> {
        self.addr_typetag.write_i32_tag()?;
        Ok(self.args.osc_write_i32(value)?)
    }
    fn serialize_f32(self, value: f32) -> ResultE<Self::Ok> {
        self.addr_typetag.write_f32_tag()?;
        Ok(self.args.osc_write_f32(value)?)
    }
    fn serialize_str(self, value: &str) -> ResultE<Self::Ok> {
        self.addr_typetag.write_str_tag()?;
        Ok(self.args.osc_write_str(value)?)
    }
    fn serialize_bytes(self, value: &[u8]) -> ResultE<Self::Ok> {
        self.addr_typetag.write_blob_tag()?;
        Ok(self.args.osc_write_blob(value)?)
    }
    default_ser!{bool i8 i16 i64 u8 u16 u32 u64 f64 char
        none some unit unit_struct unit_variant newtype_struct newtype_variant
        seq seq_fixed_size tuple tuple_struct tuple_variant map struct struct_variant}
}

impl<'a, W: Write + 'a> SerializeSeq for PktContents<'a, W> {
    type Ok = ();
    type Error = Error;

    fn serialize_element<'b, T: ?Sized>(&'b mut self, value: &T) -> ResultE<()>
        where T: Serialize
    {
        match self.state {
            State::UnknownType => {
                // Determine the type of the packet.
                // If the first element is a string, then we become a message;
                //   will accept i32, f32, blob, str args.
                // If the first element we see is a timecode (seq of u32, u32),
                //   then we become a bundle.
                let mut decoder = PktTypeDecoder::new();
                value.serialize(&mut decoder)?;

                match decoder.pkt_type() {
                    PktType::Unknown => Err(Error::BadFormat),
                    PktType::Msg => {
                        let mut addr_typetag = decoder.data();
                        // Prepare to append type arguments in future calls
                        addr_typetag.write_u8(b',')?;
                        self.state = State::Msg(MsgSerializer{
                            addr_typetag,
                            args: Cursor::new(Vec::new()),
                        });
                        Ok(())
                    },
                    PktType::Bundle => {
                        self.state = State::Bundle(BundleSerializer{
                            contents: decoder.data(),
                        });
                        Ok(())
                    },
                }
            },
            State::Msg(ref mut msg) => {
                value.serialize(msg)
            },
            State::Bundle(ref mut bundle) => {
                // each bundle element is itself a packet.
                let mut ser = PktSerializer{ output: bundle.contents.by_ref() };
                value.serialize(&mut ser)
            },
        }
    }

    fn end(self) -> ResultE<()> {
        match self.state {
            // Packet has no contents!
            State::UnknownType => Err(Error::BadFormat),
            // Write the message header & data to the output
            State::Msg(msg) => {
                let typetag = msg.addr_typetag.into_inner();
                let args = msg.args.into_inner();
                let tag_pad = 4 - (typetag.len() % 4);
                let payload_size = typetag.len() + tag_pad + args.len();
                if payload_size % 4 != 0 {
                    // Sanity check; OSC requires packets to be a multiple of 4 bytes.
                    return Err(Error::BadFormat);
                }

                // Write the packet length
                self.output.output.osc_write_i32(payload_size.try_into()?)?;
                // Write the address and type tag
                self.output.output.write_all(&typetag)?;
                let zeros = b"\0\0\0\0";
                self.output.output.write_all(&zeros[..tag_pad])?;
                // Write the arguments
                Ok(self.output.output.write_all(&args)?)
            },
            // Write the bundle header & data to the output
            State::Bundle(bundle) => {
                let payload = bundle.contents.into_inner();
                // Add 8 because we have yet to write the #bundle address
                let payload_size = 8 + payload.len();
                if payload_size % 4 != 0 {
                    // Sanity check; OSC requires packets to be a multiple of 4 bytes.
                    return Err(Error::BadFormat);
                }
                // Write the packet length
                let output = &mut self.output.output;
                output.osc_write_i32(payload_size.try_into()?)?;
                // Write the packet payload
                output.osc_write_str("#bundle")?;
                Ok(output.write_all(&payload)?)
            }
        }
    }
}

impl<'a, W: Write + 'a> SerializeStruct for PktContents<'a, W> {
    type Ok = ();
    type Error = Error;

    fn serialize_field<T: ?Sized>(&mut self, _key: &'static str, value: &T) -> ResultE<()>
        where T: Serialize
    {
        SerializeSeq::serialize_element(self, value)
    }

    fn end(self) -> ResultE<()> {
        SerializeSeq::end(self)
    }
}

impl<'a, W: Write + 'a> SerializeTuple for PktContents<'a, W> {
    type Ok = ();
    type Error = Error;

    fn serialize_element<T: ?Sized>(&mut self, value: &T) -> ResultE<()>
        where T: Serialize
    {
        SerializeSeq::serialize_element(self, value)
    }

    fn end(self) -> ResultE<()> {
        SerializeSeq::end(self)
    }
}
<|endoftext|>


<commit_before>macro_rules! json {
    {$($keys:expr => $values:expr),*} => ({
        use ::rustc_serialize::json::Json;
        let kv_pairs = vec![ $(($keys.to_string(), json!($values))),* ];
        Json::Object(kv_pairs.into_iter().collect())
    });
    ($value:expr) => ({
        use ::rustc_serialize::json::ToJson;
        $value.to_json()
    });
    [[ $($values:expr),* ]] => (::rustc_serialize::json::Json::Array(vec![ $(json!($values)),* ]));
}
<commit_msg>Avoid unused import warning<commit_after>macro_rules! json {
    {$($keys:expr => $values:expr),*} => ({
        let kv_pairs = vec![ $(($keys.to_string(), json!($values))),* ];
        ::rustc_serialize::json::Json::Object(kv_pairs.into_iter().collect())
    });
    ($value:expr) => ({
        use ::rustc_serialize::json::ToJson;
        $value.to_json()
    });
    [[ $($values:expr),* ]] => (::rustc_serialize::json::Json::Array(vec![ $(json!($values)),* ]));
}
<|endoftext|>


<commit_before>//
//   Copyright 2016 Andrew Hunter
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.
//

use std::cmp::Ordering;

use super::symbol_range::*;
use super::countable::*;

///
/// A symbol map maps from one set of symbol ranges to another
///
pub struct SymbolMap<Symbol: PartialOrd+Clone+Countable> {
    // Ranges in this symbol map
    ranges: Vec<SymbolRange<Symbol>>,
}

impl<Symbol: PartialOrd+Clone+Countable> SymbolMap<Symbol> {
    ///
    /// Creates a new symbol map
    ///
    pub fn new() -> SymbolMap<Symbol> {
        SymbolMap { ranges: vec![] }
    }

    ///
    /// Orders two symbols (makes unordered symbols equal)
    ///
    #[inline]
    fn order_symbols(a: &Symbol, b: &Symbol) -> Ordering {
        if let Some(order) = a.partial_cmp(b) {
            order
        } else {
            Ordering::Equal
        }
    }

    ///
    /// Orders two symbol ranges
    ///
    #[inline]
    fn order_ranges(a: &SymbolRange<Symbol>, b: &SymbolRange<Symbol>) -> Ordering {
        let ordering = SymbolMap::order_symbols(&a.lowest, &b.lowest);

        if ordering == Ordering::Equal {
            SymbolMap::order_symbols(&a.highest, &b.highest)
        } else {
            ordering
        }
    }

    ///
    /// Adds a range to those that are known about by this object
    ///
    pub fn add_range(&mut self, range: &SymbolRange<Symbol>) {
        let existing = self.ranges.binary_search_by(|test_range| { SymbolMap::order_ranges(test_range, range) });

        // Insert the range if it is not already in the map
        if let Err(insertion_pos) = existing {
            self.ranges.insert(insertion_pos, range.clone());
        }
    }

    ///
    /// Finds the ranges in this map that overlap the target ranges
    ///
    pub fn find_overlapping_ranges(&self, range: &SymbolRange<Symbol>) -> Vec<&SymbolRange<Symbol>> {
        let mut result = vec![];

        // Find the first range that matches (or the insertion position, which should be the first range wit a lowest value higher than the target range)
        let existing = self.ranges.binary_search_by(|test_range| { SymbolMap::order_ranges(test_range, range) });

        // Start returning values from here
        let mut pos = match existing {
            Ok(found_position) => found_position,
            Err(insert_position) => insert_position
        };

        // Move backwards if the previous position overlaps this one
        if pos > 0 && self.ranges[pos-1].highest >= range.lowest {
            pos -= 1;
        }

        // TODO: can we construct a set of ranges such that one is missed here? Think maybe we can
        while pos < self.ranges.len() && self.ranges[pos].lowest <= range.highest {
            result.push(&self.ranges[pos]);
            pos += 1;
        }

        result
    }

    ///
    /// Creates a non-overlapping range from an overlapping one
    ///
    pub fn to_non_overlapping_map(&self) -> SymbolMap<Symbol> {
        // Create a vector of all the range symbols
        let mut lowest:  Vec<Symbol> = self.ranges.iter().map(|r| r.lowest.clone()).collect();
        let mut highest: Vec<Symbol> = self.ranges.iter().map(|r| r.highest.clone()).collect();

        // Dedupe the lowest and highest symbols seperately
        lowest.sort_by(SymbolMap::order_symbols);
        lowest.dedup();

        highest.sort_by(SymbolMap::order_symbols);
        highest.dedup();

        // Combine into the set of ranges (each pair representing a range in the result)
        let mut range_symbols: Vec<Symbol> = lowest.into_iter().chain(highest.into_iter()).collect();
        range_symbols.sort_by(SymbolMap::order_symbols);

        // Generate a new symbol map with these ranges
        let mut result = vec![];
        for index in 0..range_symbols.len()-2 {
            result.push(SymbolRange::new(range_symbols[index].clone(), range_symbols[index+1].prev()));
        }

        if range_symbols.len() > 1 {
            // Last item is always inclusive
            result.push(SymbolRange::new(range_symbols[range_symbols.len()-2].clone(), range_symbols[range_symbols.len()-1].clone()));
        }

        // We already sorted everything, so bypass the usual 'add' method (which sorts as it goes)
        SymbolMap { ranges: result }
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use super::super::symbol_range::*;

    #[test]
    fn can_lookup_overlapping_ranges() {
        let mut map = SymbolMap::new();

        map.add_range(&SymbolRange::new(0, 4));
        map.add_range(&SymbolRange::new(2, 5));
        map.add_range(&SymbolRange::new(3, 6));

        let bottom = map.find_overlapping_ranges(&SymbolRange::new(0, 1));
        let all    = map.find_overlapping_ranges(&SymbolRange::new(1, 3));
        let top    = map.find_overlapping_ranges(&SymbolRange::new(6, 6));

        assert!(bottom == vec![&SymbolRange::new(0, 4)]);
        assert!(all == vec![&SymbolRange::new(0, 4), &SymbolRange::new(2, 5), &SymbolRange::new(3, 6)]);
        assert!(top == vec![&SymbolRange::new(3, 6)]);
    }

    #[test]
    fn can_lookup_mid_range() {
        let mut map = SymbolMap::new();

        map.add_range(&SymbolRange::new(0, 4));
        map.add_range(&SymbolRange::new(5, 10));
        map.add_range(&SymbolRange::new(11, 15));

        let mid = map.find_overlapping_ranges(&SymbolRange::new(1, 3));

        assert!(mid == vec![&SymbolRange::new(0, 4)]);
    }

    #[test]
    fn works_with_duplicate_lower_values() {
        let mut map = SymbolMap::new();

        map.add_range(&SymbolRange::new(0, 2));
        map.add_range(&SymbolRange::new(0, 3));

        let all    = map.find_overlapping_ranges(&SymbolRange::new(0, 1));

        assert!(all == vec![&SymbolRange::new(0, 2), &SymbolRange::new(0, 3)]);
    }

    #[test]
    fn can_get_non_overlapping_map() {
        let mut map = SymbolMap::new();

        map.add_range(&SymbolRange::new(0, 4));
        map.add_range(&SymbolRange::new(2, 5));
        map.add_range(&SymbolRange::new(3, 6));

        let non_overlapping = map.to_non_overlapping_map();

        let all = non_overlapping.find_overlapping_ranges(&SymbolRange::new(0, 6));

        assert!(all == vec![&SymbolRange::new(0, 1), &SymbolRange::new(2, 2), &SymbolRange::new(3, 3), &SymbolRange::new(4, 4), &SymbolRange::new(5, 6)]);
    }

    #[test]
    fn can_get_non_overlapping_map_with_single_symbols() {
        let mut map = SymbolMap::new();

        map.add_range(&SymbolRange::new(0, 5));
        map.add_range(&SymbolRange::new(2, 2));
        map.add_range(&SymbolRange::new(3, 6));

        let non_overlapping = map.to_non_overlapping_map();

        let all = non_overlapping.find_overlapping_ranges(&SymbolRange::new(0, 6));

        assert!(all == vec![&SymbolRange::new(0, 1), &SymbolRange::new(2, 2), &SymbolRange::new(3, 4), &SymbolRange::new(5, 6)]);
    }

    #[test]
    fn generate_correctly_for_single_symbol() {
        let mut map = SymbolMap::new();

        map.add_range(&SymbolRange::new(0, 0));

        let non_overlapping = map.to_non_overlapping_map();

        let all = non_overlapping.find_overlapping_ranges(&SymbolRange::new(0, 10));

        assert!(all == vec![&SymbolRange::new(0, 0)]);
    }

    #[test]
    fn generate_correctly_for_two_single_symbols() {
        let mut map = SymbolMap::new();

        map.add_range(&SymbolRange::new(0, 0));
        map.add_range(&SymbolRange::new(1, 1));

        let non_overlapping = map.to_non_overlapping_map();

        let all = non_overlapping.find_overlapping_ranges(&SymbolRange::new(0, 10));

        assert!(all == vec![&SymbolRange::new(0, 0), &SymbolRange::new(1, 1)]);
    }

    #[test]
    fn generate_correctly_for_non_overlapping_ranges() {
        let mut map = SymbolMap::new();

        map.add_range(&SymbolRange::new(0, 1));
        map.add_range(&SymbolRange::new(2, 4));

        let non_overlapping = map.to_non_overlapping_map();

        let all = non_overlapping.find_overlapping_ranges(&SymbolRange::new(0, 10));

        assert!(all == vec![&SymbolRange::new(0, 1), &SymbolRange::new(2, 4)]);
    }

    #[test]
    fn generate_correctly_for_single_overlap() {
        let mut map = SymbolMap::new();

        // Here the symbol '5' is in both ranges, so we should generate it as a seperate range in the non-overlapping version
        map.add_range(&SymbolRange::new(0, 5));
        map.add_range(&SymbolRange::new(5, 10));

        let non_overlapping = map.to_non_overlapping_map();

        let all = non_overlapping.find_overlapping_ranges(&SymbolRange::new(0, 10));
        println!("{:?}", all);

        assert!(all == vec![&SymbolRange::new(0, 4), &SymbolRange::new(5,5), &SymbolRange::new(6, 10)]);
    }

    #[test]
    fn can_get_non_overlapping_map_with_single_symbols_at_start() {
        let mut map = SymbolMap::new();

        map.add_range(&SymbolRange::new(0, 0));
        map.add_range(&SymbolRange::new(0, 1));

        let non_overlapping = map.to_non_overlapping_map();

        let all = non_overlapping.find_overlapping_ranges(&SymbolRange::new(0, 6));

        assert!(all == vec![&SymbolRange::new(0, 0), &SymbolRange::new(1, 1)]);
    }

    #[test]
    fn can_get_non_overlapping_map_with_single_symbols_at_start_and_gap() {
        let mut map = SymbolMap::new();

        map.add_range(&SymbolRange::new(0, 0));
        map.add_range(&SymbolRange::new(0, 1));
        map.add_range(&SymbolRange::new(3, 6));

        let non_overlapping = map.to_non_overlapping_map();

        let all = non_overlapping.find_overlapping_ranges(&SymbolRange::new(0, 6));

        assert!(all == vec![&SymbolRange::new(0, 0), &SymbolRange::new(1, 1), &SymbolRange::new(2, 2), &SymbolRange::new(3, 6)]);
    }
}
<commit_msg>First pass at a new algorithm that explicitly uses ranges<commit_after>//
//   Copyright 2016 Andrew Hunter
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.
//

use std::cmp::Ordering;

use super::symbol_range::*;
use super::countable::*;

///
/// A symbol map maps from one set of symbol ranges to another
///
pub struct SymbolMap<Symbol: PartialOrd+Clone+Countable> {
    // Ranges in this symbol map
    ranges: Vec<SymbolRange<Symbol>>,
}

impl<Symbol: PartialOrd+Clone+Countable> SymbolMap<Symbol> {
    ///
    /// Creates a new symbol map
    ///
    pub fn new() -> SymbolMap<Symbol> {
        SymbolMap { ranges: vec![] }
    }

    ///
    /// Orders two symbols (makes unordered symbols equal)
    ///
    #[inline]
    fn order_symbols(a: &Symbol, b: &Symbol) -> Ordering {
        if let Some(order) = a.partial_cmp(b) {
            order
        } else {
            Ordering::Equal
        }
    }

    ///
    /// Orders two symbol ranges
    ///
    #[inline]
    fn order_ranges(a: &SymbolRange<Symbol>, b: &SymbolRange<Symbol>) -> Ordering {
        let ordering = SymbolMap::order_symbols(&a.lowest, &b.lowest);

        if ordering == Ordering::Equal {
            SymbolMap::order_symbols(&b.highest, &a.highest)
        } else {
            ordering
        }
    }

    ///
    /// Adds a range to those that are known about by this object
    ///
    pub fn add_range(&mut self, range: &SymbolRange<Symbol>) {
        let existing = self.ranges.binary_search_by(|test_range| { SymbolMap::order_ranges(test_range, range) });

        // Insert the range if it is not already in the map
        if let Err(insertion_pos) = existing {
            self.ranges.insert(insertion_pos, range.clone());
        }
    }

    ///
    /// Finds the ranges in this map that overlap the target ranges
    ///
    pub fn find_overlapping_ranges(&self, range: &SymbolRange<Symbol>) -> Vec<&SymbolRange<Symbol>> {
        let mut result = vec![];

        // Find the first range that matches (or the insertion position, which should be the first range wit a lowest value higher than the target range)
        let existing = self.ranges.binary_search_by(|test_range| { SymbolMap::order_ranges(test_range, range) });

        // Start returning values from here
        let mut pos = match existing {
            Ok(found_position) => found_position,
            Err(insert_position) => insert_position
        };

        // Move backwards if the previous position overlaps this one
        if pos > 0 && self.ranges[pos-1].highest >= range.lowest {
            pos -= 1;
        }

        // TODO: can we construct a set of ranges such that one is missed here? Think maybe we can
        while pos < self.ranges.len() && self.ranges[pos].lowest <= range.highest {
            result.push(&self.ranges[pos]);
            pos += 1;
        }

        result
    }

    ///
    /// Creates a non-overlapping range from an overlapping one
    ///
    pub fn to_non_overlapping_map(&self) -> SymbolMap<Symbol> {
        // Stack, popping the lowest ordered ranges first
        let mut to_process = self.ranges.clone();
        to_process.reverse();

        let mut result = vec![];

        while let Some(might_overlap) = to_process.pop() {
            if let Some(overlap_with) = to_process.pop() {
                // Stack has two ranges on top. They might overlap
                if !might_overlap.overlaps(&overlap_with) {
                    // Doesn't overlap: can just push might_overlap and continue
                    result.push(might_overlap);
                    to_process.push(overlap_with);
                } else {
                    // Got an overlap
                    if might_overlap == overlap_with {
                        // Ranges are the same, just discard one
                        to_process.push(overlap_with);
                    } else if might_overlap.lowest == overlap_with.lowest {
                        // Ranges start at the same location. We need to divide them in case more than two ranges are overlapping
                        let (smaller_range, larger_range) = (overlap_with, might_overlap);      // Because of the sort order

                        // Chop out the smaller range from the larger range, then insert into the stack in order
                        let larger_range_without_smaller_range = SymbolRange::new(smaller_range.highest.next(), larger_range.highest.clone());

                        to_process.push(smaller_range);

                        if let Err(insertion_pos) = to_process.binary_search_by(|test_range| { SymbolMap::order_ranges(&larger_range_without_smaller_range, test_range) }) {
                            to_process.insert(insertion_pos, larger_range_without_smaller_range);
                        }
                    } else {
                        // There's a range from the lowest of the first range to the lowest of the second ranges
                        result.push(SymbolRange::new(might_overlap.lowest.clone(), overlap_with.lowest.prev()));

                        // Chop out the bit we just pushed from might_overlap and push back both ranges
                        to_process.push(overlap_with.clone());
                        to_process.push(SymbolRange::new(overlap_with.lowest, might_overlap.highest));
                    }
                }
            } else {
                // Last range should never overlap
                result.push(might_overlap);
            }
        }

        // Ranges should already be sorted as we worked from left to right
        SymbolMap { ranges: result }
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use super::super::symbol_range::*;

    #[test]
    fn can_lookup_overlapping_ranges() {
        let mut map = SymbolMap::new();

        map.add_range(&SymbolRange::new(0, 4));
        map.add_range(&SymbolRange::new(2, 5));
        map.add_range(&SymbolRange::new(3, 6));

        let bottom = map.find_overlapping_ranges(&SymbolRange::new(0, 1));
        let all    = map.find_overlapping_ranges(&SymbolRange::new(1, 3));
        let top    = map.find_overlapping_ranges(&SymbolRange::new(6, 6));

        assert!(bottom == vec![&SymbolRange::new(0, 4)]);
        assert!(all == vec![&SymbolRange::new(0, 4), &SymbolRange::new(2, 5), &SymbolRange::new(3, 6)]);
        assert!(top == vec![&SymbolRange::new(3, 6)]);
    }

    #[test]
    fn can_lookup_mid_range() {
        let mut map = SymbolMap::new();

        map.add_range(&SymbolRange::new(0, 4));
        map.add_range(&SymbolRange::new(5, 10));
        map.add_range(&SymbolRange::new(11, 15));

        let mid = map.find_overlapping_ranges(&SymbolRange::new(1, 3));

        assert!(mid == vec![&SymbolRange::new(0, 4)]);
    }

    #[test]
    fn works_with_duplicate_lower_values() {
        let mut map = SymbolMap::new();

        map.add_range(&SymbolRange::new(0, 2));
        map.add_range(&SymbolRange::new(0, 3));

        let all    = map.find_overlapping_ranges(&SymbolRange::new(0, 1));

        assert!(all == vec![&SymbolRange::new(0, 2), &SymbolRange::new(0, 3)]);
    }

    #[test]
    fn can_get_non_overlapping_map() {
        let mut map = SymbolMap::new();

        map.add_range(&SymbolRange::new(0, 4));
        map.add_range(&SymbolRange::new(2, 5));
        map.add_range(&SymbolRange::new(3, 6));

        let non_overlapping = map.to_non_overlapping_map();

        let all = non_overlapping.find_overlapping_ranges(&SymbolRange::new(0, 6));

        assert!(all == vec![&SymbolRange::new(0, 1), &SymbolRange::new(2, 2), &SymbolRange::new(3, 3), &SymbolRange::new(4, 4), &SymbolRange::new(5, 6)]);
    }

    #[test]
    fn can_get_non_overlapping_map_with_single_symbols() {
        let mut map = SymbolMap::new();

        map.add_range(&SymbolRange::new(0, 5));
        map.add_range(&SymbolRange::new(2, 2));
        map.add_range(&SymbolRange::new(3, 6));

        let non_overlapping = map.to_non_overlapping_map();

        let all = non_overlapping.find_overlapping_ranges(&SymbolRange::new(0, 6));

        assert!(all == vec![&SymbolRange::new(0, 1), &SymbolRange::new(2, 2), &SymbolRange::new(3, 4), &SymbolRange::new(5, 6)]);
    }

    #[test]
    fn generate_correctly_for_single_symbol() {
        let mut map = SymbolMap::new();

        map.add_range(&SymbolRange::new(0, 0));

        let non_overlapping = map.to_non_overlapping_map();

        let all = non_overlapping.find_overlapping_ranges(&SymbolRange::new(0, 10));

        assert!(all == vec![&SymbolRange::new(0, 0)]);
    }

    #[test]
    fn generate_correctly_for_two_single_symbols() {
        let mut map = SymbolMap::new();

        map.add_range(&SymbolRange::new(0, 0));
        map.add_range(&SymbolRange::new(1, 1));

        let non_overlapping = map.to_non_overlapping_map();

        let all = non_overlapping.find_overlapping_ranges(&SymbolRange::new(0, 10));

        assert!(all == vec![&SymbolRange::new(0, 0), &SymbolRange::new(1, 1)]);
    }

    #[test]
    fn generate_correctly_for_non_overlapping_ranges() {
        let mut map = SymbolMap::new();

        map.add_range(&SymbolRange::new(0, 1));
        map.add_range(&SymbolRange::new(2, 4));

        let non_overlapping = map.to_non_overlapping_map();

        let all = non_overlapping.find_overlapping_ranges(&SymbolRange::new(0, 10));

        assert!(all == vec![&SymbolRange::new(0, 1), &SymbolRange::new(2, 4)]);
    }

    #[test]
    fn generate_correctly_for_single_overlap() {
        let mut map = SymbolMap::new();

        // Here the symbol '5' is in both ranges, so we should generate it as a seperate range in the non-overlapping version
        map.add_range(&SymbolRange::new(0, 5));
        map.add_range(&SymbolRange::new(5, 10));

        let non_overlapping = map.to_non_overlapping_map();

        let all = non_overlapping.find_overlapping_ranges(&SymbolRange::new(0, 10));
        println!("{:?}", all);

        assert!(all == vec![&SymbolRange::new(0, 4), &SymbolRange::new(5,5), &SymbolRange::new(6, 10)]);
    }

    #[test]
    fn can_get_non_overlapping_map_with_single_symbols_at_start() {
        let mut map = SymbolMap::new();

        map.add_range(&SymbolRange::new(0, 0));
        map.add_range(&SymbolRange::new(0, 1));

        let non_overlapping = map.to_non_overlapping_map();

        let all = non_overlapping.find_overlapping_ranges(&SymbolRange::new(0, 6));

        assert!(all == vec![&SymbolRange::new(0, 0), &SymbolRange::new(1, 1)]);
    }

    #[test]
    fn can_get_non_overlapping_map_with_single_symbols_at_start_and_gap() {
        let mut map = SymbolMap::new();

        map.add_range(&SymbolRange::new(0, 0));
        map.add_range(&SymbolRange::new(0, 1));
        map.add_range(&SymbolRange::new(3, 6));

        let non_overlapping = map.to_non_overlapping_map();

        let all = non_overlapping.find_overlapping_ranges(&SymbolRange::new(0, 6));

        assert!(all == vec![&SymbolRange::new(0, 0), &SymbolRange::new(1, 1), &SymbolRange::new(2, 2), &SymbolRange::new(3, 6)]);
    }
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate lazy_static;

use std::{io, fs};
use std::io::BufRead;
use std::iter::FromIterator;
use std::collections::{HashMap, HashSet};
use std::error::Error;
use fst::{IntoStreamer, Streamer, Set};
use rand::thread_rng;
use rand::seq::SliceRandom;

const HIRAGANAS: [char; 81] = ['ぁ', 'あ', 'ぃ', 'い', 'ぅ', 'う', 'ぇ', 'え', 'ぉ', 'お', 'か', 'が', 'き', 'ぎ', 'く', 'ぐ', 'け', 'げ', 'こ', 'ご', 'さ', 'ざ', 'し', 'じ', 'す', 'ず', 'せ', 'ぜ', 'そ', 'ぞ', 'た', 'だ', 'ち', 'ぢ', 'っ', 'つ', 'づ', 'て', 'で', 'と', 'ど', 'な', 'に', 'ぬ', 'ね', 'の', 'は', 'ば', 'ぱ', 'ひ', 'び', 'ぴ', 'ふ', 'ぶ', 'ぷ', 'へ', 'べ', 'ぺ', 'ほ', 'ぼ', 'ぽ', 'ま', 'み', 'む', 'め', 'も', 'ゃ', 'や', 'ゅ', 'ゆ', 'ょ', 'よ', 'ら', 'り', 'る', 'れ', 'ろ', 'わ', 'を', 'ん', 'ー'];
lazy_static! {
    static ref NON_INITIALS: Vec<u8> = {
        (0..HIRAGANAS.len()).filter_map(|index| {
            if "ぁぃぅぇぉっゃゅょぢづーをん".contains(HIRAGANAS[index]) {
                Some(index as u8 + 1)
            } else {
                None
            }
        }).collect()
    };
}

#[derive(PartialEq)]
enum Direction {
    Horizontal,
    Diagonal,
    Vertical,
}

struct Constraint {
    direction: Direction,
    cells: Vec<usize>,
}

struct Context {
    constraints: Vec<Constraint>,
    sets: Vec<Set>,
    cells: HashSet<usize>,
    two_gram_counters: Vec<HashMap<[u8; 2], usize>>,
}

fn is_non_initial(c: u8) -> bool {
    (*NON_INITIALS).contains(&c)
}

fn bytes_to_string(bytes: Vec<u8>) -> String {
    String::from_iter(bytes.iter().map(|&i| {
        if i == 0 {
            '　'
        } else {
            HIRAGANAS[(i - 1) as usize]
        }
    }))
}

fn has_prefix(set: &Set, prefix: Vec<u8>) -> bool {
    let mut prefix_stop = prefix.clone();
    *prefix_stop.last_mut().unwrap() += 1;
    set.range().ge(prefix).lt(prefix_stop).into_stream().next() != None
}

fn get_prefix(set: &Set, prefix: Vec<u8>) -> Vec<Vec<u8>> {
    let mut prefix_stop = prefix.clone();
    *prefix_stop.last_mut().unwrap() += 1;
    set.range().ge(prefix).lt(prefix_stop).into_stream().into_bytes()
}

fn count_prefix(set: &Set, prefix: Vec<u8>) -> usize {
    let mut prefix_stop = prefix.clone();
    *prefix_stop.last_mut().unwrap() += 1;
    set.range().ge(prefix).lt(prefix_stop).into_stream().into_bytes().len()
}

fn get_board(context: &Context, board: [u8; 36]) -> Option<[u8; 36]> {
    if context.cells.iter().all(|&c| board[c] != 0) {
        return Some(board);
    }

    let mut rng = thread_rng();

    let vertical_constraints = context.constraints.iter().filter(|&c| c.direction == Direction::Vertical);
    let vertical_prefixes = vertical_constraints.map(|c| {
        (c.cells.iter().map(|&c| board[c]).take_while(|&c| c != 0).collect::<Vec<u8>>(), c)
    });

    let horizontal_constraints = context.constraints.iter().filter(|&c| c.direction == Direction::Horizontal);
    let horizontal_prefixes = horizontal_constraints.map(|c| {
        (c.cells.iter().map(|&c| board[c]).take_while(|&c| c != 0).collect::<Vec<u8>>(), c)
    });

    for (index, (vertical_constraint, horizontal_constraint)) in vertical_prefixes.zip(horizontal_prefixes).enumerate() {
        let constraints = vec![vertical_constraint, horizontal_constraint];
        let (prefix, constraint) = constraints.iter().min_by_key(|(c, _)| c.len()).unwrap();

        if prefix.len() == constraint.cells.len() {
            continue;
        }

        if index == 0 && prefix.len() == 0 {
            let mut new_values: Vec<u8> = (1..(HIRAGANAS.len() as u8 + 1)).collect();
            new_values.shuffle(&mut rng);
            'values: for new_value in new_values {
                if is_non_initial(new_value) {
                    continue;
                }

                let mut cloned_board = board.clone();
                cloned_board[0] = new_value;

                // no need to check constraints

                let result = get_board(context, cloned_board);
                if let Some(board) = result {
                    return Some(board);
                }
            }

            return None;
        }

        if index == 0 && prefix.len() == 1 {
            let mut new_values: Vec<u8> = (1..(HIRAGANAS.len() as u8 + 1)).collect();
            new_values.shuffle(&mut rng);
            for new_value in new_values {
                if is_non_initial(new_value) {
                    continue;
                }

                if let Some(&count) = context.two_gram_counters[constraint.cells.len() - 3].get(&[prefix[0], new_value]) {
                    if count < 1 {
                        continue;
                    }
                }

                let mut cloned_board = board.clone();
                cloned_board[constraint.cells[1]] = new_value;

                // no need to check constraints

                let result = get_board(context, cloned_board);
                if let Some(board) = result {
                    return Some(board);
                }
            }
            break;
        }

        if index == 1 && prefix.len() == 1 {
            let mut new_values: Vec<u8> = (1..(HIRAGANAS.len() as u8 + 1)).collect();
            new_values.shuffle(&mut rng);
            'second_values: for new_value in new_values {
                let mut cloned_board = board.clone();
                cloned_board[constraint.cells[1]] = new_value;

                // check if constraints are met
                for constraint in context.constraints.iter() {
                    let prefix: Vec<u8> = constraint.cells.iter().map(|&c| cloned_board[c]).take_while(|&c| c != 0).collect();
                    if prefix.len() == 0 {
                        continue;
                    }
                    if !has_prefix(&context.sets[constraint.cells.len() - 3], prefix) {
                        continue 'second_values;
                    }
                }

                let result = get_board(context, cloned_board);
                if let Some(board) = result {
                    return Some(board);
                }
            }
            break;
        }

        let mut words = get_prefix(&context.sets[constraint.cells.len() - 3], prefix.to_vec());
        words.shuffle(&mut rng);
        'words: for word in words {
            if index == 0 {
                if word.iter().any(|&c| is_non_initial(c)) {
                    continue;
                }
            }

            let mut cloned_board = board.clone();
            for (&cell, &letter) in constraint.cells.iter().zip(word.iter()) {
                cloned_board[cell] = letter;
            }

            // check if constraints are met
            for constraint in context.constraints.iter() {
                let prefix: Vec<u8> = constraint.cells.iter().map(|&c| cloned_board[c]).take_while(|&c| c != 0).collect();
                if prefix.len() == 0 {
                    continue;
                }
                if !has_prefix(&context.sets[constraint.cells.len() - 3], prefix) {
                    continue 'words;
                }
            }

            let result = get_board(context, cloned_board);
            if let Some(board) = result {
                return Some(board);
            }
        }

        break;
    }

    None
}

fn main() -> Result<(), Box<dyn Error>> {
    let f = fs::File::open("crossword.txt")?;
    let file = io::BufReader::new(f);

    let mut word_lists: [Vec<Vec<u8>>; 4] = [Vec::new(), Vec::new(), Vec::new(), Vec::new()];
    'lines: for line in file.lines() {
        let word = line?;
        let mut indices: Vec<u8> = Vec::new();
        for char in word.chars() {
            match HIRAGANAS.iter().position(|&c| c == char) {
                Some(i) => indices.push((i + 1) as u8),
                None => continue 'lines,
            }
        }
        word_lists[indices.len() - 3].push(indices);
    }

    let sets = word_lists.iter_mut().map(|word_list| {
        word_list.sort();
        Set::from_iter(word_list).unwrap()
    }).collect::<Vec<Set>>();

    let mut two_gram_counters = vec![
        HashMap::new(),
        HashMap::new(),
        HashMap::new(),
        HashMap::new(),
    ];

    for i in 0..HIRAGANAS.len() {
        for j in 0..HIRAGANAS.len() {
            for (two_gram_counter, set) in two_gram_counters.iter_mut().zip(sets.iter()) {
                two_gram_counter.insert([i as u8, j as u8], count_prefix(&set, vec![i as u8, j as u8]));
            }
        }
    }

    /*
    let constraints: Vec<Constraint> = vec![
        Constraint {cells: vec![0, 1, 2, 3], direction: Direction::Horizontal},
        Constraint {cells: vec![4, 5, 6, 7], direction: Direction::Horizontal},
        Constraint {cells: vec![8, 9, 10, 11], direction: Direction::Horizontal},
        Constraint {cells: vec![12, 13, 14, 15], direction: Direction::Horizontal},
        Constraint {cells: vec![0, 5, 10, 15], direction: Direction::Diagonal},
        Constraint {cells: vec![0, 4, 8, 12], direction: Direction::Vertical},
        Constraint {cells: vec![1, 5, 9, 13], direction: Direction::Vertical},
        Constraint {cells: vec![2, 6, 10, 14], direction: Direction::Vertical},
        Constraint {cells: vec![3, 7, 11, 15], direction: Direction::Vertical},
    ];
    */

    let constraints: Vec<Constraint> = vec![
        Constraint {cells: vec![0, 1, 2], direction: Direction::Horizontal},
        Constraint {cells: vec![4, 5, 6], direction: Direction::Horizontal},
        Constraint {cells: vec![8, 9, 10, 11], direction: Direction::Horizontal},
        Constraint {cells: vec![12, 13, 14, 15], direction: Direction::Horizontal},
        Constraint {cells: vec![17, 18, 19], direction: Direction::Horizontal},
        Constraint {cells: vec![21, 22, 23], direction: Direction::Horizontal},
        Constraint {cells: vec![0, 4, 8, 12], direction: Direction::Vertical},
        Constraint {cells: vec![1, 5, 9, 13, 17, 21], direction: Direction::Vertical},
        Constraint {cells: vec![2, 6, 10, 14, 18, 22], direction: Direction::Vertical},
        Constraint {cells: vec![11, 15, 19, 23], direction: Direction::Vertical},
    ];

    let cells: HashSet<usize> = constraints.iter().map(|c| c.cells.clone()).flatten().collect();

    let context = Context {
        sets: sets,
        constraints: constraints,
        two_gram_counters: two_gram_counters,
        cells: cells,
    };

    for _i in 0..100 {
        let board = get_board(&context, [0; 36]);
        if let Some(board) = board {
            println!("{}", bytes_to_string(board.to_vec()));
        }
    }

    Ok(())
}
<commit_msg>Fix bug<commit_after>#[macro_use]
extern crate lazy_static;

use std::{io, fs};
use std::io::BufRead;
use std::iter::FromIterator;
use std::collections::{HashMap, HashSet};
use std::error::Error;
use fst::{IntoStreamer, Streamer, Set};
use rand::thread_rng;
use rand::seq::SliceRandom;

const HIRAGANAS: [char; 81] = ['ぁ', 'あ', 'ぃ', 'い', 'ぅ', 'う', 'ぇ', 'え', 'ぉ', 'お', 'か', 'が', 'き', 'ぎ', 'く', 'ぐ', 'け', 'げ', 'こ', 'ご', 'さ', 'ざ', 'し', 'じ', 'す', 'ず', 'せ', 'ぜ', 'そ', 'ぞ', 'た', 'だ', 'ち', 'ぢ', 'っ', 'つ', 'づ', 'て', 'で', 'と', 'ど', 'な', 'に', 'ぬ', 'ね', 'の', 'は', 'ば', 'ぱ', 'ひ', 'び', 'ぴ', 'ふ', 'ぶ', 'ぷ', 'へ', 'べ', 'ぺ', 'ほ', 'ぼ', 'ぽ', 'ま', 'み', 'む', 'め', 'も', 'ゃ', 'や', 'ゅ', 'ゆ', 'ょ', 'よ', 'ら', 'り', 'る', 'れ', 'ろ', 'わ', 'を', 'ん', 'ー'];
lazy_static! {
    static ref NON_INITIALS: Vec<u8> = {
        (0..HIRAGANAS.len()).filter_map(|index| {
            if "ぁぃぅぇぉっゃゅょぢづーをん".contains(HIRAGANAS[index]) {
                Some(index as u8 + 1)
            } else {
                None
            }
        }).collect()
    };
}

#[derive(PartialEq)]
enum Direction {
    Horizontal,
    Diagonal,
    Vertical,
}

struct Constraint {
    direction: Direction,
    cells: Vec<usize>,
}

struct Context {
    constraints: Vec<Constraint>,
    sets: Vec<Set>,
    cells: HashSet<usize>,
    two_gram_counters: Vec<HashMap<[u8; 2], usize>>,
}

fn is_non_initial(c: u8) -> bool {
    (*NON_INITIALS).contains(&c)
}

fn bytes_to_string(bytes: Vec<u8>) -> String {
    String::from_iter(bytes.iter().map(|&i| {
        if i == 0 {
            '　'
        } else {
            HIRAGANAS[(i - 1) as usize]
        }
    }))
}

fn has_prefix(set: &Set, prefix: Vec<u8>) -> bool {
    let mut prefix_stop = prefix.clone();
    *prefix_stop.last_mut().unwrap() += 1;
    set.range().ge(prefix).lt(prefix_stop).into_stream().next() != None
}

fn get_prefix(set: &Set, prefix: Vec<u8>) -> Vec<Vec<u8>> {
    let mut prefix_stop = prefix.clone();
    *prefix_stop.last_mut().unwrap() += 1;
    set.range().ge(prefix).lt(prefix_stop).into_stream().into_bytes()
}

fn count_prefix(set: &Set, prefix: Vec<u8>) -> usize {
    let mut prefix_stop = prefix.clone();
    *prefix_stop.last_mut().unwrap() += 1;
    set.range().ge(prefix).lt(prefix_stop).into_stream().into_bytes().len()
}

fn get_board(context: &Context, board: [u8; 36]) -> Option<[u8; 36]> {
    if context.cells.iter().all(|&c| board[c] != 0) {
        return Some(board);
    }

    let mut rng = thread_rng();

    let vertical_constraints = context.constraints.iter().filter(|&c| c.direction == Direction::Vertical).collect::<Vec<&Constraint>>();
    let horizontal_constraints = context.constraints.iter().filter(|&c| c.direction == Direction::Horizontal).collect::<Vec<&Constraint>>();

    let max_len = vertical_constraints.len().max(horizontal_constraints.len());

    let vertical_prefixes = vertical_constraints.iter().map(|c| {
        Some((c.cells.iter().map(|&c| board[c]).take_while(|&c| c != 0).collect::<Vec<u8>>(), c))
    }).chain(std::iter::repeat(None)).take(max_len);
    let horizontal_prefixes = horizontal_constraints.iter().map(|c| {
        Some((c.cells.iter().map(|&c| board[c]).take_while(|&c| c != 0).collect::<Vec<u8>>(), c))
    }).chain(std::iter::repeat(None)).take(max_len);

    for (index, (vertical_prefix, horizontal_prefix)) in vertical_prefixes.zip(horizontal_prefixes).enumerate() {
        let mut constraints = Vec::new();
        if let Some(vertical_constraint) = vertical_prefix {
            constraints.push(vertical_constraint);
        }
        if let Some(horizontal_constraint) = horizontal_prefix {
            constraints.push(horizontal_constraint);
        }
        let (prefix, constraint) = constraints.iter().min_by_key(|(c, _)| c.len()).unwrap();

        if prefix.len() == constraint.cells.len() {
            continue;
        }

        if index == 0 && prefix.len() == 0 {
            let mut new_values: Vec<u8> = (1..(HIRAGANAS.len() as u8 + 1)).collect();
            new_values.shuffle(&mut rng);
            'values: for new_value in new_values {
                if is_non_initial(new_value) {
                    continue;
                }

                let mut cloned_board = board.clone();
                cloned_board[0] = new_value;

                // no need to check constraints

                let result = get_board(context, cloned_board);
                if let Some(board) = result {
                    return Some(board);
                }
            }

            return None;
        }

        if index == 0 && prefix.len() == 1 {
            let mut new_values: Vec<u8> = (1..(HIRAGANAS.len() as u8 + 1)).collect();
            new_values.shuffle(&mut rng);
            for new_value in new_values {
                if is_non_initial(new_value) {
                    continue;
                }

                if let Some(&count) = context.two_gram_counters[constraint.cells.len() - 3].get(&[prefix[0], new_value]) {
                    if count < 1 {
                        continue;
                    }
                }

                let mut cloned_board = board.clone();
                cloned_board[constraint.cells[1]] = new_value;

                // no need to check constraints

                let result = get_board(context, cloned_board);
                if let Some(board) = result {
                    return Some(board);
                }
            }
            break;
        }

        if index == 1 && prefix.len() == 1 {
            let mut new_values: Vec<u8> = (1..(HIRAGANAS.len() as u8 + 1)).collect();
            new_values.shuffle(&mut rng);
            'second_values: for new_value in new_values {
                let mut cloned_board = board.clone();
                cloned_board[constraint.cells[1]] = new_value;

                // check if constraints are met
                for constraint in context.constraints.iter() {
                    if is_non_initial(cloned_board[constraint.cells[0]]) {
                        continue 'second_values;
                    }
                    let prefix: Vec<u8> = constraint.cells.iter().map(|&c| cloned_board[c]).take_while(|&c| c != 0).collect();
                    if prefix.len() == 0 {
                        continue;
                    }
                    if !has_prefix(&context.sets[constraint.cells.len() - 3], prefix) {
                        continue 'second_values;
                    }
                }

                let result = get_board(context, cloned_board);
                if let Some(board) = result {
                    return Some(board);
                }
            }
            break;
        }

        let mut words = get_prefix(&context.sets[constraint.cells.len() - 3], prefix.to_vec());
        words.shuffle(&mut rng);
        'words: for word in words {
            if index == 0 {
                if word.iter().any(|&c| is_non_initial(c)) {
                    continue;
                }
            }

            let mut cloned_board = board.clone();
            for (&cell, &letter) in constraint.cells.iter().zip(word.iter()) {
                cloned_board[cell] = letter;
            }

            // check if constraints are met
            for constraint in context.constraints.iter() {
                if is_non_initial(cloned_board[constraint.cells[0]]) {
                    continue 'words;
                }
                let prefix: Vec<u8> = constraint.cells.iter().map(|&c| cloned_board[c]).take_while(|&c| c != 0).collect();
                if prefix.len() == 0 {
                    continue;
                }
                if !has_prefix(&context.sets[constraint.cells.len() - 3], prefix) {
                    continue 'words;
                }
            }

            let result = get_board(context, cloned_board);
            if let Some(board) = result {
                return Some(board);
            }
        }

        break;
    }

    None
}

fn main() -> Result<(), Box<dyn Error>> {
    let f = fs::File::open("crossword.txt")?;
    let file = io::BufReader::new(f);

    let mut word_lists: [Vec<Vec<u8>>; 4] = [Vec::new(), Vec::new(), Vec::new(), Vec::new()];
    'lines: for line in file.lines() {
        let word = line?;
        let mut indices: Vec<u8> = Vec::new();
        for char in word.chars() {
            match HIRAGANAS.iter().position(|&c| c == char) {
                Some(i) => indices.push((i + 1) as u8),
                None => continue 'lines,
            }
        }
        word_lists[indices.len() - 3].push(indices);
    }

    let sets = word_lists.iter_mut().map(|word_list| {
        word_list.sort();
        Set::from_iter(word_list).unwrap()
    }).collect::<Vec<Set>>();

    let mut two_gram_counters = vec![
        HashMap::new(),
        HashMap::new(),
        HashMap::new(),
        HashMap::new(),
    ];

    for i in 0..HIRAGANAS.len() {
        for j in 0..HIRAGANAS.len() {
            for (two_gram_counter, set) in two_gram_counters.iter_mut().zip(sets.iter()) {
                two_gram_counter.insert([i as u8, j as u8], count_prefix(&set, vec![i as u8, j as u8]));
            }
        }
    }

    /*
    let constraints: Vec<Constraint> = vec![
        Constraint {cells: vec![0, 1, 2, 3], direction: Direction::Horizontal},
        Constraint {cells: vec![4, 5, 6, 7], direction: Direction::Horizontal},
        Constraint {cells: vec![8, 9, 10, 11], direction: Direction::Horizontal},
        Constraint {cells: vec![12, 13, 14, 15], direction: Direction::Horizontal},
        Constraint {cells: vec![0, 5, 10, 15], direction: Direction::Diagonal},
        Constraint {cells: vec![0, 4, 8, 12], direction: Direction::Vertical},
        Constraint {cells: vec![1, 5, 9, 13], direction: Direction::Vertical},
        Constraint {cells: vec![2, 6, 10, 14], direction: Direction::Vertical},
        Constraint {cells: vec![3, 7, 11, 15], direction: Direction::Vertical},
    ];
    */

    let constraints: Vec<Constraint> = vec![
        Constraint {cells: vec![0, 1, 2], direction: Direction::Horizontal},
        Constraint {cells: vec![4, 5, 6], direction: Direction::Horizontal},
        Constraint {cells: vec![8, 9, 10, 11], direction: Direction::Horizontal},
        Constraint {cells: vec![12, 13, 14, 15], direction: Direction::Horizontal},
        Constraint {cells: vec![17, 18, 19], direction: Direction::Horizontal},
        Constraint {cells: vec![21, 22, 23], direction: Direction::Horizontal},
        Constraint {cells: vec![0, 4, 8, 12], direction: Direction::Vertical},
        Constraint {cells: vec![1, 5, 9, 13, 17, 21], direction: Direction::Vertical},
        Constraint {cells: vec![2, 6, 10, 14, 18, 22], direction: Direction::Vertical},
        Constraint {cells: vec![11, 15, 19, 23], direction: Direction::Vertical},
    ];

    let cells: HashSet<usize> = constraints.iter().map(|c| c.cells.clone()).flatten().collect();

    let context = Context {
        sets: sets,
        constraints: constraints,
        two_gram_counters: two_gram_counters,
        cells: cells,
    };

    for _i in 0..100 {
        let board = get_board(&context, [0; 36]);
        if let Some(board) = board {
            println!("{}", bytes_to_string(board.to_vec()));
        }
    }

    Ok(())
}
<|endoftext|>