Printing a Count in C Only Printing to 65 - c

I am trying to make a very simple 64 bit operating system, and so far have done really well, but since I am not very familiar with C I have been having some problems with it, and this one stumped me. The output would count like normal (1 2 3 4 5 6 7 8 9 10 11 12 etc.) but it would stop printing at 65. I know that "print.h" works because I have tested it many times, but I am not so sure on my method of converting the numbers to a character array. Any help at all would be much appreciated. Here's my code:
#include "print.h"
int getLen(int x) {
unsigned int n = x;
int count = 0;
while(n!=0)
{
n=n/10;
count++;
}
return count;
}
char ITC(unsigned int x) {
char ret;
unsigned int n = x;
if(n==0){
ret='0';
}
if(n==1){
ret='1';
}
if(n==2){
ret='2';
}
if(n==3){
ret='3';
}
if(n==4){
ret='4';
}
if(n==5){
ret='5';
}
if(n==6){
ret='6';
}
if(n==7){
ret='7';
}
if(n==8){
ret='8';
}
if(n==9){
ret='9';
}
return ret;
}
void kernel_main(){
print_clear();
print_set_color(PRINT_COLOR_GREEN, PRINT_COLOR_BLACK);
char out[512];
int onOut = 0;
for (int i = 0; i < 100; i++)
{
onOut++;
unsigned int n = i;
while (n != 0) {
out[onOut + getLen(n)] = ITC(n%10);
n /= 10;
}
out[onOut + getLen(i) + 1] = '\n';
onOut += getLen(i) + 1;
}
for (int i = 0; i < 512; i++)
{
print_char(out[i]);
}
}

The issue is with the algorithm rather then perhaps familiarity with C. Your indexing into the unitialised out array was leaving gaps so outputting junk that happened to be in the array.
Consider the following - the parts I changed annotated - not all are part of the solution; just good practice:
char out[512] = {0}; // <<< Good idea to initialise
int onOut = 0;
for (int i = 1; i < 100; i++) // Start form 1 not zero
{
int n = i; // <<< Type agreement with i
int numlen = getLen(n) ; // <<< Get the length of the initial number
// Don't unnecessarily calculate in the loop
// when you know it decrements by 1 on each
// iteration
for( int j = onOut + numlen; // <<< Start from the end position
(n!=0) && j >= onOut; // <<< toward the start position
j-- ) // <<< backward
{
out[j - 1] = ITC(n % 10); // <<< Insert digit, starting from index zero
n /= 10;
}
onOut += numlen ; // <<< Move to end of newly inserted number
out[onOut++] = '\n'; // <<< Add the newline
}
Note that you have over-complicated this code somewhat; especially w.r.t. to ITC() if you code like that habitually your "operating system" will run very slowly. ITC() can be reduced to a simple look-up thus:
char ITC(unsigned int x)
{
static const char digits[] = "0123456789" ;
return digits[x] ;
}
Or in any likely character set where digits are contiguous and in order, arithmetically thus:
char ITC(unsigned int x)
{
return '0' + x ;
}
I'd give two pieces of advice for success in this project and programming in general.
Comment your code. If you have to explain it to yourself, you are more likely to find the flaws. But also later maintainers or people assisting you with debugging will have an idea of your intended semantics.
Use a debugger. I used a debugger to figure out were your code was going wrong because it was quicker and more direct that other methods. Certainly quicker than posting questions of StackOverflow!

I don't understand why you make that one function so complicated, what's wrong with this?
char ITC(unsigned int x) {
return (char)((int)'0' + n);
}

