Friday, April 29, 2011

WPF - DispatcherUnhandledException does not seem to work

Hi

I started a new WPF project in VS2008 and then add code to trap DispatcherUnhandledException.

Then I add throw an exception to Window1 but the error is not trapped by the handler.

Why?????

   public App()
    {
        this.DispatcherUnhandledException += new DispatcherUnhandledExceptionEventHandler(App_DispatcherUnhandledException);

    }

    void App_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
    {
        System.Windows.MessageBox.Show(string.Format("An error occured: {0}", e.Exception.Message), "Error");
        e.Handled = true;
    }

 void Window1_MouseDown(object sender, MouseButtonEventArgs e)
    {
        throw new NotImplementedException();
    }

Malcolm

From stackoverflow
  • For those interested

    It seems that the IDE is still breaking on exceptions and that if you click continue in the IDE it call the error handler.

  • This can happen because of the way you have the debugger handling exceptions -- Debug/Exceptions... should allow you to configure exactly how you want it handled.

  • Were you every able to resolve this? I've found the same issue.

  • At first, even outside the debugging environment, my handler does not seem to be triggering.....then I realized I forget to set e.Handled = true.

    In truth it was working but because e.Handled was still false the standard exception handler still kicked in and did its thing.

    Once I set e.Handled = true, then everything was hunky dory. So if its not working for you, make sure you've done that step.

  • Look at following msdn link http://msdn.microsoft.com/en-us/library/system.windows.application.dispatcherunhandledexception.aspx Following is Relevant here

    If an exception is not handled on either a background user interface (UI) thread (a thread with its own Dispatcher) or a background worker thread (a thread without a Dispatcher), the exception is not forwarded to the main UI thread. Consequently, DispatcherUnhandledException is not raised. In these circumstances, you will need to write code to do the following:

    1. Handle exceptions on the background thread.
    2. Dispatch those exceptions to the main UI thread.
    3. Rethrow them on the main UI thread without handling them to allow DispatcherUnhandledException to be raised.

Integrating Instant Messaging into an ASP.NET application

I was thinking about integrating some instant messaging function into an existing ASP.NET web application, e.g:

  • the web application can display the online-status of users (are they currently logged in with their IM client)
  • users can send messages from the web application to the IM client of other users
  • users can initiate a IM chat from the web application (without having to know the other user's IM identification beforehand)

Does anyone know about some existing libraries, sample applications or other resources that might help implementing such a feature?

Thanks a lot for sharing your knowledge.

From stackoverflow
  • You might want to look at the .net implementation of jabber:

    http://code.google.com/p/jabber-net/

  • You should try Jabber. Demo client avaiable here.

    There is an architectural overview, the main concept looks like this:

    alt text

    And some citation from the site:

    • 1. Goal Create an multi-service instant messaging AJAX-based web application with internal accounting.
    • 2. Main problem We need to connect to IM servers from HTTP client (browser). HTTP is a stateless protocol. This means that, theoretically, each HTTP request is being proccessed by separate http daemon proccess. Once request proccessed (data sent to client), server fogets about client. All IM services protocols are stateful. When client connects to IM server, socket connection being created and connection much remain open for succesfull communication.
  • There's a list on the ASP.net site.

    http://www.asp.net/Community/Control-gallery/browse.aspx?category=54

'comparison is always true due to limited range of data type' warning in C?

I have the following code

//Point.h
#define WIDTH 8
#define HEIGHT 8

typedef struct Point
{
  char x;
  char y;
} Point;

//Board.c
#include <stdbool.h>

// Some other functions that we don't care about... 

bool inBounds(Point * p)
{
  return p->x >= 0
    && p->x <= WIDTH
    && p->y >= 0
    && p->y <= HEIGHT;
}

When I compile this (ppu-gcc 4.1.1), I get the following warning

warning: comparison is always true due to limited range of data type

even though the range of char is -127 to 127 and WIDTH is 8, which is well inside the range of a char. I've already tried an explicit cast of WIDTH to a char, but still got the error.

From stackoverflow
  • Are you sure that char is signed? Try declaring the fields explictly as signed char and see what you get.

    Wedge : Yeah, I believe char is unsigned, so it's the comparison to 0 that will always be true.
    Dan Breslau : It's compiler-dependent. If you *need* char to be signed, you need to declare it as signed.
    Paul Wicks : Yeah this, fixes it. However, the lines that I was getting an error on were the lines where I was making a comparison against positive numbers (the WIDTH and HEIGHT). Strange.
    Dan Breslau : The compiler must be using 0-based line numbers :-) Actually, you may have a different problem there: Using <= and >= means that you have an effective WIDTH and HEIGHT range of 9, not 8. If that's what you want, perhaps you should use different macro names (MAX_X and MAX_Y?)
  • Hummm... isn't your char unsigned by default? In that case the range would be 0-255, which means your >=0 comparison would be always true

    ephemient : It's platform- and compiler-dependent. For example, GCC on x86 Linux uses signed char by default, while GCC on PowerPC Linux uses unsigned char by default.
  • I guess x >= 0 causes the warning because char might be implemented as unsigned char.

  • The char type may be signed or unsigned. It depends on your compiler vendor's choice. There might even be a compiler option available. Evidently, char is unsigned for you, so it's always greater than or equal to zero, and thus the compiler warns you.

    You're using char here to represent "a numeric type that takes up minimal memory." In that case, I recommend explicitly using signed char or unsigned char. (Each is distinct from plain char, despite char having to be either signed or unsigned.) Reserve char for when you're holding character data. For numeric data, use one of the other two types.

    dfa : this is confirmed by: http://www.network-theory.co.uk/docs/gccintro/gccintro_71.html

WPF style to perform translation after scaling

Hi all,

I've got a button style that I've been developing in WPF, as stated in this question. Another thing I'd like to do with this style is to have the button shrink just a little bit, to make it appear like it's getting clicked as it's getting clicked. Right now, the transform code looks like:

<Trigger Property="IsPressed" Value="True">
    <Setter Property="RenderTransform">
        <Setter.Value>
            <TransformGroup>
                <ScaleTransform ScaleX="0.98" ScaleY="0.98"/>
                <SkewTransform AngleX="0" AngleY="0"/>
                <RotateTransform Angle="0"/>
                <TranslateTransform X="0" Y="0"/>
            </TransformGroup>
        </Setter.Value>
    </Setter>
    <Setter Property="Button.BitmapEffect">
        <Setter.Value>
            <OuterGlowBitmapEffect GlowColor="Green" GlowSize="10"></OuterGlowBitmapEffect>
        </Setter.Value>                                
    </Setter>
</Trigger>

So, that's exciting. Problem is, the scale transform scales the image associated with the button to the upper left of the area where the button is (ie, it's rescaling to the 0,0 coordinate of the button, or at least, that's what I assume).

My understanding of the TranslateTransform is that it's in pixel coordinates, not in coordinates relative to the size of the object. If I put in a TranslateTransform of 0.01, 0.01, then it will move the button by 0.01 pixels in both x and y, rather than 0.01*sizeof(imagedimension) pixels in each direction. How can I get that relative transform, and how can I have it happen as a style, ie, so I don't have to do different math for every different button size I've got?

From stackoverflow
  • You need to set the RenderTransformOrigin on the Button to 0.5 by 0.5:

    RenderTransformOrigin="0.5,0.5"
    
    Josh G : You can also set the CenterX and CenterY values on the ScaleTransform if you want, but that doesn't work for buttons of all sizes.
    mmr : thanks! I had to give the answer to gcores, because he gave me the full code to fire the fruiton torpedoes and make it go that way.
    Josh G : That's fine... I thought about putting the origin in the setter, but thought that you may not want it there. If you want the transform origin to affect ALL transforms, not just the triggered one, you will need to set the origin on the button itself.
  • To scale through the center you can add in your trigger:

    <Setter Property="RenderTransformOrigin" Value=".5,.5"/>
    
    mmr : that got it, awesome!

