Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

15 Puzzle

The goal of the 15 puzzle problem is to complete pieces on $4 \times 4$ cells where one of the cells is empty space.

In this problem, the space is represented by 0 and pieces are represented by integers from 1 to 15 as shown below.

1 2 3 4
6 7 8 0
5 10 11 12
9 13 14 15

You can move a piece toward the empty space at one step. Your goal is to make the pieces the following configuration in the shortest move (fewest steps).

1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 0

Write a program which reads an initial state of the puzzle and prints the fewest steps to solve the puzzle.

Input

The $4 \times 4$ integers denoting the pieces or space are given.

Output

Print the fewest steps in a line.

Constraints

The given puzzle is solvable in at most 45 steps.

Sample Input

1 2 3 4
6 7 8 0
5 10 11 12
9 13 14 15

Sample Output

8

Solution in C (judge verdict: Accepted)

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>

typedef struct {
  int MEMBER00 [ 16 ] ;
  int MEMBER01 ;
  int MEMBER02 ;
} STRUCT00 ;

int VAR00 [ 16 ] [ 16 ] ;

STRUCT00 VAR01 ;
int VAR02 [ 4 ] = { 4 , 1 , -1 , -4 } ;

int FUNC00 ( int ARG00 , int ARG01 , int ARG02 ) ;
int FUNC01 ( STRUCT00 ARG03 ) ;
int FUNC02 ( STRUCT00 ARG04 ) ;

int main ( void ) {
  int VAR03 , VAR04 , VAR05 = 0 ;
  char VAR06 , VAR07 ;
  STRUCT00 VAR08 ;

  for ( VAR03 = 0 ; VAR03 < 15 ; VAR03 ++ ) for ( VAR04 = 0 ; VAR04 < 16 ; VAR04 ++ ) VAR00 [ VAR03 + 1 ] [ VAR04 ] = abs ( VAR03 / 4 - VAR04 / 4 ) + abs ( VAR03 % 4 - VAR04 % 4 ) ;





  for ( VAR03 = 0 ; VAR03 < 16 ; VAR03 ++ ) {








    scanf ( "%d" , & VAR08 . MEMBER00 [ VAR03 ] ) ;
    if ( VAR08 . MEMBER00 [ VAR03 ] == 0 ) VAR08 . MEMBER01 = VAR03 ;
  }

  VAR05 = 3 - VAR08 . MEMBER01 / 4 ;
  for ( VAR03 = 0 ; VAR03 < 15 ; VAR03 ++ ) for ( VAR04 = VAR03 + 1 ; VAR04 < 16 ; VAR04 ++ ) if ( VAR08 . MEMBER00 [ VAR03 ] > VAR08 . MEMBER00 [ VAR04 ] && VAR08 . MEMBER00 [ VAR04 ] != 0 ) VAR05 ++ ;
  if ( VAR05 % 2 == 1 ) printf ( "impossible\n" ) ;
  else {

    VAR08 . MEMBER02 = FUNC02 ( VAR08 ) ;

    printf ( "%d\n" , FUNC01 ( VAR08 ) ) ;
  }

  return 0 ;
}

int FUNC02 ( STRUCT00 ARG05 ) {
  int VAR09 , VAR10 = 0 ;
  for ( VAR09 = 0 ; VAR09 < 16 ; VAR09 ++ ) if ( ARG05 . MEMBER00 [ VAR09 ] != 0 ) VAR10 += VAR00 [ ARG05 . MEMBER00 [ VAR09 ] ] [ VAR09 ] ;
  ARG05 . MEMBER02 = VAR10 ;
  return VAR10 ;
}
int FUNC01 ( STRUCT00 ARG06 ) {
  int VAR11 = -1 , VAR12 ;
  for ( VAR12 = 1 ; VAR12 <= 80 ; VAR12 ++ ) {
    VAR01 = ARG06 ;
    VAR11 = FUNC00 ( VAR12 , 0 , -10 ) ;
    if ( VAR11 != -1 ) break ;
  }
  return VAR11 ;
}
int FUNC00 ( int ARG07 , int ARG08 , int ARG09 ) {

  int VAR13 , VAR14 = -1 , VAR15 ;
  STRUCT00 VAR16 = VAR01 ;

  if ( VAR16 . MEMBER02 == 0 ) return ARG08 ;

  if ( VAR01 . MEMBER02 + ARG08 >= ARG07 ) return -1 ;
  for ( VAR13 = 0 ; VAR13 < 4 ; VAR13 ++ ) {
    if ( VAR16 . MEMBER01 % 4 == 0 && VAR13 == 2 ) continue ;
    if ( VAR16 . MEMBER01 % 4 == 3 && VAR13 == 1 ) continue ;
    VAR01 = VAR16 ;

    VAR01 . MEMBER01 += VAR02 [ VAR13 ] ;

    if ( VAR01 . MEMBER01 >= 0 && VAR01 . MEMBER01 < 16 && ARG09 + VAR13 != 3 ) {

      VAR01 . MEMBER02 -= VAR00 [ VAR16 . MEMBER00 [ VAR01 . MEMBER01 ] ] [ VAR01 . MEMBER01 ] ;
      VAR01 . MEMBER02 += VAR00 [ VAR16 . MEMBER00 [ VAR01 . MEMBER01 ] ] [ VAR16 . MEMBER01 ] ;

      VAR01 . MEMBER00 [ VAR16 . MEMBER01 ] = VAR16 . MEMBER00 [ VAR01 . MEMBER01 ] ;
      VAR01 . MEMBER00 [ VAR01 . MEMBER01 ] = 0 ;




      VAR14 = FUNC00 ( ARG07 , ARG08 + 1 , VAR13 ) ;
      if ( VAR14 != -1 ) break ;
    }
  }
  return VAR14 ;
}