Some of the above comments are correct, plus you also need to terminate your string with a null character... and NOT print all 512 characters of a non-initialized array. Something like this should work much better (though you should also include the contents of print.h so we can see if there are any problems there):
#include "print.h"
int getLen(unsigned int x)
{
int count = 0;
while (n != 0) {
n = n / 10;
count++;
}
return count;
}
char ITC(unsigned int x)
{
return (x <= 9) ? x + '0' : '?';
}
void kernel_main()
{
char out[512];
int onOut = 0;
print_clear();
print_set_color(PRINT_COLOR_GREEN, PRINT_COLOR_BLACK);
for (int i = 0; i < 100; i++) {
unsigned int len = getLen(i);
unsigned int n = i;
unsigned int offs = len;
while (n != 0) {
out[onOut + offs--] = ITC(n % 10);
n /= 10;
}
out[onOut + len + 1] = '\n';
onOut += len + 1;
}
out[onOut + 1] = 0;
for (int i = 0; out[i] != 0; i++) {
print_char(out[i]);
}
}

Related

Finding the longest Collatz Chain

I am currently on my Uni homework and this is the last task. Its the 14th euler problem.
https://projecteuler.net/problem=14
So I am really new and i know that have a lot of crappy implementations. When executing this there is actually no output at all. I've been running this for 3 Minutes because i thought it needed to "load"..
My Task is to have a working function that calculates the Length and then take this length and compare it to have the longest chain as the "Final" output.
I tried to have a Loop that calculates the length for every i in 1000000 and then save this number into an array with the same size.
At the end of the Loop I want to compare the last length with the current and save the longer into the var if its longer.
I am stuck for like the past 2 hours
Here is my current Code:
#include <stdio.h>
#include <math.h>
int number = 1000000;
long sequence = 0;
int seqLen = 0;
int startingNum = 0;
int currLen = 0;
unsigned calculateCollatzLength(unsigned n){
int ans = 1;
while (n != 1) {
if (n & 1) {
n = 3 * n + 1;
} else {
n >>= 1;
}
ans ++;
}
currLen = ans;
return currLen;
}
int main() {
int cache[number];
for(int i = 0; i <= number; i++){
calculateCollatzLength(i);
cache[i] = currLen;
if (cache[i] > seqLen) {
seqLen = cache[i];
startingNum = i;
}
}
printf("The Longest Collatz Chain from 1 to 1000000 is %d long and has the starting number %d \n", seqLen, startingNum);
}
Hope that this is kind of understandable to ask in on this since this is my 3rd Question and it kind of feels like cheating asking but i dont know who to ask or cant find any answers :(
Here's a cleaned-up working version of your code. There's no need for a cache, and int64_t is a safer bet than unsigned (which is likely to be 32 bits) to avoid overflows. Your use of global variables was confusing and unnecessary – you can simply return the length of the sequence and find the maximum in main.
#include <stdio.h>
#include <stdint.h>
int collatz(int64_t n){
int len = 1;
while (n != 1) {
if (n & 1) {
n = 3 * n + 1;
} else {
n >>= 1;
}
len++;
}
return len;
}
#define N 1000000
int main(void) {
int longest_i = 0;
int longest = 0;
for(int i = 1; i <= N; i++){
int len = collatz(i);
if (len > longest) {
longest_i = i;
longest = len;
}
}
printf("**collatz(%d) = %d\n", longest_i, longest);
}

Why is the code throwing segmentation fault?

The problem is to find the number i<=n, n<=500000 for which the longest collatz series exists.
Collatz series for a number n terminates at 1, and the conditions are
if n is even, next term = n/2
if n is odd, next term = 3*n + 1
Well as a matter of fact, the collatz series always terminates at 1 for all numbers.
Hence any number won't repeat in its collatz series. Using this fact, I have written the following code
LOGIC:
I start a while loop, that goes till n and for each iteration, I store the length of the series for that i.
If i occurs in the series of some n >= r > i, then i terminate the loop and add the length of i to r.
For example, say series of 3 is 3, 10, 5, 16, 8, 4, 2, 1. Now the length corresponding to 2 will already be stored in the series_length array, so I use that value.
Then the for loop next to that, finds the longest series and displays the answer.
The code works fine for n <= 1818 to be precise, but shows segmentation fault onwards (dunno why :(). Please help
CODE :
#include <stdio.h>
int length = 0, series_length[500000], maxlength = 0;
void store_length(int n) {
while(n > 1 && series_length[n] == 0) {
length++;
if(n%2 == 0) {
n = n/2;
}
else {
n = 3*n + 1;
}
}
length += series_length[n];
}
int main() {
int n, i = 1, result;
scanf("%d", &n);
series_length[1] = 1;//redundant statement
while(i <= n) {
store_length(i);
series_length[i] = length;
length = 0;
i++;
}
for(int i = 1;i <= n; i++) {
if(maxlength <= series_length[i]) {
maxlength = series_length[i];
result = i;
}
}
printf("%d %d\n", result, maxlength);
return 0;
}
INPUT-
10
OUTPUT-
9 20 (AS Expected)
INPUT-
100000
OUTPUT-
Segmentation Fault
Expected-
77031 351
Your value for n goes outside the range.
You have a line n = 3*n + 1; in the function store_length
Running this with the gdb with input as 100000 gives
Thread 1 received signal SIGSEGV, Segmentation fault.
0x0000000000401545 in store_length (n=532060) at 29_01.c:6
6 while(n > 1 && series_length[n] == 0) {
(gdb) p n
$1 = 532060
only store it if it fits
... and use it if it already has been computed
avoid global variables
prefer unsigned values
[use descriptive variable names]
#include <stdio.h>
#define THE_SIZE 500000
unsigned series_length[THE_SIZE]= {0,};
unsigned get_length(unsigned val) {
unsigned steps;
for (steps=0; val > 1 ; steps++) {
if (val < THE_SIZE && series_length[val]) { steps += series_length[val]; break; }
if(val %2 ) val = 3*val + 1;
else val /= 2;
}
return steps;
}
int main( int argc, char **argv) {
unsigned top, val , result;
unsigned best,maxlength ;
sscanf(argv[1], "%u", &top);
series_length[1] = 1;//redundant statement
best = maxlength = 0;
for(val=1;val <= top; val++) {
result = get_length(val);
// store it if it fits;
if(val<THE_SIZE) series_length[val] = result;
if (result < maxlength) continue;
best = val; maxlength = result;
}
printf("%u %u\n", best, maxlength);
return 0;
}
Finally, just for fun, make the array smaller
#define THE_SIZE 500
, and the program should give the same result for a given value. (it does)
You get the maximum value 24,648,077,896 with n = 487039.
You must thus use the type long long int for n and you should use an array of 24,648,077,896 integers to avoid a segmentation fault. Unfortunately I never succeeded in allocating a block of 100GB. Your optimization is thus not viable.
Without the array optimization I can scan all 500000 n values in 265ms.
Here is my code:
#include <stdio.h>
int collatz_length(int n) {
int length = 0;
long long int v = (long long int)n;
while (v > 1) {
if ((v&1) == 0)
v = v / 2;
else
v = v*3 + 1;
length++;
}
return length;
}
int main() {
int max_i, max_l = 0;
for (int i = 500000; i > 0; i--) {
int l = collatz_length(i);
if (l > max_l){
max_l = l;
max_i = i;
}
}
printf("i: %d l: %d\n", max_i, max_l);
return 0;
}

Multiply a digit array by int in C

I have a very large number (>100 digits long) so it can't be stored as an int or even an unsigned long long (aka uint64_t). The array looks like this:
{5, 1, 2 ... 8, 6}
The array must contain single digit ints.
Question
What would be a simple, and most importantly efficient, way of multiplying this 'number' (keeping it as an array) by a single digit?
What I have tried
As I am fairly new to C, this code is not a masterpiece. Far from it.
struct returnpointer { int * pointer; int length; };
returnpointer mul_arrays(int * x, int y, int lengthof_x) {
returnpointer result_end;
int result[lengthof_x * 2 + 1];
int final_result[lengthof_x * 2 + 1];
int carry = 0;
int j = 0;
//multiply 'y' by all digits of x, which creates multidigit ints
//and also reverses the direction of the array (to allow carrying)
for (int i = lengthof_x; i >= 0; i--) {
result[j] = x[i] * y;
j++;
}
int i = 0;
j = lengthof_x
//this is the bit that doesn't work: it attempts to work out the carry
//however after hours of debugging I can't get it to work.
while (carry > 0 || i < lengthof_x + 1) {
if (result[j] > 9) {
carry = result[j] / 10;
final_result[i] = result[j] % 10;
final_result[i + 1] = carry;
} else {
final_result[i] = result[j];
carry = 0;
}
i++;
j--;
}
result_end.pointer = result;
result_end.length = i + 1;
return result_end;
}
This code does not work properly. It is just an illustration of what I have tried (if it worked I would not be posting this).
In addition, it would be nice to know if the approach I am (trying to) use is the most efficient, as the program it will be incorporated into is very time-intensive so the faster the function the less time the entire program will take.
Thanks in advance.
EDIT:
My compiler is g++.
As requested, here is a code example that multiplies an array by a single digit. The array is little-endian. For a simple example, I have assumed that the array is of fixed length, a more complex one would allocate array memory and extend it if the array grows too big.
#include <stdio.h>
#define BIGLEN 20
typedef struct {
int length;
int array[BIGLEN];
} biggy_t;
void bigmul(biggy_t *big, int mul)
{
int carry = 0, partial;
for(int i = 0; i < big->length; i++) {
partial = big->array[i] * mul + carry;
big->array[i] = partial % 10;
carry = partial / 10;
}
if(carry) {
big->array[big->length] = carry;
big->length++;
}
}
void bigout(biggy_t *big)
{
for(int i = big->length-1; i >= 0; i--) {
printf("%d", big->array[i]);
}
}
int main(int argc, char *argv[])
{
biggy_t big = { 6, { 5, 1, 2, 3, 8, 6 }}; // reverse order
bigout(&big);
printf(" * 7 = ");
bigmul(&big, 7);
bigout(&big);
printf("\n");
}
Program output
683215 * 7 = 4782505
I wrote a bignum implementation in which I can chose the radix. 10 or 100 for byte storage, much more for 32-bit storage. Sticking to a power of 10 makes the conversion to decimal output easier than a power of 2 radix, with a small time penalty for not using the full capacity of the storage type.
So a few observations:
1) I don't think there is any need to reverse the array. Just process it from least significant to most significant digit.
2) There is no reason to store temporary values larger than your allowable digit range. Just do the carry as you go, like you would if you were doing it by hand:
carry = 0
for i in all_the_digits:
product = x[i]*y + carry
x[i] = product%10
carry = product/10
3) you can store the digits as uint8_t without fear of overflow - this will make your array 1/4 the current size, which should improve speed due to caching effects.
There are multiple problems in your code. Not sure I have spotted all of them but here is some to start with.
This loop:
for (int i = lengthof_x; i >= 0; i--) {
result[j] = x[i] * y;
j++;
}
execute "lengthof_x + 1" times. In other words - one time too many! You want to change it to:
for (int i = lengthof_x - 1; i >= 0; i--) { // notice the "- 1"
result[j] = x[i] * y;
j++;
}
Further you have:
result_end.pointer = result;
but it seems that you have calculated the result in the variable final_result so you are returning the wrong array.
However - in any case you are not allowed to return a pointer to a local array! It will go out of scope when the function returns. So even if you do:
result_end.pointer = final_result;
it is still invalid code. You'll need to malloc the array (and that will hurt performance).
Then you have:
result_end.length = i + 1;
So you increment the length in all cases. That's wrong. You should only increment when you have a carry.
Below I have tried to fix your code, i.e. I have tried to keep the overall structure of your code so that you can see where you did mistakes.
#include <stdio.h>
#include <stdlib.h>
struct returnpointer { int * pointer; int length; };
void print_num(struct returnpointer * num)
{
printf("len=%d\nvalue=", num->length);
for(int i = 0; i <num->length; i++) {
printf("%d", num->pointer[i]);
}
}
struct returnpointer mul_arrays(int * x, int y, int lengthof_x) {
struct returnpointer result_end;
int result[lengthof_x + 1];
// Multiply all element and revert array
int j = 0;
for (int i = lengthof_x-1; i >= 0; i--) {
result[j] = x[i] * y;
j++;
}
// Handle carry
int carry = 0;
for (j = 0; j < lengthof_x; j++) {
result[j] = result[j] + carry;
carry = result[j] / 10;
result[j] = result[j] % 10;
}
// Did length increase
if (carry)
{
lengthof_x++;
result[j] = carry;
}
// malloc result and revert back to desired format
j = 0;
int* final_result = malloc(lengthof_x * sizeof *final_result);
for (int i = lengthof_x-1; i >= 0; i--) {
final_result[j] = result[i];
j++;
}
result_end.pointer = final_result;
result_end.length = lengthof_x;
return result_end;
}
int main(int argc, char *argv[])
{
int arr[] = { 5, 1, 2, 3, 8, 6};
struct returnpointer num = mul_arrays(arr, 2, 6); // 512386 * 2 -> 1024772
print_num(&num);
}
Output:
len=7
value=1024772
Notice however that this is not an optimal solution...

