FAT - What is my first action once given a file that has 6 sectors? - fat

Sorry if any of this sounds dumb, I'm trying to get a better understanding on how a FAT directory reacts when certain actions are given.
For example:
if my FAT directory has 16 entries
0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1
Then file 'a' (lets give it 6 sectors) is added.
what will my first action be?
when will I know when to stop?

Put in index/position values!
0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Find the index of the first fat entry that is a 1 (working from the left) – here that would be position 2
In your directory write
a 2 (showing you have a file called a that starts storage in sector 2)
You know you have to set up a chain of 6, so file a is going to occupy 2 -> ? -> ? -> ? -> ? -> ? and we have to find what the question marks should be and record them in the fat according to the rules.
With an empty fat like this, it is dead easy: the chain will simply be 2 -> 3 -> 4 -> 5 -> 6 -> 7 and at position 2 in the fat you record the next sector in the chain (3),
at position 3 you record the next sector in the chain (4)
at position 4 you record the next sector in the chain (5)
at position 5 you record the next sector in the chain (6)
at position 6 you record the next sector in the chain (7)
at position 7 you record 0 to show it is the end of the chain 6. so that the fat looks like:
0 0 3 4 5 6 7 0 1 1 1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Easy, but the principle used is the same even if the fat hadn’t been empty:
To set up a chain of 6, you need to repeatedly
i) find the next 1 fat entry (free sector) right of the sector position you’re currently on and ii) record its index/position back at your current index/position in the fat
until you have six sector numbers involved, then finally you enter a 0 opposite the final position number, to show that sector is at the end of the chain (it is in use for storage, not a 1, so not free, but it doesn’t link to another sector)
In our case:
i) the next 1 entry after position 2 (first sector) is at position 3. In other words sector 3 is empty and file a can spill over from sector 2 into sector 3.
ii) We record this fact (this link of the chain, 2 -> 3) by writing a 3 opposite index 2 (make a fat entry of 3 at position 2).
Then we repeat this process starting from sector/position/index 3 - i) find the next 1 fat entry, right of position 3 (turns out to be at position 4)
iii) record a 4 opposite index 3, indicating that the next sector (after 3) in the 6-sector chain that file a needs for storage, is 4 and so on until we have set up a six-sector chain, in this case: 2 -> 3 -> 4 -> 5 -> 6 -> 7
Then finally we record a 0 at position 7 to mark the end of the chain.
Try the process in the case of a fat that is not empty and see that you can do it even when later sectors in the chain don’t simply follow on directly after earlier ones.

Related

Array pattern issue to maintain uniformity

There is an existing array of size 64 that has values 6 values distributed as 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 ...
Please see the image for complete data.
The number of occurrence of 0 in the array is 11 times (at every 6th index), 1 is 11 times ... where as 4 and 5 occurs 10 times each.
There is a necessity to reduce the occurrence of any of these numbers [0 to 5] to a lesser number that could be any number from 0 to 10.
For example, it could be to reduce occurrence of 0 to 6 and 1 to 9.
I am looking for a solid idea to do this. Certainly all the numbers are to be evenly distributed and not something like 0 0 0 0 0 2 2 2 2 2 2 ...
I tried to find the index/position where the reduced value has to filled (64/occurrence of 0 or 2). But at times the index collide with each other and thus is not robust one.
From the example I quoted above, number of occurrence of 0 must be changed to 6 and occurrence of 1 to 9, the result after my algorithm is below -
New location to fill 0 = (Array size)/(new occurrence of 0) = 64/6 = ~10th index
New location to fill 1 = (Array size)/(new occurrence of 1) = 64/9 = ~7 index
For filling 6 0's and 9 1's, first the array is reset after which each of the values are filled to maintain balanced distribution.
After filling 6 0's, the array would be come like this:
Then, after filling 9 1's, the array would be come like this:
The index at 55 already has value 0 and apparently 8th 1 also index to 55 that creates a collision. So I believe, this algorithm to balance the distribution does not work.
How do I populate 6 's, 9 1's and rest of the numbers {2, 3, 4, 5} in the array in a balanced way?

