<commit_before>#ifndef _TILES_STATE_HPP_
#define _TILES_STATE_HPP_


#include <boost/functional/hash.hpp>

#include <cassert>
#include <iostream>

#include "TilesTypes.hpp"


class TilesState15
{
private:
  std::size_t hash_value;
  TileIndex blank_index;
  TileArray tiles;


public:
  TilesState15(const TileArray &tiles)
    : hash_value(compute_hash(tiles))
    , blank_index(find_blank_index(tiles))
    , tiles(tiles)
  {
    assert(tiles[blank_index] == 0);
  }

  inline Tile operator ()(unsigned i, unsigned j) const
  {
    assert(i < 4);
    assert(j < 4);
    return tiles[i * 4 + j];
  }

  inline bool operator ==(const TilesState15 &other) const
  {
    return
      hash_value == other.hash_value &&
      blank_index == other.blank_index &&
      tiles == other.tiles;
  }

  inline bool operator !=(const TilesState15 &other) const
  {
    return !(*this == other);
  }

  inline TileIndex get_blank() const
  {
    return blank_index;
  }

  inline TileIndex get_blank_row() const
  {
    return blank_index / 4;
  }

  inline TileIndex get_blank_col() const
  {
    return blank_index % 4;
  }

  inline const TileArray & get_tiles() const
  {
    return tiles;
  }

  inline size_t get_hash_value() const
  {
    return hash_value;
  }


  TilesState15 move_blank_up() const
  {
    assert(get_blank_row() > 0);
    return move_blank(-4);
  }

  TilesState15 move_blank_down() const
  {
    assert(get_blank_row() < 3);
    return move_blank(4);
  }

  TilesState15 move_blank_left() const
  {
    assert(get_blank_col() > 0);
    return move_blank(-1);
  }

  TilesState15 move_blank_right() const
  {
    assert(get_blank_col() < 3);
    return move_blank(1);
  }

  bool valid() const;


private:
  inline TilesState15 move_blank(TileIndex new_blank_offset) const
  {
    TileIndex new_blank_index = blank_index + new_blank_offset;
    TilesState15 new_state(*this);
    new_state.blank_index = new_blank_index;
    std::swap(new_state.tiles[blank_index], new_state.tiles[new_blank_index]);<commit_msg>Do not store blank index in TilesState15.<commit_after>#ifndef _TILES_STATE_HPP_
#define _TILES_STATE_HPP_


#include <boost/functional/hash.hpp>

#include <cassert>
#include <iostream>

#include "TilesTypes.hpp"


class TilesState15
{
private:
  std::size_t hash_value;
  TileArray tiles;


public:
  TilesState15(const TileArray &tiles)
    : hash_value(compute_hash(tiles))
    , tiles(tiles)
  {
    assert(tiles[get_blank()] == 0);
  }

  inline Tile operator ()(unsigned i, unsigned j) const
  {
    assert(i < 4);
    assert(j < 4);
    return tiles[i * 4 + j];
  }

  inline bool operator ==(const TilesState15 &other) const
  {
    return
      hash_value == other.hash_value &&
      tiles == other.tiles;
  }

  inline bool operator !=(const TilesState15 &other) const
  {
    return !(*this == other);
  }

  inline TileIndex get_blank() const
  {
    return find_blank_index(tiles);
  }

  inline TileIndex get_blank_row() const
  {
    return get_blank() / 4;
  }

  inline TileIndex get_blank_col() const
  {
    return get_blank() % 4;
  }

  inline const TileArray & get_tiles() const
  {
    return tiles;
  }

  inline size_t get_hash_value() const
  {
    return hash_value;
  }


  TilesState15 move_blank_up() const
  {
    assert(get_blank_row() > 0);
    return move_blank(-4);
  }

  TilesState15 move_blank_down() const
  {
    assert(get_blank_row() < 3);
    return move_blank(4);
  }

  TilesState15 move_blank_left() const
  {
    assert(get_blank_col() > 0);
    return move_blank(-1);
  }

  TilesState15 move_blank_right() const
  {
    assert(get_blank_col() < 3);
    return move_blank(1);
  }

  bool valid() const;


private:
  inline TilesState15 move_blank(TileIndex new_blank_offset) const
  {
    TileIndex blank_index = get_blank();
    TileIndex new_blank_index = blank_index + new_blank_offset;
    TilesState15 new_state(*this);
    std::swap(new_state.tiles[blank_index], new_state.tiles[new_blank_index]);
{'fraction_non_alphanumeric': 0.11035696329813977, 'fraction_numerical': 0.017596782302664656, 'mean_word_length': 3.4859075535512964, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4592568', 'n_tokens_mistral': 1518, 'n_tokens_neox': 1435, 'n_words': 301}