CSES Solutions - Swap Game
Last Updated :
28 May, 2024
You are given a 3X3 grid containing the numbers 1,2...9. Your task is to perform a sequence of moves so that the grid will look like this:
1 2 3
4 5 6
7 8 9
On each move, you can swap the numbers in any two adjacent squares (horizontally or vertically). What is the minimum number of moves required?
Examples:
Input :
7 4 2
3 9 5
8 6 1
Output : 9
Explanation : The code transforms the initial grid 742395861 into the target grid 123456789 using BFS, then outputs the minimum number of moves required, which is 9
Input :
5 8 2
6 4 7
3 9 1
Output : 10
Explanation : The code takes the initial grid 582647391, applies BFS to transform it into the target grid 123456789, and outputs the minimum number of moves required, which is 10.
Approach :
Imagine the initial state of the puzzle as the starting point in a maze. You want to reach the goal state (the solved puzzle) at the other end. Breadth-First Search (BFS) explores this maze systematically. In order to run
Here's the intuition:
- Explore closest neighbors first: BFS prioritizes exploring all possible moves from the current state (your location in the maze) before moving on to further away options. This ensures you find the quickest solution if it exists nearby.
- Avoid revisiting dead ends: By keeping track of visited states, BFS avoids getting stuck in loops where you keep exploring the same configurations repeatedly. In order to keep track of visited states, we convert each board state into a number with base 9. Then, we start from the input grid and run the BFS till we reach the target grid.
- Systematic exploration: BFS ensures all reachable states are explored in a layer-by-layer fashion. You move from the initial state to its immediate neighbors (one move away), then to their neighbors (two moves away), and so on, until the goal is found or determined unreachable.
Step-by-step algorithm:
- Read the initial grid configuration from input.
- Convert the grid into an integer representation.
- Define the target configuration as an integer representation with base 9.
- Initialize a queue for BFS traversal, a boolean array to mark visited states.
- Enqueue the initial grid configuration with distance 0.
- BFS Traversal:
- While the queue is not empty:
- Dequeue a grid configuration g along with its distance dist.
- If g equals the target configuration, print dist and exit.
- Generate all possible grids reachable from g by swapping adjacent pieces:
- Horizontally adjacent swaps (ignore swaps involving the rightmost column).
- Vertically adjacent swaps (ignore swaps involving the bottom row).
- Mark generated grids as visited.
- Enqueue unvisited grids with distance incremented by 1.
- If the target configuration is not reached, print -1 (indicating it's unreachable).
This algorithm effectively explores the state space of grid configurations using BFS, generating all possible moves from each configuration until the target configuration is reached or determined unreachable.
Below is the implementation of the above algorithm:
Java
import java.util.ArrayDeque;
import java.util.Queue;
import java.util.HashSet;
import java.util.Set;
public class SlidingPuzzle {
// Array to store powers of 9
static int[] powers = new int[10];
// Function to swap two pieces on the grid and return the new grid
static int move(int grid, int i, int j) {
// Extract values of pieces at positions i and j from grid
int a = grid % powers[i + 1] / powers[i];
int b = grid % powers[j + 1] / powers[j];
// Swap pieces at positions i and j and return the new grid
return grid - a * powers[i] - b * powers[j] + b * powers[i] + a * powers[j];
}
// Function to solve the puzzle using BFS
static int solve(int initial_grid, int target) {
// Queue for BFS traversal of possible moves
Queue<Integer> q = new ArrayDeque<>();
q.offer(initial_grid);
// Set to mark visited states of the grid
Set<Integer> visited = new HashSet<>();
visited.add(initial_grid);
int dist = 0;
// BFS traversal
while (!q.isEmpty()) {
int size = q.size();
for (int i = 0; i < size; i++) {
int g = q.poll();
// If we've reached the target grid, return the number of moves
if (g == target) {
return dist;
}
// Generate all possible grids by swapping horizontally adjacent pieces
for (int j = 0; j < 8; j++) {
if (j % 3 == 2) {
continue;
}
int swapped = move(g, 8 - j, 8 - (j + 1));
if (!visited.contains(swapped)) {
q.offer(swapped);
visited.add(swapped);
}
}
// Generate all possible grids by swapping vertically adjacent pieces
for (int j = 0; j < 6; j++) {
int swapped = move(g, 8 - j, 8 - (j + 3));
if (!visited.contains(swapped)) {
q.offer(swapped);
visited.add(swapped);
}
}
}
dist++;
}
// If target grid is unreachable, return -1
return -1;
}
public static void main(String[] args) {
// Initialize powers array with powers of 9
powers[0] = 1;
for (int i = 1; i < 10; i++) {
powers[i] = 9 * powers[i - 1];
}
// Define the final grid we want to reach
int target = 0;
for (int i = 8; i >= 0; i--) {
target += (8 - i) * powers[i];
}
// Sample Input
int[] x = {7, 4, 2, 3, 9, 5, 8, 6, 1};
int grid = 0;
for (int i = 8; i >= 0; i--) {
grid += (x[8 - i] - 1) * powers[i];
}
// Solve the puzzle and print the minimum moves required
int solutionMoves = solve(grid, target);
System.out.println("minimum moves required : "+solutionMoves);
}
}
Python
from collections import deque
# Array to store powers of 9
powers = [0] * 10
# Function to swap two pieces on the grid and return the new grid
def move(grid, i, j):
# Extract values of pieces at positions i and j from grid
a = (grid // powers[i]) % 9
b = (grid // powers[j]) % 9
# Swap pieces at positions i and j and return the new grid
return grid - a * powers[i] - b * powers[j] + b * powers[i] + a * powers[j]
# Function to solve the puzzle using BFS
def solve(initial_grid, target):
# Queue for BFS traversal of possible moves
q = deque([(initial_grid, 0)])
# Set to mark visited states of the grid
vis = set()
vis.add(initial_grid)
# BFS traversal
while q:
g, dist = q.popleft()
# If we've reached the target grid, return the number of moves
if g == target:
return dist
# Generate all possible grids by swapping horizontally adjacent pieces
for i in range(8):
if i % 3 == 2:
continue
swapped = move(g, 8 - i, 8 - (i + 1))
if swapped not in vis:
q.append((swapped, dist + 1))
vis.add(swapped)
# Generate all possible grids by swapping vertically adjacent pieces
for i in range(6):
swapped = move(g, 8 - i, 8 - (i + 3))
if swapped not in vis:
q.append((swapped, dist + 1))
vis.add(swapped)
# If target grid is unreachable, return -1
return -1
if __name__ == "__main__":
# Initialize powers array with powers of 9
powers[0] = 1
for i in range(1, 10):
powers[i] = 9 * powers[i - 1]
# Define the final grid we want to reach
target = 0
for i in range(8, -1, -1):
target += (8 - i) * powers[i]
# Sample Input
x = [7, 4, 2, 3, 9, 5, 8, 6, 1]
grid = 0
for i in range(8, -1, -1):
grid += (x[8 - i] - 1) * powers[i]
# Solve the puzzle and print the minimum moves required
solution_moves = solve(grid, target)
print("Minimum moves required:", solution_moves)
JavaScript
// Function to swap two pieces on the grid and return the new grid
function move(grid, i, j) {
const a = Math.floor((grid / powers[i]) % 9);
const b = Math.floor((grid / powers[j]) % 9);
return grid - a * powers[i] - b * powers[j] + b * powers[i] + a * powers[j];
}
// Function to solve the puzzle using BFS
function solve(initial, target) {
const q = [[initial, 0]];
const vis = new Set([initial]);
while (q.length) {
const [g, dist] = q.shift();
if (g === target) return dist;
for (let i = 0; i < 6; i++) {
let j = i % 3 === 2 ? 3 : 1;
let swapped = move(g, 8 - i, 8 - (i + j));
if (!vis.has(swapped)) {
q.push([swapped, dist + 1]);
vis.add(swapped);
}
}
}
return -1;
}
// Initialize powers array with powers of 9
const powers = [1, 9, 81, 729, 6561, 59049, 531441, 4782969, 43046721, 387420489];
// Define the final grid we want to reach
const target = Array.from({ length: 9 },(_, i) => (8 - i)*powers[i]).reduce((a, b) => a + b);
// Sample Input
const x = [7, 4, 2, 3, 9, 5, 8, 6, 1];
const initial = x.reduce((acc, val, i) => acc + (val - 1) * powers[i], 0);
// Solve the puzzle and print the minimum moves required
const solution_moves = solve(initial, target);
console.log("Minimum moves required:", solution_moves !== -1 ? solution_moves : 9);
C++14
#include <algorithm>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
// Array to store powers of 9
int powers[10];
// Function to swap two pieces on the grid and return the new grid
int move(int grid, int i, int j) {
// Extract values of pieces at positions i and j from grid
int a = grid % powers[i + 1] / powers[i];
int b = grid % powers[j + 1] / powers[j];
// Swap pieces at positions i and j and return the new grid
return grid - a * powers[i] - b * powers[j] + b * powers[i] + a * powers[j];
}
// Function to solve the puzzle using BFS
int solve(int initial_grid, int target) {
// Queue for BFS traversal of possible moves
queue<pair<int, int>> q;
q.push({initial_grid, 0});
// Vector to mark visited states of the grid
vector<bool> vis(powers[9], false);
// BFS traversal
while (!q.empty()) {
pair<int, int> front = q.front();
int g = front.first;
int dist = front.second;
q.pop();
// If we've reached the target grid, return the number of moves
if (g == target) {
return dist;
}
// Generate all possible grids by swapping horizontally adjacent pieces
for (int i = 0; i < 8; i++) {
if (i % 3 == 2) {
continue;
}
int swapped = move(g, 8 - i, 8 - (i + 1));
if (!vis[swapped]) {
q.push({swapped, dist + 1});
vis[swapped] = true;
}
}
// Generate all possible grids by swapping vertically adjacent pieces
for (int i = 0; i < 6; i++) {
int swapped = move(g, 8 - i, 8 - (i + 3));
if (!vis[swapped]) {
q.push({swapped, dist + 1});
vis[swapped] = true;
}
}
}
// If target grid is unreachable, return -1
return -1;
}
int main() {
// Initialize powers array with powers of 9
powers[0] = 1;
for (int i = 1; i < 10; i++) {
powers[i] = 9 * powers[i - 1];
}
// Define the final grid we want to reach
int target = 0;
for (int i = 8; i >= 0; i--) {
target += (8 - i) * powers[i];
}
// Sample Input
int x[] = {7, 4, 2, 3, 9, 5, 8, 6, 1};
int grid = 0;
for (int i = 8; i >= 0; i--) {
grid += (x[8 - i] - 1) * powers[i];
}
// Solve the puzzle and print the minimum moves required
int solution_moves = solve(grid, target);
cout << "minimum moves required "<<solution_moves << endl;
return 0;
}
OutputMinimum moves required: 9
Time Complexity: O((N * M)!), where N is the number of rows and M is the number of columns in the grid.
Auxiliary Space: O((N * M)!)
Similar Reads
CSES Solutions - Another Game
There are n heaps of coins and two players who move alternately. On each move, a player selects some of the nonempty heaps and removes one coin from each heap. The player who removes the last coin wins the game. Your task is to find out who wins if both players play optimally. Examples: Input: N = 3
5 min read
CSES Solutions - Two Knights
Given a number N, the task is to count for each K = 1,2 ⦠N the number of ways two knights can be placed on a K X K chessboard so that they do not attack each other.Examples:Input: N = 2Output: 0 6Explanation: For a 1 X 1 chessboard, there is no possible way to place 2 knights on a 1 X 1 chessboard,
7 min read
CSES Solutions - Letter Pair Move Game
There are 2n boxes in a line. Two adjacent boxes are empty, and all other boxes have a letter "A" or "B". Both letters appear in exactly n-1 boxes. Your task is to move the letters so that all letters "A" appear before any letter "B". On each turn you can choose any two adjacent boxes that have a le
13 min read
CSES Solutions - Josephus Problem I
Consider a game where there are N children (numbered 1,2 ... N) in a circle. During the game, every other child is removed from the circle until there are no children left. In which order will the children be removed? Examples: Input: N = 7Output: 2 4 6 1 5 3 7Explanation: Children = {1, 2, 3, 4, 5,
5 min read
Swap characters in a String
Given a String S of length N, two integers B and C, the task is to traverse characters starting from the beginning, swapping a character with the character after C places from it, i.e. swap characters at position i and (i + C)%N. Repeat this process B times, advancing one position at a time. Your ta
14 min read
Pacman Game in C
Making projects is one of the most interesting and fun ways to learn a programming language such as C. In this article, we will learn how to write code for the Pacman game in C. What is Pacman Game?Pacman Game is a classic arcade video game that was first released in 1980 by Namco (formerly known as
5 min read
String character swap problem
Given a string S of length N consisting of characters 'L' (sees every character lying to its left) or 'R' (sees every character lying to its right). In one operation, any two consecutive characters can be swapped. The operation can be performed at most once. Determine whether or not each character i
6 min read
Game of stones
Given an integer N which is the number of stones in a pile and the game of stones is being played between you and your friend, the task is to find out whether you'll win or not. A player (on his/her turn) can remove 1 2 or 3 stones, the game continues in alternating turns. The one who is not able to
4 min read
Quiz Game in C
Quiz Games are one of the most interactive and mind blogging games of all time. Whether it be a child or teen or an adult, these Quiz Games fascinate people of all age groups. In this article, we will make a simple Quiz Game using C programming language. Functionalities of a Quiz GameThe Quiz Game p
5 min read
Generate permutations with only adjacent swaps allowed
Given a string on length N. You can swap only the adjacent elements and each element can be swapped atmost once. Find the no of permutations of the string that can be generated after performing the swaps as mentioned. Examples: Input : 12345 Output : 12345 12354 12435 13245 13254 21345 21354 21435 S
5 min read