Cellular Automaton not working - c

I am trying to create a Cellular Automaton based on this. I have managed to do it in a simple way that would follow only rule 90 but when I changed it to accept any rule I did something wrong.
This is how the result should look.
http://natureofcode.com/book/imgs/chapter07/ch07_12.png
This is my code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *myFile = fopen ( "input.txt" , "r" );
int i, j, cell, iterations=100, current[80], previous[80], ruleCase, rule=90;
for(i=0;i<80;i++){
fscanf(myFile, "%1d", &previous[i]);
if(previous[i]==0)printf("%c",176);
else printf("%c",178);
}
for(i=0;i<=iterations;i++){
for(cell=0;cell<80;cell++)
{
if((cell>0) && (cell<79))
{
ruleCase=1*previous[cell-1]+2*previous[cell]+3*previous[cell+1];
}
else if(cell==0)
{
ruleCase=1*previous[79]+2*previous[cell]+3*previous[cell+1];
}
else if(cell==79)
{
ruleCase=1*previous[cell-1]+2*previous[cell]+3*previous[0];
}
if(rule & (128 >> ruleCase))
{
current[cell]=1;
printf("%c",178);
}
else
{
current[cell]=0;
printf("%c",176);
}
}
for(j=0;j<80;j++){
previous[j]=current[j];
}
}
return 0;
}
with the following input.txt
00000000000000000000000000000000000000100000000000000000000000000000000000000000
Thank you!

You appear to be computing ruleCase incorrectly. For example, in the general case you do ...
ruleCase=1*previous[cell-1]+2*previous[cell]+3*previous[cell+1]
... but you are trying to interpret the cell values as binary digits. Therefore, the coefficients should be powers of 2:
ruleCase=1*previous[cell-1]+2*previous[cell]+4*previous[cell+1]
Likewise for the special cases.

The fault is with this line:
ruleCase=1*previous[cell-1]+2*previous[cell]+3*previous[cell+1];
When I change the 3 to a 4 the program produces the Sierpinski triangles.
ruleCase=1*previous[cell-1]+2*previous[cell]+4*previous[cell+1];
and the other two similar lines.

Related

Using a for-loop in C to test the return value of a function

I'm pretty new to coding and especially to C, so I decided to take the CS50 course as an introduction to the language. I just finished watching the first lecture on C and, as a means to test my knowledge on the subject, I attempted to write a short little program. Also I am using the course's library for the get_int() function.
The goal is to test the user's input and check if it's less or equal to ten. If it matches the parameters, the program should print the "Success!" message and exit; otherwise, it should ask for input again. If the input value is over 10, the program responds just as expected, but if you input a value of 10 or less, it ends up asking you for input one more time before actually exiting. I think it's probably something with the "for" loop, but I just can't figure it out.
My code:
#include <stdio.h>
#include <cs50.h>
#include <stdlib.h>
int check_for_value();
int main()
{
for(check_for_value(); check_for_value() != 1; check_for_value())
{
printf("Failed!\n");
}
exit(0);
}
int check_for_value()
{
int i = get_int("Your value: \n");
if(i <= 10)
{
printf("Success!\n");
return 1;
}
else
{
printf("Try again!\n");
return 0;
}
}
That isn't doing exactly what you think it is. In your for loop, each time you write check_for_value(), it is going to call that function. So it will call it the first time and the return value will not matter. It will call it again for the middle statement and then the value will matter because you are comparing the output to not equal to 1. And then again it will call the function in the third statement, where again it won't matter. Usually for something like this, you would use a while loop instead. An example below:
int ret = check_for_value();
while(ret != 1) {
printf("Failed\n");
ret = check_for_value();
}
printf("Success\n");
Technically a for loop can work too as the following:
for(int ret = check_for_value(); ret != 1; ret = check_for_value()) {
printf("Failed\n");
}
The for loop can look very simply
for ( ; !check_for_value(); )
{
printf("Failed!\n");
}
In such a case it is better to use the while loop
while ( !check_for_value() )
{
printf("Failed!\n");
}
As for your for loop
for(check_for_value(); check_for_value() != 1; check_for_value())
^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^
then the underlined calls of the function are not tested.
Also bear in mind that such a definition of a for loop
for(int ret = check_for_value(); ret != 1; ret = check_for_value()) {
printf("Failed\n");
}
is a very bad style of programming. There is redundant records of the function calls. The intermediate variable ret is not used in the body of the loop. So its declaration is also redundant. Never use such a style of programming.
Pay attention to that according to the C Standard the function main without parameters shall be declared like
int main( void )
and the statement
exit( 0 );
is redundant.

Read integer untill user reaches negative integer or numbers of integer reaches upto 15