Reloading a JTree during runtime

I create a JTree and model for it out in a class separate to the GUI class. The data for the JTree is extracted from a file.

Now in the GUI class the user can add files from the file system to an AWT list. After the user clicks on a file in the list I want the JTree to update. The variable name for the JTree is schemaTree.

I have the following code for the when an item in the list is selected:

private void schemaListItemStateChanged(java.awt.event.ItemEvent evt) {
        int selection = schemaList.getSelectedIndex();
        File selectedFile = schemas.get(selection);
        long fileSize = selectedFile.length();
        fileInfoLabel.setText("Size: " + fileSize + " bytes");

        schemaParser = new XSDParser(selectedFile.getAbsolutePath());

        TreeModel model = schemaParser.generateTreeModel();
        schemaTree.setModel(model);
}

I've updated the code to correspond to the accepted answer. The JTree now updates correctly based on which file I select in the list.

From stackoverflow
  • From the Component.add API docs.

    Note: If a component has been added to a container that has been displayed, validate must be called on that container to display the new component. If multiple components are being added, you can improve efficiency by calling validate only once, after all the components have been added.

    You have called repaint and validate on a component that is not displayed, which will not be effective. You need to call those methods on the mainPanel after the add. Also revalidate tends to be better than validate as it effectively coalesces.

    Patrick Kiernan : I've tried revalidate on the mainPanel however the JTree still doesn't update. I'll modify the code in the original question to what I have now
    Tom Hawtin - tackline : It looks like you've now not added the new tree to the panel.
    Patrick Kiernan : Works now .. I now don't remove the JTree at all, I just wasn't updating the model in the correct place. Thanks for your reply
  • I not sure that I'm understanding your question, but I'll try...

    The right thing to do should be, IMHO:

    • get the file
    • create a new TreeModel from your file
    • give the model to the JTree

    In pseudocode, it would look like that:

    File newContent = getSelectedByUser(...);
    TreeModel newModel = new MyFileBasedTreeModel(newContent);
    //this next part must be done in the EventDispatcherThread
    myTree.setModel(newModel);
    

    then the JTree would be updated, without any call to repaint, etc.

    Hope it helps

    Patrick Kiernan : Very good, I've now modified the method generateTree() to return the model instead of the tree and renamed the method generateTreeModel(). The tree now updates correctly based on which file I click in the list. Thanks!

How to test asp.net membership, profile, roles with VS Test Framework?

Hey all,

We're getting some errors, if we try to test something with the asp.net membership framework. It seems that it can't instantiate the asp.net membership environment and so, it can't access all the profiles, users and so on.

Has anybody seen a similar problem? Or is it working for someone?

Cheers, Steve

From stackoverflow
  • The test framework is looking at the test project's web.config file which likely doesn't have the right configuration. You should really write interfaces around the authentication/membership providers and write some dummy implementations to test with.

    derSteve : Hi Daniel, The test project usually doesn't have a web.config to put the configuration stuff in there. Cheers, Steve
  • If you are depending on external resources such as your database and the configuration files (used when using the ASP.NET membership) you aren't writing very effective unit tests. You will have to keep everything in sync including the data in the database. This because a maintenance nightmare.

    If you want to test this way, I recommend setting up your configuration to have membership (you can grab this from your application). You then will also want to set up a test database to connect to. It needs to be populated with fake data, so you'll need scripts to make sure the data is consistent.

    I would however recommend that you take the approach of doing more proper unit tests. When we refer to a "unit test" we mean testing a very small piece of code at a time. This code should not depend on anything else, so what you need to do is use interfaces and use fakes, stubs, or mocks so that your tests scope is enclosed to a single unit of code.

    If you want to go this route I highly recommend reading Working Effectively with Legacy Code. There are also plenty of other books and resources which talk about how to find seams and decouple your code so you're able to test it. Once you get the hang of unit testing you'll be glad you looked into this.

    derSteve : Hi Benrick, Thanks for the good advice. In my case I have a fairly complicated Use Case which involves the membership roles and users. In order to test that, I would realy like to test the whole use case, i.e. test the membership related stuff as well. I'll try to setup the membership in the test project as well. Cheers, Steve
  • Going on from Benrick's answer - I recommend you take a look at the ASP.NET MVC project - this has examples of the interfaces and wrappers you would need to have to properly unit test your code.

    As the comments in the AccountController.cs file state:

    The FormsAuthentication type is sealed and contains static members, so it is difficult to unit test code that calls its members. The interface and helper class below demonstrate how to create an abstract wrapper around such a type in order to make the AccountController code unit testable.

What is tab #13119 on my VS 2008 toolbox?

I only noticed this last night, as I have not used the toolbox on this particular project for some time. Suddenly, all my Telerik controls, previously on their own tab, were missing, and this mysterious, empty tab #13119 was there. I added a new tab for Telerik and added all the controls, but the Telerik tab remained invisible, although the controls are still ticked to indicate that they are in the toolbox.

From stackoverflow
  • Maybe this helps: Toolbox Missing Controls

  • It seems to be a bug.

    Citation from here:

    1. Make sure you can see all of the folders on your box. We are heading to the realm of hidden files: (Under Tools --> Folder Options)
    2. Close Visual Studio if it is open.
    3. Go Here: C:\Users\YOUR_USER_NAME\AppData\Local\Microsoft\VisualStudio\9.0\
    4. Backup the following files in a temp folder for saftey and delete the originals. (toolboxIndex_reset.tbd ,toolboxIndex.tbd ,toolbox_reset.tbd ,toolbox.tbd)
    5. Restart Visual Studio and the files will be recreated. It'll take a few seconds for the toolbox to repopulate.
    Benjol : You probably also need `Tools>Options>Windows Form Designer>AutoToolboxPopulate` set to true (which is the default value)
    Ant : The location of the files on XP is C:\Documents and Settings\USER_NAME\Local Settings\Application Data\Microsoft\VisualStudio\9.0
  • I get this now and again. Try right clicking the Toolbox and select 'Reset Toolbox'

    romkyns : 'Reset Toolbox' doesn't help here.

Fluent NHibernate Component Mapping - String DB Value passed to a factory yields the required object type

Table:

CREATE TABLE Instrument
(   Id    INT IDENTITY
,   Name   VARCHAR(50)
,   Tenor   VARCHAR(10)
//...

Model:

    interface ITenor
    {
        int Length { get; }
        string ToString();
    }

    class DayTenor : ITenor
    {
        public int Length
        {
            get { return 1; }
        }

        public override string ToString()
        {
            return "DAY";
        }
    }

    class MonthTenor : ITenor
    {
        public int Length
        {
            get { return 30; }
        }

        public override string ToString()
        {
            return "MONTH";
        }
    }

    class TenorFactory
    {
        ITenor GetTenor(string tenorString)
        {
            switch (tenorString)
            {
                case "DAY":
                    return new DayTenor();
                    break;
                case "MONTH":
                    return new MonthTenor();
                    break;
                default:
                    throw new NotImplementedException(string.Format( "Tenor {0} is not implemented", tenorString ));
            }
        }
    }

    class Instrument
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public ITenor Tenor { get; set; }
    }

    class InstrumentMap : ClassMap<Instrument>
    {
        public InstrumentMap()
        {
            WithTable( "Instrument" );
            Id( x => x.Id );
            Map( x => x.Name );
            Map( x => x.Tenor );
        }
    }

