/*H************************************************************************************************/

/*!

 

\File    main.cpp

 

\Description

    Hacker's Delight #8 - Matrix Flip

 

\Notes

    Please read the RULE and NOTE comments below. Entries that violate RULE(s) will be rejected.

 

*/

/************************************************************************************************H*/

 

/*

 * !!!!!!!!!!!!!!!!!!!

$$RULE: All submitted code must be within the START and END tokens (see below).

 * !!!!!!!!!!!!!!!!!!!

*/

 

#include <iostream>

#include <math.h>

#include <time.h>

#include <float.h>

 

/* $$RULE: Replace "Author_Institute" with your full name and institution (company or school)

           EXAMPLE: JonDoe_ElectronicArtsTiburon

*/

namespace Author_Institute

{

 

// MatrixFlip class

class MatrixFlipC

{

public:

    MatrixFlipC(int *pMatrix, int h, int w);

   ~MatrixFlipC();

 

    void Execute();

    int  Grade(char *pStrResult);

 

    // helper func for dereferencing 2d matrix of unknown size

    // Ex: Mat2d(3,4) == &Matrix[3][4]

    inline int * Mat2d(int x, int y) { return m_pMatrix + ((y * m_Width) + x); }

 

protected:

    void FlipSignRow(int);

    void FlipSignCol(int);

    void ComputeSums();

 

    int *m_pMatrix;

    int m_Width;

    int m_Height;

 

    int *m_SumC;    // col sum

    int *m_SumR;    // row sum

    int  m_SumM;    // matrix sum

 

    // stats

    int m_RFlipCnt;

    int m_CFlipCnt;

};

 

//

// ----------------- START -----------------

//

 

/******************************************************************************/

/*! MatrixFlipC::Execute

 

    Compute the MINIMUM non-negative value of m_SumM that can be obtained by a succession

    of calls to FlipSignCol() and FlipSignRow() such that all values in m_SumC and m_SumR are

    also non-negative, AND give the shortest possible sequence of such calls which

    achieves this value m_SumM while satisfying the non-negative property for all elements

    in m_SumC and m_SumR.

 

    Please provide a written (English) description of your implementation here.

    The more detail, the better!!!

 

    Your code must compile in MS Visual Studio 2005 and run on a standard P4.

 

    Have fun,

 

    --hackers

 

*/

/******************************************************************************/

 

void MatrixFlipC::Execute()

{

#if 0

    // your tools:

    ComputeSums();      // compute m_SumC, m_SumR, and m_SumM.

    FlipSignCol(x);     // flip sign of column x

    FlipSignRow(y);     // flip sign of row y

#endif

}

 

//

// ----------------- END -----------------

//

 

MatrixFlipC::MatrixFlipC(int *pMatrix, int h, int w)

{

    m_pMatrix = pMatrix;

    m_Width = w;

    m_Height = h;

 

    m_SumC = new int[w];

    m_SumR = new int[h];

 

    m_RFlipCnt = m_CFlipCnt = 0;

}

 

void MatrixFlipC::ComputeSums()

{

    int x,y;

 

    // clear

    memset(m_SumC,0,sizeof(m_SumC[0])*m_Width);

    memset(m_SumR,0,sizeof(m_SumR[0])*m_Height);

    m_SumM = 0;

 

    // sum m_SumR/m_SumC

    for (y=0; y < m_Height; y++)

    {

        for (x=0; x < m_Width; x++)

        {

            int offset = (y * m_Width) + x;

            m_SumR[y] += m_pMatrix[offset];

            m_SumC[x] += m_pMatrix[offset];

        }

    }

 

    // sum m_SumM

    for (y=0; y < m_Height; y++)

    {

        m_SumM += m_SumR[y];

    }

    for (x=0; x < m_Width; x++)

    {

        m_SumM += m_SumC[x];

    }

}

 

MatrixFlipC::~MatrixFlipC()

{

    delete [] m_SumC;

    delete [] m_SumR;

}

 

int MatrixFlipC::Grade(char *pStrResult)

{

    int i;

 

    // determine m_SumC, m_SumR, and m_SumM

    ComputeSums();

 

    // test m_SumR

    for (i=0; i < m_Height; i++)

        if (m_SumR[i] < 0) { sprintf_s(pStrResult,1024,"FAIL: m_SumR[%d] is negative (%d)\n",i,m_SumR[i]); return -1; }

 

    // test m_SumC

    for (i=0; i < m_Width; i++)

        if (m_SumC[i] < 0) { sprintf_s(pStrResult,1024,"FAIL: m_SumC[%d] is negative (%d)\n",i,m_SumC[i]); return -1; }

 

    // minimization stats

    sprintf_s(pStrResult,1024,"Entry passed. Stats:\n\tRow flips: %d\n\tCol flips: %d\n\tS value: %d\n",

        m_RFlipCnt,m_CFlipCnt,m_SumM);

 

    return 0;

}

 

void MatrixFlipC::FlipSignRow(int i)

{

    m_RFlipCnt++;

    int *pElement = m_pMatrix + (i * m_Width);

    for (int x=0; x < m_Width; x++)

    {

        int * pElement = Mat2d(x,i);

        *pElement *= -1;

    }

}

 

void MatrixFlipC::FlipSignCol(int i)

{

    m_CFlipCnt++;

    for (int y=0; y < m_Height; y++)

    {

        int * pElement = Mat2d(i,y);

        *pElement *= -1;

    }

}

 

} // end namespace

 

