Shorten or split the code - c

Please help to shorten this function in order to have 25 or less lines!
it prints all possible combination of numbers from 0 to 99,
EX: 00 01, 00 02, 00 03, 00 04, 00 05, ..., 00 99, 01 02, ..., 97 99, 98 99
void dp_print_comb2(void)
{
char a;
char b;
char c;
char d;
a = '0';
b = '0';
while (a <= '9')
{
if (b > '9')
{
a++;
b = '0';
}
c = a;
if (b == '9')
c++;
d = b + 1;
if (b == '9')
d = '0';
while (c <= '9')
{
ok(a, b, c, d);
d++;
if (d > '9')
{
c++;
d = '0';
}
}
b++;
}
}
So if there is a way to split this function or to shorten please help me! thanks!
If the main and other function are needed i can put give them too!
ps: i started to learn C, and making some practice! (sorry for bad english)

void dp_print_comb2(void){
for(int ab = 0; ab < 100-1; ++ab)
for(int cd = ab + 1; cd < 100; ++cd)
printf("%02d %02d, ", ab, cd);
puts("");
}

If you want to make your code even shorter it is possible to make a single loop (Not tested but should work).
void foo(){
for(int i=0,j=0;j<100;i=(i+1)%100,j+=!i)
printf("%02d %02d,",i,j);
}
How does it work
i and j are initialized to 0
(Loop 0 to 99) Each loop i is incremented. As i!=0 j stay constant (=0)
(Loop 100) i returns to 0 (n%n -> 0) and j is incremented
(Loop 100 to 199) Each loop i is incremented. As i!=0 j stay constant (=1)
And so on...
PS1 : It won't be faster, and it's less clear that using two loops, but it shows a different way to do the same thing.
PS2 : It could be even possible to use only one variable (but it would be even less clear...).

from your example, when the numbers are the same, do not print them
Your question was unclear about any other constraints.
This is the code I would use:
#include <stdio.h>
#define MAX_PLUS_ONE (100)
// prototype
void dp_print_comb2( void )
void dp_print_comb2()
{
for( unsigned ab=0; ab < MAX_PLUS_ONE; ab++)
{
for( unsigned cd=0; cd < MAX_PLUS_ONE; cd++)
{
if( ab != cd )
{ // then numbers are not the same
printf( "%02u %02u, ", ab, cd);
} // end if
} // end for
} // end for
} // end function: db_print_comb2

Related

Create a function that displays all the different combinaison of two digits between 00 and 99 by ascending order ( C programming)