This is a great simplification of the problem domain.

The line Map( x => x.Tenor ); will clearly not work, as you cannot implicitly convert the VARCHAR column to an ITenor type. Is there a way I can map to automatically use the Factory to get the ITenor it requires for the specified string in the DB, and use the ToString() from the ITenor class to revert back to the DB?

If not, what refactoring would you recommend to make this feasable? Many thanks

From stackoverflow
  • A possible solution is to keep the string as it is in the database and map it to a TenorString property. Then add another typed property that simply does the transformation between the string and the typed value:

    class Instrument
    {
        public string TenorString { get; set; }
        public ITenor Tenor { 
            get { return GetTenor(this.TenorString); } 
            set { TenorString = value.ToString() }; 
        }
    }
    

    TenorString is mapped normaly but Tenor property is not mapped at all:

    Map( x => x.TenorString );
    

    Off course the Tenor get property can return a cached value that is reset when TenorString changes to avoid the factory call every time.

    Stuart Childs : This is probably the easiest method. You could also create a custom type by implementing IUserType: http://www.hibernate.org/hib_docs/nhibernate/1.2/reference/en/html/mapping.html#mapping-types-custom
    Hendrik : Many thanks Aleris and Stuart. I'll rather implement IUserType as I do not want to hack the Instrument class, but it is a very simple workaround.

What are some ways you can manage large-scale assembly language projects?

At my university the Assembly Programming (x86 and MIPs) class is drawing to an end.

I've thoroughly enjoyed my work in assembly and I would really like to continue working with it. You would think that having to do everything myself would be a drag but I have found that there is a level of transparency that I don't get with higher level languages.

Things generally work how I would expect them to, because I executed the machine code for them to happen. There is no magic.

However, at school the longest assembly program I wrote was maybe 2-3 pages in length.

I recently read about Roller Coaster tycoon being written by a single developer, in assembly.
alt text

I have difficulty imagining how someone could maintain such a large project in assembly.

Right now I'm struggling making the leap from 2-3 page assembly programs to something of a little more scale. Even on my Ti-83 calculator people have written Mario/Zelda clones in assembly that must be tremendously complex!

There have to be some nicer tools, IDEs, and methods for managing large x86 assembly projects that make it at least somewhat maintainable.

What are they?

