Related
So I need a check function to see if a specific point in a matrix, say arr[3][4], is within a border, or a figure of characters. For clarification, imagine matrix char arr[10][10] below:
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 1 1 1 1 1 0 0
0 0 0 1 0 0 0 1 0 0
0 0 0 1 0 0 0 1 0 0
0 0 0 1 0 0 0 1 0 0
0 0 0 1 1 1 1 1 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
As you can see, the '1' characters form a square of side length 5. I would like a bool function to return that true for arr[5][5] (0-indexed) because it is within the figure, but false for arr[1][1] because it is not. If relevant, the total size of the matrix will always be a constant 100*100, no matter the size of the '1' figure within. Also, please note that the figure will not always be a perfect polygon like the square in the example.
I could not solve this problem because in my example above, clearly both points (arr[5][5] and arr[1][1]) have the same surrounding squares, and the space is large enough so that I cannot just check if the four directions of up, right, down, and left (yes, diagonals can be ignored here) is a '1' because the '0' inside would be next to other '0's.
EDIT: I also want to clarify according to some shortcomings of answers that the thickness of sides may vary. The shape very well could be:
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 0 1 1 1 1 1 0 0
0 0 0 0 0 1 1 1 0 0
0 0 0 0 1 0 0 1 1 0
0 0 1 1 1 0 1 1 0 0
0 0 1 0 1 1 1 1 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
Therefore, counting whether the '1's on top of and to the left of the point is odd would not work.
So a flood fill would work, but it is quite heavy unless you want to know all the encased points. If you just want to check one point then you could do:
Count the number of ones in the vertical segment between points (x,0) and (x,y)
Count the number of ones in the horizontal segment between points (0,y) and (x,y)
If both are odd then you are inside.
Keep in mind that overlapping shapes or shapes with holes will not work with this algorithm.
So the function would look like this:
int inside(int x, int y)
{
int x_count = 0;
for(int i=0;i<x;i++)
if(matrix[y][i])
x_count++;
int y_count = 0;
for(int i=0;i<y;i++)
if(matrix[i][x])
y_count++;
return x_count%2 && y_count%2;
};
A full test program looks like:
#include <stdio.h>
int matrix1[10][10] = {
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 1, 1, 1, 1, 1, 0, 0},
{0, 0, 0, 1, 0, 0, 0, 1, 0, 0},
{0, 0, 0, 1, 0, 0, 0, 1, 0, 0},
{0, 0, 0, 1, 0, 0, 0, 1, 0, 0},
{0, 0, 0, 1, 1, 1, 1, 1, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
};
int matrix2[10][10] = {
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 1, 1, 1, 1, 1, 1, 1, 0, 0},
{0, 1, 0, 0, 0, 0, 0, 1, 0, 0},
{0, 1, 0, 1, 1, 1, 1, 1, 0, 0},
{0, 1, 0, 1, 0, 0, 0, 0, 0, 0},
{0, 1, 0, 1, 1, 1, 1, 1, 0, 0},
{0, 1, 0, 0, 0, 0, 0, 1, 0, 0},
{0, 1, 0, 0, 0, 0, 0, 1, 0, 0},
{0, 1, 1, 1, 1, 1, 1, 1, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
};
int inside(int matrix[10][10],int x, int y)
{
int x_count = 0;
for(int i=0;i<x;i++)
if(matrix[y][i])
x_count++;
int y_count = 0;
for(int i=0;i<y;i++)
if(matrix[i][x])
y_count++;
return x_count%2 && y_count%2;
};
int main()
{
printf("2,2 is %s matrix1\n",inside(matrix1,2,2)?"inside":"outside");
printf("5,5 is %s matrix1\n",inside(matrix1,5,5)?"inside":"outside");
printf("8,8 is %s matrix1\n",inside(matrix1,8,8)?"inside":"outside");
printf("3,3 is %s matrix2\n",inside(matrix2,3,3)?"inside":"outside");
printf("5,5 is %s matrix2\n",inside(matrix2,5,5)?"inside":"outside");
printf("7,7 is %s matrix2\n",inside(matrix2,7,7)?"inside":"outside");
return 0;
}
Try it online https://onlinegdb.com/UkkaA3vWZ
The standard algorithm only needs to scan left to right along the row you wish to check.
First, check if the element is a 1. If it is you are “inside or on the edge”.
Otherwise, scanning from 0 to x:
If you count an odd number of edges, you are inside.
If you count an even number of edges, you are outside.
You must be careful how you count edges. An edge is one where you have a 1 both above and below in the surrounding 8 elements. Otherwise you have not crossed an edge (you have passed a point).
Likewise, if you hit a run of 1s, you must still apply the above and below for both the left and right side of the run.
BTW, the only sure way to check is the flood-fill algorithm explained by Jonathan S.. Everything else can be tricked.
Here's a simple algorithm that'll do that:
Iterate over all elements at the edges of the matrix.
Change all 0 elements at the edge of the matrix to 2. (Leave any 1 elements intact.)
Within the entire matrix, whenever a 0 borders a 2, change that 0 to a 2 as well. Repeat this until there are no 0 elements left that are adjacent to a 2.
Any elements that are still 0 now are encased by 1 elements.
This is a flood fill starting at the edges of the matrix. It gives you all "encased" elements at once.
I've been trying to understand how this integer pool works. It is a lot of bit fiddling stuff I can't wrap my head around. I'm assuming there is a concept I'm missing with the m2id array and how it is or'ed with index 'n' that I don't know and would clear up a lot of my confusion. Are there are any general concepts/CS-theory that explain this seemingly-looking-simple code. I've put comments in the code to try and state my current understanding and where I am totally confused.
// Copyright 2009 The Go9p Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//Original source: https://github.com/rminnich/go9p/blob/master/clnt_pool.go
package go9p
import "sync"
var m2id = [...]uint8{ // I think this is where the magic is.
0, 1, 0, 2, 0, 1, 0, 3,
0, 1, 0, 2, 0, 1, 0, 4,
0, 1, 0, 2, 0, 1, 0, 3,
0, 1, 0, 2, 0, 1, 0, 5,
0, 1, 0, 2, 0, 1, 0, 3,
0, 1, 0, 2, 0, 1, 0, 4,
0, 1, 0, 2, 0, 1, 0, 3,
0, 1, 0, 2, 0, 1, 0, 6,
0, 1, 0, 2, 0, 1, 0, 3,
0, 1, 0, 2, 0, 1, 0, 4,
0, 1, 0, 2, 0, 1, 0, 3,
0, 1, 0, 2, 0, 1, 0, 5,
0, 1, 0, 2, 0, 1, 0, 3,
0, 1, 0, 2, 0, 1, 0, 4,
0, 1, 0, 2, 0, 1, 0, 3,
0, 1, 0, 2, 0, 1, 0, 7,
0, 1, 0, 2, 0, 1, 0, 3,
0, 1, 0, 2, 0, 1, 0, 4,
0, 1, 0, 2, 0, 1, 0, 3,
0, 1, 0, 2, 0, 1, 0, 5,
0, 1, 0, 2, 0, 1, 0, 3,
0, 1, 0, 2, 0, 1, 0, 4,
0, 1, 0, 2, 0, 1, 0, 3,
0, 1, 0, 2, 0, 1, 0, 6,
0, 1, 0, 2, 0, 1, 0, 3,
0, 1, 0, 2, 0, 1, 0, 4,
0, 1, 0, 2, 0, 1, 0, 3,
0, 1, 0, 2, 0, 1, 0, 5,
0, 1, 0, 2, 0, 1, 0, 3,
0, 1, 0, 2, 0, 1, 0, 4,
0, 1, 0, 2, 0, 1, 0, 3,
0, 1, 0, 2, 0, 1, 0, 0,
}
type pool struct {
sync.Mutex
need int
nchan chan uint32
maxid uint32
imap []byte
}
func newPool(maxid uint32) *pool {
p := new(pool)
p.maxid = maxid
p.nchan = make(chan uint32)
return p
}
func (p *pool) getId() uint32 {
var n uint32 = 0
var ret uint32
p.Lock()
for n = 0; n < uint32(len(p.imap)); n++ {
// it looks like every 0...n position of imap will be incremented to 255.
if p.imap[n] != 0xFF {
break
}
}
if int(n) >= len(p.imap) {
// This seems to be just growing the imap slice as needed.
// I don't quite understand the constant of '8' here.
m := uint32(len(p.imap) + 32)
if uint32(m*8) > p.maxid {
m = p.maxid/8 + 1
}
b := make([]byte, m)
copy(b, p.imap)
p.imap = b
}
if n >= uint32(len(p.imap)) {
// If you get here the I'm assuming all the ID's are used up and putId will return you the next released ID.
p.need++
p.Unlock()
ret = <-p.nchan
} else {
// This part I'm having a hard time grasping.
// It seems that each index of imap is incremented
// from 0 to 255 and magically or'd with ret to increment to the next number?
ret = uint32(m2id[p.imap[n]])
p.imap[n] |= 1 << ret
ret += n * 8
p.Unlock()
}
return ret
}
func (p *pool) putId(id uint32) {
p.Lock()
if p.need > 0 {
p.nchan <- id
p.need--
p.Unlock()
return
}
// This doesn't play well with what I thought was going on. I though that.
// I was thinking that imap[0] would always somehow magically return all the
// values from 0 to 255 and imap[1] would return 256 += 255 and so on.
// How does this work?
p.imap[id/8] &= ^(1 << (id % 8))
p.Unlock()
}
Optimization often leads to obscurity. Start with the basic concept. The pool of available Ids is represented by the underlying bit array of a slice of bytes. Id 19 is represented by left-to-right byte 2 (19 / 8) and right-to-left bit 3 (19 % 8).
Here's a simple implementation, ignoring details like locking and growing the bit array.
package main
import "fmt"
// The Id pool is represented by the underlying bit array of a slice of bytes.
var idPool = make([]byte, 4)
// Get the next available Id from the pool.
func getId() int {
// Get next available byte
for i := 0; i < len(idPool); i++ {
b := idPool[i]
if b != 0xFF {
// Get next available bit in the byte
for j := 0; j < 8; j++ {
if b&(1<<uint(j)) == 0 {
// Mark Id bit as unavailable.
idPool[i] |= 1 << uint(j)
// Return Id.
return 8*i + j
}
}
}
}
panic("Insufficient Ids")
}
// Put the Id back in the pool.
func putId(id int) {
if 0 > id || id >= 8*len(idPool) {
panic("Invalid Id")
}
i := id / 8
j := id % 8
// Mark Id bit as available.
idPool[i] &^= 1 << uint(j)
}
func main() {
for i := 0; i < 16; i++ {
getId()
}
fmt.Printf("%x\n", idPool)
for i := 10; i < 12; i++ {
putId(i)
}
fmt.Printf("%x\n", idPool)
fmt.Println(getId())
fmt.Printf("%x\n", idPool)
}
Output:
ffff0000
fff30000
10
fff70000
We can optimize this loop
// Get next available bit in the byte
for j := 0; j < 8; j++ {
if b&(1<<uint(j)) == 0 {
// Mark Id bit as unavailable.
idPool[i] |= 1 << uint(j)
// Return Id.
return 8*i + j
}
}
by replacing it with a table (m2id) lookup for the bit shift value.
// Get next available bit in the byte
j := int(m2id[idPool[i]])
// Mark Id bit as unavailable.
idPool[i] |= 1 << uint(j)
// Return Id.
return 8*i + j
The m2idInit() function shows how the m2id table bit shift values are calculated.
func m2idInit() (m2id [256]uint8) {
// For all byte values.
for i := uint(0); i < 256; i++ {
// Find an unused id
for j := uint(0); j < 8; j++ {
if i&(1<<j) == 0 {
// Bit shift value
m2id[i] = uint8(j)
break
}
}
}
return m2id
}
For example,
package main
import "fmt"
// The Id pool is represented by the underlying bit array of a slice of bytes.
var idPool = make([]byte, 4)
// Get the next available Id from the pool.
func getId() int {
// Get next available byte
for i := 0; i < len(idPool); i++ {
b := idPool[i]
if b != 0xFF {
// Get next available bit in the byte
j := int(m2id[idPool[i]])
// Mark Id bit as unavailable.
idPool[i] |= 1 << uint(j)
// Return Id.
return 8*i + j
}
}
panic("Insufficient Ids")
}
// Put the Id back in the pool.
func putId(id int) {
if 0 > id || id >= 8*len(idPool) {
panic("Invalid Id")
}
i := id / 8
j := id % 8
// Mark Id bit as available.
idPool[i] &^= 1 << uint(j)
}
var m2id = m2idInit()
func m2idInit() (m2id [256]uint8) {
// For all byte values.
for i := uint(0); i < 256; i++ {
// Find an unused id
for j := uint(0); j < 8; j++ {
if i&(1<<j) == 0 {
// Bit shift value
m2id[i] = uint8(j)
break
}
}
}
return m2id
}
func main() {
for i := 0; i < 16; i++ {
getId()
}
fmt.Printf("%x\n", idPool)
for i := 10; i < 12; i++ {
putId(i)
}
fmt.Printf("%x\n", idPool)
fmt.Println(getId())
fmt.Printf("%x\n", idPool)
fmt.Println()
fmt.Println(m2id)
}
Output:
ffff0000
fff30000
10
fff70000
[0 1 0 2 0 1 0 3
0 1 0 2 0 1 0 4
0 1 0 2 0 1 0 3
0 1 0 2 0 1 0 5
0 1 0 2 0 1 0 3
0 1 0 2 0 1 0 4
0 1 0 2 0 1 0 3
0 1 0 2 0 1 0 6
0 1 0 2 0 1 0 3
0 1 0 2 0 1 0 4
0 1 0 2 0 1 0 3
0 1 0 2 0 1 0 5
0 1 0 2 0 1 0 3
0 1 0 2 0 1 0 4
0 1 0 2 0 1 0 3
0 1 0 2 0 1 0 7
0 1 0 2 0 1 0 3
0 1 0 2 0 1 0 4
0 1 0 2 0 1 0 3
0 1 0 2 0 1 0 5
0 1 0 2 0 1 0 3
0 1 0 2 0 1 0 4
0 1 0 2 0 1 0 3
0 1 0 2 0 1 0 6
0 1 0 2 0 1 0 3
0 1 0 2 0 1 0 4
0 1 0 2 0 1 0 3
0 1 0 2 0 1 0 5
0 1 0 2 0 1 0 3
0 1 0 2 0 1 0 4
0 1 0 2 0 1 0 3
0 1 0 2 0 1 0 0]
There is no magic.
References:
Bit manipulation
The Go Programming Language Specification, Arithmetic operators
I would like to sort an array of 0 and 1. I have to sort it in linear time and in constant space. How can I do this without explicitly counting the number of 0 and 1?
I did something like this:
sort(array):
Q0 = Queue()
Q1 = Queue()
for i in (0, n-1):
if array[i] == 0:
Q0.push(array[i])
if array[i] == 1:
Q1.push(array[i])
j = 0
while Q0:
array[j] = Q0.pop()
j += 1
while Q1:
array[j] = Q1.pop()
j += 1
I think my solution is correct and has O(n) time but I am not sure of O(1) space. Any help?
Also, can we generalize the sorting to 0, 1, 2 arrays?
Here is (tested/working) Python:
# sort array of length n containing values of only 0 or 1
# in time O(n) and space O(1)
a = [1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]
first = 0
last = len(a)-1
print a
# note: don't need temp since values are only 0 and 1
while(last>first):
if a[first] == 1:
a[first] = a[last]
a[last] = 1
last -= 1
else:
first += 1
print a
The idea is to swap all the ones to the end of the array and the zeros to the beginning of the array by keeping two pointers. i points to the first index that has a 1.
Here is a pseudo-code:
i = 1
for (j = 1 to n)
if(a[j] == 0)
swap(a[i], a[j])
i++
I'm a newbie in ruby, just began to study. Can't find a solution to read from a file a square matrix in a two-dimensional array.
file graph.txt:
0 3 0 0 10 0 0
0 0 9 0 0 0 0
0 0 0 3 0 0 15
0 0 0 0 0 0 10
0 0 0 0 0 8 0
0 0 0 0 0 0 0
0 0 0 0 15 0 0
My code:
n=7
Arr = Array.new(n).map!{Array.new(n)}
text = ''
tx = File.readlines("graph.txt")
text = tx.join
i=0
text.each_line do |line|
Arr[i] = line.split(/\n/)
i+=1
end
p Arr
result:
[["0 3 0 0 10 0 0"], ["0 0 9 0 0 0 0"], ["0 0 0 3 0 0 15"], ["0 0 0 0 0 0 10"], ["0 0 0 0 0 8 0"], ["0 0 0 0 0 0 0"], ["0 0 0 0 15 0 0"]]
need result:
[[0, 3, 0, 0, 10, 0, 0], [0, 0, 9, 0, 0, 0, 0], [0, 0, 0, 3, 0, 0, 15], [0, 0, 0, 0, 0, 0, 10], [0, 0, 0, 0, 0, 8, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 15, 0, 0]]
# Replace DATA.each_line with IO.readlines('graph.txt') to use the file as a data source
matrix = DATA.each_line.map { |line| line.split.map(&:to_i) }
puts matrix.inspect
__END__
0 3 0 0 10 0 0
0 0 9 0 0 0 0
0 0 0 3 0 0 15
0 0 0 0 0 0 10
0 0 0 0 0 8 0
0 0 0 0 0 0 0
0 0 0 0 15 0 0
# => [[0, 3, 0, 0, 10, 0, 0], [0, 0, 9, 0, 0, 0, 0], [0, 0, 0, 3, 0, 0, 15], [0, 0, 0, 0, 0, 0, 10], [0, 0, 0, 0, 0, 8, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 15, 0, 0]]
A matrix of 150x150 size will describe our labyrinth, so for example if the matrix were only 10x10 we would have something like this:
1 1 1 1 1 1 1 1 1 1
1 0 0 0 0 0 0 1 0 0<-F
1 0 1 1 0 1 0 1 0 1
1 1 1 1 0 1 0 0 0 1
1 1 1 1 0 1 1 1 1 1
1 0 0 0 0 1 1 1 1 1
1 0 1 1 0 1 1 1 1 1
1 0 1 0 0 0 0 1 1 1
S->0 0 1 1 1 1 0 1 1 1
1 1 1 1 1 1 1 1 1 1
Where S marks the starting point and F the exit of the labyrinth.
The purpose of this program is to generate a Binary Tree that will describe all the paths we traveled while trying to find the exit.
How would you acomplish that? I'm really lost this time, I don't really know where to start that's why I'm not posting anything I've tried but if you could please give me a direction I would be really really grateful.
John Smith.
you might want to try backtracking
here's a complete example of how to solve this problem... however: it can't operate on a maze with "islands" in it as it would be necessary to aditionally track where you have been already. but i think you can figure out how to do this as well...
the output should be:
right, up, up, up, right, right, right, up, up, up, up, right, right, down, down, right, right, up, up, right, finish!
import java.awt.Point;
public class Maze {
enum Direction {
up, right, down, left
}
static Direction[] dirs = Direction.values();
int[][] maze = { { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, { 1, 0, 1, 1, 0, 1, 0, 1, 0, 1 },
{ 1, 1, 1, 1, 0, 1, 0, 0, 0, 1 }, { 1, 1, 1, 1, 0, 1, 1, 1, 1, 1 },
{ 1, 0, 0, 0, 0, 1, 1, 1, 1, 1 }, { 1, 0, 1, 1, 0, 1, 1, 1, 1, 1 },
{ 1, 0, 1, 0, 0, 0, 0, 1, 1, 1 }, { 0, 0, 1, 1, 1, 1, 0, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } };
Point start = new Point(0, 8);
Point finish = new Point(9, 1);
Point go(Direction dir, Point from) {
Point result = new Point(from);
switch (dir) {
case up:
if ((from.y == 0) || (maze[from.y - 1][from.x] != 0))
return null;
result.translate(0, -1);
break;
case right:
if ((from.x == maze[0].length) || (maze[from.y][from.x + 1] != 0))
return null;
result.translate(1, 0);
break;
case down:
if ((from.y == maze.length) || (maze[from.y + 1][from.x] != 0))
return null;
result.translate(0, 1);
break;
case left:
if ((from.x == 0) || (maze[from.y][from.x - 1] != 0))
return null;
result.translate(-1, 0);
break;
}
return result;
}
String tryToGo(Direction dir, Point from) {
String result;
Point newPosition = go(dir, from);
if (newPosition == null)
return null;
else if (newPosition.equals(start))
return null;
else if (newPosition.equals(finish))
return "finish!";
else {
for (Direction newDir : dirs) {
switch (newDir) {
case up:
if (dir == Direction.down)
continue;
break;
case down:
if (dir == Direction.up)
continue;
break;
case left:
if (dir == Direction.right)
continue;
break;
case right:
if (dir == Direction.left)
continue;
break;
}
result = tryToGo(newDir, newPosition);
if (result == null)
continue;
else
return newDir + ", " + result;
}
return null;
}
}
public static void main(String[] args) {
Maze maze = new Maze();
System.out.println("right" + maze.tryToGo(Direction.right, maze.start));
}
}