Recently came across an interview question in glassdoor-like site and I can't find an optimized solution to solve this problem:
This is nothing like trapping water problem. Please read through the examples.
Given an input array whose each element represents the height of towers, the amount of water will be poured and the index number indicates the pouring water position.The width of every tower is 1. Print the graph after pouring water.
Notes:
Use * to indicate the tower, w to represent 1 amount water.
The pouring position will never at the peak position.No need to consider the divide water case.
(A Bonus point if you gave a solution for this case, you may assume that if Pouring N water at peak position, N/2 water goes to left, N/2 water goes to right.)
The definition for a peak: the height of peak position is greater than the both left and right index next to it.)
Assume there are 2 extreme high walls sits close to the histogram.
So if the water amount is over the capacity of the histogram,
you should indicate the capacity number and keep going. See Example 2.
Assume the water would go left first, see Example 1
Example 1:
int[] heights = {4,2,1,2,3,2,1,0,4,2,1}
It look like:
* *
* * **
** *** **
******* ***
+++++++++++ <- there'll always be a base layer
42123210431
Assume given this heights array, water amout 3, position 2:
Print:
* *
*ww * **
**w*** **
******* ***
+++++++++++
Example 2:
int[] heights = {4,2,1,2,3,2,1,0,4,2,1}, water amout 32, position 2
Print:
capacity:21
wwwwwwwwwww
*wwwwwww*ww
*www*www**w
**w***ww**w
*******w***
+++++++++++
At first I though it's like the trapping water problem but I was wrong. Does anyone have an algorithm to solve this problem?
An explanation or comments in the code would be welcomed.
Note:
The trapping water problem is asked for the capacity, but this question introduced two variables: water amount and the pouring index. Besides, the water has the flowing preference. So it not like trapping water problem.
I found a Python solution to this question. However, I'm not familiar with Python so I quote the code here. Hopefully, someone knows Python could help.
Code by #z026
def pour_water(terrains, location, water):
print 'location', location
print 'len terrains', len(terrains)
waters = [0] * len(terrains)
while water > 0:
left = location - 1
while left >= 0:
if terrains[left] + waters[left] > terrains[left + 1] + waters[left + 1]:
break
left -= 1
if terrains[left + 1] + waters[left + 1] < terrains[location] + waters[location]:
location_to_pour = left + 1
print 'set by left', location_to_pour
else:
right = location + 1
while right < len(terrains):
if terrains[right] + waters[right] > terrains[right - 1] + waters[right - 1]:
print 'break, right: {}, right - 1:{}'.format(right, right - 1)
break
right += 1
if terrains[right - 1] + waters[right - 1] < terrains[location] + waters[right - 1]:
location_to_pour = right - 1
print 'set by right', location_to_pour
else:
location_to_pour = location
print 'set to location', location_to_pour
waters[location_to_pour] += 1
print location_to_pour
water -= 1
max_height = max(terrains)
for height in xrange(max_height, -1, -1):
for i in xrange(len(terrains)):
if terrains + waters < height:
print ' ',
elif terrains < height <= terrains + waters:
print 'w',
else:
print '+',
print ''
Since you have to generate and print out the array anyway, I'd probably opt for a recursive approach keeping to the O(rows*columns) complexity. Note each cell can be "visited" at most twice.
On a high level: first recurse down, then left, then right, then fill the current cell.
However, this runs into a little problem: (assuming this is a problem)
*w * * *
**ww* * instead of **ww*w*
This can be fixed by updating the algorithm to go left and right first to fill cells below the current row, then to go both left and right again to fill the current row. Let's say state = v means we came from above, state = h1 means it's the first horizontal pass, state = h2 means it's the second horizontal pass.
You might be able to avoid this repeated visiting of cells by using a stack, but it's more complex.
Pseudo-code:
array[][] // populated with towers, as shown in the question
visited[][] // starts with all false
// call at the position you're inserting water (at the very top)
define fill(x, y, state):
if x or y out of bounds
or array[x][y] == '*'
or waterCount == 0
return
visited = true
// we came from above
if state == v
fill(x, y+1, v) // down
fill(x-1, y, h1) // left , 1st pass
fill(x+1, y, h1) // right, 1st pass
fill(x-1, y, h2) // left , 2nd pass
fill(x+1, y, h2) // right, 2nd pass
// this is a 1st horizontal pass
if state == h1
fill(x, y+1, v) // down
fill(x-1, y, h1) // left , 1st pass
fill(x+1, y, h1) // right, 1st pass
visited = false // need to revisit cell later
return // skip filling the current cell
// this is a 2nd horizontal pass
if state == h2
fill(x-1, y, h2) // left , 2nd pass
fill(x+1, y, h2) // right, 2nd pass
// fill current cell
if waterCount > 0
array[x][y] = 'w'
waterCount--
You have an array height with the height of the terrain in each column, so I would create a copy of this array (let's call it w for water) to indicate how high the water is in each column. Like this you also get rid of the problem not knowing how many rows to initialize when transforming into a grid and you can skip that step entirely.
The algorithm in Java code would look something like this:
public int[] getWaterHeight(int index, int drops, int[] heights) {
int[] w = Arrays.copyOf(heights);
for (; drops > 0; drops--) {
int idx = index;
// go left first
while (idx > 0 && w[idx - 1] <= w[idx])
idx--;
// go right
for (;;) {
int t = idx + 1;
while (t < w.length && w[t] == w[idx])
t++;
if (t >= w.length || w[t] >= w[idx]) {
w[idx]++;
break;
} else { // we can go down to the right side here
idx = t;
}
}
}
return w;
}
Even though there are many loops, the complexity is only O(drops * columns). If you expect huge amount of drops then it could be wise to count the number of empty spaces in regard to the highest terrain point O(columns), then if the number of drops exceeds the free spaces, the calculation of the column heights becomes trivial O(1), however setting them all still takes O(columns).
You can iterate over the 2D grid from bottom to top, create a node for every horizontal run of connected cells, and then string these nodes together into a linked list that represents the order in which the cells are filled.
After row one, you have one horizontal run, with a volume of 1:
1(1)
In row two, you find three runs, one of which is connected to node 1:
1(1)->2(1) 3(1) 4(1)
In row three, you find three runs, one of which connects runs 2 and 3; run 3 is closest to the column where the water is added, so it comes first:
3(1)->1(1)->2(1)->5(3) 6(1) 4(1)->7(1)
In row four you find two runs, one of which connects runs 6 and 7; run 6 is closest to the column where the water is added, so it comes first:
3(1)->1(1)->2(1)->5(3)->8(4) 6(1)->4(1)->7(1)->9(3)
In row five you find a run which connects runs 8 and 9; they are on opposite sides of the column where the water is added, so the run on the left goes first:
3(1)->1(1)->2(1)->5(3)->8(4)->6(1)->4(1)->7(1)->9(3)->A(8)
Run A combines all the columns, so it becomes the last node and is given infinite volume; any excess drops will simply be stacked up:
3(1)->1(1)->2(1)->5(3)->8(4)->6(1)->4(1)->7(1)->9(3)->A(infinite)
then we fill the runs in the order in which they are listed, until we run out of drops.
Thats my 20 minutes solution. Each drop is telling the client where it will stay, so the difficult task is done.(Copy-Paste in your IDE) Only the printing have to be done now, but the drops are taking their position. Take a look:
class Test2{
private static int[] heights = {3,4,4,4,3,2,1,0,4,2,1};
public static void main(String args[]){
int wAmount = 10;
int position = 2;
for(int i=0; i<wAmount; i++){
System.out.println(i+"#drop");
aDropLeft(position);
}
}
private static void aDropLeft(int position){
getHight(position);
int canFallTo = getFallPositionLeft(position);
if(canFallTo==-1){canFallTo = getFallPositionRight(position);}
if(canFallTo==-1){
stayThere(position);
return;
}
aDropLeft(canFallTo);
}
private static void stayThere(int position) {
System.out.print("Staying at: ");log(position);
heights[position]++;
}
//the position or -1 if it cant fall
private static int getFallPositionLeft(int position) {
int tempHeight = getHight(position);
int tempPosition = position;
//check left , if no, then check right
while(tempPosition>0){
if(tempHeight>getHight(tempPosition-1)){
return tempPosition-1;
}else tempPosition--;
}
return -1;
}
private static int getFallPositionRight(int position) {
int tempHeight = getHight(position);
int tempPosition = position;
while(tempPosition<heights.length-1){
if(tempHeight>getHight(tempPosition+1)){
return tempPosition+1;
}else if(tempHeight<getHight(tempPosition+1)){
return -1;
}else tempPosition++;
}
return -1;
}
private static int getHight(int position) {
return heights[position];
}
private static void log(int position) {
System.out.println("I am at position: " + position + " height: " + getHight(position));
}
}
Of course the code can be optimized, but thats my straightforward solution
l=[0,1,0,2,1,0,1,3,2,1,2,1]
def findwater(l):
w=0
for i in range(0,len(l)-1):
if i==0:
pass
else:
num = min(max(l[:i]),max(l[i:]))-l[i]
if num>0:
w+=num
return w
col_names=[1,2,3,4,5,6,7,8,9,10,11,12,13] #for visualization
bars=[4,0,2,0,1,0,4,0,5,0,3,0,1]
pd.DataFrame(dict(zip(col_names,bars)),index=range(1)).plot(kind='bar') # Plotting bars
def measure_water(l):
water=0
for i in range(len(l)-1): # iterate over bars (list)
if i==0: # case to avoid max(:i) situation in case no item on left
pass
else:
vol_at_curr_bar=min(max(l[:i]),max(l[i:]))-l[i] #select min of max heighted bar on both side and minus current height
if vol_at_curr_bar>0: # case to aviod any negative sum
water+=vol_at_curr_bar
return water
measure_water(bars)
Related
I am suppose to code the snake game in java with processing for IT classes and since I had no idea how to do it I searched for a YouTube tutorial. Now I did find one but he used the keys 'w','s','d','a' to move the snake around - I on the other hand want to use the arrow keys. Could someone explain to me how I transform this code:
if (keyPressed == true) {
int newdir = key=='s' ? 0 : (key=='w' ? 1 : (key=='d' ? 2 : (key=='a' ? 3 : -1)));
}
if(newdir != -1 && (x.size() <= 1 || !(x.get(1) ==x.get(0) + dx[newdir] && y.get (1) == y.get(0) + dy[newdir]))) dir = newdir;
}
into something like this:
void keyPressed () {
if (key == CODED) {
if (keyCode == UP) {}
else if (keyCode == RIGHT) {}
else if (keyCode == DOWN) {}
else if (keyCode == LEFT) {}
}
This is my entire coding so far:
ArrayList<Integer> x = new ArrayList<Integer> (), y = new ArrayList<Integer> ();
int w = 900, h = 900, bs = 20, dir = 1; // w = width ; h = height ; bs = blocksize ; dir = 2 --> so that the snake goes up when it starts
int[] dx = {0,0,1,-1} , dy = {1,-1,0,0};// down, up, right, left
void setup () {
size (900,900); // the 'playing field' is going to be 900x900px big
// the snake starts off on x = 5 and y = 30
x.add(5);
y.add(30);
}
void draw() {
//white background
background (255);
//
// grid
// vertical lines ; the lines are only drawn if they are smaller than 'w'
// the operator ++ increases the value 'l = 0' by 1
//
for(int l = 0 ; l < w; l++) line (l*bs, 0, l*bs, height);
//
// horizontal lines ; the lines are only drawn if they are smaller than 'h'
// the operator ++ increases the value 'l = 0' by 1
//
for(int l = 0 ; l < h; l++) line (0, l*bs, width, l*bs);
//
// snake
for (int l = 0 ; l < x.size() ; l++) {
fill (0,255,0); // the snake is going to be green
rect (x.get(l)*bs, y.get(l)*bs, bs, bs);
}
if(frameCount%5==0) { // will check it every 1/12 of a second -- will check it every 5 frames at a frameRate = 60
// adding points
x.add (0,x.get(0) + dx[dir]); // will add a new point x in the chosen direction
y.add (0,y.get(0) + dy[dir]); // will add a new point y in the chosen direction
// removing points
x.remove(x.size()-1); // will remove the previous point x
y.remove(y.size()-1); // will remove the previous point y
}
}
It's hard to answer general "how do I do this" type questions. Stack Overflow is designed for more specific "I tried X, expected Y, but got Z instead" type questions. That being said, I'll try to answer in a general sense:
You're going to have a very difficult time trying to take random code you find on the internet and trying to make it work in your sketch. That's not a very good way to proceed.
Instead, you need to take a step back and really think about what you want to happen. Instead of taking on your entire end goal at one time, try breaking your problem down into smaller steps and taking on those steps one at a time.
Step 1: Can you store the state of your game in variables? You might store things like the direction the snake is traveling the location of the snake, etc.
Step 2: Can you write code that just prints something to the console when you press the arrow keys? You might do this in a separate example sketch instead of trying to add it directly to your full sketch.
Step 3: Can you combine those two steps and change the state of your sketch when an arrow key is pressed? Maybe you change the direction the snake is traveling.
The point is that you need to try something instead of trying to copy-paste random code without really understanding it. Break your problem down into small steps, and then post an MCVE of that specific step if you get stuck. Good luck.
You should take a look into Java API KeyEvent VK_LEFT.
And as pczeus already told you, you need to implement a capturing of the keystrokes! This can be checked here (Link from this SO answer).
In a recent interview question I got the following problem.
In a particular city we have a row of buildings with varying heights.
The collapse of a building with height h causes the next h-1 buildings on its right to collapse too.
The height of the buildings can be between 1 and 5000. Given the heights of all the buildings (arranged from left to right ie; for leftmost building index=1 and for rightmost building index=N) we needed to find out the index of the building which would cause the maximum devastation.
For example:
Input:
Number of buildings : 6
Height of Buildings:
2 1 3 3 1 6
Answer should be building at the index 3
The solution I tried was using the brute force technique with a complexity of O(N^2).
What I did was for each building in the list I found out the number of buildings that it would destroy.
Could a better solution for this question be constructed?
Simply go from the left, collapse the first building, and calculate how much total(*) damage it did.
Do this again and again from the very next building (which hasn't collapsed).
From these, pick the maximum.
Complexity: O(n).
This greedy algorithm works because the whole process is a chain reaction, if building A forces the collapse of B, then you cannot achieve better score starting from B.
(*) You can do this by maintaining one counter which stores how many buildings to the right should be collapsed. counter = max(counter - 1, height of next building).
some areas of the city function as "firewalls" - collapse stops at that point. a little thought shows that these are sections to the left of a value of 1 where height increases (to the left) no more than once per step (if you can have 0 heights that complicates things very slightly).
and the highest scoring region must start just after a firewall (since if it didn't there would be a higher region just to the left).
so scan from the right, finding these firewalls, and then find which section to the right of a firewall has the largest damage. this is O(n) because it's just linear scans (once from right to left and then once for each section, with no overlap).
actually, Karoly's answer is equivalent and simpler to implement.
Start with rightmost index.
The last building shall cause a devastation value of 1.
Iterate leftwards.
Something like (devastation from building i)
D[i] = 1 + min( N-i, max( index[i]-1, 0+D[i+1],1+D[i+2],... to index[i]-1 terms ) )
Same approach as #Karoly's answer. In ruby:
def find_max_damage_index(buildings)
max_damage = 0
max_start_index = nil
current_start_index = nil
current_h = 0
current_damage = 0
buildings.each_with_index{|h,i|
if current_h == 0 #end of batch
if current_damage > max_damage
max_damage = current_damage
max_start_index = current_start_index
end
#start new batch
current_h = h
current_damage = 1
current_start_index = i
else
current_h = h if h > current_h
current_damage += 1
end
current_h -= 1
}
#last batch
if current_damage > max_damage
max_damage = current_damage
max_start_index = current_start_index
end
return max_start_index
end
In Java, without considering subsequent collapses:
public static int collapse(int[] buildings) {
int i, maxDamage, index, currentDamage;
// do not consider the last building, it will cause only its own fall
maxDamage = 1;
index = buildings.length - 1;
for(i = buildings.length - 1; i >= 0; i--) {
// update maximum damage as the mimimum value between the building[i] (the height of the building at index i) and the remaining number of elements from i to the end of the array
currentDamage = Math.min(buildings[i], buildings.length - i);
System.out.println(currentDamage);
if(currentDamage > maxDamage) {
maxDamage = currentDamage;
index = i;
}
}
return index;
}
My final solution is different from the accepted one, which by the way I didn't fully understand.
The idea is to count starting from the rightmost position the number of buildings that the current index will collapse.
index: 7 6 5 4 3 2 1 0
height: 1 3 1 2 4 1 3 2
damage: 1 2 1 2 4 1 3 2
Then I just make a cumulative sum, starting from the rightmost position again. I add to the number of buildings the current position collapses the number of buildings that were collapsed staring from the next building to the right that didn't collapse until the end.
index: 7 6 5 4 3 2 1 0
height: 1 3 1 2 4 1 3 2
damage: 1 2 1 2 5 1 7 8
In the end, I just return the index with the maximum damage.
This solution runs in O(n) but uses an extra O(n) space.
The next code is the complete version (also works for subsequent collapses):
public static int collapse(int[] buildings) {
int i, maxIndex, max;
int damage[] = new int[buildings.length];
for(i = buildings.length - 1; i >= 0; i--) {
// compute damage for each position
damage[i] = Math.min(buildings[i], buildings.length - i);
}
for(i = buildings.length - 1; i >= 0; i--) {
// update total accumulated damage for each position
if(damage[i] > 1) {
if(damage[i] + i - 1 < buildings.length && i != (i + damage[i] - 1) ) {
damage[i] += damage[i + damage[i] - 1] - 1;
}
}
}
max = damage[0];
maxIndex = 0;
for(i = 1; i < buildings.length; i++) {
// find the maximum damage
if(damage[i] > max) {
max = damage[i];
maxIndex = i;
}
}
return maxIndex;
}
I'm trying to implement this data structure, a Barnes-Hut Octree, and I keep running into an endless loop, terminated by an out of memory exception.
The complete fiddle is here: http://jsfiddle.net/cWvex/
but the functions I'm looping between are these:
OctreeNode.prototype.insert = function (body) {
console.log('insert');
if(this.isInternal){
this.internalInsert(body);
return;
}
if(this.isExternal){
// insert the body into the spec. quadrant, call internalUpdate
for(var quadrant in this.internal.quadrants){
if(this.internal.quadrants.hasOwnProperty(quadrant)){
this.internal.quadrants[quadrant] = new OctreeNode();
}
}
this.isExternal = false;
this.isInternal = true;
this.internalInsert(this.external);
this.external = null;
this.internalInsert(body);
return;
}
if(this.isEmpty){
this.external = body;
this.isEmpty = false;
this.isExternal = true;
return;
}
};
// Precondition: quadrants' nodes must be instantiated
OctreeNode.prototype.internalInsert = function(body) {
console.log('internalInsert');
this.internal.quadrants[this.quadrant(body)].insert(body);
this.internalUpdate(body);
};
Anyone got an idea of what I'm missing?
I think the problem is to do with the quadrant function:
OctreeNode.prototype.quadrant = function (body) {
console.log('quadrant');
var pos = this.internal.pos;
var quadrant = (body.pos.x < pos ? 'l' : 'r') +
(body.pos.y < pos ? 'u' : 'd') +
(body.pos.z < pos ? 'i' : 'o');
return quadrant;
};
The chosen quadrant should be based on the centre of the quadrant, not on the centre of mass. I think you need to create a new variable to define the centre of the quadrant.
Note that when you add nodes, the centre of mass (stored in pos) can change, but the centre of the quadrant remains fixed (otherwise things will go wrong when you descend into the octtree).
At the moment, each new node is generated with a pos of 0,0,0 and so every point will always end up being assigned into the same quadrant of the node. Therefore when you try to place two bodies into the tree, you end up with an infinite recursion:
Body 1 is inserted into node x
Body 2 is inserted into node x
Node 1 is split.
Body 1 is inserted into quadrant 1 of node x
Body 2 is inserted into quadrant 1 of node x
Back to step 1 with x changed to the node at quadrant 1 of node x
EDIT
Incidentally, in the code that reads:
avgPos.x = (body.pos.x*body.mass +
avgPos.x * totalMass) / totalMass + body.mass
I think you need some more brackets to become
avgPos.x = (body.pos.x*body.mass +
avgPos.x * totalMass) / (totalMass + body.mass)
or the update of centre of mass will go wrong.
Problem: We have x checkboxes and we want to check y of them evenly.
Example 1: select 50 checkboxes of 100 total.
[-]
[x]
[-]
[x]
...
Example 2: select 33 checkboxes of 100 total.
[-]
[-]
[x]
[-]
[-]
[x]
...
Example 3: select 66 checkboxes of 100 total:
[-]
[x]
[x]
[-]
[x]
[x]
...
But we're having trouble to come up with a formula to check them in code, especially once you go 11/111 or something similar. Anyone has an idea?
Let's first assume y is divisible by x. Then we denote p = y/x and the solution is simple. Go through the list, every p elements, mark 1 of them.
Now, let's say r = y%x is non zero. Still p = y/x where / is integer devision. So, you need to:
In the first p-r elements, mark 1 elements
In the last r elements, mark 2 elements
Note: This depends on how you define evenly distributed. You might want to spread the r sections withx+1 elements in between p-r sections with x elements, which indeed is again the same problem and could be solved recursively.
Alright so it wasn't actually correct. I think this would do though:
Regardless of divisibility:
if y > 2*x, then mark 1 element every p = y/x elements, x times.
if y < 2*x, then mark all, and do the previous step unmarking y-x out of y checkboxes (so like in the previous case, but x is replaced by y-x)
Note: This depends on how you define evenly distributed. You might want to change between p and p+1 elements for example to distribute them better.
Here's a straightforward solution using integer arithmetic:
void check(char boxes[], int total_count, int check_count)
{
int i;
for (i = 0; i < total_count; i++)
boxes[i] = '-';
for (i = 0; i < check_count; i++)
boxes[i * total_count / check_count] = 'x';
}
total_count is the total number of boxes, and check_count is the number of boxes to check.
First, it sets every box to unchecked. Then, it checks check_count boxes, scaling the counter to the number of boxes.
Caveat: this is left-biased rather than right-biased like in your examples. That is, it prints x--x-- rather than --x--x. You can turn it around by replacing
boxes[i * total_count / check_count] = 'x';
with:
boxes[total_count - (i * total_count / check_count) - 1] = 'x';
Correctness
Assuming 0 <= check_count <= total_count, and that boxes has space for at least total_count items, we can prove that:
No check marks will overlap. i * total_count / check_count increments by at least one on every iteration, because total_count >= check_count.
This will not overflow the buffer. The subscript i * total_count / check_count
Will be >= 0. i, total_count, and check_count will all be >= 0.
Will be < total_count. When n > 0 and d > 0:
(n * d - 1) / d < n
In other words, if we take n * d / d, and nudge the numerator down, the quotient will go down, too.
Therefore, (check_count - 1) * total_count / check_count will be less than total_count, with the assumptions made above. A division by zero won't happen because if check_count is 0, the loop in question will have zero iterations.
Say number of checkboxes is C and the number of Xes is N.
You example states that having C=111 and N=11 is your most troublesome case.
Try this: divide C/N. Call it D. Have index in the array as double number I. Have another variable as counter, M.
double D = (double)C / (double)N;
double I = 0.0;
int M = N;
while (M > 0) {
if (checkboxes[Round(I)].Checked) { // if we selected it, skip to next
I += 1.0;
continue;
}
checkboxes[Round(I)].Checked = true;
M --;
I += D;
if (Round(I) >= C) { // wrap around the end
I -= C;
}
}
Please note that Round(x) should return nearest integer value for x.
This one could work for you.
I think the key is to keep count of how many boxes you expect to have per check.
Say you want 33 checks in 100 boxes. 100 / 33 = 3.030303..., so you expect to have one check every 3.030303... boxes. That means every 3.030303... boxes, you need to add a check. 66 checks in 100 boxes would mean one check every 1.51515... boxes, 11 checks in 111 boxes would mean one check every 10.090909... boxes, and so on.
double count = 0;
for (int i = 0; i < boxes; i++) {
count += 1;
if (count >= boxes/checks) {
checkboxes[i] = true;
count -= count.truncate(); // so 1.6 becomes 0.6 - resetting the count but keeping the decimal part to keep track of "partial boxes" so far
}
}
You might rather use decimal as opposed to double for count, or there's a slight chance the last box will get skipped due to rounding errors.
Bresenham-like algorithm is suitable to distribute checkboxes evenly. Output of 'x' corresponds to Y-coordinate change. It is possible to choose initial err as random value in range [0..places) to avoid biasing.
def Distribute(places, stars):
err = places // 2
res = ''
for i in range(0, places):
err = err - stars
if err < 0 :
res = res + 'x'
err = err + places
else:
res = res + '-'
print(res)
Distribute(24,17)
Distribute(24,12)
Distribute(24,5)
output:
x-xxx-xx-xx-xxx-xx-xxx-x
-x-x-x-x-x-x-x-x-x-x-x-x
--x----x----x---x----x--
Quick html/javascript solution:
<html>
<body>
<div id='container'></div>
<script>
var cbCount = 111;
var cbCheckCount = 11;
var cbRatio = cbCount / cbCheckCount;
var buildCheckCount = 0;
var c = document.getElementById('container');
for (var i=1; i <= cbCount; i++) {
// make a checkbox
var cb = document.createElement('input');
cb.type = 'checkbox';
test = i / cbRatio - buildCheckCount;
if (test >= 1) {
// check the checkbox we just made
cb.checked = 'checked';
buildCheckCount++;
}
c.appendChild(cb);
c.appendChild(document.createElement('br'));
}
</script>
</body></html>
Adapt code from one question's answer or another answer from earlier this month. Set N = x = number of checkboxes and M = y = number to be checked and apply formula (N*i+N)/M - (N*i)/M for section sizes. (Also see Joey Adams' answer.)
In python, the adapted code is:
N=100; M=33; p=0;
for i in range(M):
k = (N+N*i)/M
for j in range(p,k-1): print "-",
print "x",
p=k
which produces
- - x - - x - - x - - x - - [...] x - - x - - - x where [...] represents 25 --x repetitions.
With M=66 the code gives
x - x x - x x - x x - x x - [...] x x - x x - x - x where [...] represents mostly xx- repetitions, with one x- in the middle.
Note, in C or java: Substitute for (i=0; i<M; ++i) in place of for i in range(M):. Substitute for (j=p; j<k-1; ++j) in place of for j in range(p,k-1):.
Correctness: Note that M = x boxes get checked because print "x", is executed M times.
What about using Fisher–Yates shuffle ?
Make array, shuffle and pick first n elements. You do not need to shuffle all of them, just first n of array. Shuffling can be find in most language libraries.
I need to write a program for Pascal that makes array in spiral form like this:
(7) (8) (9) (10)
(6) (1) (2) (11)
(5) (4) (3) (12)
(16)(15)(14)(13)
Start from 1 and continue to 36 but this is not so important.
After 3 days thinking I have no idea how to realize this.
Problem is not in language syntax or arrays, it is just in the algorithm.
Can you help me with any ideas, links, pseudo-code or program code in any programming language?
Think of splitting the nxn matrix into concentric submatrixes of 2x2, 4x4, .. nxn. In your case we would have the outer sub-matrix (elements 5 to 16) and the inner one (elements 1 to 4).
Now, for each level you should iterate over the four edges, and fill them with the needed elements. You can go inside-out or outside-in. I will go outside-in. We keep a counter which is initially n*n (16 in our example).
For i going from 1 to n/2:
First take the bottom edge (elements 16-13 for outer level). We go from x[n-i+1][i] to x[n-i+1][n-i+1] and fill (this would be 16, 15, 14, 13 for the first level and 4,3 for the second level)
Then we take the right edge (elements 12-10 for outer level). We go from x[n-i][n-i+1] to x[i][n-i+1] (elements 12, 11, 10 for outer level).
Then we take the top edge (elements 9-7 for outer level). We go from x[i][n-i] to x[i][i] (elements 9, 8, 7 for outer level)
At last we take the left edge (elements 6-5 for outer level). We go from x[i+1][i] to x[n-i][i] and fill that side (this would be 6, 5 for outer level).
And at last you have the middle element if n is odd. Then all you have to do is to assign x[n/2+1][n/2+1] = 1
I hope I made the the idea clear; if there is something you don't understand, ask.
Also I didn't implement the solution because I assume that the problem you have is only the idea, not the implementation
There is one sweet idea you can use to change direction while iterating over the matrix. Look at the following table. Input (dX, dY) are the previous direction in increment values, and output (cwdx, cwdy) are the next clock-wise direction, and output (ccwdx, ccwdy) are the next counter-clockwise direction (coordinate (0,0) is in upper-left corner):
dx dy | cwdx cwdy | ccwdx ccwdy
-------------------------------
1 0 | 0 1 | 0 -1
0 1 | -1 0 | 1 0
-1 0 | 0 -1 | 0 1
0 -1 | 1 0 | -1 0
So, given direction (dx,dy) to turn clockwise you need direction (-dy,dx), and to turn counter-clockwise you need direction (dx,-dy). This means that you don't need a switch in your code to turn direction, you just do it by three lines of code:
temp = dx; // this is for clockwise turn
dx = -dy;
dy = temp;
And there is one more little trick. To fill the matrix you can actually start from the end and largest number, and make your way to center and number 1. If you start from edge and go to the center then you can fill the numbers in a line until you can (until you reach the edge of matrix or another number). If you can't fill in current direction anymore because (x+dx, y+dy) is not "fillable" then change direction.
The easiest idea is to start from the end of the spiral and work your way back.
Have four variables (left, top, right, bottom) that tell you how much you have filled appropriately from each side.
Make a matrix of appropriate size.
Initialize left = top = 0 and right and bottom to the last column and row index.
Fill the bottom row from left -> right. Decrease bottom by one.
Fill right from bottom -> top. Decrease right by one.
Fill top from right -> left. Increase top by one.
Fill left from top -> bottom. Increase left by one.
Iterate until you filled the whole matrix.
How about just apply the right-hand rule (like solving a maze).
Consider each cell after you walked become the wall.
Here's a snippet from a Java program to perform a spiral matrix visit. It tracks changes in directions to sense how many more visits to make while traveling in any given direction. The pattern that simplifies this problem is that while traveling in any given direction, the next time you visit that direction the number of visits to make is reduced by one. More simply put, if the first time you travel in the horizontal direction you will be making 6 visits the next time you travel in the horizontal direction you will make 5 visits. It should also be noted that the horizontal and vertical visits are tracked separately. A single equation below has been used to calculate the number of visits for a given direction after a change in direction is needed. This equation selects vertical or horizontal by deriving it from the total number of direction changes and using mod as a selector. Finally, thinking of the visits as a snake moving along the matrix I represented the step as the change in row/column as velocity (dy and dx). As another person pointed out there is a pattern that can be used and is expressed in the formula for dy and dx.
int[][] matrix = { { 1, 2, 3, 4, 5, 6, 7, 8 },
{ 24, 25, 26, 27, 28, 29, 30, 9 },
{ 23, 40, 41, 42, 43, 44, 31, 10 },
{ 22, 39, 48, 47, 46, 45, 32, 11 },
{ 21, 38, 37, 36, 35, 34, 33, 12 },
{ 20, 19, 18, 17, 16, 15, 14, 13 } };
int n = matrix.length;
int m = matrix[0].length;
int row = 0;
int col = 0;
int dx = 1;
int dy = 0;
int dirChanges = 0;
int visits = m;
for (int i = 0; i < n * m; i++) {
System.out.print(matrix[row][col] + " ");
visits--;
if (visits == 0) {
visits = m * (dirChanges %2) + n * ((dirChanges + 1) %2) - (dirChanges/2 - 1);
int temp = dx;
dx = -dy;
dy = temp;
dirChanges++;
}
col += dx;
row += dy;
}
The output of this program is:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
To #1
I wrote the program but the result looks like this:
00000
10000
11000
11100
.....
I don't know maybe I have not understood your algorythm or any other problem happened.
Here is code:
n:=16;
x:=1;
For i:=1 to (n div 2) do
begin
For p:=i to n-i+1 do
begin
a[n-i+1,p]:=x;
end;
For q:=n-i to i do
begin
a[q,n-i+1]:=x;
end;
For o:=n-i to i do
begin
a[i,o]:=x;
end;
For u:=i+1 to n-i do
begin
a[u,i]:=x;
end;
end;
So I tried to write #2 program from php to pascal and it works.
Now I will fix it to write numbers clockwise and start from center of array.
Big thank you all.
CurValue = n * n;
End point is the most down left point.
We'll visit from the end point to the first point ( we assign values with visiting )
Every cell has zero value at the beginning.
x = n-1;
y = 0;
arr[x][y] = CurValue;
while ( CurValue greater than zero )
{
keep going right until you face a cell that has non-zero value or until you reach the most right cell
keep going top until you face a cell that has non-zero value or until you reach the most top cell
keep going left until you face a cell that has non-zero value or until you reach the most left cell
keep going down until you face a cell that has non-zero value or until you reach the most down cell
}
note: with each cell you visit then do the following :
CurValue --;
Assign CurValue to the current visited cell;
I hope the algorithm above is clear to understand.
Here's a recursive solution written in PHP.
<?php
header('Content-type: text/plain');
function fill($x, $y, $dir, $leftInDir, $index, $stepSize, $stop){
global $out;
// set the value for the current item //
$out[$y][$x] = $index;
// everything that comes after this point is computing for the parameters of the next call //
// activate this for debugging //
//echo $x, ',', $y, ',', $dir, ',', $leftInDir, ',', $index, ',', $stepSize, ',', $stop, "\n";
// decrease the number of steps left to take in the current direction //
$leftInDir--;
// check if this is the last item //
if($index == $stop)
return;
// we're going up for the next item //
if($dir == 'U')
$y--;
// we're going right for the next item //
if($dir == 'R')
$x++;
// we're going down for the next item //
if($dir == 'D')
$y++;
// we're going left for the next item //
if($dir == 'L')
$x--;
// if this was the last step in this direction we need to change the direction //
if($leftInDir == 0){
// after two direction changes we need to increase the numbers of steps to take //
if($dir == 'D' || $dir == 'U'){
$stepSize++;
}
// update the direction clockwise //
if($dir == 'U')
$dir = 'R';
else if($dir == 'R')
$dir = 'D';
else if($dir == 'D')
$dir = 'L';
else if($dir == 'L')
$dir = 'U';
// set the number of steps left as the step size //
$leftInDir = $stepSize;
}
// increase the number to put in the cell //
$index++;
// call for the next item //
fill($x,$y,$dir,$leftInDir,$index,$stepSize,$stop);
}
// set the size //
$size = 100;
// start the process from the center of the matrix //
fill((int)$size/2, (int)$size/2, 'R', 1, 1, 1, $size*$size);
// just output //
ksort($out);
foreach($out as $row){
ksort($row);
foreach($row as $item){
echo str_pad($item, 7);
}
echo "\n";
}
?>
The principle is quite straight forward (well, not straight, but in a spiral, forward :) ). You start from where 1 should be and start walking. 1 RIGHT, 1 DOWN, 2 LEFT, 2 UP, 3 RIGHT, etc. until you reach n*n.
I wrote it as a recursive function, but it can easily be converted to a loop.
Do you mean that it has to print out the numbers from left-to-right, top to bottom? It helps to know that to make square numbers, you add consecutive odd numbers together - 1 + 3 + 5 + 7 + 9 + 11 = 36.
In this spiral, the left-hand edge is simple ... except for the bottom row. So one way to go is to write your algorithm as if the spiral was one loop bigger, but don't print out the first row and first and last column.
import java.util.Scanner;
class CircularMatrixFromInnerClockwise
{
Scanner sc= new Scanner(System.in);
void main()
{
System.out.println("Enter size.");
int n=sc.nextInt();
int a[][]= new int [n][n];
int r1,c1,r2,c2;
if(n%2==0)
{
r1=n/2-1;
c1=n/2-1;
r2=n/2-1;
c2=n/2-1;
}
else
{
r1=(n+1)/2-1;
c1=(n+1)/2-1;
r2=(n+1)/2-1;
c2=(n+1)/2-1;
}
int k=1;
do
{
if(c2<n-1&&r2<n-1)
{
r2++;
c2++;
}
for(int i=c1;i<=c2;i++)
a[r1][i]=k++;
if(k>=n*n)
break;
for(int i=r1+1;i<=r2;i++)
a[i][c2]=k++;
if(k>=n*n)
break;
if(c1>0&&r1>0)
{
c1--;
r1--;
}
for(int i=c2-1;i>=c1;i--)
a[r2][i]=k++;
if(k>=n*n)
break;
for(int i=r2-1;i>=r1+1;i--)
a[i][c1]=k++;
if(k>=n*n)
break;
}while(k<=n*n);
System.out.println("Circular matrix");
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
System.out.print( a[i][j]+"\t");
}
System.out.println();
}
}
}
You're going from left to right, then down. left , up and all over again. Hope it helps. :)