Similar to a previous exercise, I am arranging cubes in a letter W. Again, if you're having trouble visualizing the end result, then think of every cube as a pixel, building a sprite of 'W'.
I created 4 sections of my code, 1 for each stroke making up the letter, but 2 of each have the same 'root point':
file -f -new;
//Specifies starting coordinates
int $xpnt1 = 5.5;
int $xpnt2 = -5.5;
//////////////////
for($i=1;$i<=25;$i++) { //BRANCH 1, POINT 1, DIR L
polyCube;
move -ws $xpnt1 0 0;
//select "pCube1";
move -r ($i*1) ($i*1) 0;
move -r $xpnt1 0 0 pCube1.scalePivot;
}
for($i=1;$i<=25;$i++) {//BRANCH 2, POINT 1, DIR R
polyCube;
move -ws $xpnt1 0 0;
//select "pCube26";
move -r ($i*-1) ($i*1) 0;
move -r $xpnt1 0 0 pCube26.scalePivot;
}
for($i=1;$i<=25;$i++) {//BRANCH 3, POINT 2, DIR L
polyCube;
move -ws $xpnt2 0 0;
//select "pCube51";
move -r ($i*1) ($i*1) 0;
move -r $xpnt2 0 0 pCube51.scalePivot;
}
for($i=1;$i<=25;$i++) { //BRANCH 4, POINT 2, DIR R
polyCube;
move -ws $xpnt2 0 0;
//select "pCube76";
move -r ($i*-1) ($i*1) 0;
move -r $xpnt2 0 0 pCube76.scalePivot;
}
So far, I've been able to get the cubes to spawn how I'd like. The main problem here is one that came up erroneously: despite having 2 of each share either 5.5 or -5.5 as starting coordinates, they end up being spaced apart by what appears to be the program:
this is the current result. What ever could I be missing or ignoring that's causing this problem?
KEEP IN MIND THAT I'M AWARE 5.5/-5.5 WILL NOT PRODUCE A CORRECT W. I'M USING THESE COORDS TO TEST SPAWNING BASE CUBES TO OCCUPY THE SAME SPACE.
Shifting the part in the for loops from for($i=1;$i<=25;$i++) to for($i=0;$i<25;$i++) will stop there being a gap.
Previously when the loops started with $i=1, it meant that, in the first iteration, the lines with move -r ($i*±1) ($i*±1) 0; would move the first block by 1 diagonal from the starting coordinate.
Since we would like the first block in each branch not to be shifted from the starting coordinate, we want the line move -r ($i*±1) ($i*±1) 0; to have no effect in the first iteration. To fix it, we can have $i equal to 0 in the first iteration so that the line becomes move -r 0 0 0; for the first block.
And at the end you still want there to be 25 blocks in each branch, so the ending condition for the For loop is changed from $i<=25 to $i<25 to account for there being a shift at the start.
Here is the code (the only thing that is changed is the conditions for each of the 4 For loops.)
file -f -new;
//Specifies starting coordinates
int $xpnt1 = 5.5;
int $xpnt2 = -5.5;
//////////////////
for($i=0;$i<25;$i++) { //BRANCH 1, POINT 1, DIR L
polyCube;
move -ws $xpnt1 0 0;
//select "pCube1";
move -r ($i*1) ($i*1) 0;
move -r $xpnt1 0 0 pCube1.scalePivot;
}
for($i=0;$i<25;$i++) {//BRANCH 2, POINT 1, DIR R
polyCube;
move -ws $xpnt1 0 0;
//select "pCube26";
move -r ($i*-1) ($i*1) 0;
move -r $xpnt1 0 0 pCube26.scalePivot;
}
for($i=0;$i<25;$i++) {//BRANCH 3, POINT 2, DIR L
polyCube;
move -ws $xpnt2 0 0;
//select "pCube51";
move -r ($i*1) ($i*1) 0;
move -r $xpnt2 0 0 pCube51.scalePivot;
}
for($i=0;$i<25;$i++) { //BRANCH 4, POINT 2, DIR R
polyCube;
move -ws $xpnt2 0 0;
//select "pCube76";
move -r ($i*-1) ($i*1) 0;
move -r $xpnt2 0 0 pCube76.scalePivot;
}
Here is an image of what it now looks like and there are two blocks in the starting coordinates as expected.
Related
I'm trying to write a program that generates a crossword grid, so I'm using the ncurses library because I just need a simple interface to display the grid, the problem is when I use box() function with ACS_VLINE and ACS_HLINE, it doesn't work; it writes 'q' and 'x' instead of the box lines. It worked at the beginning but suddenly it stopped working; I don't know why.
I'm simply initializing ncurses with initscr() and noecho().
Here's the part of the code where I draw the box:
int crossword(char ***grid, WINDOW **win, WINDOW ****c, int x, int y)
{
int i;
int j;
int ch;
t_word_list *wrdlist;
clear();
(void)x;
(void)y;
if (!(wrdlist = get_words("data/words.list")))
return (-1);
box(*win, ACS_VLINE, ACS_HLINE);
i = -1;
while ((*c)[++i])
{
j = -1;
while ((*c)[i][++j])
mvwaddch((*c)[i][j], 0, 0, (*grid)[i][j]);
}
wrefresh(stdscr);
while ((ch = getch()))
if (ch == 27)
{
nodelay(stdscr, TRUE);
ch = getch();
nodelay(stdscr, FALSE);
if (ch < 0)
break ;
}
return (endwin());
}
Output:
lqqqqqqqqqqqqqqqqqqqqqk
x 0 0 0 0 0 0 0 0 0 0 x
x 0 0 0 0 0 0 0 0 0 0 x
x 0 0 0 0 0 0 0 0 0 0 x
x 0 0 0 0 0 0 0 0 0 0 x
x 0 0 0 0 0 0 0 0 0 0 x
x 0 0 0 0 0 0 0 0 0 0 x
x 0 0 0 0 0 0 0 0 0 0 x
x 0 0 0 0 0 0 0 0 0 0 x
x 0 0 0 0 0 0 0 0 0 0 x
x 0 0 0 0 0 0 0 0 0 0 x
mqqqqqqqqqqqqqqqqqqqqqj
EDIT: I recreated the problem with minimal code:
#include <curses.h>
int main(void)
{
WINDOW *win;
initscr();
win = subwin(stdscr, 10, 10, 1, 1);
box(win, ACS_VLINE, ACS_HLINE);
wrefresh(stdscr);
getch();
return (0);
}
Output:
lqqqqqqqqk
x x
x x
x x
x x
x x
x x
x x
x x
mqqqqqqqqj
The flags I use for compilation: gcc main.c -lcurses
Converting parts of comments into an answer.
What did you change between when it worked and when it stopped working? … Can you recreate the steps you would have used while creating the working version in a new MCVE (Minimal, Complete, Verifiable Example
— or MRE or whatever name SO now uses)
or an
SSCCE (Short, Self-Contained, Correct Example).
This would allow you to find out what breaks the working code with the bare minimum of code?
… I just edited my atoi function that I just use in the main for the sizeX and sizeY; I didn't touch anything else and it suddenly stopped working. I tried to undo what I did after it wasn't working and it still doesn't work.
So you changed something else as well, whether or not you realized it. It's possible that the terminal settings are screwed up — funnier things have been known. Have you tried creating a new terminal window and trying again in the new window?
Oh yes! It was the terminal! It worked after a 'reset', thank you! I don't know why I didn't think about that earlier.
Until curses (ncurses) programs have proved themselves reliable, always consider the possibility that a flawed version of the program under test messed up the terminal settings. Use stty -g to generate a string when the terminal is working properly (when first created, before you run your program). You can then use that string to reset the terminal to the same known state (assuming it is stty settings that are the problem). Sometimes, a new terminal window is necessary even so.
good_stty=$(stty -g)
…testing program under development…
stty "$good_stty"
Sometimes, you may need to type control-J and then stty "$good_stty" (or stty sane) and another control-J because the line ending settings have been modified and not restored correctly.
The problem may be the console encoding for your console. Also if you access from putty you must follow the following steps.
Verif console configuration is UTF
dpkg-reconfigure console-setup
I wrote a function that sets every number of a line in a .txt file to zero and clears the other file.
I originally wrote this logic in main and it worked perfectly fine. But now I need to make a menu for my program, so I need to put this logic into a function.
That's where the things go wrong. Once I move the logic into a function, it doesn't set the numbers to zero, it just clears the file, and I didn't changed anything.
Expected result:
Workers.txt : Adam Washington Monday Friday --(use function)--> {clear}
days.txt: 1 0 0 0 1 0 0 --(use function)--> 0 0 0 0 0 0 0
Actual result:
It's clear in both files.
void ResetOwnData(){
printf("--------------------------------------------------------------------------\n");
FILE* freset = fopen ("workers.txt", "w");
close(freset);
FILE* freset2 = fopen ("days.txt", "w");
for(int i = 0; i < 7; i++){
fprintf(freset2,"%d ",i+1);
}
fprintf(freset2,"\n");
for(int i = 0; i < 7; i++){
fprintf(freset2,"%d ",0);
}
close(freset2);
printf("Everything get reset!\n");
printf("--------------------------------------------------------------------------\n");
}
There are two main things that appear to be incorrect.
You are using close rather than fclose. fclose is used with file streams (like you are using)
Your function is overwriting the one line that you want (e.g., 0 0 0 0 0 0 0) with two lines because you have two for loops
Here is a CodingGround link to the corrections that I believe you are seeking.
You should add some error checking to ensure that you truly have opened the file and that you release any allocated memory
I have an array like this (0,0 is bottom left):
0 0 0 0 0 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 0 1 0 1 0 0
0 0 1 1 1 1 1 1 1
1 0 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1
My goal is to get the index of the higher line who is not completely set to 0. For this I made the code below (which works fine):
max=0;
for (i=0 ; i<width ; ++i) {
for (j=max ; j<height ; ++j) {
if (array[i*height+j]!=0) {
max=j;
}
}
}
For the second loop I initialize j to max, because the global maximum cannot be less than a local maximum. And this way I can reduce the number of tests.
The I tried to parallelize it with OpenMp. My code is now:
max=0;
#pragma omp parallel for default(none) \
shared(spec, width, height) \
collapse(2) \
reduction(max:max)
for (i=0 ; i<width ; ++i) {
for (j=max ; j<height ; ++j) {
if (array[i*height+j]!=0) {
max=j;
}
}
}
Which leads to a segmentation fault. In order to make it works, I changed j=max to j=0. So the problem seems to come from the max variable.
I don't understand why, because with the reduction this variable should be private (or lastprivate) between each threads. So why does it make it crash ? And how can I use my "optimization" with OpenMP ?
First of all, the user High Performance Mark is right in his comment. You shouldn't be using collapse if your loop index values depend on the value of a calculation. In your example, "j" depends on "max", which will produce an incorrect result. However, this is not the cause of your segmentation fault.
I would suggest you to debug your example so that you can find the source of the crash; "max" is being initialized with a negative number by default, which causes "j" to also have said value. Thus, when trying to access array[i*height+(-2147483648)], you get a segmentation fault.
This happens because OpenMP specifies an initial value for each reduction operator. In the case of the max operator, you can find the following description in the specification of OpenMP 3.1:
max Least representable value in the reduction list item type
In our case, that means that each thread will have at the start of the parallel region a private copy of the max variable holding the value of the lowest number that can be stored as an int (usually -2147483648).
I've written a very rudimentary workaround for your example. I removed the collapse clause and I'm initializing the max variable manually at the start of the parallel region:
#pragma omp parallel default(none) private(j) shared(array, width, height) reduction(max:max)
{
// Explicit initialization
max = 0;
#pragma omp for
for (i=0 ; i<width ; ++i) {
for (j=max ; j<height ; ++j) {
if (array[i*height+j]!=0) {
max=j;
}
}
}
}
As an extra remark, you shouldn't need to use max=j everytime. You could try to check when the first 0 is found and use the previous position.
Hope it helps
Given an array with just 0's and 1's.
If a 0 is left of a 1 then they swap theirs values
count the number of steps to take all 0's to the right of the array.
EXAMPLE1
if array=[0 1 0 0 1 0 1 0 1]
[1 0 0 1 0 1 0 1 0]
[1 0 1 0 1 0 1 0 0]
[1 1 0 1 0 1 0 0 0]
[1 1 1 0 1 0 0 0 0]
[1 1 1 1 0 0 0 0 0]
the Answer is ```5``` steps.
EXAMPLE2
if array=[0 1 0 1 0]
[1 0 1 0 0]
[1 1 0 0 0]
The Answer= 2
I wrote code to do what is asked. But its very slow for large size of the array :( pls help
I think this problem can be best solved using A* search with hamming like heuristic function (we need to prove the heuristic is admissible). Here are the steps:
For the given array, first compute the goal array that we want to reach (simply sort the array descending).
Represent the problem as a (graph) search problem, where the source node is the given array, adjacent nodes are defined to be the arrays that can be obtained by a single 0 1 swap.
Push the source node to a priority queue, where the priority is defined to be as the sum of the distance from the source node (f(.)) and heuristic function (h(.)=hamming distance) from the goal node. The node in the queue with minimum priority will be popped first, breaking ties arbitrarily.
Iteratively pop a node from the priority queue until the goal node is reached and push all the adjacent nodes not visited yet to the queue, updating the distance from the source for the popped node.
Stop once the goal node is popped.
Calculate the waiting time for each 1. now take the waiting time of the last 1 say t1 and add the number of zeros before it say totatlz.
your answer = t1 + totalz
#include <bits/stdc++.h>
using namespace std;
#define mp make_pair
#define pb push_back
#define vll vector<ll>
#define F first
#define S second
#define pll pair<ll,ll>
#define FOR1(i,a) for(i=0;i<=a;i++)
#define FOR2(i,a,b) for(i=a;i<=b;i++)
#define endl '\n'
#define clr(a) memset(a,0,sizeof(a))
#define all(x) x.begin(),x.end()
typedef long long ll;
int main()
{
ll t,i;
cin>>t;
while(t--)
{
ll n,totalz=0,interval=0,k=0,j;
cin>>n;
ll asyncTime[n]={0},a[n]={0};
bool flag=false;
FOR1(i,n-1)
cin>>a[i];
FOR1(i,n-1)
{
if(!a[i])
totalz+=1;
else
{
flag=true;
asyncTime[k]=0;
k+=1;
j=i+1;
break;
}
}
int l,lastpos;
FOR2(i,j,n-1)
{
if(!a[i])
totalz+=1,interval+=1;
else
{
if(asyncTime[k-1]>=interval)
asyncTime[k]=asyncTime[k-1]-interval+1;
else
asyncTime[k]=0;
interval=0;
k+=1;
lastpos=i;
}
}
// FOR1(i,n-1)
// cout<<a[i]<<" ";
// cout<<endl;
// FOR1(i,k-1)
// cout<<asyncTime[k]<<" ";
// cout<<endl;
if(flag)
{
if(asyncTime[k-1]==k-1&&lastpos==k-1)
cout<<"0"<<endl;
else
cout<<asyncTime[k-1]+totalz<<endl;
}
else
cout<<"0"<<endl;
}
return 0;
}
I'm making this project that includes sensors. I have two sensors, one at left and right. I have succeeded detecting left and right motions, but when I just spam "sense" a sensor, let's say left sensor, it reads as i have swiped left. Can you tell me what's the problem?
to understand my code I have drawn the "required" sequence to say that I have swiped. (0 detected, 1 nothing detected)
For left
1. L=1, R=1
2. L=0, R=1
3. L=0, R=0
4. L=1, R=0
For right
1. L=1, R=1
2. L=1, R=0
3. L=0, R=0
4. L=0, R=1
Here's my code
int rs=7,ls=6,r,l,x,xx,xxx,z; //rs right sensor, ls left sensor
void setup() {
Serial.begin(9600);
pinMode(rs, INPUT);
pinMode(ls, INPUT);
pinMode(13,OUTPUT);
}
void loop() {
digitalWrite(12,LOW);
digitalWrite(13,LOW);
r= digitalRead(rs);
l= digitalRead(ls);
if(r==1&&l==1)
x=1;
else x=0;
//RIGHT MOTION
if(x==1){
for(z=1;z<10000;z++){
if(digitalRead(ls)<digitalRead(rs)){
z=10000;xx=1;}}
if(xx=1){
for(z=1;z<10000;z++){
if(digitalRead(ls)==0&&digitalRead(rs)==0){
z=10000;xxx=1;}}}
if(xxx==1){
for(z=1;z<10000;z++){
if(digitalRead(ls)>digitalRead(rs)){
z=10000;Serial.println("Right motion");digitalWrite(12,HIGH);}}}}
//LEFT MOTION
if(x==1){
for(z=1;z<10000;z++){
if(digitalRead(ls)>digitalRead(rs)){
z=10000;xx=1;}}
if(xx=1){
for(z=1;z<10000;z++){
if(digitalRead(ls)==0&&digitalRead(rs)==0){
z=10000;xxx=1;}}}
if(xxx==1){
for(z=1;z<10000;z++){
if(digitalRead(ls)<digitalRead(rs)){
z=10000;Serial.println("Left motion");digitalWrite(13,HIGH);}}}}
}
I set my loop 10000 times because 1 whole loop is so fast to detect a motion.
Thanks in advance.
In short: You never reset your vars x, xx, xxx back to 0. Also you use both "Sets" of variables for both kinds of Motion. So the
digitalRead(ls) < digitalRead(rs)
sets xx = 1 and
digitalRead(ls) > digitalRead(rs)
Also sets xx = 1.
The first thing to do would be to name the "first" (everything after //RIGHT MOTION to //LEFT MOTION) x, xx, xxx to something like: rightMotionStep1 rightMotionStep2 and rightMotionStep3 and the later x, xx, xxx to: leftMotionStep1 leftMotionStep2 and leftMotionStep3.
of course you also have to declare these Vars.
The next thing is that you have to reset all of the vars so after your
Serial.println("Right motion");
there should be
rightMotionStep1 = 0;
rightMotionStep2 = 0;
rightMotionStep3 = 0;
same thing for left motion.