i wrote following program but it is not right. would you please assist me where i went wrong?
#include<stdio.h>
void main()
{
int count=0,a;
do
{
scanf("%d",&a);
if(a>0 )
{
for(count=0;count<15;count++);
else;
}
while(int>=0);
}
So would you tell me the correct code?
Please use building blocks of correct syntax:
main:
#include <stdio.h>
int main(void)
{
/* other code */
return 0;
}
do-while:
do
{
/* other code */
} while(count>=0);
if:
if(a>0 )
{
/* code if true */
} else
{
/* code if false */
}
for:
for(a=0;a<15;a++)
{
/* repeated code */
}
For getting input right, please read:
http://sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html
How to read / parse input in C? The FAQ
When the syntax is right and the input is done correctly, then we can discuss the behaviour of your code; which I think is what you are actually asking about. Though what you are describing might already be solved/achieved once you spend some work on how to get input properly, based on the links above.

can someone help me with my c code

Hello so i am creating a program that reads from a file and outputs each category of the things in the text in sorted for example i want it to output like this :
Company name: air france Date of creation: 06281957 Flight number: AT6801 Incoming city: london Arrival city: paris Amount of fuel liters left: 380 Plane category: B777
this is the input :
air qatar06281957AT680londonmadrid380B777 turkish airlines05201933TK1298istanbulmadrid250A380 lufthansa01061953LH29frankfurtmadrid75B747 air canada06281957AT7245ammanmadrid120A320 turkish airlines05201933TK1266dohamadrid522A320 air france10071933AF123parismadrid105B777 -1
The code:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main()
{
FILE *inp,*outp;
int i,j,c=0,l,c2=0,c3=0;int c4=0;int c5=0,c6=0,k,m,c7=0,flag=0;int c8=0,c9=0,c10=0,flag2=0,n,c11=0,c12=0,c13=0,c14=0,p=0,c15=0,c16=0,t,t1,t2,t3,t4,t5,t6,t7,s;
char ultimate_array[600];char plane[100][6];char date[600][6];char nflight[600][6];char destination[100][6];char fuel [100][6];char planetype [100][6];
inp=fopen("input.txt","r");
for(i=0;!feof(inp);i++)
{
fscanf(inp,"%c",&ultimate_array[i]);
}
s=strlen(ultimate_array);
for(i=0;i<s;i++)
{
printf("%c",ultimate_array[i]);
}
printf("\n\n\n\n\n\n\n\n\n\n\n\n");
for(t=0;t<6;t++)
{
for(j=0;j<200;j++)
{
c++;
if(isdigit(ultimate_array[j]))
{
c3=c;
while(c>=0)
{
plane[t][c]=ultimate_array[j];
c--; j--;
}
break;
}
}
for(k=0;k<200;k++)
{
c2++;
if(isupper(ultimate_array[k]))
{
c5=c2; c2=c2-c3; c9=c2;
while(c2>=0)
{
date[t][c2]=ultimate_array[k];
k--; c2--;
}
break;
}
}
for(l=c3;l<200;l++)
{
c4++;
if(islower(ultimate_array[l]))
{
c4=c4+c3-c5;
while(c4>=0)
{
while(flag==0)
{
c8=c4; c6=c4+c5; flag=1;
}
nflight[t][c4]=ultimate_array[l];
c4--; l--;
}
break;
}
}
c10=c9+c8;
for(m=c6;m<200;m++)
{
c7++;
if(isdigit(ultimate_array[m]))
{
c7--;m--;
while(c7>=0)
{
while(flag2==0)
{
c13=c7; flag2=1;
}
destination[t][c7]=ultimate_array[m];
c7--; m--;
}
break;
}
}
for(n=c14;n<200;n++)
{
c11++; c14=c3+c13+c10;
if(isupper(ultimate_array[n]))
{
c12=c11; c11=c11-1;
while(c11>=0)
{
fuel[t][c11]=ultimate_array[n];
c11--; n--;
}
break;
}
}
c15=c14+c12;
for(p=c15;p<200;p++)
{
c16++;
if(ultimate_array[p]=='\n')
{
while(c16>=0)
{
planetype[t][c16]=ultimate_array[p];
c16--; p--;
}
break;
}
}
for(t1=0;t1<20;t1++)
{
printf(" %c",plane[t1][t]);
}
printf("\n");
for(t2=0;t2<100;t2++)
{
printf("%c",destination[t2][t]);
}
printf("\n");
for(t3=0;t3<100;t3++)
{
printf("%c",date[t3][t]);
}
printf("\n");
for(t4=0;t4<100;t4++)
{
printf(" %c",fuel[t4][t]);
}
printf("\n");
for(t5=0;t5<100;t5++)
{
printf(" %c",nflight[t5][t]);
}
printf("\n");
for(t6=0;t6<5;t6++)
{
printf(" %c",planetype[t][t6]);
}
}
return 0;
}
I have been struggling with a lot of things but I finally managed to separate every category to a different array, however , when I tried to do it for 2D array I always get garbage can someone point out what the mistake I did ?
we couldn't read in the input file and write it in a 2D array so the concept that i have used in this code i search in the array until i find something that would help me separate the word from the others such as 06281957 in the input i used isdigit to identify which index has it then i copy the previous characters into a new array this trick seemed to work for a 1d array however when i tried to scan it to 2d it stopped working and only random chars seemed to appeari wanted to print the whole 2d array of each category but i failed to do so, for the variables i used them as checkpoints for the next check to put the things i want in a new array. For minimizing the code i cant seem to find another solution to do so i know that my code is very big but if someone has a better idea it would be awesome.
One thing that will simplify your code is using scansets. It will make it much easier to extract and separate digits from non-digits, lower from upper case. Fixed width specifiers is also a concept you should read into. To see how many characters where extracted, use %n described in previous link. Examples:
/* ... */
inp=fopen("input.txt","r");
/* your code... */
for(i=0;!feof(inp);i++)
{
fscanf(inp,"%c",&ultimate_array[i]);
}
s=strlen(ultimate_array);
for(i=0;i<s;i++)
{
printf("%c",ultimate_array[i]);
}
/* ...can be replaced by something similar to this (untested) */
fscanf(inp, "%599s%n", ultimate_array, &s); /* read up to 599 characters, put number of read characters in s */
ultimate_array[s]=0; /* set null terminator */
char a[10]; sprintf(a, "%%%ds", s); /* create print format, e.g. "%123s" */
printf(a, ultimate_array) /* print 's' number of characters */
Make sure to take it slow as the lines can be hard to read initially. As you become more familiar with it I'm sure you will find scanf does "exactly what is needed" using no loops or conditions at all.
Don't use feof. Instead check the return value from scanf. If you try extract a single "something" from file using scanf and it returns 0 (zero arguments were filled), you are done reading the file.
Making 2D arrays is almost always wrong. Group your variables in structures:
typedef struct flights_t {
char plane[100];
char date[100];
/* ... */
} flights[6]; unsigned int nrOfFlights = 0;
int c[16];
int t[7];
Make symbolic constants instead of litering the code with copies of 20, 100 and 6 all over for improved readability and maintainance. You will also recieve much better help from forums such as SO.
Your posted code is sadly beyond saving without proper description of what each code section is supposed to do. Hopefully this "answer" will get you going making better code.

One Step from Happiness --all my inputs give correct output but still it says wrong answer

I'm trying to do Timus Online Judge question #1493, "One Step from Happiness":
Vova bought a ticket in a tram of the 13th route and counted the sums of the first three and the last three digits of the ticket's number (the number has six digits). It turned out that the sums differed by one exactly. "I'm one step from happiness," Vova thought, "either the previous or the next ticket is lucky." Is he right?
Input
The input contains the number of the ticket. The number consists of six digits, some of which can be zeros. It is guaranteed that Vova counted correctly, i.e., that the sum of the first three digits differs from the sum of the last three digits by one exactly.
Output
Output "Yes" if Vova is right and "No" otherwise.
Samples
input output
--------------------
715068 Yes
445219 No
012200 Yes
Hint
All tram tickets have exactly six digits. A ticket is considered lucky if the sum of its first three digits equals the sum of its last three digits.
Here is my code in Visual C(2010) format.
#include <stdio.h>
int main()
{
int arr[5],arr1[5],arr2[5],i,a=0,b=0,n,x=0,y=0;
printf("Enter number");
scanf("%d",&n);
x=n+1;
y=n-1;
while(n>0)
{
for(i=5;i>=0;i--)
{
arr[i]=n%10;
n=n/10;
}
}
a=( arr[0]+arr[1]+arr[2]);
b=(arr[3]+arr[4]+arr[5]);
if((a-b==1)||(a-b==-1))
{
while(x>0)
{
for(i=5;i>=0;i--)
{
arr1[i]=x%10;
x=x/10;
}
}
while(y>0)
{
for(i=5;i>=0;i--)
{
arr2[i]=y%10;
y=y/10;
}
}
if ((arr1[0]+arr1[1]+arr1[2]==arr1[3]+arr1[4]+arr1[5]) ||
(arr2[0]+arr2[1]+arr2[2]==arr2[3]+arr2[4]+arr2[5]))
{ printf("Yes");}
else
{ printf("No");}
}
else
{
printf("No");
}
return 0;
}
The above code is the one I submitted and received a wrong answer in Timus Online Judge. The format in which it was submitted was Visual C (2010). I use Dev-C++ on my computer, so the code I run on my computer is the following:
#include <stdio.h>
#include <conio.h>
main()
{
int arr[5],arr1[5],arr2[5],i,a=0,b=0,n,x=0,y=0;
printf("Enter number");
scanf("%d",&n);
x=n+1;
y=n-1;
while(n>0)
{
for(i=5;i>=0;i--)
{
arr[i]=n%10;
n=n/10;
}
}
a=( arr[0]+arr[1]+arr[2]);
b=(arr[3]+arr[4]+arr[5]);
if((a-b==1)||(a-b==-1))
{
while(x>0)
{
for(i=5;i>=0;i--)
{
arr1[i]=x%10;
x=x/10;
}
}
while(y>0)
{
for(i=5;i>=0;i--)
{
arr2[i]=y%10;
y=y/10;
}
}
if ((arr1[0]+arr1[1]+arr1[2]==arr1[3]+arr1[4]+arr1[5]) ||
(arr2[0]+arr2[1]+arr2[2]==arr2[3]+arr2[4]+arr2[5]))
{ printf("Yes");}
else
{ printf("No");}
}
else
{
printf("No");
}
getch();
}
I received no compilation errors. The code ran perfectly on my Dev-C++ compiler and also gave me correct output. The problem is when I submit this code in the Visual C format and they tell me it is a wrong answer.
The exercise states:
Output "Yes" if Vova is right and "No" otherwise.
Your program prints Enter number, which the exercise does not ask for. Try to remove that.
Also, for your own and our sanity, I strongly recommend you format your program better. Finding errors is much easier in a beautiful, well-formatted program. For tips on how to make your code more readable and clean, you can head over to CodeReview.SE.

Why am I getting a "Segmentation Fault" error when I try to run the tests?

I've written a function that determines whether or not to assign default values (it assigns default values if the flag is not present, and it assigns values the user passes if the flag is present). And I'm trying to test my function with a string to see if it did give me the right numbers. I keep getting "Segmentation Fault" when I try to run the tests, it compiles, but the tests just don't work. :(
Here's my header file:
#ifndef COMMANDLINE_H
#define COMMANDLINE_H
#include "data.h"
#include <stdio.h>
struct point eye;
/* The variable listed above is a global variable */
void eye_flag(int arg_list, char *array[]);
#endif
Here's my implementation file:
#include <stdio.h>
#include "commandline.h"
#include "data.h"
#include "string.h"
/* Used global variables for struct point eye */
void eye_flag(int arg_list, char *array[])
{
eye.x = 0.0;
eye.y = 0.0;
eye.z = -14.0;
/* The values listed above for struct point eye are the default values. */
for (int i = 0; i <= arg_list; i++)
{
if (strcmp(array[i], "-eye") == 0)
{
sscanf(array[i+1], "%lf", &eye.x);
sscanf(array[i+2], "%lf", &eye.y);
sscanf(array[i+3], "%lf", &eye.z);
}
}
}
And here are my test cases:
#include "commandline.h"
#include "checkit.h"
#include <stdio.h>
void eye_tests(void)
{
char *arg_eye[6] = {"a.out", "sphere.in.txt", "-eye", "2.4", "3.5", "6.7"};
eye_flag(6, arg_eye);
checkit_double(eye.x, 2.4);
checkit_double(eye.y, 3.5);
checkit_double(eye.z, 6.7);
char *arg_eye2[2] = {"a.out", "sphere.in.txt"};
eye_flag(2, arg_eye2);
checkit_double(eye.x, 0.0);
checkit_double(eye.y, 0.0);
checkit_double(eye.z, -14.0);
}
int main()
{
eye_tests();
return 0;
}
The absolute easiest way to solve this one is run it in a debugger. You probably won't even need to learn how to step through your code or anything - just fire up, run, and read the line.
If you are on a *nix system:
Compile your code with -g flag.
Load as, e.g. gdb a.out.
Run now that it's loaded - (gdb) run.
Do whatever you need to reproduce the segfault.
bt or where should give you a stack trace - and an exact line that is causing your problem.
I'm sure enough you can solve it from there to post this as an answer; but if not, knowing the exact line will make it very much easier to research and solve.
The errors are here:
for (int i = 0; i <= arg_list; i++)
{ ///^^
if (strcmp(array[i], "-eye") == 0)
{
sscanf(array[i+1], "%lf", &eye.x);
//^^^
sscanf(array[i+2], "%lf", &eye.y);
sscanf(array[i+3], "%lf", &eye.z);
}
}
i <= arg_list is wrong since you pass in 6, array index starts from 0, the max value is 5
i+1, i+2,i+3 will give you out of bounds index when you iterate from 0 to 5.
Your loop condition is wrong. It should be i < arg_list.
Think about what happens when i == arg_list.

Resources