Is there a algorithm to print all arrengments of subsequences of an array?

I am working with combinatorics and I would like to know if there is an algorithm that prints all arrangments of subsequences of a given array. That is, if I give to this algorithm the sequence "ABCDEF" it will print :
A,
B,
C,
D,
E,
F,
AB,
AC,
AD,
AE,
AF,
BC,
BD,
BE,
BF,
CD,
CE,
CF,
DE,
DF,
EF,
ABC,
ABD,
ABE,
ABF,
ACD,
ACE,
ACF,
ADE,
ADF,
AEF,
BCD,
BCE,
BCF,
BDE,
BDF,
BEF,
CDE,
CDF,
CEF,
DEF,
ABCD,
ABCE,
ABCF,
ABDE,
ABDF,
ABEF,
ACDE,
ACDF,
ACEF,
ADEF,
BCDE,
BCDF,
BCEF,
BDEF,
CDEF,
ABCDE,
ABCDF,
ABCEF,
ABDEF,
ACDEF,
BCDEF,
ABCDEF,
or for a more simple case, if i give it 1234, it will print:
1,2,3,4,12,13,14,23,24,34,123,124,134,234,1234.
As you can see it is not an arbitrary permutation it is only the permutation of the last members of a subsequence in a way it still reains a subsequence.
I have tried to make a function in c that does this but i got really confused, my idea would be to make a int L that keeps the size of the subsequence,and another tree integers one that keeps the head of the subsequence, one that marks the separation from the head and one that slides trought the given number of characters, but it gets too confused too quickly.
Can anyone help me with this ?
my code is:
int Stringsize( char m[] ){
int k;
for(k=0;;k++){
if( m[k] == '\0') break;
}
return (k-1);
}
void StringOrdM(char m[]){
int q,r,s,k;
for(k=0;k<=Stringsize(m);k++)
for(q=0;q<=Stringsize(m);q++)
for(s=q;s<=Stringsize(m);s++ )
printf("%c",m[q]);
for(r=q+1; r<=Stringsize(m) && (r-q+1)<= k ;r++ )
printf("%c", m[r] );
}
And for ABCD it prints A,A,A,A,B,B,B,C,C,D,AA,AB,AC,AD,BC,BD,CC,CD,DD,... so it is not right because it keeps repeating the A 4 times the B three times and so on, when it should have been A,B,C,D,AB,AC,AD,BC,BD,CD,...
As I said in my comment above, one solution is simple: count in binary up to (1<<n)-1.
So if you have four items, count up to 15, with each bit pattern being a selection of the elements. You'll get 0001, 0010, 0011, 0100, 0101, 0110, 0111, 1000, 1001, 1010, 1011, 1100, 1101, 1110, 1111. Each bit is a true/false value as to whether to include that element of the array.
#include <stdio.h>
int main(void) {
////////////////////////////////////////////////////////////////////////
int A[] = { 1, 2, 3, 4, 5 };
////////////////////////////////////////////////////////////////////////
size_t len = sizeof A / sizeof A[0]; // Array length (in elements)
size_t elbp = (1<<len) - 1; // Element selection bit pattern
size_t i, j; // Iterators
// Cycle through all the bit patterns
for (i = 1; i<=elbp; i++) {
// For each bit pattern, print out the 'checked' elements
for (j = 0; j < len; j++) {
if (i & (1<<j)) printf("%d ", A[j]);
}
printf("\n");
}
return 0;
}
If you want the elements sorted shortest to longest, you could always store these results in a string array (using sprintf()) and then sort (using a stable sorting algorithm!) by string length.
I mentioned in a comment above that if you didn't want to use a bit pattern to find all permutations, and sort the results according to whatever criteria you'd like, you could also use a recursive algorithm.
I suspect this is a homework assignment, and you only asked for an algorithm, so I left some of the key code as an exercise for you to finish. However, the algorithm itself is complete (the key parts are just described in comments, rather than functional code being inserted).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void printpermutations(const int *A, const size_t n, const char *pfix, const size_t rd);
int main(void) {
/////////////////////////////////////////////////////////////////////
int A[] = { 1, 2, 3, 4, 5 };
/////////////////////////////////////////////////////////////////////
size_t n = sizeof A / sizeof A[0]; // Array length (in elements)
size_t i; // Iterator
for (i = 1; i <= n; i++) {
printpermutations(A, n, "", i);
}
return 0;
}
// Recursive function to print permutations of a given length rd,
// using a prefix set in pfix.
// Arguments:
// int *A The integer array we're finding permutations in
// size_t n The size of the integer array
// char *pfix Computed output in higher levels of recursion,
// which will be prepended when we plunge to our
// intended recursive depth
// size_t rd Remaining depth to plunge in recursion
void printpermutations(const int *A, const size_t n, const char *pfix, const size_t rd) {
size_t i;
char newpfix[strlen(pfix)+22]; // 20 digits in 64-bit unsigned int
// plus a space, plus '\0'
if (n < rd) return; // Don't bother if we don't have enough
// elements to do a permutation
if (rd == 1) {
for (i = 0; i < n; i++) {
// YOUR CODE HERE
// Use printf() to print out:
// A string, consisting of the prefix we were passed
// Followed immediately by A[i] and a newline
}
}
else {
strcpy(newpfix, pfix);
for (i = 1; i <= n; i++) {
// YOUR CODE HERE
// Use sprintf() to put A[i-1] and a space into the new prefix string
// at an offset of strlen(pfix).
// Then, call printpermutations() starting with the ith offset into A[],
// with a size of n-i, using the new prefix, with a remaining
// recursion depth one less than the one we were called with
}
}
}
Depending on torstenvl's answer I did this code and It works perfectly.
If there is any problem let me know.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char str[] = "1234";
size_t len = strlen(str); // Array length (in elements)
char *A = malloc(sizeof(char) * len);
strcpy(A,str);
size_t elbp = (1<<len) - 1; // Element selection bit pattern
size_t i, j; // Iterators
int a = 0, b = 0, n = 0;
char **arr = malloc(sizeof(char*) * (10000)); //allocating memory
if (A[0] >= 'A' && A[0] <= 'Z') //If the string given is "ABCD...." transfer 'A' to '1' ; 'C' to '3' ...etc
for(int i = 0; i < len; i++)
A[i] = A[i] - 'A' + '1';
// Cycle through all the bit patterns
for (i = 1; i<=elbp; i++)
{
arr[b] = malloc(sizeof(char) * len);
// For each bit pattern, store in arr[b] the 'checked' elements
for (j = 0, a = 0; j < len; j++)
if (i & (1<<j))
arr[b][a++] = A[j];
b++;
}
int *num = calloc(sizeof(int) ,10000);
for (i = 0; i < b; i++)
num[i] = strtol(arr[i], NULL, 10); //convert char to int
for (i = 0; i < b; i++) //sort array numbers from smallest to largest
for (a = 0; a < i; a++)
if (num[i] < num[a])
{
n = num[i];
num[i] = num[a];
num[a] = n;
}
char *result = calloc(sizeof(char),10000);
for (i = 0, a = 0; i<b; i++)
a += sprintf(&result[a], "%d,", num[i]); //convert int to char and store it in result[a]
result[a - 1] = '\0'; //remove the last ','
len = strlen(result);
if (str[0] >= 'A' && str[0] <= 'Z') //if the string given is "ABCD..." transfer '1' to 'A' ; '12' to 'AB' ; '13' to 'AC'.....etc
for (i = 0; i < len; i++)
if(result[i] != ',')
result[i] = 'A' + (result[i] - '1') ;
///test
printf("%s",result);
return 0;
}
the output for "1234":
1,2,3,4,12,13,14,23,24,34,123,124,134,234,1234
the output for "123456789":
1,2,3,4,5,6,7,8,9,12,13,14,15,16,17,18,19,23,24,25,26,27,28,29,34,35,36,37,38,39,45,46,47,48,49,56,57,58,59,67,68,69,78,79,89,123,124,125,126,127,128,129,134,135,136,137,138,139,145,146,147,148,149,156,157,158,159,167,168,169,178,179,189,234,235,236,237,238,239,245,246,247,248,249,256,257,258,259,267,268,269,278,279,289,345,346,347,348,349,356,357,358,359,367,368,369,378,379,389,456,457,458,459,467,468,469,478,479,489,567,568,569,578,579,589,678,679,689,789,1234,1235,1236,1237,1238,1239,1245,1246,1247,1248,1249,1256,1257,1258,1259,1267,1268,1269,1278,1279,1289,1345,1346,1347,1348,1349,1356,1357,1358,1359,1367,1368,1369,1378,1379,1389,1456,1457,1458,1459,1467,1468,1469,1478,1479,1489,1567,1568,1569,1578,1579,1589,1678,1679,1689,1789,2345,2346,2347,2348,2349,2356,2357,2358,2359,2367,2368,2369,2378,2379,2389,2456,2457,2458,2459,2467,2468,2469,2478,2479,2489,2567,2568,2569,2578,2579,2589,2678,2679,2689,2789,3456,3457,3458,3459,3467,3468,3469,3478,3479,3489,3567,3568,3569,3578,3579,3589,3678,3679,3689,3789,4567,4568,4569,4578,4579,4589,4678,4679,4689,4789,5678,5679,5689,5789,6789,12345,12346,12347,12348,12349,12356,12357,12358,12359,12367,12368,12369,12378,12379,12389,12456,12457,12458,12459,12467,12468,12469,12478,12479,12489,12567,12568,12569,12578,12579,12589,12678,12679,12689,12789,13456,13457,13458,13459,13467,13468,13469,13478,13479,13489,13567,13568,13569,13578,13579,13589,13678,13679,13689,13789,14567,14568,14569,14578,14579,14589,14678,14679,14689,14789,15678,15679,15689,15789,16789,23456,23457,23458,23459,23467,23468,23469,23478,23479,23489,23567,23568,23569,23578,23579,23589,23678,23679,23689,23789,24567,24568,24569,24578,24579,24589,24678,24679,24689,24789,25678,25679,25689,25789,26789,34567,34568,34569,34578,34579,34589,34678,34679,34689,34789,35678,35679,35689,35789,36789,45678,45679,45689,45789,46789,56789,123456,123457,123458,123459,123467,123468,123469,123478,123479,123489,123567,123568,123569,123578,123579,123589,123678,123679,123689,123789,124567,124568,124569,124578,124579,124589,124678,124679,124689,124789,125678,125679,125689,125789,126789,134567,134568,134569,134578,134579,134589,134678,134679,134689,134789,135678,135679,135689,135789,136789,145678,145679,145689,145789,146789,156789,234567,234568,234569,234578,234579,234589,234678,234679,234689,234789,235678,235679,235689,235789,236789,245678,245679,245689,245789,246789,256789,345678,345679,345689,345789,346789,356789,456789,1234567,1234568,1234569,1234578,1234579,1234589,1234678,1234679,1234689,1234789,1235678,1235679,1235689,1235789,1236789,1245678,1245679,1245689,1245789,1246789,1256789,1345678,1345679,1345689,1345789,1346789,1356789,1456789,2345678,2345679,2345689,2345789,2346789,2356789,2456789,3456789,12345678,12345679,12345689,12345789,12346789,12356789,12456789,13456789,23456789,123456789
the output for "ABCDEF":
A,B,C,D,E,F,AB,AC,AD,AE,AF,BC,BD,BE,BF,CD,CE,CF,DE,DF,EF,ABC,ABD,ABE,ABF,ACD,ACE,ACF,ADE,ADF,AEF,BCD,BCE,BCF,BDE,BDF,BEF,CDE,CDF,CEF,DEF,ABCD,ABCE,ABCF,ABDE,ABDF,ABEF,ACDE,ACDF,ACEF,ADEF,BCDE,BCDF,BCEF,BDEF,CDEF,ABCDE,ABCDF,ABCEF,ABDEF,ACDEF,BCDEF,ABCDEF
Combinations, or k-combinations, are the unordered sets of k elements chosen from a set of size n.
Source: http://www.martinbroadhurst.com/combinations.html
This is the code:
unsigned int next_combination(unsigned int *ar, size_t n, unsigned int k)
{
unsigned int finished = 0;
unsigned int changed = 0;
unsigned int i;
if (k > 0) {
for (i = k - 1; !finished && !changed; i--) {
if (ar[i] < (n - 1) - (k - 1) + i) {
/* Increment this element */
ar[i]++;
if (i < k - 1) {
/* Turn the elements after it into a linear sequence */
unsigned int j;
for (j = i + 1; j < k; j++) {
ar[j] = ar[j - 1] + 1;
}
}
changed = 1;
}
finished = i == 0;
}
if (!changed) {
/* Reset to first combination */
for (i = 0; i < k; i++) {
ar[i] = i;
}
}
}
return changed;
}