so i was working on the school 42 subjects on my own, and i dont fully understand the code here.
I understand that this part is used to print the result on the screen
void ft_putchar(char c)
{
write(1, &c, 1);
}
and that the following part is the setup of the limit and the incrementation, but i have my first question here :
Why does i starts at '-1' ?
My second question is concerning the division and modulus part, i dont understand much here, for example,how do the '-1' from the beginning becomes "00 01" ?
For the last part if i understand correctly it just adds a ',' and ' ' evrywhere to separate the combinaisons except at the very end.
#include <unistd.h>
void ft_putchar(char c)
{
write(1, &c, 1);
}
void ft_print_comb2(void)
{
int i;
int j;
i = -1 ;
while (++i <= 98)
{
j = i;
while (++j <= 99)
{
ft_putchar((char)(i/10) + '0');
ft_putchar((char)(i%10) + '0');
ft_putchar(' ');
ft_putchar((char)(j/10) + '0');
ft_putchar((char)(j%10) + '0');
if ( (i != 98))
{
ft_putchar(',');
ft_putchar(' ');
}
}
}
}
int main()
{
ft_print_comb2();
return(0);
}
ft_print_comb2 C00
Why does i starts at '-1' ?
Because its incremented before the evaluation of the loop
while (++i <= 98)
how do the '-1' from the beginning becomes "00 01" ?
i = -1 ;
while (++i <= 98) // i is 0 now
{
j = i; //j is equal to i (==0)
while (++j <= 99) // j is 1 now
about the division you are saying that the first char (who is going to be < 98) is the second digit so you divide it by 10 to get it. And since you are working with ints the fraction gets cut off.
Ex:
i = 25
i/10 => 2.5 => 2
And % modulus does the same but for the 1st digit
i=49
i%10 => remainder of 49/10 => 9
Then you do (char) to convert from int to char although it's redundant since you have the + '0' there
I hope you passed the piscine!

Easiest way to make 4 letters permutations in C

I need to write a function that returns something like this, given only "1234":
char *permutations[] = {"1234","1324", "1342","1423","1432","2134",
"2143","2314","2341","2413","2431","3124","3142",
"3214","3241","3412","3421","4123","4132","4213",
"4231","4312","4321", "1243"};
I wrote "letters" in the title because I actually need those numbers to be characters. I have read various posts here, but all aff them are very complicated since they try to get permutations for an N letters string. I don't need that, I only need those combinations but have no clue whatsoever about how to do this. I know I should tell what I tried, but I really do have nothing yet, since all codes I have tried inspiring at use concepts I am totally unfamiliar like backtracking and recursion. Is there a really 'easy' way to do this without using any libraries?
Hoping you will understand, I thank you all very much in advance.
Here is an example :
A. The first number has 4 possible values, we simply traverse them in the outer loop.
B. The same is done for the second at each pass of the outer loop, except that we avoid duplicating A so that loop has a length of 3.
C. The same for C whose the loop has a length of 2 because it avoids duplicating A and B.
D. The last value has a unique choice and we can find it this way : D = 10 - (A + B + C), where 10 = 1+2+3+4.
Each time a new D is found we collect the sequence of four numbers and that finally results in a sorted series of length 24.
static inline char increase(char c) { return (c - '0') % 4 + '1'; }
#define A seq[0]
#define B seq[1]
#define C seq[2]
#define D seq[3]
int main()
{
char seq[5] = { '0', '0', '0', '0', 0};
char collector[24][5];
char icollect = 0;
//--- A
for (char i = 0; i<4; i++) {
A = increase(A);
//---- B
B = '0';
for (char j = 0; j<3; j++) {
B = increase(B);
//---- C
C = '0';
if (B == A) B = increase(B);
for (char k = 0; k<2; k++) {
do { C = increase(C); } while (C == A || C == B);
//---- D
D = 10 - ((A - '0') + (B - '0') + (C - '0')) + '0';
//Collects
memcpy(collector[icollect++], seq, 5);
}
}
}
//Prints
for (char i=0; i<24; i++) {
printf("%s%c", collector[i], i && (i+1)%6==0 ? '\n' : ' ');
}
}
/* printed
1234 1243 1324 1342 1423 1432
2134 2143 2314 2341 2413 2431
3124 3142 3214 3241 3412 3421
4123 4132 4213 4231 4312 4321
*/

Brute force function for decrypting string in C (Caesar cipher )

I found this problem interesting, as it is given that you need to use the alphabet as an array in C. Task is to brute force every possible K value, in basic Caesar's cipher manner.
However, code I come up with compile non-true values after K = 1. For example, a letter C is turned to Z instead of A etc. Can anyone spot what I did wrong?
#include <stdio.h>
#include <string.h>
void bruteforce (char*);
int main() {
char cyphertext[] = "kyvtrmrcipnzccrkkrtbwifdkyvefikynvjkrkeffe";
bruteforce(cyphertext);
return 0;
}
void bruteforce (char *cyphertext) {
char alphabet[26] = "abcdefghijklmnopqrstuvwxyz";
long int size = strlen(cyphertext);
for (int k = 0; k < 26; k++){
for (long int i = 0; i < size; i++){
for (int j = 0; j < 26; j++){
if (alphabet[j] == cyphertext[i]){
cyphertext[i] = alphabet[j - k];
if (k > j){
cyphertext[i] = alphabet[26 + j - k];
}
break;
}
}
}
printf("%s\n ", cyphertext);
}
}
For Caesar Cypher shifting, you don't need to use the alphabet string. You can just shift the character in ASCII code. ASCII codes of 'a' - 'z' are 97 - 122. Thus if decode with + 1. If the characters are a - z, you can just add one to each character. If after adding the shift value to the character value and the character value become larger than 122 then take the character value and subtract it to 122 then add 96 to that.
For shifting negative, if character value become smaller than 97. Take 97 subtract to character's value. Then subtract 123 to the previous equation value. Nonetheless, I built the code so that negative shift will be convert to positive shift. If the shift is negative we take 26 and add to that. Example is, shifting -1 will make a become z. So that is similar to shifting 26 + -1 = 25.
Shift value can be larger than +25 or smaller than -25. Nonetheless, if it is, it will be modulus to 26.
If you want to bruteforce all the possible combinations for a string. Just use the function below and run it in a loop from 1 to 25. But your function modify the original string. Thus, when doing bruteforce, you would have to copy the string of your function to a temporary string and let the function work on that. The examples are below.
#include <stdio.h>
#include <string.h>
void bruteforce (char *cyphertext, int shiftBy);
int main() {
char cyphertext[] = "kyvtrmrcipnzccrkkrtbwifdkyvefikynvjkrkeffe";
char cyphertext2[] = "yvccf wifd bvmze";
bruteforce(cyphertext, -17);
puts("");
bruteforce(cyphertext2, 9);
/* Bruteforce example */
puts("");
puts("Bruteforce section:");
// +9
char cyphertext3[] = "kyzjkvokzjkfsvtirtb nyrk tre kyzj sv zj zk yvccf nficu";
char temp[50];
for (int i = 1; i < 26; i++){
printf("Trying to crack by shifting %d \n", i );
strcpy(temp, cyphertext3);
bruteforce(temp, i);
puts("");
}
/* End Bruteforce example */
return 0;
}
// If there is no shift i.e 0, 26, 52, -26
// It won't print
void bruteforce (char *cyphertext, int shiftBy){
size_t size = strlen(cyphertext);
if ( shiftBy > 25){
shiftBy = shiftBy % 26;
} else if ( shiftBy < 0 ) {
shiftBy = 26 + (shiftBy % 26);
// If shiftBy is 26
// there is no need to shift.
if ( shiftBy == 26 ) return;
}
// If there is no shift return.
if ( shiftBy == 0 ) return;
for ( size_t i = 0; i < size; i++){
// 97 - 122 is a - z
// if char is a - z
if ( cyphertext[i] > 96 && cyphertext[i] < 123 ){
// add shift by
cyphertext[i] += shiftBy;
// if char > z
// then take char - z then add to the ascii code that just before 'a'.
// Since shiftBy is converted fomr negative to positive.,
// There will not be a negative shiftBy.
if ( (unsigned char)cyphertext[i] > 122 )
cyphertext[i] = ((unsigned char) cyphertext[i]) - 122 + 96;
}
// If want to do A - Z
// ASCII code are 65 - 90.
}
printf("%s\n", cyphertext);
}

I need to add string characters in C. A + B must = C. Literally

I am writing a program that is due tonight at midnight, and I am utterly stuck. The program is written in C, and takes input from the user in the form SOS where S = a string of characters, O = an operator (I.E. '+', '-', '*', '/'). The example input and output in the book is the following:
Input> abc+aab
Output: abc + aab => bce
And that's literally, not variable. Like, a + a must = b.
What is the code to do this operation? I will post the code I have so far, however all it does is take the input and divide it between each part.
#include <stdio.h>
#include <string.h>
int main() {
system("clear");
char in[20], s1[10], s2[10], o[2], ans[15];
while(1) {
printf("\nInput> ");
scanf("%s", in);
if (in[0] == 'q' && in[1] == 'u' && in[2] == 'i' && in[3] == 't') {
system("clear");
return 0;
}
int i, hold, breakNum;
for (i = 0; i < 20; i++) {
if (in[i] == '+' || in[i] == '-' || in[i] == '/' || in[i] == '*') {
hold = i;
}
if (in[i] == '\0') {
breakNum = i;
}
}
int j;
for (j = 0; j < hold; j++) {
s1[j] = in[j];
}
s1[hold] = '\0';
o[0] = in[hold];
o[1] = '\0';
int k;
int l = 0;
for (k = (hold + 1); k < breakNum; k++) {
s2[l] = in[k];
l++;
}
s2[breakNum] = '\0';
printf("%s %s %s =>\n", s1, o, s2);
}
}
Since this is homework, let's focus on how to solve this, rather than providing a bunch of code which I suspect your instructor would frown upon.
First, don't do everything from within the main() function. Break it up into smaller functions each of which do part of the task.
Second, break the task into its component pieces and write out the pseudocode:
while ( 1 )
{
// read input "abc + def"
// convert input into tokens "abc", "+", "def"
// evaluate tokens 1 and 3 as operands ("abc" -> 123, "def" -> 456)
// perform the operation indicated by token 2
// format the result as a series of characters (579 -> "egi")
}
Finally, write each of the functions. Of course, if you stumble upon roadblocks along the way, be sure to come back to ask your specific questions.
Based on your examples, it appears “a” acts like 1, “b” acts like 2, and so on. Given this, you can perform the arithmetic on individual characters like this:
// Map character from first string to an integer.
int c1 = s1[j] - 'a' + 1;
// Map character from second string to an integer.
int c2 = s2[j] - 'a' + 1;
// Perform operation.
int result = c1 + c2;
// Map result to a character.
char c = result - 1 + 'a';
There are some things you have to add to this:
You have to put this in a loop, to do it for each character in the strings.
You have to vary the operation according to the operator specified in the input.
You have to do something with each result, likely printing it.
You have to do something about results that extended beyond the alphabet, like “y+y”, “a-b”, or “a/b”.
If we assume, from your example answer, that a is going to be the representation of 1, then you can find the representation values of all the other values and subtract the value representation of a from it.
for (i = 0; i < str_len; i++) {
int s1Int = (int)s1[i];
int s2Int = (int)s1[i];
int addAmount = 1 + abs((int)'a' - s2Int);
output[i] = (char)(s1Int + addAmount)
}
Steps
1) For the length of the s1 or s2
2) Retrieve the decimal value of the first char
3) Retrieve the decimal value of the second char
4) Find the difference between the letter a (97) and the second char + 1 <-- assuming a is the representation of 1
5) Add the difference to the s1 char and convert the decimal representation back to a character.
Example 1:
if S1 char is a, S2 char is b:
s1Int = 97
s2Int = 98
addAmount = abs((int)'a' - s2Int)) = 1 + abs(97 - 98) = 2
output = s1Int + addAmount = 97 + 2 = 99 = c
Example 2:
if S1 char is c, S2 char is a:
s1Int = 99
s2Int = 97
addAmount = abs((int)'a' - s2Int)) = 1 + abs(97 - 97) = 1
output = s1Int + addAmount = 99 + 1 = 100 = d

