patterncMinor
Matrix falling effect
Viewed 0 times
effectmatrixfalling
Problem
How can I make this matrix effect more like the matrix movie?
Here is how it looks like:
Of course it is better if it was moving but that's all what I can show.
Also it takes a notable time to compile, is there anything wrong I'm doing?
#include
#include
int main()
{
srand((unsigned) time(0));
int i,j;
system("color 0a");
while(1)
{
i = rand() % 2;
j= rand() % 2;
if(j)
{
printf("%d ", i);
}
else
{
printf(" %d", i);
}
}
return 0;
}Here is how it looks like:
Of course it is better if it was moving but that's all what I can show.
Also it takes a notable time to compile, is there anything wrong I'm doing?
Solution
What You Have Now:
You code is simple and concise. That in and of itself can be a desirable quality. I think we can make the code a little bit more concise while gaining some runtime efficiency.
Some changes I would make:
Change
Change
Change
Change your while loop to remove intermediate variables:
All together I think you could simplify your code to this:
This is a pretty small and eloquent code for generating a matrix style output. If your happy with this you can stop right here.
However, it should be pointed out that
Note that now we have a Magic Number 48 in out code, that is no good! Let's let the preprocessor help us make the code a little bit more readable:
Next is a matter of personal preference. I personally don't like 2 line
We could use the comma operator to clean up the line a little:
Using the comma operator is a matter of preference. I think that there are times that it is perfectly clear & reasonable to use it, others say the comma operator should never be used because it is too opaque. While that code is more compact, I don't think it helps readability or efficiency.
Lets try abstraction that into a method instead and see how that looks:
That makes the while loop look better but the methods might incur some performance cost. Since your tag
You will notice in your all the code examples above, there is some repetition in the while loop. In all the cases we have 2 statements printing the one or zero. Repetition is often a good thing to focus on because it can alert you to things that can be improved. There is a mantra of Don't Repeat Yourself (DRY) in programming which is designed to help programmers locate inefficiencies and refactor their code for better readability & efficency.
Consider this loop:
Here we have a single binary number printing statement but conditionally print a space before or after the number. From a runtime efficiency perspective this is probably optimal (though I have not done any benchmarking).
If we put this all together we have the following:
I hope this has given you a lot of different angles to view you code from and given you the tools to decide what you value when improving this code, readability or runtime efficiency.
You code is simple and concise. That in and of itself can be a desirable quality. I think we can make the code a little bit more concise while gaining some runtime efficiency.
Some changes I would make:
Change
srand((unsigned) time(0)); to srand(time(NULL));- While both are correct, this is how I have seen seeds set more often, hence it is the idiomatic approach
Change
return 0 to return EXIT_SUCCESS- Exit codes are included in
stdlib, since you already using that library, you should also use the provided exit codes.
Change
rand()%2 to rand()&1- The modulo operator (
%) can be very inefficient on some architectures. Since you are only usingrand()to get binary values, we can much more efficiently use the bitwise and operator (&) to get a 1 if the number is odd and a 0 if the number is even.
Change your while loop to remove intermediate variables:
while(1) {
if(rand() & 1)
printf("%d ", rand() & 1);
else
printf(" %d", rand() & 1);
}All together I think you could simplify your code to this:
#include
#include
int main() {
srand(time(NULL));
system("color 0a");
while(1) {
if(rand() & 1)
printf("%d ", rand() & 1);
else
printf(" %d", rand() & 1);
}
return EXIT_SUCCESS;
}This is a pretty small and eloquent code for generating a matrix style output. If your happy with this you can stop right here.
However, it should be pointed out that
printf is a little heavy handed for just printing spaces, ones, and zeros. You could utilize putchar which will, unsurprisingly, put a character to STDOUT.while(1) {
if(rand() & 1) {
putchar(48 + (rand()&1))
putchar(' ');
}
else {
putchar(' ')
putchar(48 + (rand()&1));
}
}Note that now we have a Magic Number 48 in out code, that is no good! Let's let the preprocessor help us make the code a little bit more readable:
#define ASCII_NUMBER_OFFSET 48
while(1) {
if(rand() & 1) {
putchar(ASCII_NUMBER_OFFSET + (rand()&1));
putchar(' ');
}
else {
putchar(' ');
putchar(ASCII_NUMBER_OFFSET + (rand()&1));
}
}Next is a matter of personal preference. I personally don't like 2 line
if statements. If the if statement has 3 lines, it should probably be abstracted into a separate method, if it has one line, that’s perfect, but if we have 2 lines... that's murky water.We could use the comma operator to clean up the line a little:
#define ASCII_NUMBER_OFFSET 48
while(1) {
if(rand() & 1)
putchar(ASCII_NUMBER_OFFSET + (rand()&2)), putchar(' ');
else
putchar(' '), putchar(ASCII_NUMBER_OFFSET + (rand()&1));
}Using the comma operator is a matter of preference. I think that there are times that it is perfectly clear & reasonable to use it, others say the comma operator should never be used because it is too opaque. While that code is more compact, I don't think it helps readability or efficiency.
Lets try abstraction that into a method instead and see how that looks:
while(1) {
if(rand() & 1)
printLeft();
else
printRight();
}
.
.
.
#define ASCII_NUMBER_OFFSET 48
void printLeft() {
putchar(' ');
putchar(ASCII_NUMBER_OFFSET + (rand()&1));
}
void printRight() {
putchar(ASCII_NUMBER_OFFSET + (rand()&1));
putchar(' ');
}That makes the while loop look better but the methods might incur some performance cost. Since your tag
Optimization implies that you care most about runtime efficiency and not readability/maintainability lets try something else.You will notice in your all the code examples above, there is some repetition in the while loop. In all the cases we have 2 statements printing the one or zero. Repetition is often a good thing to focus on because it can alert you to things that can be improved. There is a mantra of Don't Repeat Yourself (DRY) in programming which is designed to help programmers locate inefficiencies and refactor their code for better readability & efficency.
Consider this loop:
int b;
while(1) {
if(b = rand() & 1)
putchar(' ');
putchar(ASCII_NUMBER_OFFSET + (rand() & 1));
if(!b)
putchar(' ');
}Here we have a single binary number printing statement but conditionally print a space before or after the number. From a runtime efficiency perspective this is probably optimal (though I have not done any benchmarking).
If we put this all together we have the following:
#include
#include
#define ASCII_NUMBER_OFFSET 48
int main() {
int b;
srand(time(NULL));
system("color 0a");
while(1) {
if(b = (rand() & 1))
putchar(' ');
putchar(ASCII_NUMBER_OFFSET + (rand() & 1));
if(!b)
putchar(' ');
}
return EXIT_SUCCESS;
}I hope this has given you a lot of different angles to view you code from and given you the tools to decide what you value when improving this code, readability or runtime efficiency.
Code Snippets
while(1) {
if(rand() & 1)
printf("%d ", rand() & 1);
else
printf(" %d", rand() & 1);
}#include<stdlib.h>
#include<stdio.h>
int main() {
srand(time(NULL));
system("color 0a");
while(1) {
if(rand() & 1)
printf("%d ", rand() & 1);
else
printf(" %d", rand() & 1);
}
return EXIT_SUCCESS;
}while(1) {
if(rand() & 1) {
putchar(48 + (rand()&1))
putchar(' ');
}
else {
putchar(' ')
putchar(48 + (rand()&1));
}
}#define ASCII_NUMBER_OFFSET 48
while(1) {
if(rand() & 1) {
putchar(ASCII_NUMBER_OFFSET + (rand()&1));
putchar(' ');
}
else {
putchar(' ');
putchar(ASCII_NUMBER_OFFSET + (rand()&1));
}
}#define ASCII_NUMBER_OFFSET 48
while(1) {
if(rand() & 1)
putchar(ASCII_NUMBER_OFFSET + (rand()&2)), putchar(' ');
else
putchar(' '), putchar(ASCII_NUMBER_OFFSET + (rand()&1));
}Context
StackExchange Code Review Q#46370, answer score: 2
Revisions (0)
No revisions yet.