// -------------------------------------------------------------

 

int main (int argc, char * const argv[])

{

    int matrix[27][9] = {

    { 33,    30,    10,    -6,    18,    -7,   -11,    23,    -6, },

    { 16,   -19,     9,   -26,    -8,   -19,    -8,   -21,   -14, },

    { 17,    12,   -14,    31,   -30,    13,   -13,    19,    16, },

    { -6,   -11,     1,    17,   -12,    -4,    -7,    14,   -21, },

    { 18,   -31,    34,   -22,    17,   -19,    20,    24,     6, },

    { 33,   -18,    17,   -15,    31,    -5,     3,    27,    -3, },

   { -18,   -20,   -18,    31,     6,     4,    -2,   -12,    24, },

    { 27,    14,     4,   -29,    -3,     5,   -29,     8,   -12, },

   { -15,    -7,   -23,    23,    -9,    -8,     6,     8,   -12, },

    { 33,   -23,   -19,    -4,    -8,    -7,    11,   -12,    31, },

   { -20,    19,   -15,   -30,    11,    32,     7,    14,    -5, },

   { -23,    18,   -32,    -2,   -31,    -7,     8,    24,    16, },

    { 32,    -4,   -10,   -14,    -6,    -1,     0,    23,    23, },

    { 25,     0,   -23,    22,    12,    28,   -27,    15,     4, },

   { -30,   -13,   -16,    -3,    -3,   -32,    -3,    27,   -31, },

    { 22,     1,    26,     4,    -2,   -13,    26,    17,    14, },

    { -9,   -18,     3,   -20,   -27,   -32,   -11,    27,    13, },

   { -17,    33,    -7,    19,   -32,    13,   -31,    -2,   -24, },

   { -31,    27,   -31,   -29,    15,     2,    29,   -15,    33, },

   { -18,   -23,    15,    28,     0,    30,    -4,    12,   -32, },

   {  -3,    34,    27,   -25,   -18,    26,     1,    34,    26, },

   { -21,   -31,   -10,   -13,   -30,   -17,   -12,   -26,    31, },

    { 23,   -31,   -19,    21,   -17,   -10,     2,   -23,    23, },

    { -3,     6,     0,    -3,   -32,     0,   -10,   -25,    14, },

   { -19,     9,    14,   -27,    20,    15,    -5,   -27,    18, },

    { 11,    -6,    24,     7,   -17,    26,    20,   -31,   -25, },

   { -25,     4,   -16,    30,    33,    23,    -4,    -4,    23, },

 

    };

 

    Author_Institute::MatrixFlipC FlipperObj(*matrix,27,9);

    char strResult[1024];

 

    FlipperObj.Execute();

    FlipperObj.Grade(strResult);

 

    printf(strResult);

 

    return 0;

}