How to remove supersets from a list of sets using C program

I have a list of sets like the following in a text file. These are the output of my Code which generates paths of a graph. Node 0 is connected with 1 and 5.Node 1 is connected with 0, 5 and 2. Node 5 is connected with 0 , 1 and 6.Thus all the nodes are connected.
The graph looks like below:
0
1 5
2 6
3 7
4 8
9
( source 0 , destination 9)
Created paths:
0 1 2 3 4 9
0 1 2 3 7 8 9
0 1 2 6 7 3 4 9
0 1 2 6 7 8 9
0 5 6 2 3 4 9
0 5 6 2 3 7 8 9
0 5 6 7 3 4 9
0 5 6 7 8 9
I want to remove all the lines that are superset (a set that contain all the elements of another set, but with additional elements) of another set.
For the example above, removing the supersets should result in the following:
0 1 2 3 4 9
0 1 2 6 7 8 9
0 1 2 3 7 8 9
0 5 6 7 8 9
0 5 6 2 3 4 9
0 5 6 7 3 4 9
removed superset:
0 1 2 6 7 3 4 9
0 5 6 2 3 7 8 9
How can I do this in C program. I have to accomplish this for large number of graph paths.
Consider two paths, path1 and path2, such that path2 > path1, i.e. path2 contains all nodes or path1 + some additional nodes. That means that at some node1 path2 must diverge from path1, and at some node2 later reconnect. However, because path1 does not have any nodes which are not in path2, there should be no nodes in path1 which are between node1 and node2. In other words, node2 must be located just under node1. Consequently, the only possibility for path2 to diverge from and later reconnect to path1 is to make a small loop: move one node right, one down and one left OR the symmetrical path: one left, one down, one right. So, path2 must contain the full 'square' of nodes:
node node
node node
The reversed is also true - if some path contains a full square of nodes, then it can be simplified by going directly down without moving left-right. So, you just need to remove all paths, which contain any square of adjacent nodes. In your example you need to remove paths which contain any of
1 5 2 6
2 6 3 7
3 7 4 8
Also, you must exclude paths which contain avoidable loops at the start and the end:
0 1 5
4 8 9
This solution however requires that you generate all possible paths from top to bottom. Right now you are not generating all possible paths, for example path
0 1 5 6 7 8 9
is missing.
Of course, it will be much easier just to generate paths without superset. When you generate such paths you just can't allow switching branches right under each other. Branch switches must be separated by at least one vertical move.

correctness of fast small order statistic algorithm for odd-length array

