For my java class one of the exercises is to print out a diamond using nested for loops. In the exercise you need to use the minimum amount of outputs, while using nested for loops. The other stipulation is that each output can only output 1 character such as a single space, a single asterisk, or a single end line statement.
I've finished it but i was wondering if there was an easier way to do it, or if anyone has tips on cleaning up my code. It just seems like ended up writing way more than was needed. Any help and tips are greatly appreciated. :)
Here is what the end result needs to look like:
Here is my code:
public class Diamond
{
public static void main(String args[])
{
int b = 11; // secondary asterisk loop counter
int ac = 2; // asterisk count
int sc = 5; // space count
int elc = 2; // end line count
int slc = 1; // space loop count
int sslc = 1; // secondary space loop count
for(int e = 1; e < elc && elc < 12;e++)
{
if(elc <= 6)
{
for(int a = 1; a < ac; a++)
{
for(;sc <= 5 && sc > 0; sc--)
{
System.out.print(" ");
}
System.out.print("*");
}
ac += 2;
sc = 5 - slc;
slc += 1;
}
else if (elc > 6)
{
ac -= 2;
sc = 1;
for (; b < ac ; b++)
{
for(;sc <= sslc && sc > -2; sc++)
{
System.out.print(" ");
}
System.out.print("*");
}
b = 1;
sslc += 1;
}
if(elc != 6)
{
System.out.println();
}
elc += 1;
}
}
}
You may try writing down the 4 edges of the diamond as equations (x+y=4; x-y=2... for example). Then just make a nested loop through each of the cell in the grid to see if you should print a space or a star. The test would look like
If f1(x,y) or f2(x,y) or f3(x,y) or f4(x,y): print '*' else print ' '
where f1,f2,f3,f4 are the equations for the 4 diagonals.
If you are required to minimize the number of characters to be printed, either use an array to prepare, then ignore the trailing spaces; or use some ad-hoc rule (like every row only 2 stars except the 1st and last...)
public class ASultan
{
public static void main(String[] args) {
int size = 9;
for (int i = 1; i < size; i += 2) {
for (int k = size; k >= i; k -= 2) {
System.out.print(" ");
}
for (int j = 1; j <= i; j++) {
System.out.print("*");
}
System.out.println();
}
for (int i = 1; i <= size; i += 2) {
for (int k = 1; k <= i; k += 2) {
System.out.print(" ");
}
for (int j = size; j >= i; j--) {
System.out.print("*");
}
System.out.println();
}
}
}
Related
void evolve(board prv, board nxt){
int i, j;
int n;
printf("\rGeneration %d\n", generation++);
if (printLazy == 1){
lazyPrint(prv);
for (j=0; j < WIDTH; ++j) {
for (i = 0; i < HEIGHT; ++i) {
n = neighbors(prv, i, j);
if (prv[i][j] && (n == 3 || n == 2))
nxt[i][j] = true;
else if (!prv[i][j] && (n == 3))
nxt[i][j] = true;
else
nxt[i][j] = false;
}
}
}
** Some asked me to add the neighbors method so
static int neighbors (board b, int i, int j) {
int n = 0;
int i_left = max(0,i-1);
int i_right = min(HEIGHT, i+2);
int j_left = max(0,j-1);
int j_right = min(WIDTH, j+2);
int ii, jj;
for (ii = i_left; ii < i_right; ++ii) {
for (jj = j_left; jj < j_right; ++jj) {
n += b[ii][jj];
}
}
return n - b[i][j];
}
So I am working on optimizing this so that it will go faster and I'm stuck on how to optimize this more. Here's what I have so far
void evolve(board prv, board nxt) {
register int i, j;
int n;
bool next;
printf("\rGeneration %d\n", generation++);
if (printLazy == 1){
lazyPrint(prv);
}
for (j=0; j < WIDTH; ++j) {
for (i = 0; i < HEIGHT; ++i) {
n = neighbors(prv, i, j);
if (prv[i][j])
if (n == 2)
next = true;
else if (n == 3)
next = true;
else
next = false;
else
if(n == 3)
next = true;
else
next = false;
nxt[i][j] = next;
}
}
}
Is there a better way to do this or are there any resources or videos y'all recommend?
Thanks, any help is appreciated.
Some ideas Inline your function neighbors(). Or turn it into a macro. Tidy up the conditional. To unroll the inner loop replace every use of i with the literal values so your code looks like :
for (j =0;.......
n = fun(prev, 0 ,j);
If.....
n = fun(prev, 1, j);
if......
and so on.
If the value of HEIGHT was let's say 100, then you get a code explosion of 100 function calls and 100 compound conditionals. Even worse if you unroll the outer loop.
If n was limited to say 8 neighbors, use a lookup table
bool foo[2][8] = { [1][2] = true, [1][3] = true, [0][3] = true };
for (j=0; j < WIDTH; ++j) {
for (i = 0; i < HEIGHT; ++i) {
n = neighbors(prv, i, j);
nxt[i][j] = foo[prv[i][j]][n];
}
}
A common weakness is the neighbors(prv, i, j) function itself. One trick to to oversize the 2D array by 1 on all four sides and populate the edge with false so neighbors() can always check 8 neighbors as it is never used on the edge/corners.
Making sure the 2nd dimension is a power of 2 helps also - simplifies index calculation. So if the original array way 12*11, make the new array (1+12+1)*(1+11+1+4) or 14*16.
I am new to C, and I am trying to print diamond shapes according to the rows(2~10), columns(2~10) and the length(3, 5, 7, 9) of the diamond input from the user.
Using the code below I can print diamond and number of diamonds correctly, but I just can't get the correct distance between them.
void printDiamondWith(int diamondlength, int numberOfDiamonds) {
int i, j, k;
int star, space;
star = 1;
space = diamondlength;
for (i = 1; i < diamondlength * 2 - 1; i++) {
for (k = 0; k < numberOfDiamonds; k++) {
for (j = 0; j < space; j++) {
printf(" "); // Print the distance for the previous star
}
for (j = 1; j < star * 2; j++) {
printf("*");
}
for (j = 0; j < space; j++) {
printf(" "); // Print the distance for the next star
}
}
printf("\n");
// Check if length is equal 3, else length -1 to get the correct rows of second half of the diamond
if (diamondlength == 3) {
// Loops until the first half of the diamond is finished, then reverse the process to print the second half
if(i < (diamondlength - diamondlength / 3)) {
space--;
star++;
} else {
space++;
star--;
}
} else if (diamondlength >= 3) {
if (i < (diamondlength - 1 - diamondlength / 3)) {
space--;
star++;
} else {
space++;
star--;
}
}
}
}
Actual running result:
Expected result:
Your formulas for calculating the space is off. It works for me when I change this
space = diamondlength;
to this
space = diamondlength/2+1;
And this
for (k = 0; k < numberOfDiamonds; k++) {
for (j = 0; j < space; j++) {
to this:
for (k = 0; k < numberOfDiamonds; k++) {
for (j = 0; j < space-1; j++) {
In such situations I recommend hardcoding the variable for different parameters and write down what the variable has to be for what parameter so you can try to find a function that maps the parameter to the value. For instance I saw that as diamondlength increased, the space error also increased, so the relation between parameter and variable can't be one to one.
I'm trying to develop a code to solve the Travelling salesman problem in C, but I have some restrictions: I can only use "for, "while", "do", arrays, matrix and simple things like that, so, no functions or recursion (unfortunately).
What I've got so far:
The user will will type the city coordinates X and Y like this:
8.15 1.58
9.06 9.71
1.27 9.57
9.13 4.85
The code to storage the coordinates.
float city[4][2];
int i;
for (i=0; i<4; i++)
scanf("%f %f", &cidade[i][0], &cidade[i][1]);
There are 4 cities, so "i" goes from 0 to 3. X and Y are storaged on the second dimension of the matrix, [0] and [1].
The problem now is that I have to generate ALL POSSIBLE permutations of the first dimension of the matrix. It seems easy with just 4 cities, because all possible routes are (it must starts with city A everytime):
A B C D
A B D C
A C B D
A C D B
A D C B
A D B C
But I'll have to expand it for 10 cities. People have told me that it will use 9 nested foor loops, but I'm not being able to develop it =(
Can somebody give me an idea?
Extending to 10 (and looking up city names) as an exercise for the reader. And it's horrid, but that's what you get with your professor's limitations
#include <stdio.h>
int main(void) {
for (int one = 0; one < 4; one++) {
for (int two = 0; two < 4; two++) {
if (two != one) {
for (int three = 0; three < 4; three++) {
if (one != three && two != three) {
for (int four = 0; four < 4; four++)
if (one != four && two != four && three != four) {
printf("%d %d %d %d\n", one, two, three, four);
}
}
}
}
}
}
return 0;
}
This is based on https://stackoverflow.com/a/3928241/5264491
#include <stdio.h>
int main(void)
{
enum { num_perm = 10 };
int perm[num_perm];
int i;
for (i = 0; i < num_perm; i++) {
perm[i] = i;
}
for (;;) {
int j, k, l, tmp;
for (i = 0; i < num_perm; i++) {
printf("%d%c", perm[i],
(i == num_perm - 1 ? '\n' : ' '));
}
/*
* Find largest j such that perm[j] < perm[j+1].
* Break if no such j.
*/
j = num_perm;
for (i = 0; i < num_perm - 1; i++) {
if (perm[i + 1] > perm[i]) {
j = i;
}
}
if (j == num_perm) {
break;
}
for (i = j + 1; i < num_perm; i++) {
if (perm[i] > perm[j]) {
l = i;
}
}
tmp = perm[j];
perm[j] = perm[l];
perm[l] = tmp;
/* reverse j+1 to end */
k = (num_perm - 1 - j) / 2; /* pairs to swap */
for (i = 0; i < k; i++) {
tmp = perm[j + 1 + i];
perm[j + 1 + i] = perm[num_perm - 1 - i];
perm[num_perm - 1 - i] = tmp;
}
}
return 0;
}
I'm trying to track a player's location with x marking their spot. When the player enters a string I increment the coordinates accordingly. However when the player is located one space from the perimeter, then attempts to move to the edge of the map, the player disappears.
Example:
.....
...x.
.....
.....
.....
Player located at 'x'
If player enters string "right" and I move player_loc, array simply returns:
.....
.....
.....
.....
.....
I attempted to add a sort of buffer by increasing the size of the array. No luck. I've been stuck on this for almost a week now. Any help would be appreciated. I apologize for messy code. I'm a total newbie at this and I'm really just futzing around in the dark with all this stuff. I've researched this across the forums here and haven't found a solution. If you know of something that I possibly (probably) missed feel free to point me in that direction.
#include <stdio.h>
#include <string.h>
char map[6][6];
char player_loc = 'x';
int row;
int col;
void init_map()
{
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
map[i][j] = '.';
}
}
}
void print_map()
{
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
printf("%c", map[i][j]);
}
printf("\n");
}
}
int get_player_loc()
{
for (int j = 0; j < 5; j++) {
for (int k = 0; k < 5; k++) {
if(map[j][k] == player_loc)
{
row = k;
col = j;
}
}
}
return row;
return col;
}
void init_player_loc()
{
int check = 1;
for (int g = 0; g < 5; g++) {
for (int h = 0; h < 5; h++) {
if (map[g][h] == 'x') {
check = 0;
}
}
}
if(check == 1) {
map[0][0] = player_loc;
} else {
get_player_loc();
}
}
void move_left()
{
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
if (map[i][j] == player_loc) {
map[i][j-1] = player_loc;
map[i][j] = '.';
}
}
}
}
void move_right()
{
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
if (map[i][j] == player_loc) {
map[i][j+1] = player_loc;
map[i][j] = '.';
}
}
}
}
int main(int argc, char* argv[])
{
char input[15];
printf("You enter a room...you can go left, right, or straight. Which way do you go?\n");
int done = 0;
init_map();
map[3][3] = player_loc;
//init_player_loc();
print_map();
while (!done) {
scanf("%s", input);
if (strcmp("left", input) == 0) {
move_left();
printf("You go left...\n");
print_map();
get_player_loc();
printf("%d %d\n", row, col);
done = 1;
}
else if (strcmp("right", input) == 0) {
move_right();
printf("You go right...\n");
print_map();
get_player_loc();
printf("%d %d\n", row, col);
done = 1;
}
else if (strcmp("straight", input) == 0) {
printf("You go straight...");
done = 1;
}
else {
printf("Sorry, can't do that.\n");
}
}
}
You must break the loop if you find the player location, e.g
void move_right()
{
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
if (map[i][j] == player_loc) {
map[i][j+1] = player_loc;
map[i][j] = '.';
return;
}
}
}
}
In your code you move right the player, and the next loop will find the player in the new location and do the right move again, forever.
Moreover in your code you are not taking care of boundaries of your 2d matrix: j+1 is valid only if j<5.
Then a better code should be
void move_right()
{
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (map[i][j] == player_loc) {
map[i][j+1] = player_loc;
map[i][j] = '.';
return;
}
}
}
}
The problem is that your move_right function picks up the player and moves them completely off of the map. Let's say your player is at [0, 2] and step through the code.
for (int j = 0; j < 5; j++) {
if (map[i][j] == player_loc) {
map[i][j+1] = player_loc;
map[i][j] = '.';
}
}
[0, 0] No player here, move along
[0, 1] No player here, move along
[0, 2] Found a player! Move them right to [0, 3]
[0, 3] Found a player! Move them right to [0, 4]
[0, 4] Found a player! Move them right to [0, 5]
At 5, the loop ends. Because of the buffer you added, your array is 6x6, so the player is stashed in the wings without crashing the program. There are a few things you should do:
Once you've found and moved the player, break or return so they'll only move once.
Make your array 5x5 (or print all 6x6) so you can see everything.
Do some bounds checking so the player isn't allowed to move right from j = 5.
Watch out for this same bug in move_up, where it would happen as you increment i.
Your loops allow for checking the position twice, once at i,j, and again at i,(j+1) (or some other variant). This probably isn't what you intend. After you find the player you should make the updates and then break out of the loops.
Also, the code as is allows for indexing passed the bounds of the array, in theory. Also not what is desired. You may consider bounds checking. I don't know what is supposed to happen when the player moves right and there is a wall to the right. Does he not move? Wrap around? LR corner could cause seg fault as it is now.
You appear to have row and column indeces transposed in the get_player_loc function, as well as having two return statements (the compiler should warn you about unreachable code), neither of which is required or used by the calling code.
At the start, initialise the row and col variables. (Values taken from your main.)
int row = 3;
int col = 3;
Change the get_player_loc function so that it just updates the globals row and col. It sets row and col to 0 if the player is not found, as per the original.
void get_player_loc(void)
{
for (int j = 0; j < 5; j++) {
for (int k = 0; k < 5; k++) {
if(map[j][k] == player_loc)
{
// The meaning of row and col is set by how they are used
// to index the array in the move and print functions. Keep
// the same order and meaning here.
row = j;
col = k;
return;
}
}
}
// Set row and col to 0 if the location is not found.
row = 0;
col = 0;
map[0][0] = player_loc;
}
You'll still have problems when they reach an edge, due to the index into the array going out of bounds in the move functions, but that's a different problem.
Consider a zero-indexed array A of N integers. Indices of this array are integers from 0 to N−1. Take an index K.
Index J is called an ascender of K if A[J] > A[K]. Note that if A[K] is a maximal value in the array A, then K has no ascenders.
Ascender J of K is called the closest ascender of K if abs(K−J) is the smallest possible value (that is, if the distance between J and K is minimal).
Note that K can have at most two closest ascenders: one smaller and one larger than K.
Here is a C++ solution where complexity is O(n).
Note that there are two loops however each iteration the number of element goes by a factor of 1/2 or the search range goes up by a factor of x2.
For example the first iteration take N time, but the second iteration is already N/2.
vector<long> ascender(vector <long> A)
{
long N = A.size();
vector<long> R(N,0);
vector<long> IndexVector(N,0); //This vector contains the index of elements with R=0
vector<long> RangeVector(N,0); //This vector define the loop range for each element
IndexVector[N-1]=N-1;
unsigned long CompxTest = 0;
for (long counter=0;counter<N;counter++)
{
IndexVector[counter] = counter; // we start that all elements needs to be consider
RangeVector[counter] = 1; // we start by looking only and neighbors
}
long Length = N;
long range;
while (Length>1)
{
long index = 0;
cout<<endl<<Length;
long J;
for (long counter=0;counter<Length;counter++)
{
CompxTest++; // Just to test complexity
J = IndexVector[counter]; // Get the index that need to be consider
range = RangeVector[J];
//cout<<" ("<<A[J]<<","<<J<<")";
if (range > N)
{
cout<<endl<<"Mini assert "<<range<<" N "<<N;
break;
}
if (J<(N-range) && A[J+range] > A[J])
{
R[J] = range;
}
if (J<(N-range) && A[J+range] < A[J] && R[J+range]==0)
{
R[J+range] = range;
}
if (J<(N-range) && A[J] == A[J+range] && R[J+range]==0)
{
R[J+range] = - range;
}
if (R[J]==0) // Didn't find ascender for this element - need to consider in next iteration
{
if (R[J+range]>2) //We can increase the range because the current element is smaller
RangeVector[J] += R[J+range]-2;
if (R[J+range]<-2)
RangeVector[J] += -R[J+range]-2;
RangeVector[J]++;
IndexVector[index] = J;
index++;
}
}
Length = index;
}
for (long counter=0;counter<N;counter++)
{
if (R[counter] < 0)
{
unsigned Value = abs(R[counter]);
if (counter+Value<N && A[counter]<A[counter+Value])
R[counter] = Value;
if (counter > Value && R[counter-Value]==0)
R[counter] = 0;
R[counter] = Value + R[counter-Value];
if (counter > Value && Value < R[counter - Value])
{
long PossibleSolution = R[counter - Value] + Value;
if (PossibleSolution <N && A[PossibleSolution]>A[counter])
R[counter] = abs(counter - PossibleSolution);
}
}
}
cout<<endl<<"Complex "<<CompxTest;
return R;
}
//
// C++ using multimap. -- INCOMPLETE
// The multimap MM is effectively the "inverse" of the input array AA
// since it is ordered by pair(value, index), where index refers to the index in
// input array AA, and value is the value in AA at that index.
// Input AA is of course ordered as (index, value).
// So when we read out of MM in value order, (a sorted set of values), each value
// is mapped to the index in the original array AA.
//
int ascender(int AA[], int N, int RR[]) {
multimap<int, int> MM;
// simply place the AA array into the multimap
int i;
for (i = 0; i < N; i++) {
int value = AA[i];
int index = i;
MM.insert(make_pair(value, index));
}
// simply read the multimap in order,
// and set output RR as the distance from one value's
// original index to the next value's original index.
//
// THIS code is incomplete, since it is wrong for duplicate values.
//
multimap<int, int>::iterator pos;
for (pos = MM.begin(); pos != MM.end(); ++pos) {
int value = pos->first;
int index = pos->second;
++pos;//temporarily move ahead to next item
// NEED to FURTHER CONSIDER repeat values in setting RR
RR[index] = (pos)->second - index;
--pos;
}
return 1;
}
1. Sort the array (if not pre-sorted)
2. Subtract every element with its adjacent element and store result in another
array.
Example: 1 3 5 6 8 -----> (after subtraction) 2 2 1 2
3. Find the minimal element in the new array.
4. Device a logic which would relate the minimal element in the new array to the
two elements in the original one.
public class Solution {
final static int MAX_INTEGER = 2147483647;
public static int maximal(int[] A) {
int max = A[0];
int length = A.length;
for (int i = 1; i < length; i++) {
if (A[i] > max) {
max = A[i];
}
}
return max;
}
public static int ascender(int[] a,int length, int k) {
int smallest = MAX_INTEGER;
int index = 0;
if (k<0 || k>length-1) {
return -1;
}
for (int i = 0; i < length; i++) {
// Index J is called an ascender of K if A[J] > A[K].
if(a[i] > a[k]) {
int abs = Math.abs(i-k);
if ( abs < smallest) {
smallest = abs;
index = i;
}
}
}
return index;
}
public static int[] array_closest_ascenders(int[] A) {
int length = A.length;
int[] R = new int[length];
for (int K = 0; K < length; K++) {
// Note that if A[K] is a maximal value in the array A,
// then K has no ascenders.
// if K has no ascenders then R[K] = 0.
if (A[K] == maximal(A)) {
R[K] = 0;
break;
}
// if K has the closest ascender J, then R[K] = abs(K-J);
// that is, R[K] is equal to the distance between J and K
int J = ascender(A, A.length, K);
if (J != -1) {
R[K] = Math.abs(K - J);
}
}
return R;
}
public static void main(String[] args) {
int[] a = { 4, 3, 1, 4, -1, 2, 1, 5, 7 };
/* int[] a = {-589630174, 806785750, -495838474, -648898313,
149290786, -798171892, 584782920, -288181260, -252589640,
133741336, -174886978, -897913872 }; */
int[] R = array_closest_ascenders(a);
for (int element : R) {
System.out.print(element + " ");
}
}
}
Some notes about the code. I guess break in array_closest_ascenders method should be replaced by continue so that all elements are analyzed for their ascenders.
And, surely, maximal(A) have to be moved out of a loop; instead assign maximal value to some variable before entering the loop and use it within the loop, thus avoiding redundant calculation of max value.
Here is C# Solution
class Program
{
static void Main(string[] args)
{
int[] A = new int[] { 4, 3, 1, 4, -1, 2, 1, 5, 7 };
int[] B = new int[A.Length];
int[] R = new int[A.Length];
Program obj = new Program();
obj.ABC(A,B, R);
}
public void ABC(int[] A,int[]B, int[] R)
{
int i, j, m,k;
// int temp = 0;
int n = A.Length - 1;
for (i = 0; i < n; i++)
{
for (j = 0; j <= n; j++)
{
if (A[i] < A[j])
{
m = Math.Abs(j - i);
R[i] = m;
break;
}
}
for (j = i-1; j > 0; j--)
{
if (A[i] < A[j])
{
k = Math.Abs(j - i);
B[i] = k;
break;
}
}
}
for (i = 0; i < n; i++)
{
if (R[i] > B[i] && (B[i] == 0))
{
R[i] = R[i];
//Console.WriteLine(R[i]);
//Console.ReadLine();
}
else { R[i] = B[i]; }
}
}
}
Basically in the search function I compare the first element of the array with the one immediately right, if it's bigger this means it is the first closest ascendant. For the other elements I compare the one immediately at left and afterward the one immediately right his first right element. The first one which is bigger is the closest ascendant, and I keep iterate this way until I don't find an element bigger than one I am considering or I return 0.
class ArrayClosestAscendent {
public int[] solution(int[] A) {
int i;
int r[] = new int[A.length];
for(i=0;i<A.length;i++){
r[i] = search(A, i);
}
return r;
}
public int search(int[] A, int i) {
int j,k;
j=i+1;
k=i-1;
int result = 0;
if(j <= A.length-1 && (A[j]>A[i]))
return Math.abs(j-i);
j++;
while(k>=0 || j < A.length){
if(k >= 0 && A[k] > A[i]){
return Math.abs(i-k);
}else if(j < A.length && A[j] > A[i]){
return Math.abs(i-j);
}else{
j++;
k--;
}
}
return result;
}
}