SPOJ ADDREV Wrong Answer

I'm trying to solve the Adding Reversed Numbers problem (ADDREV) at the Sphere Online Judge but my submission keeps coming up wrong answer.
I've tried int, unsigned int, long, and unsigned long for my variables and they all work equally well on my computer with some test data (also below) but they all fail the SPOJ.
I'm hoping someone might be able to shed some insight into why my program would be failing on their system. I've also left a message on their forum but there doesn't seem to be a lot of traffic.
Here's my code:
#include <stdio.h>
#define FIRST 1
#define SECOND 2
int main()
{
int c, k, x, y, state, place, total, reverse = 0;
do
{
c = getchar();
if (c < 48 || c > 57)
{
continue;
}
else
{
k = k * 10;
k = k + (c - 48);
}
} while (c != '\n');
state = FIRST;
place = 1;
do
{
c = getchar();
if (c == ' ')
{
state = SECOND;
place = 1;
continue;
}
else if (c == '\n')
{
total = x + y;
place = 1;
while ((total / place) >= 10)
{
place = place * 10;
}
while (place > 0)
{
reverse = reverse + ((total % 10) * place);
total = total / 10;
place = place / 10;
}
printf("%d\n", reverse);
state = FIRST;
place = 1;
reverse = 0;
x = 0;
y = 0;
k--;
continue;
}
if (state == FIRST && (c >= 48 && c <= 57))
{
x = x + ( (c - 48) * place );
place = place * 10;
}
else if (state == SECOND && (c >= 48 && c <= 57))
{
y = y + ((c - 48) * place );
place = place * 10;
}
} while (k > 0);
return 0;
}
And... here's the test data I'm using:
12
24 1
4358 754
305 794
2762 2563
435 4320
0 0
123 456
20 20
10000 10000
999999 999999
321 583
9999999 999999
And here's the results my program gives on my computer:
34
1998
1
4236
867
0
579
4
2
8999991
805
89999901
Any help would be appreciated :)
At this point:
int c, k, x, y, state, place, total, reverse = 0;
you create a variable k but give it no value. Shortly after:
k = k * 10;
you use this variable. At that point, your program exhibits undefined behaviour - anything might happen.

Resources