Avoid if statements for checking neighboring indexes in a 2D array

kerdemdemir via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sun Jul 16 14:50:19 PDT 2017


Hi Guys,

@Nicholas , thanks a lot for cool solution but actually I weren't 
working on image processing. I was trying to solve 
"http://codeforces.com/contest/828/problem/B". I really needed 
finding connected components this time.

@Ivan, your solution is much more elegant than what I did. But I 
find @Timon's solution with cartesian product a bit nicer in this 
case since I love to see std function more and more.

Thanks guys for all your advises. D community is really the best.

Here is my solution to question. It seems I didn't get it working 
completely yet. In my debugger(Msvc MonoD) even there are many 
rows it seems Recurse function only loops the columns in the 
first row. And debugger is jumping so strangely I couldn't tag 
the problem.
But I don't expect a big change there should be a small bug that 
is it.

Sorry if code contains some foreign words I just replaced many 
variable names from my native language I might be missing some.

import std.stdio;
import std.string;
import std.algorithm;
import std.conv;
import std.array;
import std.range;
import std.math;

int totalrow;
int totalcolumn;
dchar[][] twoDimensionArray;

struct ConnectedElementsSolver
{
	this(  dchar[][] twoDimArray )
	{
		m_twoDimStruct = twoDimArray;
		Recurse(0, 0);
	}

	void Recurse ( int row, int column )
	{
		if( row < 0 || column < 0  )
			return;

		for ( ; row <  m_twoDimStruct.length ; row++  )
		{
			for ( ; column <  m_twoDimStruct[row].length; column++  )
			{
				Process( row, column, m_twoDimStruct.length, 
m_twoDimStruct[row].length );
			}
		}
	}

	void Process( int row, int column, ulong maxrow, ulong maxcolumn 
)
	{
		if( row < 0 || column < 0 || row >= maxrow || column >= 
maxcolumn  )
			return;

		if (  m_twoDimStruct[row][column] == 'B' )
		{
			m_twoDimStruct[row][column] = 'W';
			m_tempResult.Process(row, column );
			Process(row-1,column-1, maxrow, maxcolumn);
			Process(row,column-1, maxrow, maxcolumn);
			Process(row+1,column-1, maxrow, maxcolumn);				
			Process(row-1,column, maxrow, maxcolumn);				
			Process(row+1,column, maxrow, maxcolumn);				
			Process(row-1,column+1, maxrow, maxcolumn);			
			Process(row,column+1, maxrow, maxcolumn);		
			Process(row-1,column+1, maxrow, maxcolumn);
		}
		else
		{
			if ( m_tempResult.HowManyFilled )
				m_results ~= m_tempResult;
			m_tempResult.Resetle();
		}	
	}

	SquareCandidate   m_tempResult;
	SquareCandidate[] m_results;
	dchar[][] m_twoDimStruct;
}

struct SquareCandidate
{
	int MaxY;
	int MinY;
	int MaxX;
	int MinX;
     int HowManyFilled;

	this( int howManyFilled )
	{
		HowManyFilled = howManyFilled;
	}
	
	void Resetle()
	{
		this = SquareCandidate();
	}


	void Process( int row, int column )
	{
		HowManyFilled++;
		MaxY = max( column, MaxY);
		MinY = min( column, MinY);
		MaxX = max( row, MaxX);
		MinX = min( row, MinX);
	}

	int FindEmptySlots()
	{
		int kareKenarUzunlugu = max(MaxX-MinX, MaxY-MinY);
		int kareAlani = kareKenarUzunlugu*kareKenarUzunlugu;
		return kareAlani - HowManyFilled;
	}
	
	bool CanCreateSquare( int xMax, int yMax )
	{
		int xUzunlugu = MaxX-MinX;
		int yUzunlugu = MaxY-MinY;
		if ( xUzunlugu > yUzunlugu )
         {
			return yMax >= xUzunlugu;
		}
		else
		{
			return xMax >= yUzunlugu;
		}
	}
}


void main()
{
     auto dimensions = stdin.readln.strip.split().map!(a => 
to!int(a)).array();
	totalrow = dimensions[0];
	totalcolumn = dimensions[1];
     twoDimensionArray = stdin
		.byLine()
		.take(totalrow)
		.map!(line => line
			  .map!(a => to!dchar(a))
			  .array())
		.array;

	ConnectedElementsSolver baglantiliElemCozucu = 
ConnectedElementsSolver(twoDimensionArray);
	bool isAnyProblemMakingSquare = 
baglantiliElemCozucu.m_results.any!(a => 
a.CanCreateSquare(totalrow, totalcolumn) == false );
	if ( isAnyProblemMakingSquare )
		writeln(-1);
	
	int sonuc;
	baglantiliElemCozucu.m_results.each!( a => sonuc += 
a.FindEmptySlots() );
	writeln( sonuc );
}


More information about the Digitalmars-d-learn mailing list