added psets
@ -0,0 +1,65 @@
|
||||
#include <cs50.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
int main(int argc, string argv[])
|
||||
{
|
||||
// Make sure program was run with just one command-line argument
|
||||
if (argc > 2 || argc < 2)
|
||||
{
|
||||
printf("Usage: ./caesar {key}\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Make sure every character in argv[1] is a digit
|
||||
for (int i = 0; i < strlen(argv[1]); i++)
|
||||
{
|
||||
if (!isdigit(argv[1][i]))
|
||||
{
|
||||
printf("Usage: ./caesar {key}\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Convert argv[1] from a `string` to an `int`
|
||||
int key = atoi(argv[1]);
|
||||
|
||||
// Prompt user for plaintext
|
||||
string plaintext = get_string("plaintext: ");
|
||||
|
||||
// For each character in the plaintext:
|
||||
string ciphertext = plaintext;
|
||||
for (int i = 0; i < strlen(plaintext); i++)
|
||||
{
|
||||
if (isalpha(plaintext[i]))
|
||||
{
|
||||
int n;
|
||||
// Rotate the character if it's a letter
|
||||
char plaintextChar = (char) plaintext[i];
|
||||
if (isupper(plaintextChar))
|
||||
{
|
||||
n = 65;
|
||||
}
|
||||
else
|
||||
{
|
||||
n = 97;
|
||||
}
|
||||
int plainAlphaIndex = (int) plaintextChar - n;
|
||||
int cipherAlphaIndex = (plainAlphaIndex + key) % 26;
|
||||
char ciphertextChar = (char) cipherAlphaIndex + n;
|
||||
// printf("pT = %c, pAI = %i, cAI = %i, cT = %c", plaintextChar, plainAlphaIndex,
|
||||
// cipherAlphaIndex, ciphertextChar);
|
||||
ciphertext[i] = ciphertextChar;
|
||||
}
|
||||
else
|
||||
{
|
||||
ciphertext[i] = plaintext[i];
|
||||
}
|
||||
// printf("\n");
|
||||
}
|
||||
printf("ciphertext: %s", ciphertext);
|
||||
printf("\n\n");
|
||||
return 0;
|
||||
}
|
||||
@ -0,0 +1,106 @@
|
||||
#include <cs50.h>
|
||||
#include <ctype.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int count_letters(string text);
|
||||
int count_words(string text);
|
||||
int count_sentences(string text);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// Prompt the user for some text
|
||||
string text = get_string("Text: ");
|
||||
|
||||
int words = 1;
|
||||
int sentences = 0;
|
||||
int letters = 0;
|
||||
|
||||
// Count the number of letters, words, and sentences in the text
|
||||
for (int i = 0, n = strlen(text); i < n; i++)
|
||||
{
|
||||
if (text[i] == ' ')
|
||||
{
|
||||
words += 1;
|
||||
}
|
||||
else if (text[i] == '.' || text[i] == '!' || text[i] == '?')
|
||||
{
|
||||
sentences += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isalpha(text[i]))
|
||||
{
|
||||
letters += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// printf("Letters: %i\n", letters);
|
||||
// printf("Words: %i\n", words);
|
||||
// printf("Sentences: %i\n", sentences);
|
||||
|
||||
// Compute the Coleman-Liau index
|
||||
float L = (float) letters / (float) words * 100;
|
||||
float S = (float) sentences / (float) words * 100;
|
||||
float X = 0.0588 * L - 0.296 * S - 15.8;
|
||||
int Xint = (int) round(X);
|
||||
// printf("L=%f, S=%f, X=%f, Xint=%i", L, S, X, Xint);
|
||||
|
||||
// Print the grade level
|
||||
if (Xint >= 16)
|
||||
{
|
||||
printf("Grade 16+\n");
|
||||
}
|
||||
else if (Xint < 1)
|
||||
{
|
||||
printf("Before Grade 1\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Grade %i\n", Xint);
|
||||
}
|
||||
}
|
||||
|
||||
int count_letters(string text)
|
||||
{
|
||||
// Return the number of letters in text
|
||||
int letters = 0;
|
||||
for (int i = 0, n = strlen(text); i < n; i++)
|
||||
{
|
||||
if (isalpha(text[i]))
|
||||
{
|
||||
letters += 1;
|
||||
}
|
||||
}
|
||||
return letters;
|
||||
}
|
||||
|
||||
int count_words(string text)
|
||||
{
|
||||
// Return the number of words in text
|
||||
int words = 0;
|
||||
for (int i = 0, n = strlen(text); i < n; i++)
|
||||
{
|
||||
if (text[i] == ' ' && (text[i - 1] != '.' || text[i - 1] != '!' || text[i - 1] != '?'))
|
||||
{
|
||||
words += 1;
|
||||
}
|
||||
}
|
||||
return words;
|
||||
}
|
||||
|
||||
int count_sentences(string text)
|
||||
{
|
||||
// Return the number of sentences in text
|
||||
int sentences = 0;
|
||||
for (int i = 0, n = strlen(text); i < n; i++)
|
||||
{
|
||||
if (text[i] == '.' || text[i] == '!' || text[i] == '?')
|
||||
{
|
||||
sentences += 1;
|
||||
}
|
||||
}
|
||||
return sentences;
|
||||
}
|
||||
@ -0,0 +1,53 @@
|
||||
#include <cs50.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
// Points assigned to each letter of the alphabet
|
||||
int POINTS[] = {1, 3, 3, 2, 1, 4, 2, 4, 1, 8, 5, 1, 3, 1, 1, 3, 10, 1, 1, 1, 1, 4, 4, 8, 4, 10};
|
||||
|
||||
int compute_score(string word)
|
||||
{
|
||||
// Keep track of score
|
||||
int score = 0;
|
||||
|
||||
// Compute score for each character
|
||||
for (int i = 0, len = strlen(word); i < len; i++)
|
||||
{
|
||||
if (isupper(word[i]))
|
||||
{
|
||||
score += POINTS[word[i] - 'A'];
|
||||
}
|
||||
else if (islower(word[i]))
|
||||
{
|
||||
score += POINTS[word[i] - 'a'];
|
||||
}
|
||||
}
|
||||
|
||||
return score;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// Prompt the user for two words
|
||||
string word1 = get_string("Player 1: ");
|
||||
string word2 = get_string("Player 2: ");
|
||||
|
||||
// Compute the score of each word
|
||||
int score1 = compute_score(word1);
|
||||
int score2 = compute_score(word2);
|
||||
|
||||
// Print the winner
|
||||
if (score1 > score2)
|
||||
{
|
||||
printf("Player 1 wins!\n");
|
||||
}
|
||||
else if (score1 < score2)
|
||||
{
|
||||
printf("Player 2 wins!\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Tie!\n");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,117 @@
|
||||
#include <cs50.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
// Max number of candidates
|
||||
#define MAX 9
|
||||
|
||||
// Candidates have name and vote count
|
||||
typedef struct
|
||||
{
|
||||
string name;
|
||||
int votes;
|
||||
} candidate;
|
||||
|
||||
// Array of candidates
|
||||
candidate candidates[MAX];
|
||||
|
||||
// Number of candidates
|
||||
int candidate_count;
|
||||
|
||||
// Function prototypes
|
||||
bool vote(string name);
|
||||
void print_winner(void);
|
||||
|
||||
int main(int argc, string argv[])
|
||||
{
|
||||
// Check for invalid usage
|
||||
if (argc < 2)
|
||||
{
|
||||
printf("Usage: plurality [candidate ...]\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Populate array of candidates
|
||||
candidate_count = argc - 1;
|
||||
if (candidate_count > MAX)
|
||||
{
|
||||
printf("Maximum number of candidates is %i\n", MAX);
|
||||
return 2;
|
||||
}
|
||||
for (int i = 0; i < candidate_count; i++)
|
||||
{
|
||||
candidates[i].name = argv[i + 1];
|
||||
candidates[i].votes = 0;
|
||||
}
|
||||
|
||||
int voter_count = get_int("Number of voters: ");
|
||||
|
||||
// Loop over all voters
|
||||
for (int i = 0; i < voter_count; i++)
|
||||
{
|
||||
string name = get_string("Vote: ");
|
||||
|
||||
// Check for invalid vote
|
||||
if (!vote(name))
|
||||
{
|
||||
printf("Invalid vote.\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Display winner of election
|
||||
print_winner();
|
||||
}
|
||||
|
||||
// Update vote totals given a new vote
|
||||
bool vote(string name)
|
||||
{
|
||||
// Iterate over each candidate
|
||||
for (int i = 0; i < candidate_count; i++)
|
||||
{
|
||||
// Check if candidate's name matches given name
|
||||
if (strcmp(candidates[i].name, name) == 0)
|
||||
{
|
||||
// If yes, increment candidate's votes and return true
|
||||
candidates[i].votes += 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// If no match, return false
|
||||
return false;
|
||||
}
|
||||
|
||||
// Print the winner (or winners) of the election
|
||||
void print_winner(void)
|
||||
{
|
||||
// Find the maximum number of votes
|
||||
int max = 0;
|
||||
int winnerCount = 0;
|
||||
candidate winners[MAX];
|
||||
|
||||
for (int i = 0; i < candidate_count; i++)
|
||||
{
|
||||
if (candidates[i].votes > max)
|
||||
{
|
||||
// Found new max and save the candidate only
|
||||
// printf("%s has the most votes currently!\n", candidates[i].name);
|
||||
winnerCount = 0;
|
||||
winners[0] = candidates[i];
|
||||
max = candidates[i].votes;
|
||||
}
|
||||
else if (candidates[i].votes == max)
|
||||
{
|
||||
// Found new equal max and save the candidate addtl
|
||||
winnerCount += 1;
|
||||
// printf("%s has the equal votes compared to %s!\n", candidates[i].name, winners[winnerCount -1].name);
|
||||
winners[winnerCount] = candidates[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Print the candidate (or candidates) with maximum votes
|
||||
for (int i = 0; i <= winnerCount; i++)
|
||||
{
|
||||
printf("%s\n", winners[i].name);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@ -0,0 +1,219 @@
|
||||
#include <cs50.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
// Max voters and candidates
|
||||
#define MAX_VOTERS 100
|
||||
#define MAX_CANDIDATES 9
|
||||
|
||||
// preferences[i][j] is jth preference for voter i
|
||||
int preferences[MAX_VOTERS][MAX_CANDIDATES];
|
||||
|
||||
// Candidates have name, vote count, eliminated status
|
||||
typedef struct
|
||||
{
|
||||
string name;
|
||||
int votes;
|
||||
bool eliminated;
|
||||
} candidate;
|
||||
|
||||
// Array of candidates
|
||||
candidate candidates[MAX_CANDIDATES];
|
||||
|
||||
// Numbers of voters and candidates
|
||||
int voter_count;
|
||||
int candidate_count;
|
||||
|
||||
// Function prototypes
|
||||
bool vote(int voter, int rank, string name);
|
||||
void tabulate(void);
|
||||
bool print_winner(void);
|
||||
int find_min(void);
|
||||
bool is_tie(int min);
|
||||
void eliminate(int min);
|
||||
|
||||
int main(int argc, string argv[])
|
||||
{
|
||||
// Check for invalid usage
|
||||
if (argc < 2)
|
||||
{
|
||||
printf("Usage: runoff [candidate ...]\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Populate array of candidates
|
||||
candidate_count = argc - 1;
|
||||
if (candidate_count > MAX_CANDIDATES)
|
||||
{
|
||||
printf("Maximum number of candidates is %i\n", MAX_CANDIDATES);
|
||||
return 2;
|
||||
}
|
||||
for (int i = 0; i < candidate_count; i++)
|
||||
{
|
||||
candidates[i].name = argv[i + 1];
|
||||
candidates[i].votes = 0;
|
||||
candidates[i].eliminated = false;
|
||||
}
|
||||
|
||||
voter_count = get_int("Number of voters: ");
|
||||
if (voter_count > MAX_VOTERS)
|
||||
{
|
||||
printf("Maximum number of voters is %i\n", MAX_VOTERS);
|
||||
return 3;
|
||||
}
|
||||
|
||||
// Keep querying for votes
|
||||
for (int i = 0; i < voter_count; i++)
|
||||
{
|
||||
|
||||
// Query for each rank
|
||||
for (int j = 0; j < candidate_count; j++)
|
||||
{
|
||||
string name = get_string("Rank %i: ", j + 1);
|
||||
|
||||
// Record vote, unless it's invalid
|
||||
if (!vote(i, j, name))
|
||||
{
|
||||
printf("Invalid vote.\n");
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
// Keep holding runoffs until winner exists
|
||||
while (true)
|
||||
{
|
||||
// Calculate votes given remaining candidates
|
||||
tabulate();
|
||||
|
||||
// Check if election has been won
|
||||
bool won = print_winner();
|
||||
if (won)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Eliminate last-place candidates
|
||||
int min = find_min();
|
||||
bool tie = is_tie(min);
|
||||
|
||||
// If tie, everyone wins
|
||||
if (tie)
|
||||
{
|
||||
for (int i = 0; i < candidate_count; i++)
|
||||
{
|
||||
if (!candidates[i].eliminated)
|
||||
{
|
||||
printf("%s\n", candidates[i].name);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Eliminate anyone with minimum number of votes
|
||||
eliminate(min);
|
||||
|
||||
// Reset vote counts back to zero
|
||||
for (int i = 0; i < candidate_count; i++)
|
||||
{
|
||||
candidates[i].votes = 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Record preference if vote is valid
|
||||
bool vote(int voter, int rank, string name)
|
||||
{
|
||||
for (int i = 0; i < candidate_count; i++)
|
||||
{
|
||||
if (strcmp(name, candidates[i].name) == 0)
|
||||
{
|
||||
preferences[voter][rank] = i;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Tabulate votes for non-eliminated candidates
|
||||
void tabulate(void)
|
||||
{
|
||||
for (int i = 0; i < voter_count; i++)
|
||||
{
|
||||
for (int j = 0; j < candidate_count; j++)
|
||||
{
|
||||
if (!candidates[preferences[i][j]].eliminated)
|
||||
{
|
||||
candidates[preferences[i][j]].votes += 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Print the winner of the election, if there is one
|
||||
bool print_winner(void)
|
||||
{
|
||||
for (int i = 0; i < candidate_count; i++)
|
||||
{
|
||||
if (!candidates[i].eliminated && candidates[i].votes > voter_count / 2)
|
||||
{
|
||||
printf("%s\n", candidates[i].name);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return the minimum number of votes any remaining candidate has
|
||||
int find_min(void)
|
||||
{
|
||||
int lastMin = MAX_VOTERS;
|
||||
for (int i = 0; i < candidate_count; i++)
|
||||
{
|
||||
if (!candidates[i].eliminated)
|
||||
{
|
||||
if (candidates[i].votes < lastMin)
|
||||
{
|
||||
lastMin = candidates[i].votes;
|
||||
}
|
||||
}
|
||||
}
|
||||
return lastMin;
|
||||
}
|
||||
|
||||
// Return true if the election is tied between all candidates, false otherwise
|
||||
bool is_tie(int min)
|
||||
{
|
||||
int candidates_in = 0;
|
||||
int candidates_tied = 0;
|
||||
for (int i = 0; i < candidate_count; i++)
|
||||
{
|
||||
if (!candidates[i].eliminated)
|
||||
{
|
||||
candidates_in += 1;
|
||||
if (candidates[i].votes == min)
|
||||
{
|
||||
candidates_tied += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (candidates_tied == candidates_in);
|
||||
}
|
||||
|
||||
// Eliminate the candidate (or candidates) in last place
|
||||
void eliminate(int min)
|
||||
{
|
||||
for (int i = 0; i < candidate_count; i++)
|
||||
{
|
||||
if (candidates[i].votes == min)
|
||||
{
|
||||
candidates[i].eliminated = true;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
sort1 uses: Bubble Sort
|
||||
|
||||
How do you know?: slowest, but fast with sorted
|
||||
|
||||
sort2 uses: Merge Sort
|
||||
|
||||
How do you know?: fastest, especially with reversed or random
|
||||
|
||||
sort3 uses: Selection Sort
|
||||
|
||||
How do you know?: fast with random, but slow with reversed
|
||||
@ -0,0 +1,2 @@
|
||||
filter:
|
||||
clang -ggdb3 -gdwarf-4 -O0 -Qunused-arguments -std=c11 -Wall -Werror -Wextra -Wno-gnu-folding-constant -Wno-sign-compare -Wno-unused-parameter -Wno-unused-variable -Wshadow -lm -o filter filter.c helpers.c
|
||||
@ -0,0 +1,57 @@
|
||||
// BMP-related data types based on Microsoft's own
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// These data types are essentially aliases for C/C++ primitive data types.
|
||||
// Adapted from http://msdn.microsoft.com/en-us/library/cc230309.aspx.
|
||||
// See https://en.wikipedia.org/wiki/C_data_types#stdint.h for more on stdint.h.
|
||||
|
||||
typedef uint8_t BYTE;
|
||||
typedef uint32_t DWORD;
|
||||
typedef int32_t LONG;
|
||||
typedef uint16_t WORD;
|
||||
|
||||
// The BITMAPFILEHEADER structure contains information about the type, size,
|
||||
// and layout of a file that contains a DIB [device-independent bitmap].
|
||||
// Adapted from http://msdn.microsoft.com/en-us/library/dd183374(VS.85).aspx.
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WORD bfType;
|
||||
DWORD bfSize;
|
||||
WORD bfReserved1;
|
||||
WORD bfReserved2;
|
||||
DWORD bfOffBits;
|
||||
} __attribute__((__packed__))
|
||||
BITMAPFILEHEADER;
|
||||
|
||||
// The BITMAPINFOHEADER structure contains information about the
|
||||
// dimensions and color format of a DIB [device-independent bitmap].
|
||||
// Adapted from http://msdn.microsoft.com/en-us/library/dd183376(VS.85).aspx.
|
||||
|
||||
typedef struct
|
||||
{
|
||||
DWORD biSize;
|
||||
LONG biWidth;
|
||||
LONG biHeight;
|
||||
WORD biPlanes;
|
||||
WORD biBitCount;
|
||||
DWORD biCompression;
|
||||
DWORD biSizeImage;
|
||||
LONG biXPelsPerMeter;
|
||||
LONG biYPelsPerMeter;
|
||||
DWORD biClrUsed;
|
||||
DWORD biClrImportant;
|
||||
} __attribute__((__packed__))
|
||||
BITMAPINFOHEADER;
|
||||
|
||||
// The RGBTRIPLE structure describes a color consisting of relative intensities of
|
||||
// red, green, and blue. Adapted from http://msdn.microsoft.com/en-us/library/aa922590.aspx.
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BYTE rgbtBlue;
|
||||
BYTE rgbtGreen;
|
||||
BYTE rgbtRed;
|
||||
} __attribute__((__packed__))
|
||||
RGBTRIPLE;
|
||||
@ -0,0 +1,150 @@
|
||||
#include "helpers.h"
|
||||
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// Define allowable filters
|
||||
char *filters = "bgrs";
|
||||
|
||||
// Get filter flag and check validity
|
||||
char filter = getopt(argc, argv, filters);
|
||||
if (filter == '?')
|
||||
{
|
||||
printf("Invalid filter.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Ensure only one filter
|
||||
if (getopt(argc, argv, filters) != -1)
|
||||
{
|
||||
printf("Only one filter allowed.\n");
|
||||
return 2;
|
||||
}
|
||||
|
||||
// Ensure proper usage
|
||||
if (argc != optind + 2)
|
||||
{
|
||||
printf("Usage: ./filter [flag] infile outfile\n");
|
||||
return 3;
|
||||
}
|
||||
|
||||
// Remember filenames
|
||||
char *infile = argv[optind];
|
||||
char *outfile = argv[optind + 1];
|
||||
|
||||
// Open input file
|
||||
FILE *inptr = fopen(infile, "r");
|
||||
if (inptr == NULL)
|
||||
{
|
||||
printf("Could not open %s.\n", infile);
|
||||
return 4;
|
||||
}
|
||||
|
||||
// Open output file
|
||||
FILE *outptr = fopen(outfile, "w");
|
||||
if (outptr == NULL)
|
||||
{
|
||||
fclose(inptr);
|
||||
printf("Could not create %s.\n", outfile);
|
||||
return 5;
|
||||
}
|
||||
|
||||
// Read infile's BITMAPFILEHEADER
|
||||
BITMAPFILEHEADER bf;
|
||||
fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);
|
||||
|
||||
// Read infile's BITMAPINFOHEADER
|
||||
BITMAPINFOHEADER bi;
|
||||
fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);
|
||||
|
||||
// Ensure infile is (likely) a 24-bit uncompressed BMP 4.0
|
||||
if (bf.bfType != 0x4d42 || bf.bfOffBits != 54 || bi.biSize != 40 || bi.biBitCount != 24 ||
|
||||
bi.biCompression != 0)
|
||||
{
|
||||
fclose(outptr);
|
||||
fclose(inptr);
|
||||
printf("Unsupported file format.\n");
|
||||
return 6;
|
||||
}
|
||||
|
||||
// Get image's dimensions
|
||||
int height = abs(bi.biHeight);
|
||||
int width = bi.biWidth;
|
||||
|
||||
// Allocate memory for image
|
||||
RGBTRIPLE(*image)[width] = calloc(height, width * sizeof(RGBTRIPLE));
|
||||
if (image == NULL)
|
||||
{
|
||||
printf("Not enough memory to store image.\n");
|
||||
fclose(outptr);
|
||||
fclose(inptr);
|
||||
return 7;
|
||||
}
|
||||
|
||||
// Determine padding for scanlines
|
||||
int padding = (4 - (width * sizeof(RGBTRIPLE)) % 4) % 4;
|
||||
|
||||
// Iterate over infile's scanlines
|
||||
for (int i = 0; i < height; i++)
|
||||
{
|
||||
// Read row into pixel array
|
||||
fread(image[i], sizeof(RGBTRIPLE), width, inptr);
|
||||
|
||||
// Skip over padding
|
||||
fseek(inptr, padding, SEEK_CUR);
|
||||
}
|
||||
|
||||
// Filter image
|
||||
switch (filter)
|
||||
{
|
||||
// Blur
|
||||
case 'b':
|
||||
blur(height, width, image);
|
||||
break;
|
||||
|
||||
// Grayscale
|
||||
case 'g':
|
||||
grayscale(height, width, image);
|
||||
break;
|
||||
|
||||
// Reflection
|
||||
case 'r':
|
||||
reflect(height, width, image);
|
||||
break;
|
||||
|
||||
// Sepia
|
||||
case 's':
|
||||
sepia(height, width, image);
|
||||
break;
|
||||
}
|
||||
|
||||
// Write outfile's BITMAPFILEHEADER
|
||||
fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);
|
||||
|
||||
// Write outfile's BITMAPINFOHEADER
|
||||
fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, outptr);
|
||||
|
||||
// Write new pixels to outfile
|
||||
for (int i = 0; i < height; i++)
|
||||
{
|
||||
// Write row to outfile
|
||||
fwrite(image[i], sizeof(RGBTRIPLE), width, outptr);
|
||||
|
||||
// Write padding at end of row
|
||||
for (int k = 0; k < padding; k++)
|
||||
{
|
||||
fputc(0x00, outptr);
|
||||
}
|
||||
}
|
||||
|
||||
// Free memory for image
|
||||
free(image);
|
||||
|
||||
// Close files
|
||||
fclose(inptr);
|
||||
fclose(outptr);
|
||||
return 0;
|
||||
}
|
||||
@ -0,0 +1,149 @@
|
||||
#include "helpers.h"
|
||||
#include <cs50.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
// Prototype
|
||||
int RoundCastCap(float color);
|
||||
|
||||
// Convert image to grayscale
|
||||
void grayscale(int height, int width, RGBTRIPLE image[height][width])
|
||||
{
|
||||
// Loop over all pixels
|
||||
for (int i = 0; i < height; i++)
|
||||
{
|
||||
for (int j = 0; j < width; j++)
|
||||
{
|
||||
// Take average of red, green, and blue
|
||||
int average = (int) round(((float) image[i][j].rgbtRed + (float) image[i][j].rgbtGreen +
|
||||
(float) image[i][j].rgbtBlue) /
|
||||
3.0);
|
||||
// Update pixel values
|
||||
image[i][j].rgbtRed = average;
|
||||
image[i][j].rgbtGreen = average;
|
||||
image[i][j].rgbtBlue = average;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Convert image to sepia
|
||||
void sepia(int height, int width, RGBTRIPLE image[height][width])
|
||||
{
|
||||
// Loop over all pixels
|
||||
for (int i = 0; i < heightbuffer; i++)
|
||||
{
|
||||
for (int j = 0; j < width; j++)
|
||||
{
|
||||
// Get original colors
|
||||
int originalRed = image[i][j].rgbtRed;
|
||||
int originalGreen = image[i][j].rgbtGreen;
|
||||
int originalBlue = image[i][j].rgbtBlue;
|
||||
// Compute sepia values
|
||||
float sepiaRed = .393 * originalRed + .769 * originalGreen + .189 * originalBlue;
|
||||
float sepiaGreen = .349 * originalRed + .686 * originalGreen + .168 * originalBlue;
|
||||
float sepiaBlue = .272 * originalRed + .534 * originalGreen + .131 * originalBlue;
|
||||
// Round, cast and cap between 0 and 255
|
||||
int sepiaRedInt = RoundCastCap(sepiaRed);
|
||||
int sepiaGreenInt = RoundCastCap(sepiaGreen);
|
||||
int sepiaBlueInt = RoundCastCap(sepiaBlue);
|
||||
|
||||
// Update pixel values
|
||||
image[i][j].rgbtRed = sepiaRedInt;
|
||||
image[i][j].rgbtGreen = sepiaGreenInt;
|
||||
image[i][j].rgbtBlue = sepiaBlueInt;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Reflect image horizontally
|
||||
void reflect(int height, int width, RGBTRIPLE image[height][width])
|
||||
{
|
||||
// Copy complete image
|
||||
RGBTRIPLE image_copy[height][width];
|
||||
for (int i = 0; i < height; i++)
|
||||
{
|
||||
for (int j = 0; j < width; j++)
|
||||
{
|
||||
image_copy[i][j] = image[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
// Loop over all pixels
|
||||
for (int k = 0; k < height; k++)
|
||||
{
|
||||
for (int l = 0; l < width / 2; l++)
|
||||
{
|
||||
image[k][l] = image_copy[k][width - l - 1];
|
||||
image[k][width - l - 1] = image_copy[k][l];
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Blur image
|
||||
void blur(int height, int width, RGBTRIPLE image[height][width])
|
||||
{
|
||||
RGBTRIPLE blurred_image[height][width];
|
||||
|
||||
for (int col = 0; col < height; col++)
|
||||
{
|
||||
for (int row = 0; row < width; row++)
|
||||
{
|
||||
|
||||
double sumRed = 0;
|
||||
double sumGreen = 0;
|
||||
double sumBlue = 0;
|
||||
double divider = 0;
|
||||
|
||||
for (int y = col - 1; y <= col + 1; y++)
|
||||
{
|
||||
for (int x = row - 1; x <= row + 1; x++)
|
||||
{
|
||||
// If a pixel is within a valid range
|
||||
if ((y >= 0 && y < height) && (x >= 0 && x < width))
|
||||
{
|
||||
sumRed = image[y][x].rgbtRed + sumRed;
|
||||
sumGreen = image[y][x].rgbtGreen + sumGreen;
|
||||
sumBlue = image[y][x].rgbtBlue + sumBlue;
|
||||
divider++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
blurred_image[col][row].rgbtRed = round((sumRed / divider));
|
||||
blurred_image[col][row].rgbtGreen = round((sumGreen / divider));
|
||||
blurred_image[col][row].rgbtBlue = round((sumBlue / divider));
|
||||
}
|
||||
}
|
||||
|
||||
// Overwrite the orinal image with the blurred image
|
||||
for (int i = 0; i < height; i++)
|
||||
{
|
||||
for (int j = 0; j < width; j++)
|
||||
{
|
||||
image[i][j].rgbtRed = blurred_image[i][j].rgbtRed;
|
||||
image[i][j].rgbtGreen = blurred_image[i][j].rgbtGreen;
|
||||
image[i][j].rgbtBlue = blurred_image[i][j].rgbtBlue;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Round, cast and cap between 0 and 255
|
||||
int RoundCastCap(float color)
|
||||
{
|
||||
int colorInt = (int) round(color);
|
||||
if (colorInt > 255)
|
||||
{
|
||||
colorInt = 255;
|
||||
}
|
||||
else if (colorInt < 0)
|
||||
{
|
||||
colorInt = 0;
|
||||
}
|
||||
return colorInt;
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
#include "bmp.h"
|
||||
|
||||
// Convert image to grayscale
|
||||
void grayscale(int height, int width, RGBTRIPLE image[height][width]);
|
||||
|
||||
// Convert image to sepia
|
||||
void sepia(int height, int width, RGBTRIPLE image[height][width]);
|
||||
|
||||
// Reflect image horizontally
|
||||
void reflect(int height, int width, RGBTRIPLE image[height][width]);
|
||||
|
||||
// Blur image
|
||||
void blur(int height, int width, RGBTRIPLE image[height][width]);
|
||||
|
After Width: | Height: | Size: 703 KiB |
|
After Width: | Height: | Size: 703 KiB |
|
After Width: | Height: | Size: 703 KiB |
|
After Width: | Height: | Size: 703 KiB |
|
After Width: | Height: | Size: 703 KiB |
|
After Width: | Height: | Size: 703 KiB |
|
After Width: | Height: | Size: 703 KiB |
|
After Width: | Height: | Size: 703 KiB |
|
After Width: | Height: | Size: 703 KiB |
|
After Width: | Height: | Size: 703 KiB |
|
After Width: | Height: | Size: 703 KiB |
|
After Width: | Height: | Size: 703 KiB |
|
After Width: | Height: | Size: 703 KiB |
|
After Width: | Height: | Size: 703 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 9.5 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 9.5 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 9.5 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 9.5 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 9.5 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 9.5 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 9.5 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 9.5 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 9.5 KiB |
|
After Width: | Height: | Size: 9.5 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 9.5 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 9.5 KiB |
|
After Width: | Height: | Size: 9.5 KiB |
|
After Width: | Height: | Size: 10 KiB |
@ -0,0 +1,55 @@
|
||||
#include <cs50.h>
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// Accept a single command-line argument
|
||||
if (argc != 2)
|
||||
{
|
||||
printf("Usage: ./recover FILE\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Open the memory card
|
||||
FILE *inptr = fopen(argv[1], "r");
|
||||
if (inptr == NULL)
|
||||
{
|
||||
printf("Unable to open file\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Create a buffer for a block of data
|
||||
uint8_t buffer[512];
|
||||
int block_counter = 0;
|
||||
FILE *outptr = NULL;
|
||||
char filename[8];
|
||||
|
||||
// While there's still data left to read from the memory card
|
||||
int i = 0;
|
||||
while (fread(buffer, 1, 512, inptr) == 512)
|
||||
{
|
||||
if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff &&
|
||||
(buffer[3] & 0xf0) == 0xe0)
|
||||
{
|
||||
if (outptr != 0)
|
||||
{
|
||||
fclose(outptr);
|
||||
}
|
||||
sprintf(filename, "%03i.jpg", block_counter);
|
||||
outptr = fopen(filename, "w");
|
||||
block_counter++;
|
||||
}
|
||||
if (outptr != 0)
|
||||
{
|
||||
// if already found, continue writing
|
||||
fwrite(buffer, 512, 1, outptr);
|
||||
}
|
||||
}
|
||||
fclose(inptr);
|
||||
fclose(outptr);
|
||||
return 0;
|
||||
}
|
||||
@ -0,0 +1,52 @@
|
||||
// Modifies the volume of an audio file
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// Number of bytes in .wav header
|
||||
const int HEADER_SIZE = 44;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// Check command-line arguments
|
||||
if (argc != 4)
|
||||
{
|
||||
printf("Usage: ./volume input.wav output.wav factor\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Open files and determine scaling factor
|
||||
FILE *input = fopen(argv[1], "r");
|
||||
if (input == NULL)
|
||||
{
|
||||
printf("Could not open file.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
FILE *output = fopen(argv[2], "w");
|
||||
if (output == NULL)
|
||||
{
|
||||
printf("Could not open file.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
float factor = atof(argv[3]);
|
||||
|
||||
// Copy header from input file to output file
|
||||
uint8_t header[HEADER_SIZE];
|
||||
fread(header, HEADER_SIZE, 1, input);
|
||||
fwrite(header, HEADER_SIZE, 1, output);
|
||||
|
||||
// Read samples from input file and write updated data to output file
|
||||
int16_t buffer;
|
||||
while (fread(&buffer, sizeof(int16_t), 1, input))
|
||||
{
|
||||
buffer *= factor;
|
||||
fwrite(&buffer, sizeof(int16_t), 1, output);
|
||||
}
|
||||
|
||||
// Close files
|
||||
fclose(input);
|
||||
fclose(output);
|
||||
}
|
||||