learning the basics of C programming which can clear my doubts on arrays and strings

I am new to C so this question may seem a bit stupid :P .
I have an array arr[] which stores numbers from 100 to 999.
Now, I have to take each element of the array and subtract the subsequent digits.
For example if I have a number in that array as 1234 then I need another array that stores 1,2,3,4 distinctly so that I can perform 1-2= -1, 2-3 =-1, 3-4= -1.
So if I change a data like 1234 to char through typecasting then how to store this char into an array and then break it into 1,2,3,4 so that I can call it in a for loop by arr[i].
#include <stdio.h>
#include<string.h>
int main()
{
int t,n,w;
int mod = 1000007;
scanf("%d",&t);
while(t--)
{
scanf("%d %d",&n,&w);
int start = 1;
int end = 10;
int i,j,z;
for(i=0;i<=n-2;i++)
{
start = start*10;
end = end*100;
}
end--;
char arr[10000];
for(i= start;i<=end;i++)
{
scanf("%c",&arr[i]);
}
int len = strlen(arr);
int count = 0;
int Value=0;
for(i=0;i<len;i++)
{
char b[10000];
b[0] = arr[i] + '0';
char arr2[10000];
int g = strlen(b);
for(j=0;j<g;j++)
{
strncpy(arr2, b + j, j+1);
}
int k = strlen(arr2);
for(z=0;z<k;z++)
{
int u = arr2[z] - '0';
int V = arr2[z+1] - '0';
if(u>V)
{
Value = Value + (u-V);
}
else
{
Value = Value + (V-u);
}
}
if (Value == w)
{
count++;
}
}
int ans = count % mod;
printf("%d",ans);
}
return 0;
}
Actually its a question from codechef.com called weight of numbers in the easy section of the practice problems
you can split number by digits in this way
int num = 123;
int digits[3];
for (int i = 2; i >= 0; i--)
{
digits[i] = num % 10;
num /= 10;
}
Also if you'll cast num to char that wouldn't help you. You'll just get some character if you try to print it. Nothing more will change.

Resources