Language: C++

#define FOR(i,n) for(int i=0; i<n; ++i)
#define GET(type,name) type name; std::cin >> name;

//include STL libs
#include <iostream>
#include <vector>
#include <utility>
#include <utility>
#include <algorithm>
#include <queue>
#include <numeric>
#include <unordered_map>
#include <unordered_set>



    typedef std::vector<std::vector<int>> State;
    typedef unsigned long long ulong;
    const ulong N = 4;


    State ulong_to_state(ulong c){
      std::vector<std::vector<int>> state(N, std::vector<int>(N));
      FOR(i, N) {
        FOR(j, N) {
          ulong r = c%(N*N);
          c = c/(N*N);
          state[i][j] = r;
        }
      }
      return state;
    }
    ulong state_to_ulong(State state) {
      ulong c = 0;
      ulong p = 1;
      FOR(i, N) {
        FOR(j, N) {
          c += state[i][j] * p;
          p *= (N*N);
//          std::cout << c << ", " << p  << std::endl;
//          std::cout <<  << std::endl;
        }
      }
      return c;
    }


    void show(std::vector<std::vector<int>> state){
      return;
      FOR(i, N) {
        FOR(j, N) {
          std::cout << state[i][j] << " ";
        }
        std::cout << std::endl;
      }
      std::cout << std::endl;
    }

    bool is_solved(const State& state) {
      FOR(i, N) {
        FOR(j, N) {
          if(state[i][j] != 0 and state[i][j] != (1 + N*i + j)) return false;
        }
      }
      return true;
    }

    std::vector<State> next_states_of(State state){
      std::vector<State> res;
      FOR(i,N){
        FOR(j,N){
          if(state[i][j] == 0){
            State ns;
            if(i<N-1){
              ns = state;
              std::swap(ns[i][j], ns[i+1][j]);
              res.push_back(ns);
            }
            if(j<N-1){
              ns = state;
              std::swap(ns[i][j], ns[i][j+1]);
              res.push_back(ns);
            }
            if(i>0){
              ns = state;
              std::swap(ns[i][j], ns[i-1][j]);
              res.push_back(ns);
            }
            if(j>0){
              ns = state;
              std::swap(ns[i][j], ns[i][j-1]);
              res.push_back(ns);
            }
            return res;
          }
        }
      }

//      auto ns = state; std::swap(ns[0][0], ns[0][1]); res.push_back(ns);
//      ns = state; std::swap(ns[0][1], ns[0][2]); res.push_back(ns);
//      ns = state; std::swap(ns[1][0], ns[1][1]); res.push_back(ns);
//      ns = state; std::swap(ns[1][1], ns[1][2]); res.push_back(ns);
//      ns = state; std::swap(ns[2][0], ns[2][1]); res.push_back(ns);
//      ns = state; std::swap(ns[2][1], ns[2][2]); res.push_back(ns);
//      ns = state; std::swap(ns[0][0], ns[1][0]); res.push_back(ns);
//      ns = state; std::swap(ns[1][0], ns[2][0]); res.push_back(ns);
//      ns = state; std::swap(ns[0][1], ns[1][1]); res.push_back(ns);
//      ns = state; std::swap(ns[1][1], ns[2][1]); res.push_back(ns);
//      ns = state; std::swap(ns[0][2], ns[1][2]); res.push_back(ns);
//      ns = state; std::swap(ns[1][2], ns[2][2]); res.push_back(ns);
//      std::cout << res.size() <<std::endl;
      return res;
    }

    int solve_puzzle(State state){

      std::priority_queue<
        std::pair<int, ulong >,
        std::vector<std::pair<int, ulong>>,
        std::greater<std::pair<int, ulong>>
      > q;
      std::unordered_set<ulong> h;

      q.push(std::make_pair(0, state_to_ulong(state)));

      for(;not q.empty();){
        auto d_s = q.top(); q.pop();
        int d = d_s.first;

        ulong st_int = d_s.second;
//        std::cout<<st_int<<std::endl;
        State state = ulong_to_state(d_s.second);
        show(state);//for dev


        if(is_solved(state)){
//          std::cout << "z"<< std::endl;
          return d;
        }

        if(h.find(st_int) == h.end()){
          h.insert(st_int);
//          h[st_int] = d;
          std::vector<State> next_states = next_states_of(state);
          for(auto ns : next_states){
            q.push(std::make_pair(d+1, state_to_ulong(ns)));
          }
        }
      }
      return -1;
    }

    int main(){
      std::vector<std::vector<int>> state(N, std::vector<int>(N));

      FOR(i, N){
        FOR(j, N){
          GET(int, x);
          state[i][j] = x;
        }
      }
      show(state);
//      int c = state_to_int(state);
//      std::cout << c << std::endl;
//      std::cout << "?" <<std::endl;
//      State s2 = int_to_state(c);
//      std::cout << "!" <<std::endl;
//
//      show(s2);
//      int min_steps = rec_min_steps_
//      std::cout <<is_solved(state);
//      exit(0);
      std::cout << solve_puzzle(state) << std::endl;
      return 0;
    }

Compiler output:
a.cc:18:32: error: conflicting declaration 'typedef long long unsigned int ulong'
   18 |     typedef unsigned long long ulong;
      |                                ^~~~~
In file included from /usr/include/stdlib.h:514,
                 from /usr/include/c++/14/cstdlib:79,
                 from /usr/include/c++/14/ext/string_conversions.h:43,
                 from /usr/include/c++/14/bits/basic_string.h:4154,
                 from /usr/include/c++/14/string:54,
                 from /usr/include/c++/14/bits/locale_classes.h:40,
                 from /usr/include/c++/14/bits/ios_base.h:41,
                 from /usr/include/c++/14/ios:44,
                 from /usr/include/c++/14/ostream:40,
                 from /usr/include/c++/14/iostream:41,
                 from a.cc:5:
/usr/include/x86_64-linux-gnu/sys/types.h:148:27: note: previous declaration as 'typedef long unsigned int ulong'
  148 | typedef unsigned long int ulong;
      |                           ^~~~~