It is possible to connect 8x8 matrix of buttons to the Pi using 16 GPIO pins, 8 for rows and 8 for columns? What are possible alternatives of doing this?
Known as multiplexing but you will get bonus points for mentioning Charlieplexing where it all began.
So you save allot of GPIO's but you have to work out a software solution now. There are several ways to work out the pins but you can leverage the speed of the Pi to set the GPIO's in a specific way, thousands of times a second. The benefit of this circuit is that you do not need diodes to control voltage flow.
Sequential exploration of rows:
In this method, the I/O pins connecting the rows are all configured as output and those connecting the columns are defined as input, or vice-versa. The column lines, which are inputs to the microcontroller, are pulled-high using the internal pull-up resistors. Therefore, the default input to these lines is 1. The state for the matrix keypad can be explored by turning the rows low sequentially, one at a time, and reading the columns. For example, set the first row to 0 and read all the columns. If any key has been pressed in that row, the corresponding column line must read as 0. Otherwise, go to the next row and set it to 0, and read the columns again. This process is repeated until a 0 is found in a column. This determines the row and column for the pressed key, thus giving the exploration code for that key.
Simultaneous exploration of rows and columns:
In this method, all rows and columns are explored simultaneously in two phases. First, the rows are configured as output and the columns as input. Internal pull-ups are enabled on the column lines. Then all rows are set to 0 and the columns are read. In any key has been pressed, the corresponding column will be read as 0. This detects the column but not its row. The whole process is reversed next. The rows are configured as input and the columns as output. Internal weak pull-ups are now enabled on row lines. All columns are set to 0, and the rows are read. The row that reads 0 contains the pressed key. This gives both the row and column for the pressed key. This approach of exploring the keypad is relatively faster than sequential exploration approach.
Multiplexing can also be applied the other way, by turning on things at specific places in the matrix. A nice example are LED's cubes, where you can trigger LED's in a 3D matrix using the correct sequence of GPIO's.