Problem 9-3 of the textbook Intro to Algorithms (CLRS) describes a fast O(n) algorithm for finding the k-th order statistic (k-th element in the array when sorted) of a length-n array, for the particular case that k is much smaller than n. I am not certain about the correctness of this algorithm when n is odd, and want to see a way to prove that it is correct.
The basic idea is that we first split the array into two halves, the first with floor(n/2) elements, and the second with ceil(n/2) elements. Then, we "partner" each element in the first half with the corresponding element in the second half. When n is odd this leaves a remaining unpartnered element.
For each pair of partners, we make sure that the left partner is >= the right partner, swapping the two if not. Then, recursively find the k-th order statistic of the second half, mirroring any swaps made in the second half with corresponding swaps in the first half. After this, the k-th order statistic of the entire array must be either in the first k elements in the first half, or the first k elements in the second half.
My confusion comes from the case when the array length n is odd, and there is a lone element in the second half that has no partner. Since the recursion is performed on the second half, consisting of the last ceil(n/2) elements of the array, including the lone partnerless last element, and we are supposed to mirror all swaps made in second half with swaps made within the corresponding partners in the first half, it is unclear what to do when one of the swaps involves the final element, since it has no partner.
The textbook doesn't seem to take particular care on this issue, so I'm assuming that when a swap involves the final element, then just don't make any mirror moves of the partner in the first half at all. As a result, the final element simply "steals" the partner of whoever it got swapped with. However, in this case, is there an easy way to see if the algorithm is still correct? What if when the last element steals someone else's partner, the partner is actually the k-th order statistic, and gets swapped later on to an inaccessible location? The mechanics of the recursion and partitioning involving in order-statistic selection are sufficiently opaque to me such that I cannot confidently rule out that scenario.
I don't think your description of the algorithm is entirely accurate (but then the explanation you linked to is far from clear). As I understand it, the reason why the algorithm is correct for an odd-length array is as follows:
Let's first look at a few examples of even-length arrays, with n=10 and k=3 (i.e. we're looking for the third-smallest element, which is 2):
a. 5 2 7 6 1 9 3 8 4 0
b. 5 1 7 6 2 9 3 8 4 0
c. 5 0 7 6 2 9 3 8 4 1
d. 5 0 7 6 2 9 3 8 1 4
If we split the arrays into two parts, we get:
a. 5 2 7 6 1 9 3 8 4 0
b. 5 1 7 6 2 9 3 8 4 0
c. 5 0 7 6 2 9 3 8 4 1
d. 5 0 7 6 2 9 3 8 1 4
and these couples:
a. (5,9) (2,3) (7,8) (6,4) (1,0) <- 0 coupled with 1
b. (5,9) (1,3) (7,8) (6,4) (2,0) <- 0 coupled with 2
c. (5,9) (0,3) (7,8) (6,4) (2,1) <- 1 coupled with 2
d. (5,9) (0,3) (7,8) (6,1) (2,4) <- 0, 1 and 2 not coupled with each other
After comparing and swapping the couples so that their smallest element is in the first group, we get:
a. 5 2 7 4 0 9 3 8 6 1
b. 5 1 7 4 0 9 3 8 6 2
c. 5 0 7 4 1 9 3 8 6 2
d. 5 0 7 1 2 9 3 8 6 4
You'll see that the smallest element 0 will always be in the first group. The second-smallest element 1 will be either in the first group, or in the second group if it was coupled with the smallest element 0. The third-smallest element 2 will be either in the first group, or in the second group if it was coupled with either the smallest element 0 or the second-smallest element 1.
So the smallest element is in the first group, and the second- and third-smallest elements can be in either group. That means that the third-smallest element is either one of the 3 smallest elements in the first group, or one of the 2 (!) smallest elements in the second group.
a. 5 2 7 4 0 9 3 8 6 1 -> 0 2 4 + 1 3
b. 5 1 7 4 0 9 3 8 6 2 -> 0 1 4 + 2 3
c. 5 0 7 4 1 9 3 8 6 2 -> 0 1 4 + 2 3
d. 5 0 7 1 2 9 3 8 6 4 -> 0 1 2 + 3 4
So if we say that the k-th smallest element of the whole array is now one of the k-th smallest elements in either of the groups, there is an available spot in the the second group, and that's why, in an odd-length array, we'd add the uncoupled element to the second group. Whether or not the uncoupled element is the element we're looking for, it will certainly be one of the k-th smallest elements in either of the groups.
It is in fact more correct to say that the k-th smallest element is either one of the k smallest elements in the first group, or one of the k/2+1 smallest elements in the second group. I'm actually not sure that the algorithm is optimal, or even correct. There's a lot of repeated comparing and swapping going on, and the idea of keeping track of the couples and swapping elements in one group when their corresponding elements in the other group are swapped doesn't seem to make sense.

Algorithm for Vertex connections From List of Directed Edges

The square of a directed graph G = (V, E) is the graph G2 = (V, E2) such that u→w is in E2 if and only if u ≠ w and there is a vertex v such that both u→v and v→w are in E2. The input file simply lists the edges in arbitrary order as ordered pairs of vertices, with each edge on a separate line. The vertices are numbered in order from 1 to the total number of vertices.
*self-loops and duplicate/parallel edges are not allowed
If we look at the an example of input data:
1 6
1 4
1 3
2 4
2 8
2 6
2 5
3 5
3 2
3 6
4 7
4 5
4 6
4 8
5 1
5 8
5 7
6 3
6 4
7 5
7 4
7 6
8 1
Then the output would be:
1: 3 4 7 8 5 2 6
2: 5 6 3 4 1 8 7
3: 1 7 8 6 5 4
4: 5 6 8 7 3 1
5: 3 1 4 6
6: 2 7 5 8
7: 1 5 6 8 3 4
8: 6 4 3
I'm writing the code in C.
My thoughts are to run through the file, see how many vertices they are and then allocate an array of pointers. Proceed to go through the list again searching for just where the line has a 1 in it, then look at where those corresponding numbers lead. If its not a duplicate or the same number(1) then I'll add it to a linked list, from the array of pointers. I will do this for every number vertex number in the file.
However, I feel this is terribly inefficient, and not the best way to go about doing this. If anyone has any other suggestions I would be extremely grateful.
if I get it right, you want to build a result set for each node where all nodes with a distance of one and two for each node are stated.
therefore, one can hold the edges in an adjacency matrix of bit arrays, where a bit is one when an edge exists and zero if not.
now one can multiply this matrix with itself. in this case multiply means you can make an AND on row and column.
A small example (sorry, don't know how to insert a matrix properly):
0 1 0 0 1 0 0 0 1
0 0 1 x 0 0 1 = 1 1 0
1 1 0 1 1 0 0 1 1
This matrix contains a one for all nodes reachable in two steps. simply it's the adjacency matrix for two instead of one steps. If you now OR this matrix with your initial matrix you have a matrix which holds all paths of length one and two.
this approach has multiple advantages. at first bit operations are very fast. the cpu parallyzes your calculations and you can stop for the result matrix cell if one pair is found where the results gives one.
furthermore it is well documented how to calculate matrix multiplication in parallel.
you can easily calculate all other length of pathes. for a length k one has to calculate:
A^k = A^(k-1) * A
hope that helped

Brute-force sudoku solver: backtracking?

An implementation of a brute-force algorithm to solve Sudoku puzzles fails if a cell is discovered in which placing any of the digits 1-9 would be an illegal move.
The implementation is written in C, with the board represented by a 9x9 array. The solver counts down from 9 until a legal number's reached, and if none can be reached, it outputs a zero in its place.
A zero also represents a cell to be filled in. Here's the output (truncated) if a string of zeros (an empty board) is the input:
9 8 7 6 5 4 3 2 1
6 5 4 9 8 7 0 0 0
Those last three zeros are there because the values filled in previously aren't changing. How can I stop the solver from failing like this?
If you would currently put a zero in a spot, instead go back to the previous spot you put a number in and continue to count down till you find another value number for that spot.
For instance, in your example:
9 8 7 6 5 4 3 2 1
6 5 4 9 8 7 0 0 0
Instead of putting the zero in below the three, you would instead go back and try putting a 6 in below the 4.
don't treat every "move" like the right move. E.g. placing the last 7 seemed ok but makes it so that in the next cell no valid moves are left. So upon hitting the "no move possible" situation, go back, and try the next option. Iterate and you will have your solution.
A better way of course would be to start brute forcing for places with a small set of options left; run through all cells and start brute forcing with the cell with the least number of options left. When starting out with all-zero, you would then end up with
9 8 7 6 5 4 3 2 1
6 5 4 0 0 0 0 0 0
3 2 1 0 0 0 0 0 0
which is legal, without backtracking once.
You can do this by pushing your guesses onto a stack. Every time you end up wanting to output a zero, instead pop your last answer off the board and continue counting from it.
So if you guess 3 in (2,3) and next you're looking at (3,3) and get to zero, go back to (2,3) and try 2, then 1, then pop to before your (2,3) guess, etc.

Resources