From stackoverflow
  • I know people that work with assembler (not intel). They have build an extensive macro library so they can use it almost as if it is a high level language.

    To create something lika a macro library, start simple. By grouping often used constructions in a single macro. Eventually wou will be able to create more complex functionality.

  • Not really the answer to your question, but In many real world scenarios, applications are written in a Higher language using the idioms common to that language, and only use a bit of assembly language where performance or hardware needs require. This is probably the only sensible approach for real projects, because assembly language just isn't as productive as other languages, in terms of getting the computer to do more for each hour spent programming it.

    That being said, All of the tools and techniques for managing a project in any other language apply equally to assembly language. Source Control, TDD, Project specifications, meaningful names for identifiers, Separation of concerns, object oriented design patterns (you can have object oriented design without an object oriented language) all apply equally to assembly language as it does to C# or PHP

    Davy8 : "meaningful names for identifiers" Unless my understanding of what assembly language is is way off (which it very well could be) don't you just refer to memory locations and cpu registers directly? How do you get meaningful names out of that?
    Bastien Léonard : It's rare to use memory addresses. Generally the assembler binds them to variables.
    Davy8 : ah, I wasn't aware you could give variable names in assembly
    TokenMacGuy : Well, you can't really do much about 'variable' names, but in assembly, there's much 'goto'. Use labels with meaningful names.
    Zifre : In assembly, there are no local variable names, unless you use a macro, but global variable are usually named with a label (like for gotos).
    Bastien Léonard : With FASM I use somewhat advanced pseudoinstructions to automate a bit local variables definitions (and still understand how it works). I can post an example if someone is interested.
  • I always did just like is done in high-level languages. Write it in modules that are linked together to form the runtime.

  • The only modern project entirely written in assembly that I know if is FASM (my favorite assembler).

    Some assemblers support high-level constructs, and if the macro engine is good, you can write your own. I personally find this useless; if I want high-level constructs and to understand what I do, I use C or C++. (I don't think they are good languages for managing big projects, though).

    I just use assembly when needed, or for learning.

    If you want to write a project in assembly, keep in mind that:

    • There probably won't be many people who want to help you with your project, even they find it interesting. Few people like assembly and your code must be very well commented if you expect someone to understand it.
    • Assembly isn't portable. Even for shifting from 32-bit PC to 64-bit you will basically have to rewrite everything.
    • The "assembly is faster" argument doesn't hold anymore.
  • Here is a white paper by Peter Langston describing the tools and reasoning they used for writing Ballblazer and Rescue from Fractalus, which covers the organization etc.

  • Large scale assembly programmes are managed just like any other programme - well partitioned functional blocks with clear interfaces. Since you are working in assembly, your interfaces will be limited to things on the register file or stack. It is ultimately about having a good design plan ahead of actually implementation. You need to be crystal clear about what to write and how to write it.

    That being said, if you like assembly, there is another way to be able to indulge in your passion without actually writing assembly code - you can write in C or C++ and see how code compiles to assembly. Then, write the same thing in a different way and understand how that changes the assembly. As a result, you will soon be able to think like a compiler and write highly optimal code.

    Either way, knowing how things work in assembly will ultimately make you a better programmer.

  • Macros, functions, and libraries. It takes years to develop your own from scratch, so search for x86 assembler resources and lean on others - there are many people still doing active assembly development for the PC.

    One active member of the assembly community is Steve Gibson, he has a whole bunch of links to good resources for assembly programming here:

    http://www.grc.com/smgassembly.htm

  • On top of what has already been mentioned, I should mention literate programming; I wrote an application that was on the order of 20KLOC of ARM assembly (not huge, but not insignificant, either), and I found structuring the code with noweb to be extremely helpful.

    This allowed me to break the code into small conceptual pieces, even when several pieces actually had to be combined together/unrolled/et cetera for performance reasons. It also made it much easier for other programmers to understand what I had written, particularly the reasons why I made certain subtle decisions (for example, deciding which operand should go first in a multiply based on expected size of the operands).

Best algorithm for this interview problem

Given a NxN matrix with 0s and 1s. Set every row that contains a 0 to all 0s and set every column that contains a 0 to all 0s.

For example

1 0 1 1 0
0 1 1 1 0
1 1 1 1 1
1 0 1 1 1
1 1 1 1 1

results in

0 0 0 0 0
0 0 0 0 0
0 0 1 1 0
0 0 0 0 0
0 0 1 1 0

A Microsoft Engineer told me that there is a solution that involves no extra memory, just two boolean variables and one pass, so I'm looking for that answer.

BTW, imagine it is a bit matrix, therefore just 1s and 0s are allow to be in the matrix.

From stackoverflow
  • I can do it with two integer variables and two passes (up to 32 rows and columns...)

    bool matrix[5][5] = 
    { 
     {1, 0, 1, 1, 0},
     {0, 1, 1, 1, 0},
     {1, 1, 1, 1, 1},
     {1, 0, 1, 1, 1},
     {1, 1, 1, 1, 1}
    };
    
    int CompleteRows = ~0;
    int CompleteCols = ~0;
    
    // Find the first 0
    for (int row = 0; row < 5; ++row)
    {
     for (int col = 0; col < 5; ++col)
     {
      CompleteRows &= ~(!matrix[row][col] << row);
      CompleteCols &= ~(!matrix[row][col] << col);
     }
    }
    
    for (int row = 0; row < 5; ++row)
     for (int col = 0; col < 5; ++col)
      matrix[row][col] = (CompleteRows & (1 << row)) && (CompleteCols & (1 << col));
    
    sker : Is this C#? What does the ~ mean?
    Eclipse : It's C++. `~` inverts all the bits in a variable. 0x00000000 becomes 0x00000000. I basically start out with the all ones, and clear the bit for a row/column when I find a 0. CompleteCols has bits 2 and 3 set, and CompleteRows has bits 2 and 4 set (0 based).
    Eclipse : Then you just set the bits in the matrix corresponding to a one in both CompleteCols and CompleteRows.
    Eclipse : Sorry - 0x00000000 becomes 0xffffffff - too bad you can't edit comments..
  • You can calculate the new value of each cell by multiplying all values of the matrix' column and row of that cell.

    edit: I would not do that destructively, just return a new array.

    jaircazarin-old-account : I'm looking for an answer that uses no extra memory.
    Svante : You mean, "in place"?
  • This cannot be done in one pass since a single bit has an effect on bits before and after it in any ordering. IOW Whatever order you traverse the array in, you may later come accross a 0 which means you have to go back and change a previous 1 to a 0.

    Update

    People seem to think that by restricting N to some fixed value (say 8) you can solve this is one pass. Well that's a) missing the point and b) not the original question. I wouldn't post a question on sorting and expect an answer which started "assuming you only want to sort 8 things...".

    That said, it's a reasonable approach if you know that N is in fact restricted to 8. My answer above answers the original question which has no such retriction.

    ceretullis : It cannot be done in one pass without additional memory. It can be done in one pass if there there is another NxN matrix to store results in. Likewise, with some bit twiddles and two passes it can be done without additional memory.
    Lasse V. Karlsen : You still cannot do it in one pass even if you use a temporary matrix, or else there is something weird I'm not getting here. You need one pass to deduce the row/column information, and one to set everything.
    Daniel Papasian : I solved this problem by recognizing that there is only one unique non-zero value possible per row, and just assigning it by reference.
    Draemon : @ceretullis, lassevk: I still think it can't be done in one pass. Passes over that second matrix would have to count - otherwise you could just copy the matrix in one pass, and work with the copy however you wanted. @Daniel Papasian: Your solution doesn't scale where N > #bits in int/long/whatever
    Daniel Papasian : Draemon, the technique scales fine, it's just math - you can either build hardware that does it, or you can use software techniques to manipulate numbers larger than your word size. Neither violates the constraints of the problem, IMHO
    Draemon : such software techniques would effectively increase the number of passes.
    Adam : Best cast scenario I can figure is O( 2*(N^2) )
    Tony Lambert : my solution proves most of the above to be just plain wrong! as for this answer getting 8 points well!
    Draemon : @Anthony: That's a straw-man argument. You've solved a different problem. My answer is absolutely correct - you cannot solve the OP's question in one pass. You have solved a different problem where N is restricted to 8. I can propose an O(1) algorithm if N=1. Make sure you answer the actual question
    recursive : Adam: O(2*N^2) = O(N^2) Constant coefficients don't effect complexity class.
  • Ok, so I'm tired as it's 3AM here, but I have a first try inplace with exactly 2 passes on each number in the matrix, so in O(NxN) and it is linear in the size of the matrix.

    I use 1rst column and first row as markers to know where are rows/cols with only 1's. Then, there are 2 variables l and c to remember if 1rst row/column are all 1's also. So the first pass sets the markers and resets the rest to 0's.

    The second pass sets 1 in places where rows and cols where marked to be 1, and resets 1st line/col depending on l and c.

    I doubt strongly that I can be done in 1 pass as squares in the beginning depend on squares in the end. Maybe my 2nd pass can be made more efficient...

    import pprint
    
    m = [[1, 0, 1, 1, 0],
         [0, 1, 1, 1, 0],
         [1, 1, 1, 1, 1],
         [1, 0, 1, 1, 1],
         [1, 1, 1, 1, 1]]
    
    
    
    N = len(m)
    
    ### pass 1
    
    # 1 rst line/column
    c = 1
    for i in range(N):
        c &= m[i][0]
    
    l = 1
    for i in range(1,N):
        l &= m[0][i]
    
    
    # other line/cols
    # use line1, col1 to keep only those with 1
    for i in range(1,N):
        for j in range(1,N):
            if m[i][j] == 0:
                m[0][j] = 0
                m[i][0] = 0
            else:
                m[i][j] = 0
    
    ### pass 2
    
    # if line1 and col1 are ones: it is 1
    for i in range(1,N):
        for j in range(1,N):
            if m[i][0] & m[0][j]:
                m[i][j] = 1
    
    # 1rst row and col: reset if 0
    if l == 0:
        for i in range(N):
            m [i][0] = 0
    
    if c == 0:
        for j in range(1,N):
            m [0][j] = 0
    
    
    pprint.pprint(m)
    
    Steve Jessop : +1 for correct answer (IMO), shame I can't give you another +1 for working out the correct question :-)
    Adam : One problem here is if n > sizeof( c ) then it breaks down. To expand this to work in the general case of n, you would need to dynamically size your bit field which I think would violate the constraint given by the problem.
    Steve Jessop : No, c isn't a bitfield, it's just a bool. The &= isn't a bitwise op (well, it is, but on a 1-bit value), it's there because c tells you whether the first column is all 1 (true) or contains a 0 (false).
    paperhorse : It fails if the top row is [0,1,1,1...] My bug fix is to initialize l to m[0][0] rather than 1
    Kristof Neirynck : indeed l = 1 for i in range(1,N): l &= m[0][i] should be l = 1 for i in range(N): l &= m[0][i]
    jaircazarin-old-account : BTW, I believe that the condition in the second pass should be something like: if m[i][0] | m[0][j]:
  • I don't think it's doable. When you're on the first square and its value is 1, you have no way of knowing what the values of the other squares in the same row and column are. So you have to check those and if there's a zero, return to the first square and change its value to zero. I'll recommend doing it in two passes - the first pass gathers information about which rows and columns must be zeroed out (the information is stored in an array, so we're using some extra memory). The second pass changes the values. I know that's not the solution you're looking for, but I think it's a practical one. The constraints given by you render the problem unsolvable.

    Piotr Lesnicki : I have nearly the same solution (see below) without additional arrays. and it is linear time (but 2 passes though)
    Boyan : @Piotr: Yes, the second pass seems unavoidable. The introduction of arrays to store the rows and columns information that I've proposed makes the algorithm more straight-forward and a little bit faster as there's less checking and value-changing. It's a trade-off between storage and efficiency.
  • While impossible given the constraints, the most space efficient way to do it is by traversing the matrix in an overlaping, alternating row/column fashion, which would make a pattern similar to laying bricks in a zig-zag fashion:

    -----
    |----
    ||---
    |||--
    ||||-
    

    Using this, you would go in each row/column, as indicated, and if you encounter a 0 at any time, set a boolean variable, and re-walk that row/column, setting the entries to 0 as you go.

    This will require no extra memory, and will only use one boolean variable. Unfortunately, if the "far" edge is set to all be 0, that is the worst case and you walk the whole array twice.

    Steve Jessop : I could be wrong, but are you sure this works? When you're doing the 3rd column, say, how do you know whether the value at the top of it, in the first row, was a 1 or a 0 before you processed the first row?
    Dave Sherohman : You don't know, but you also don't need to. If it was a 0, the whole column needs to be 0. If the value on the previous row is 1, you know that all rows above it are 1 (and always have been).
  • create a result matrix and set all the values to 1. go through the data matrix as soon as a 0 is encountered, set the result matrix row column to 0

    At the end of the first pass, the result matrix will have the correct answer.

    Looks pretty simple. Is there a trick I am missing? Are you not allowed to use a result set?

    EDIT:

    Looks like a F# function, but that is cheating a bit since even though you are doing a single pass, the function can be recursive.

    It looks like the interviewer is trying to figure out if you know functional programming.

    cdeszaq : Using a result set would be taking extra memory.
    Svante : Functional programming would not modify the original array in place.
  • Based on the result the algorithm is a complex way to say, find all positions where the full row and column are all 1 ?

    so any 0 makes its row and column 0 on the target matrix.

    cdeszaq : This is a correct re-statement of the problem, yes
  • So my idea is to use the values in the last row/column as a flag to indicate whether all of the values in the corresponding column/row are 1s.

    Using a Zig Zag scan through the entire matrix EXCEPT the final row/column. At each element, you set the value in the final row/column as to the logical AND of itself with the value in the current element. In other words, if you hit a 0, the final row/column will be set to 0. If you it a 1, the value in the final row/column will be 1 only if it was 1 already. In any case set the current element to 0.

    When you've finished, your final row/column should have 1s iff the corresponding column/row was filled with 1s.

    Do a linear scan through the final row and column and looking for 1s. Set 1s in the corresponding elements in body of the matrix where the final row and column are both 1s.

    Coding it will be tricky to avoid off-by-one errors etc but it should work in one pass.

    Dave Sherohman : Very nice... I was thinking on the same lines, but missed using the final row/column to store that information, so I was stuck with extra memory for a pair of Nx1 arrays.
    Adam Rosenfield : That looks like two passes to me - one pass is the zig-zag scan, the second is the "Set 1s in the corresponding elements in body of the matrix where the final row and column are both 1s".
    Alastair : The zig-zag scan (which as someone pointed out to me isn't strictly necessary) traverses all BUT the final row/column. So scanning the final/row column does not duplicate elements previously scanned. Hence one pass. In other words it's O(N^2) for an N*N matrix.
  • Nice challange. This solution sort of uses just two booleans created on the stack, but the booleans are created several times on the stack since the function is recursive.

    typedef unsigned short     WORD;
    typedef unsigned char      BOOL;
    #define true  1
    #define false 0
    BYTE buffer[5][5] = {
    1, 0, 1, 1, 0,
    0, 1, 1, 1, 0,
    1, 1, 1, 1, 1,
    1, 0, 1, 1, 1,
    1, 1, 1, 1, 1
    };
    int scan_to_end(BOOL *h,BOOL *w,WORD N,WORD pos_N)
    {
        WORD i;
        for(i=0;i<N;i++)
        {
         if(!buffer[i][pos_N])
          *h=false;
         if(!buffer[pos_N][i])
          *w=false;
        }
        return 0;
    }
    int set_line(BOOL h,BOOL w,WORD N,WORD pos_N)
    {
        WORD i;
        if(!h)
         for(i=0;i<N;i++)
          buffer[i][pos_N] = false;
        if(!w)
         for(i=0;i<N;i++)
          buffer[pos_N][i] = false;
        return 0;
    }
    int scan(int N,int pos_N)
    {
        BOOL h = true;
        BOOL w = true;
        if(pos_N == N)
         return 0;
        // Do single scan
        scan_to_end(&h,&w,N,pos_N);
        // Scan all recursive before changeing data
        scan(N,pos_N+1);
        // Set the result of the scan
        set_line(h,w,N,pos_N);
        return 0;
    }
    int main(void)
    {
        printf("Old matrix\n");
        printf( "%d,%d,%d,%d,%d \n", (WORD)buffer[0][0],(WORD)buffer[0][1],(WORD)buffer[0][2],(WORD)buffer[0][3],(WORD)buffer[0][4]);
        printf( "%d,%d,%d,%d,%d \n", (WORD)buffer[1][0],(WORD)buffer[1][1],(WORD)buffer[1][2],(WORD)buffer[1][3],(WORD)buffer[1][4]);
        printf( "%d,%d,%d,%d,%d \n", (WORD)buffer[2][0],(WORD)buffer[2][1],(WORD)buffer[2][2],(WORD)buffer[2][3],(WORD)buffer[2][4]);
        printf( "%d,%d,%d,%d,%d \n", (WORD)buffer[3][0],(WORD)buffer[3][1],(WORD)buffer[3][2],(WORD)buffer[3][3],(WORD)buffer[3][4]);
        printf( "%d,%d,%d,%d,%d \n", (WORD)buffer[4][0],(WORD)buffer[4][1],(WORD)buffer[4][2],(WORD)buffer[4][3],(WORD)buffer[4][4]);
        scan(5,0);
        printf("New matrix\n");
        printf( "%d,%d,%d,%d,%d \n", (WORD)buffer[0][0],(WORD)buffer[0][1],(WORD)buffer[0][2],(WORD)buffer[0][3],(WORD)buffer[0][4]);
        printf( "%d,%d,%d,%d,%d \n", (WORD)buffer[1][0],(WORD)buffer[1][1],(WORD)buffer[1][2],(WORD)buffer[1][3],(WORD)buffer[1][4]);
        printf( "%d,%d,%d,%d,%d \n", (WORD)buffer[2][0],(WORD)buffer[2][1],(WORD)buffer[2][2],(WORD)buffer[2][3],(WORD)buffer[2][4]);
        printf( "%d,%d,%d,%d,%d \n", (WORD)buffer[3][0],(WORD)buffer[3][1],(WORD)buffer[3][2],(WORD)buffer[3][3],(WORD)buffer[3][4]);
        printf( "%d,%d,%d,%d,%d \n", (WORD)buffer[4][0],(WORD)buffer[4][1],(WORD)buffer[4][2],(WORD)buffer[4][3],(WORD)buffer[4][4]);
        system( "pause" );
        return 0;
    }
    

    This scans in a pattern like:

    s,s,s,s,s
    s,0,0,0,0
    s,0,0,0,0
    s,0,0,0,0
    s,0,0,0,0
    


    0,s,0,0,0
    s,s,s,s,s
    0,s,0,0,0
    0,s,0,0,0
    0,s,0,0,0
    

    and so on

    And then changeing the values in this pattern on return on each of the scan functions. (Bottom up):

    0,0,0,0,c
    0,0,0,0,c
    0,0,0,0,c
    0,0,0,0,c
    c,c,c,c,c
    


    0,0,0,c,0
    0,0,0,c,0
    0,0,0,c,0
    c,c,c,c,c
    0,0,0,c,0
    

    and so on

    csl : I would guess this isn't correct, since you still use up many more than two booleans on your stack.
    eaanon01 : As I sad sort of two booleans. This is the closest I can think of to the specs he provided. I would love to see an actual solution here. If it is fesable.
    Adam : I don't think the requirements are referring to growing the stack. I think this is a perfectly valid solution.
    eaanon01 : That is my thougt as well. But I cant be sure until somone else posts a better solution. At least my solution is compilable and can be verified by anyone. :) ... I am not to found of psudo code for practical problems. Thnx
  • Another solution that takes two passes, is to accumulate ANDs horizontally and vertically:

    1 0 1 1 0 | 0
    0 1 1 1 0 | 0
    1 1 1 1 1 | 1
    1 0 1 1 1 | 0
    1 1 1 1 1 | 1
    ----------+
    0 0 1 1 0
    

    I thought I could design such an algorithm using parity bits, Hamming codes or dynamic programming, possibly using those two booleans as a 2-bit number, but I've had no success yet.

    Can you please re-check the problem statement with your engineer and let us know? If there is indeed a solution, I want to keep chipping away at the problem.

  • Keep a single variable to keep track of what all of the rows ANDed together are.

    If a row is -1 (all 1s), then make the next row a reference to that variable

    If a row is anything but, it's a 0. You can do everything in one pass. Psuedo-code:

    foreach (my $row) rows {
         $andproduct = $andproduct & $row;
         if($row != -1) {
            zero out the row
         }  else {
            replace row with a reference to andproduct
         }
    }
    

    That should do it, in a single pass -- but there is an assumption here that N is small enough for the CPU to do arithmetic on a single row, else you're going to need to loop over each row to determine if it's all 1s or not, I believe. But given you're asking about algos and not constraining my hardware, I would just start my answer with "Build a CPU that supports N-bit arithmetic..."

    Here's one example how it can be done in C. Note I argue that values and arr taken together represent the array, and p and numproduct are my iterator and AND product variables use to implement the problem. (I could have looped over arr with pointer arithmetic to validate my work, but once was enough!)

    int main() {
        int values[] = { -10, 14, -1, -9, -1 }; /* From the problem spec, converted to decimal for my sanity */
        int *arr[5] = { values, values+1, values+2, values+3, values+4 };
        int **p;
        int numproduct = 127;
    
        for(p = arr; p < arr+5; ++p) {
            numproduct = numproduct & **p;
            if(**p != -1) {
                **p = 0;
            } else {
                *p = &numproduct;
            }
        }
    
        /* Print our array, this loop is just for show */
        int i;
        for(i = 0; i < 5; ++i) {
            printf("%x\n",*arr[i]);
        }
        return 0;
    }
    

    This produces 0, 0, 6, 0, 6, which is the result for the given inputs.

    Or in PHP, if people think my stack games in C are cheating (I suggest to you that it's not, because I should be able to store the matrix whichever way I please):

    <?php
    
    $values = array(-10, 14, -1, -9, -1);
    $numproduct = 127;
    
    for($i = 0; $i < 5; ++$i) {
        $numproduct = $numproduct & $values[$i];
        if($values[$i] != -1) {
            $values[$i] = 0;
        } else {
            $values[$i] = &$numproduct;
        }
    }
    
    print_r($values);
    

    Am I missing something?

    Draemon : This doesn't work if N is bigger than the number of bits in an int/long/whatever so I don't think it counts.
    Eclipse : It also won't catch things if the 0's are at the bottom of the array (try it with values[] = { -1, -9, -1, 14, -10 }).
    Daniel Papasian : Draemon, I specify in my answer that without hardware constraints as part of the question, you start with "Build a CPU that supports N-bit arithmetic."
    Daniel Papasian : Josh, I don't follow. With either the C or PHP solution and the array you suggested, I get 6 0 6 0 0, which I believe is the correct answer.
    Draemon : @Daniel - You can't, because N isn't a constant. Besides "build a new computer with 1Mbit words is hardly a reasonable algorithmic step.
    Daniel Papasian : It may be a bit harder for a 32-bit machine to do binary operations on a 124-bit, 1M-bit, or N-bit number, but I assure you it's not impossible. To borrow the language of a textbook, I "leave that as an exercise for the reader" - and I don't think doing so violates the constraints on the problem
    Draemon : @Daniel: Sure, but it's no longer one step
    Daniel Papasian : Depends on your definition of pass. I believe it's a single pass if we don't need to read the same value multiple times. N-bit arithmetic, while more steps, would just be a more complicated "single pass" and not an additional pass - but I see where you're coming from.
  • I've got a solution here, it runs in a single pass, and does all processing "in place" with no extra memory (save for growing the stack).

    It uses recursion to delay the writing of zeros which of course would destroy the matrix for the other rows and cols:

    #include <iostream>
    
    /**
    * The idea with my algorithm is to delay the writing of zeros
    * till all rows and cols can be processed. I do this using
    * recursion:
    * 1) Enter Recursive Function:
    * 2) Check the row and col of this "corner" for zeros and store the results in bools
    * 3) Send recursive function to the next corner
    * 4) When the recursive function returns, use the data we stored in step 2
    *       to zero the the row and col conditionally
    *
    * The corners I talk about are just how I ensure I hit all the row's a cols,
    * I progress through the matrix from (0,0) to (1,1) to (2,2) and on to (n,n).
    *
    * For simplicities sake, I use ints instead of individual bits. But I never store
    * anything but 0 or 1 so it's still fair ;)
    */
    
    // ================================
    // Using globals just to keep function
    // call syntax as straight forward as possible
    int n = 5;
    int m[5][5] = {
                    { 1, 0, 1, 1, 0 },
                    { 0, 1, 1, 1, 0 },
                    { 1, 1, 1, 1, 1 },
                    { 1, 0, 1, 1, 1 },
                    { 1, 1, 1, 1, 1 }
                };
    // ================================
    
    // Just declaring the function prototypes
    void processMatrix();
    void processCorner( int cornerIndex );
    bool checkRow( int rowIndex );
    bool checkCol( int colIndex );
    void zeroRow( int rowIndex );
    void zeroCol( int colIndex );
    void printMatrix();
    
    // This function primes the pump
    void processMatrix() {
        processCorner( 0 );
    }
    
    // Step 1) This is the heart of my recursive algorithm
    void processCorner( int cornerIndex ) {
        // Step 2) Do the logic processing here and store the results
        bool rowZero = checkRow( cornerIndex );
        bool colZero = checkCol( cornerIndex );
    
        // Step 3) Now progress through the matrix
        int nextCorner = cornerIndex + 1;
        if( nextCorner < n )
            processCorner( nextCorner );
    
        // Step 4) Finially apply the changes determined earlier
        if( colZero )
            zeroCol( cornerIndex );
        if( rowZero )
            zeroRow( cornerIndex );
    }
    
    // This function returns whether or not the row contains a zero
    bool checkRow( int rowIndex ) {
        bool zero = false;
        for( int i=0; i<n && !zero; ++i ) {
            if( m[ rowIndex ][ i ] == 0 )
                zero = true;
        }
        return zero;
    }
    
    // This is just a helper function for zeroing a row
    void zeroRow( int rowIndex ) {
        for( int i=0; i<n; ++i ) {
            m[ rowIndex ][ i ] = 0;
        }
    }
    
    // This function returns whether or not the col contains a zero
    bool checkCol( int colIndex ) {
        bool zero = false;
        for( int i=0; i<n && !zero; ++i ) {
            if( m[ i ][ colIndex ] == 0 )
                zero = true;
        }
    
        return zero;
    }
    
    // This is just a helper function for zeroing a col
    void zeroCol( int colIndex ) {
        for( int i=0; i<n; ++i ) {
            m[ i ][ colIndex ] = 0;
        }
    }
    
    // Just a helper function for printing our matrix to std::out
    void printMatrix() {
        std::cout << std::endl;
        for( int y=0; y<n; ++y ) {
            for( int x=0; x<n; ++x ) {
                std::cout << m[y][x] << " ";
            }
            std::cout << std::endl;
        }
        std::cout << std::endl;
    }
    
    // Execute!
    int main() {
        printMatrix();
        processMatrix();
        printMatrix();
    }
    
    csl : Nice solution, but you are, technically, using more memory than the two allowed booleans (although on the stack).
    Draemon : This is >1 pass. If you print (rowIndex, i) and (i, colIndex) as they are accessed in checkRow and checkCol you will see that each element is accessed multiple times.
    Adam : Draemon: You are correct, I think we need a clear definition of "single pass" from the riddle maker. If he indeed means that each element can only be accessed once, then we need a different solution.
    Adam : I imagine the original problem (which has come to us via the telephone game) meant the problem should be solved "in place" meaning you don't have another copy of the matrix. And more optimal solutions don't even need temporary swap() like storage for processing.
    Adam : Also I sort of doubt the constraints are referring to the resulting machine code. Meaning, the "code" I provided only uses 2 bools. Depending on what optimizations my compiler does, the whole darn thing could be inlined or who knows what else. I think my solution is correct ;)
  • Well, I came up with a single-pass, in-place (non-recursive) solution using 4 bools and 2 loop counters. I've not managed to reduce it to 2 bools and 2 ints, but I wouldn't be surprised if it was possible. It does around 3 reads and 3 writes of each cell, and it should be O(N^2) ie. linear in the array size.

    Took me a couple of hours to puzzle this one out - I wouldn't want to have to come up with it under the pressure of an interview! If I've made a booboo I'm too tired to spot it...

    Um... I'm choosing to define "single-pass" as making one sweep through the matrix, rather than touching each value once! :-)

    #include <stdio.h>
    #include <memory.h>
    
    #define SIZE    5
    
    typedef unsigned char u8;
    
    u8 g_Array[ SIZE ][ SIZE ];
    
    void Dump()
    {
        for ( int nRow = 0; nRow < SIZE; ++nRow )
        {
         for ( int nColumn = 0; nColumn < SIZE; ++nColumn )
         {
          printf( "%d ", g_Array[ nRow ][ nColumn ] );
         }
         printf( "\n" );
        }
    }
    
    void Process()
    {
        u8 fCarriedAlpha = true;
        u8 fCarriedBeta = true;
        for ( int nStep = 0; nStep < SIZE; ++nStep )
        {
         u8 fAlpha = (nStep > 0) ? g_Array[ nStep-1 ][ nStep ] : true;
         u8 fBeta = (nStep > 0) ? g_Array[ nStep ][ nStep - 1 ] : true;
         fAlpha &= g_Array[ nStep ][ nStep ];
         fBeta &= g_Array[ nStep ][ nStep ];
         g_Array[ nStep-1 ][ nStep ] = fCarriedBeta;
         g_Array[ nStep ][ nStep-1 ] = fCarriedAlpha;
         for ( int nScan = nStep + 1; nScan < SIZE; ++nScan )
         {
          fBeta &= g_Array[ nStep ][ nScan ];
          if ( nStep > 0 )
          {
           g_Array[ nStep ][ nScan ] &= g_Array[ nStep-1 ][ nScan ];
           g_Array[ nStep-1][ nScan ] = fCarriedBeta;
          }
    
          fAlpha &= g_Array[ nScan ][ nStep ];
          if ( nStep > 0 )
          {
           g_Array[ nScan ][ nStep ] &= g_Array[ nScan ][ nStep-1 ];
           g_Array[ nScan ][ nStep-1] = fCarriedAlpha;
          }
         }
    
         g_Array[ nStep ][ nStep ] = fAlpha & fBeta;
    
         for ( int nScan = nStep - 1; nScan >= 0; --nScan )
         {
          g_Array[ nScan ][ nStep ] &= fAlpha;
          g_Array[ nStep ][ nScan ] &= fBeta;
         }
         fCarriedAlpha = fAlpha;
         fCarriedBeta = fBeta;
        }
    }
    
    int main()
    {
        memset( g_Array, 1, sizeof(g_Array) );
        g_Array[0][1] = 0;
        g_Array[0][4] = 0;
        g_Array[1][0] = 0;
        g_Array[1][4] = 0;
        g_Array[3][1] = 0;
    
        printf( "Input:\n" );
        Dump();
        Process();
        printf( "\nOutput:\n" );
        Dump();
    
        return 0;
    }
    
  • You can sorta do it in one pass -- if you don't count accessing the matrix in random-access order, which eliminates the benefits of doing it single-pass in the first place (cache-coherence/memory-bandwidth).

    [edit: simple, but wrong solution deleted]

    You should get better performance than any single-pass method by doing it in two passes: one to accumulate row/column info, and one to apply it. The array (in row-major order) is accessed coherently; for arrays exceeding the cache size (but whose rows can fit in cache), data should be read from memory twice, and stored once:

    void fixmatrix2(int M[][], int rows, int cols) {
        bool clearZeroRow= false;
        bool clearZeroCol= false;
        for(int j=0; j < cols; ++j) {
            if( ! M[0][j] ) {
                clearZeroRow= true;
            }
        }
        for(int i=1; i < rows; ++i) { // scan/accumulate pass
            if( ! M[i][0] ) {
                clearZeroCol= true;
            }
            for(int j=1; j < cols; ++j) {
                if( ! M[i][j] ) {
                    M[0][j]= 0;
                    M[i][0]= 0;
                }
            }
        }
        for(int i=1; i < rows; ++i) { // update pass
            if( M[i][0] ) {
                for(int j=0; j < cols; ++j) {
                    if( ! M[j][0] ) {
                        M[i][j]= 0;
                    }
                }
            } else {
                for(int j=0; j < cols; ++j) {
                    M[i][j]= 0;
                }
            }
            if(clearZeroCol) {
                M[i][0]= 0;
            }
        }
        if(clearZeroRow) {
            for(int j=0; j < cols; ++j) {
                M[0][j]= 0;
            }
        }
    }
    

  • I'm sure the solution has something to do with recursion. The nice thing about recursion is that it acts like a time machine in that if you set your matrix cell (in this case) to the value of the recursive function, you will be able to set it to a value that you don't find out about until the future, thus enabling you to go back in time, making it so you can do this thing in one pass. Also, you'll be doing your indexing via parameters in the recursive function rather than in for loops.

  • Okay this is a solution that

    • uses just one extra long value for working storage.
    • uses no recursion.
    • one pass of only N, not even N*N.
    • will work for other values of N but will need new #defines.
    #include <stdio.h>
    #define BIT30 (1<<24)
    #define COLMASK 0x108421L
    #define ROWMASK 0x1fL
    
    unsigned long long STARTGRID = 
    ((0x10 | 0x0 | 0x4 | 0x2 | 0x0) << 20) |
    ((0x00 | 0x8 | 0x4 | 0x2 | 0x0) << 15) |
    ((0x10 | 0x8 | 0x4 | 0x2 | 0x1) << 10) |
    ((0x10 | 0x0 | 0x4 | 0x2 | 0x1) << 5) |
    ((0x10 | 0x8 | 0x4 | 0x2 | 0x1) << 0);
    
    
    void dumpGrid (char* comment, unsigned long long theGrid) {
        char buffer[1000];
        buffer[0]='\0';
        printf ("\n\n%s\n",comment);
        for (int j=1;j<31; j++) {
         if (j%5!=1)
          printf( "%s%s", ((theGrid & BIT30)==BIT30)? "1" : "0",(((j%5)==0)?"\n" : ",") ); 
         theGrid = theGrid << 1;
        }
    }
    
    int main (int argc, const char * argv[]) {
        unsigned long long rowgrid = STARTGRID;
        unsigned long long colGrid = rowgrid;
    
        unsigned long long rowmask = ROWMASK;
        unsigned long long colmask = COLMASK;
    
        dumpGrid("Initial Grid", rowgrid);
        for (int i=0; i<5; i++) {
         if ((rowgrid & rowmask)== rowmask) rowgrid |= rowmask;
         else rowgrid &= ~rowmask;
         if ((colGrid & colmask) == colmask) colmask |= colmask;
         else colGrid &=  ~colmask;
         rowmask <<= 5;
         colmask <<= 1;
        }
        colGrid &= rowgrid;
        dumpGrid("RESULT Grid", colGrid);
        return 0;
        }
    
    Tony Lambert : I just worked out how to do this in even less code....
    Adam : It is a nice solution to be sure. And I suppose every ones solution here neglects at least one of the requirements. So having a solution with a max allowed value for N isn't the worst thing in the world, so nice job on this one :)
    Draemon : Restricting N to 8 and claiming this meets the one pass requirement is just plain dumb. This is not a general solution. No restriction of the size of N was stated in the question, so you have only solved a sub-problem.
    Tony Lambert : but all these solutions have a limit on N in one way or another.
  • i hope you enjoy my 1-pass c# solution

    you can retrieve an element with O(1) and only need the space of one row and one column of the matrix

    bool[][] matrix =
    {
        new[] { true, false, true, true, false }, // 10110
        new[] { false, true, true, true, false }, // 01110
        new[] { true, true, true, true, true },   // 11111
        new[] { true, false, true, true, true },  // 10111
        new[] { true, true, true, true, true }    // 11111
    };
    
    int n = matrix.Length;
    bool[] enabledRows = new bool[n];
    bool[] enabledColumns = new bool[n];
    
    for (int i = 0; i < n; i++)
    {
        enabledRows[i] = true;
        enabledColumns[i] = true;
    }
    
    for (int rowIndex = 0; rowIndex < n; rowIndex++)
    {
        for (int columnIndex = 0; columnIndex < n; columnIndex++)
        {
         bool element = matrix[rowIndex][columnIndex];
         enabledRows[rowIndex] &= element;
         enabledColumns[columnIndex] &= element;
        }
    }
    
    for (int rowIndex = 0; rowIndex < n; rowIndex++)
    {
        for (int columnIndex = 0; columnIndex < n; columnIndex++)
        {
         bool element = enabledRows[rowIndex] & enabledColumns[columnIndex];
         Console.Write(Convert.ToInt32(element));
        }
        Console.WriteLine();
    }
    
    /*
        00000
        00000
        00110
        00000
        00110
    */
    
  • Ok, I realize that it isn't quite a match, but I got it in one pass using a bool and a byte instead of two bools... close. I also wouldn't vouch for the efficiency of it but these types of questions often require less than optimal solutions.

        private static void doIt(byte[,] matrix)
        {
            byte zeroCols = 0;
            bool zeroRow = false;
    
            for (int row = 0; row <= matrix.GetUpperBound(0); row++)
            {
                zeroRow = false;
                for (int col = 0; col <= matrix.GetUpperBound(1); col++)
                {
                    if (matrix[row, col] == 0)
                    {
    
                        zeroRow = true;
                        zeroCols |= (byte)(Math.Pow(2, col));
    
                        // reset this column in previous rows
                        for (int innerRow = 0; innerRow < row; innerRow++)
                        {
                            matrix[innerRow, col] = 0;
                        }
    
                        // reset the previous columns in this row
                        for (int innerCol = 0; innerCol < col; innerCol++)
                        {
                            matrix[row, innerCol] = 0;
                        }
                    }
                    else if ((int)(zeroCols & ((byte)Math.Pow(2, col))) > 0)
                    {
                        matrix[row, col] = 0;
                    }
    
                    // Force the row to zero
                    if (zeroRow) { matrix[row, col] = 0; }
                }
            }
        }
    
  • 1 pass, 2 booleans. I just have to assume the integer indexes in the iterations don't count.

    This is not a complete solution but I can't get pass this point.

    If I could only determine if a 0 is an original 0 or a 1 that was converted to a 0 then I wouldn't have to use -1's and this would work.

    My output is like this:

    -1  0 -1 -1  0
     0 -1 -1 -1  0
    -1 -1  1  1 -1
    -1  0 -1 -1 -1
    -1 -1  1  1 -1
    

    The originality of my approach is using the first half of the examination of a row or column to determine if it contains a 0 and the last half to set the values - this is done by looking at x and width-x and then y and height-y in each iteration. Based on the results of the first half of the iteration, if a 0 in the row or column was found, I use the last half of the iteration to change the 1's to -1's.

    I just realized this could be done with only 1 boolean leaving 1 to ...?

    I'm posting this hoping someone might say, "Ah, just do this..." (And I spent way too much time on it not to post.)

    Here's the code in VB:

    Dim D(,) As Integer = {{1, 0, 1, 1, 1}, {0, 1, 1, 0, 1}, {1, 1, 1, 1, 1}, {1, 1, 1, 1, 1}, {0, 0, 1, 1, 1}}
    
    Dim B1, B2 As Boolean
    
    For y As Integer = 0 To UBound(D)
    
        B1 = True : B2 = True
    
        For x As Integer = 0 To UBound(D)
    
            // Scan row for 0's at x and width - x positions. Halfway through I'll konw if there's a 0 in this row.
            //If a 0 is found set my first boolean to false.
            If x <= (Math.Ceiling((UBound(D) + 1) / 2) - 1) Then
                If D(x, y) = 0 Or D(UBound(D) - x, y) = 0 Then B1 = False
            End If
    
            //If the boolean is false then a 0 in this row was found. Spend the last half of this loop
            //updating the values. This is where I'm stuck. If I change a 1 to a 0 it will cause the column
            //scan to fail. So for now I change to a -1. If there was a way to change to 0 yet later tell if
            //the value had changed this would work.
            If Not B1 Then
                If x >= (Math.Ceiling((UBound(D) + 1) / 2) - 1) Then
                    If D(x, y) = 1 Then D(x, y) = -1
                    If D(UBound(D) - x, y) = 1 Then D(UBound(D) - x, y) = -1
                End If
            End If
    
            //These 2 block do the same as the first 2 blocks but I switch x and y to do the column.
            If x <= (Math.Ceiling((UBound(D) + 1) / 2) - 1) Then
                If D(y, x) = 0 Or D(y, UBound(D) - x) = 0 Then B2 = False
            End If
    
            If Not B2 Then
                If x >= (Math.Ceiling((UBound(D) + 1) / 2) - 1) Then
                    If D(y, x) = 1 Then D(y, x) = -1
                    If D(y, UBound(D) - x) = 1 Then D(y, UBound(D) - x) = -1
                End If
            End If
    
        Next
    Next
    
  •     int[,] A = { 
                { 1, 0, 1, 1, 0 }, 
                { 0, 1, 1, 1, 0 }, 
                { 1, 1, 1, 1, 1 }, 
                { 1, 0, 1, 1, 1 }, 
                { 1, 1, 1, 1, 1 } };
    
        int i, j;
        int[] r = new int[5]; 
        int[] c = new int[5];
    
    
        for(i=0;i<5;i++)
        {
            r[i]=1; c[i]=1;
            for(j=0; j<5; j++)
            {
                r[i]=A[i,j]*r[i];
                c[i]=A[j,i]*c[i];
            }
        }
    
        for(i=0;i<5;i++)
            for(j=0;j<5;j++)
        A[i,j] = r[i]*r[j];
    
        for(i=0;i<5;i++)
        {
            for(j=0;j<5;j++)
            {
                Console.Write("{0}\t", A[i,j]);
            }
            Console.WriteLine();
        }