Skip to content

Instantly share code, notes, and snippets.

@ClarkeRemy
Last active April 22, 2024 15:23
Show Gist options
  • Save ClarkeRemy/2578454e250c00b7bcc362a739cc5b89 to your computer and use it in GitHub Desktop.
Save ClarkeRemy/2578454e250c00b7bcc362a739cc5b89 to your computer and use it in GitHub Desktop.
I wrote C code for a friend
// I was challenged to do this for a friend. I know it isn't generic.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define FINAL_ROWS 52
#define FINAL_COLS 7
#define FIRST_ROW 12
#define END_OF_DATA 418
#define BLOCK_COLUMNS 10
#define BLOCK_COLUMNS_FINAL 11
static char* TABLE[FINAL_ROWS * FINAL_COLS] = {0};
static char* SCRATCH[FINAL_COLS*BLOCK_COLUMNS_FINAL] = {0};
static size_t transpose(void* matrix, void* scratch_buffer, size_t input_row, size_t input_col, size_t size);
int main() {
// slurp the file into a buffer
FILE* input_file = fopen("Pregnancy.txt", "r");
fseek(input_file, 0, SEEK_END);
size_t file_len = ftell(input_file);
fseek(input_file,0,SEEK_SET);
char* buffer = calloc(file_len, sizeof(char));
size_t remaining = file_len;
while (remaining) remaining -= fread(buffer,sizeof(char), remaining, input_file);
fclose(input_file);
// slurp complete
// Reach the the start of the useful data.
char* buffer_cursor = buffer;
int line = 1;
while (line < FIRST_ROW) {
++buffer_cursor;
if (*buffer_cursor == '\n') ++line;
}
// Fill the TABLE with slices pointing to the buffer.
char** table_cursor = TABLE;
size_t len = 0;
char* start_cursor = buffer_cursor;
while (line < END_OF_DATA) {
if (*buffer_cursor == '\n') {
*buffer_cursor = '\0'; // replace '\n' with '\0' making the pointers nullterminated stings
++line;
if (len != 0) {
*table_cursor = start_cursor;
++table_cursor;
}
++buffer_cursor;
len=0;
start_cursor=buffer_cursor;
continue;
}
++len;
++buffer_cursor;
}
// TABLE is now filled but in the wrong order
// Move cursor after the first row, it is already in the correct order
table_cursor = TABLE+7;
// The array needs to be reordered with a matrix transpose for each "block", the last one is longer than the others
size_t total_blocks = 5;
for (size_t block = 0; block<total_blocks ; ++block) {
size_t columns = BLOCK_COLUMNS;
if (block==total_blocks-1) { columns = BLOCK_COLUMNS_FINAL; }
table_cursor = table_cursor+transpose(table_cursor, SCRATCH, FINAL_COLS, columns, sizeof(char*));
}
memset(SCRATCH, 0, FINAL_COLS*BLOCK_COLUMNS_FINAL*sizeof(char*));
// output the data to a file
FILE* output_file = fopen("Pregnancy_output.csv", "w");
table_cursor = TABLE;
for (; table_cursor < TABLE + FINAL_ROWS*FINAL_COLS; ++table_cursor) {
fputs(*table_cursor,output_file);
if ((table_cursor-TABLE) % 7 == 6) { putc('\n',output_file); } else { putc(',',output_file); }
}
fclose(output_file);
memset(TABLE, 0, FINAL_ROWS*FINAL_COLS*sizeof(char*)); // clear the table
free(buffer); // the buffer that the TABLE points to is freed
return 0;
}
// returns the size of the block that was transposed in units of the size passed in
static size_t transpose(void* matrix, void* scratch_buffer, size_t input_row, size_t input_col, size_t size) {
memcpy(scratch_buffer,matrix,input_col*input_row*size);
for (size_t r = 0; r<input_row; ++r) {
for (size_t c = 0; c<input_col; ++c) {
memcpy(
(void*)((char*)matrix+((c*input_row)+r)*size),
scratch_buffer,
size);
scratch_buffer = (void*)((char*)scratch_buffer+size);
}
}
return input_row*input_col;
}
Table 2. Average age of mother at first birth: United States and each state, 2006
[By place of residence]
All races and
origins
Non-Hispanic
white
Non-Hispanic
black
United States
25.0
26.0
22.7
21.9
28.5
23.1
Alabama
Alaska
Arizona
Arkansas
California
Colorado
Connecticut
Delaware
District of Columbia
Florida
23.6
24.3
24.0
23.0
25.6
25.7
27.2
25.0
26.5
25.0
24.4
25.5
25.8
23.5
27.9
27.2
28.9
26.3
32.6
25.9
21.9
22.4
23.0
21.2
23.5
23.4
23.7
22.9
23.4
22.7
23.9
21.2
21.2
21.7
22.8
23.0
26.3
*
*
22.9
28.1
24.8
28.4
27.3
29.3
28.3
29.2
28.5
29.6
28.1
22.4
23.7
22.0
22.3
23.1
22.3
23.1
22.6
23.2
24.7
Georgia
Hawaii
Idaho
Illinois
Indiana
Iowa
Kansas
Kentucky
Louisiana
Maine
24.5
25.7
23.8
25.4
24.0
24.5
24.2
23.8
23.3
25.6
25.4
26.6
24.1
26.9
24.3
24.7
24.7
24.0
24.3
25.6
22.9
24.6
23.7
21.8
21.5
21.7
21.6
21.7
21.4
23.1
24.8
23.9
21.2
23.4
26.0
21.8
22.0
22.8
23.0
21.1
28.5
25.6
25.9
29.2
28.6
27.4
27.5
28.1
27.7
28.6
23.0
23.2
22.1
23.2
23.0
22.1
21.9
22.7
23.7
24.1
Maryland
Massachusetts
Michigan
Minnesota
Mississippi
Missouri
Montana
Nebraska
Nevada
New Hampshire
26.1
27.7
25.0
25.8
22.6
24.1
24.5
24.7
24.6
26.7
27.3
28.7
25.7
26.4
23.8
24.5
25.0
25.3
25.8
26.7
24.1
25.2
21.9
23.5
21.1
21.5
*
21.7
22.7
25.3
26.0
26.1
23.5
21.1
19.8
22.3
20.3
20.4
22.5
*
29.0
29.1
28.3
25.9
27.4
27.8
28.2
27.1
27.6
28.8
24.1
23.1
23.0
22.9
22.5
22.8
22.3
22.2
22.8
24.2
New Jersey
New Mexico
New York
North Carolina
North Dakota
Ohio
Oklahoma
Oregon
Pennsylvania
Rhode Island
27.2
23.0
26.8
24.6
24.7
24.7
23.1
25.4
25.5
26.2
29.2
25.3
28.3
25.7
25.2
25.1
23.6
25.9
26.4
27.6
23.9
22.6
24.6
22.4
22.4
21.8
21.4
22.9
22.0
23.5
25.0
21.6
23.8
21.5
20.3
22.8
21.7
22.1
22.6
22.6
29.3
28.9
28.7
28.1
27.7
28.8
27.0
28.5
28.2
27.0
24.3
21.8
24.3
22.5
22.5
23.0
21.7
22.4
22.3
22.5
South Carolina
South Dakota
Tennessee
Texas
Utah
Vermont
Virginia
Washington
West Virginia
Wisconsin
Wyoming
24.0
24.0
24.0
23.9
23.9
26.5
25.8
25.9
23.9
25.3
23.7
25.1
24.7
24.6
25.5
24.2
26.5
26.6
26.3
23.8
26.1
23.9
21.9
23.3
22.1
22.8
22.0
25.0
23.2
24.1
22.2
20.8
22.8
22.2
20.1
22.6
23.5
21.2
*
23.9
21.9
*
21.9
21.3
27.2
25.7
27.4
28.6
25.8
30.5
29.0
28.4
29.1
25.9
26.1
22.8
23.2
22.6
22.4
22.2
24.6
24.4
22.8
24.0
22.7
22.1
* Figure does not meet standards of reliability or precision; based on fewer than 20 births.
American Indian Asian or Pacific
or Alaska Native
Islander
Hispanic
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment