Code Monkey home page Code Monkey logo

Comments (23)

ErikSchierboom avatar ErikSchierboom commented on July 18, 2024

Exercise: space-age

Code

#include <math.h>
#include "space_age.h"

double
convert_planet_age(planet planet, unsigned long age) {
    switch (planet) {
        case MERCURY:
            return age / (EARTH_YEAR * 0.2408467);
            break;
        case VENUS:
            return age / (EARTH_YEAR * 0.61519726);
        case EARTH:
            return age / EARTH_YEAR;
        case MARS:
            return age / (EARTH_YEAR * 1.8808158);
        case JUPITER:
            return age / (EARTH_YEAR * 11.862615);
        case SATURN:
            return age / (EARTH_YEAR * 29.447498);
        case URANUS:
            return age / (EARTH_YEAR * 84.016846);
        default: /* NEPTUNE */
            return age / (EARTH_YEAR * 164.79132);
    }
}

Tags:

construct:break
construct:comment
construct:divide
construct:double
construct:floating-point-number
construct:header
construct:include
construct:long
construct:multiply
construct:return
construct:switch
construct:unsigned
construct:variable
construct:visibility-modifiers
paradigm:imperative
paradigm:procedural

from c.

ErikSchierboom avatar ErikSchierboom commented on July 18, 2024

Exercise: raindrops

Code

#include <string.h>
#include <stdio.h>

void convert(char *result, int drops)
{
	char *p = result;

	if (drops % 3 == 0) {
		strcpy(p, "Pling");
		p += 5;
	}

	if (drops % 5 == 0) {
		strcpy(p, "Plang");
		p += 5;
	}

	if (drops % 7 == 0) {
		strcpy(p, "Plong");
		p += 5;
	}

	if (p == result)
		sprintf(p, "%d", drops);
}

Tags:

construct:add
construct:assignment
construct:char
construct:comment
construct:conditional
construct:if
construct:include
construct:int
construct:integral-number
construct:invocation
construct:parameter
construct:string
construct:variable
construct:visibility-modifier
paradigm:imperative
paradigm:procedural
uses:stdio.h
uses:string.h

from c.

ErikSchierboom avatar ErikSchierboom commented on July 18, 2024

Exercise: bob

Code

#include "bob.h"
#include <ctype.h>

char *hey_bob(char *phrase) {
  int is_question = 0;
  int any_upper = 0;
  int any_lower = 0;
  int all_empty = 1;

  char ch;
  while ((ch = *phrase++) != '\0') {
    if (ch != ' ')
      is_question = 0;
    if (ch == '?')
      is_question = 1;
    if (ch != ' ')
      all_empty = 0;
    if (islower(ch))
      any_lower = 1;
    if (isupper(ch))
      any_upper = 1;
  }

  if (any_upper && !any_lower)
    return "Whoa, chill out!";
  if (is_question)
    return "Sure.";
  if (all_empty)
    return "Fine. Be that way!";
  return "Whatever.";
}

Tags:

construct:assignment
construct:char
construct:header
construct:if
construct:include
construct:int
construct:integral
construct:invocation
construct:logical-and
construct:loop
construct:return
construct:string
construct:variable
construct:visibility-modifiers
construct:while-loop
paradigm:imperative
paradigm:procedural
technique:looping

from c.

ErikSchierboom avatar ErikSchierboom commented on July 18, 2024

Exercise: sum-of-multiples

Code

int is_multiple(const unsigned int *multiples, int count, int n)
{
	int j;

	if (!multiples)
		return 0;

	for (j = 0; j < count; j++) {
		if (multiples[j] && !(n % multiples[j]))
			return 1;
	}

	return 0;
}

int sum_of_multiples(const unsigned int *multiples, int count, int n)
{
	int s = 0;
	int i;

	for (i = 1; i < n; i++) {
		if (is_multiple(multiples, count, i))
			s += i;
	}

	return s;
}

Tags:

construct:assignment
construct:boolean
construct:const
construct:for-loop
construct:function
construct:if
construct:indexing
construct:int
construct:integral-number
construct:logical-and
construct:number
construct:parameter
construct:return
construct:unsigned-int
construct:variable
construct:visibility-modifiers
paradigm:imperative
paradigm:object-oriented
technique:boolean-logic
technique:looping

from c.

ErikSchierboom avatar ErikSchierboom commented on July 18, 2024

Exercise: roman-numerals

Code

#include <stdlib.h>

static int handle_special_val(int rest, int val, char **pp, char c1, char c2)
{
	if (rest >= val) {
		if (c1)
			*(*pp)++ = c1;
		if (c2)
			*(*pp)++ = c2;
		rest -= val;
	}

	return rest;
}

static int handle_val(int rest, int val, char **pp, char c)
{
	int i;
	int quotient = rest / val;

	for (i = 0; i < quotient; i++)
		*(*pp)++ = c;

	return rest % val;	
}

char *to_roman_numeral(int n)
{
	char *res = malloc(256);
	char *p = res;
	int rest;

	rest = handle_val(n, 1000, &p, 'M');
	rest = handle_special_val(rest, 900, &p, 'C', 'M');
	rest = handle_special_val(rest, 500, &p, 'D', 0);
	rest = handle_special_val(rest, 400, &p, 'C', 'D');
	rest = handle_val(rest, 100, &p, 'C');
	rest = handle_special_val(rest, 90, &p, 'X', 'C');
	rest = handle_special_val(rest, 50, &p, 'L', 0);
	rest = handle_special_val(rest, 40, &p, 'X', 'L');
	rest = handle_val(rest, 10, &p, 'X');
	rest = handle_special_val(rest, 9, &p, 'I', 'X');
	rest = handle_special_val(rest, 5, &p, 'V', 0);
	rest = handle_special_val(rest, 4, &p, 'I', 'V');
	rest = handle_val(rest, 1, &p, 'I');

	// Nul terminate
	*p++ = 0;
	
	return res;
}

Tags:

construct:assignment
construct:bitwise-and
construct:char
construct:comment
construct:divide
construct:for-loop
construct:function
construct:if
construct:implicit-conversion
construct:int
construct:integral-number
construct:invocation
construct:malloc
construct:nested-function
construct:number
construct:parameter
construct:return
construct:static
construct:string
construct:subtract
construct:variable
construct:visibility-modifiers
paradigm:functional
paradigm:imperative
paradigm:object-oriented
technique:bit-manipulation
technique:bit-shifting
technique:looping
uses:malloc

from c.

ErikSchierboom avatar ErikSchierboom commented on July 18, 2024

Exercise: series

Code

/*================================================================
*   Copyright (C) 2017. All rights reserved.
*   
*   name:series.c
*   creator:x
*   date:2017ๅนด04ๆœˆ19ๆ—ฅ
*   description:
*
================================================================*/


#include "series.h"
#include <string.h>
#include <stdlib.h>

static SeriesResults_t result;
SeriesResults_t series(char *inputText, unsigned int substringLength)
{
	result.substringCount = 0;
	result.substring = NULL;
	size_t len = strlen(inputText);
	if(len < substringLength || substringLength == 0)
		return result;
	size_t count = len - substringLength + 1;
	result.substringCount = count;
	char **pptr;
	if((pptr = malloc(count * sizeof(char *))) == NULL)
		exit(1);
	result.substring = pptr;
	for(size_t i = 0; i < count; i++){
		if((pptr[i] = malloc(substringLength + 1)) == NULL)
			exit(1);
		pptr[i][substringLength] = '\0';
		strncpy(pptr[i], inputText+i, substringLength);
	}
	return result;
}

Tags:

construct:add
construct:assignment
construct:char
construct:comment
construct:constructor
construct:exit
construct:for-loop
construct:header
construct:if
construct:implicit-conversion
construct:index
construct:int
construct:integral-number
construct:logical-or
construct:long-long
construct:method
construct:multiply
construct:null
construct:nullability
construct:number
construct:parameter
construct:return
construct:size_t
construct:static
construct:string
construct:struct
construct:subtract
construct:typedef
construct:variable
construct:visibility-modifiers
paradigm:imperative
paradigm:object-oriented
technique:boolean-logic
technique:looping
uses:strlen

from c.

ErikSchierboom avatar ErikSchierboom commented on July 18, 2024

Exercise: phone-number

Code

/*================================================================
*   Copyright (C) 2017. All rights reserved.
*   
*   name:phone_number.c
*   creator:x
*   date:2017ๅนด04ๆœˆ16ๆ—ฅ
*   description:
*
================================================================*/


#include "phone_number.h"
#include <ctype.h>
#include <stdlib.h>
#include <string.h>

#define valid_nondigit "() -."
#define is_invalid(c) ((c) != '(' && (c) != ')' && (c) != ' '\
		&& (c) != '-' && (c) != '.' )
char * phone_number_clean(const char *input)
{
	char * ptr;
	if((ptr = malloc(10 + 1)) == NULL)
		exit(1);
	ptr[10] = '\0';
	int len = strlen(input);
	if(len < 10)
		return memset(ptr, '0', 10);
	if(len == 11){
		if(input[0] == '1')
			input++;
		else
			return memset(ptr, '0', 10);
	}
	for(unsigned int i = 0; *input; input++){
		if(isdigit(*input)){
			if(i == 10)
				return memset(ptr, '0', 10);
			ptr[i++] = *input;
		}
		else if(is_invalid(*input))
			return memset(ptr,'0', 10);
	}
	return ptr;
}
char * phone_number_get_area_code(const char *input)
{
	char * area = phone_number_clean(input);
	area[3] = 0;
	return area;
}
char * phone_number_format(const char * input)
{
	char * clean = phone_number_clean(input);
	char * formatted;
	if((formatted = malloc(15)) == NULL)
		exit(1);
	formatted[14] = 0;
	strcpy(formatted, "(xxx) xxx-xxxx");
	strncpy(&formatted[1], clean, 3);
	strncpy(&formatted[6], &clean[3], 3);
	strncpy(&formatted[10], &clean[6], 4);
	free(clean);

	return formatted;
}

Tags:

construct:assignment
construct:bitwise-and
construct:char
construct:define
construct:for-loop
construct:function
construct:header
construct:if
construct:implicit-conversion
construct:indexing
construct:int
construct:integral-number
construct:invocation
construct:logical-and
construct:macro
construct:malloc
construct:number
construct:parameter
construct:return
construct:string
construct:typedef
construct:variable
construct:visibility-modifiers
paradigm:imperative
paradigm:metaprogramming
paradigm:procedural
technique:bit-manipulation
technique:bit-shifting
technique:looping
uses:char
uses:malloc

from c.

ErikSchierboom avatar ErikSchierboom commented on July 18, 2024

Exercise: sieve

Code

#include "sieve.h"

#include <stdlib.h>

unsigned int sieve(const unsigned int limit, primesArray_t primes) {
  char *composite = calloc(limit + 1, sizeof(char));
  if (!composite) {
    return -1;
  }

  for (unsigned int i = 2; i * i <= limit; ++i) {
    if (composite[i]) {
      continue;
    }

    for (unsigned int mult = i * i; mult <= limit; mult += i) {
      composite[mult] = 1;
    }
  }

  unsigned int n_primes = 0;
  for (unsigned int i = 2; i <= limit; ++i) {
    if (!composite[i]) {
      primes[n_primes++] = i;
    }
  }

  free(composite);

  return n_primes;
}

Tags:

construct:add
construct:assignment
construct:char
construct:continue
construct:for-loop
construct:if
construct:indexing
construct:int
construct:integral-number
construct:invocation
construct:loop
construct:multiply
construct:number
construct:parameter
construct:return
construct:size_t
construct:subtract
construct:typedef
construct:unsigned-int
construct:variable
construct:visibility
paradigm:imperative
paradigm:procedural
technique:looping

from c.

ErikSchierboom avatar ErikSchierboom commented on July 18, 2024

Exercise: pascals-triangle

Code

#include "pascals_triangle.h"

size_t **create_triangle(int n) {
    size_t **result = NULL;
    int count = 0, row = 1;

    if (n < 0) return NULL;

    if ((n == 0) || (n == 1)) {
        result = (size_t **)malloc(1 * sizeof(size_t *));
        result[0] = calloc(1, sizeof(size_t));
        if (n == 1) result[0][0] = 1;
        return result;
    }
    else {
        result = (size_t **)malloc(n * sizeof(size_t *));
        for (; count < n; count++)
            result[count] = (size_t *)calloc(n, sizeof(size_t));
    }

    result[0][0] = 1;

    for (; row < n; row++)
        for (count = 0; count < n; count++)
            result[row][count] = (count - 1) >= 0? result[row - 1][count - 1] + result[row - 1][count] : result[row - 1][count];

    return result;
}

void free_triangle(size_t **in, int size) {
    for (; size > 0; size--)
        free(in[size - 1]);

    free(in);
}

Tags:

construct:add
construct:assignment
construct:bitwise-or
construct:calloc
construct:conditional
construct:for-loop
construct:if
construct:implicit-conversion
construct:indexing
construct:int
construct:integral-number
construct:invocation
construct:logical-or
construct:malloc
construct:number
construct:null
construct:nullability
construct:parameter
construct:return
construct:size_t
construct:subtract
construct:ternary
construct:variable
construct:visibility-modifiers
paradigm:imperative
paradigm:bitwise
paradigm:declarative
paradigm:functional
paradigm:object-oriented
technique:bit-manipulation
technique:bit-shifting
technique:looping
technique:type-conversion
uses:bitwise-operators
uses:dynamic-memory-allocation

from c.

ErikSchierboom avatar ErikSchierboom commented on July 18, 2024

Exercise: all-your-base

Code

#include "all_your_base.h"
#include <math.h>
#include <string.h>

size_t rebase(int8_t digits[DIGITS_ARRAY_SIZE], int16_t from_base,
              int16_t to_base, size_t num_digits)
{
   uint16_t denary = 0;
   size_t new_num_digits = 0;

   if ((from_base <= 1) || (to_base <= 1) || (num_digits <= 0))
      return 0;                 /* invalid bases or length */
   if (digits[0] == 0)
      return 0;                 /* leading zeros */

   /* convert to denary */
   for (size_t i = 0; i < num_digits; ++i) {
      if (digits[i] < 0)
         return 0;              /* negative digits */
      if (digits[i] >= from_base)
         return 0;              /* invaid positive digit */
      denary += digits[i] * pow(from_base, (num_digits - i - 1));
   }

   /* calculate number of new digits */
   for (uint16_t j = denary; j > 0;) {
      j /= to_base;
      ++new_num_digits;
   }

   /* calculate and store new digits */
   for (size_t i = new_num_digits - 1; denary > 0; --i) {
      digits[i] = denary % to_base;
      denary /= to_base;
   }

   /* ensure rest of array is zero */
   memset(&digits[new_num_digits], 0, DIGITS_ARRAY_SIZE - new_num_digits);

   return new_num_digits;
}

Tags:

construct:assignment
construct:auto
construct:boolean
construct:comment
construct:divide
construct:double
construct:for-loop
construct:floating-point-number
construct:function
construct:if
construct:implicit-conversion
construct:include
construct:int
construct:integral-number
construct:logical-or
construct:method
construct:multiply
construct:number
construct:parameter
construct:return
construct:size_t
construct:subtract
construct:uint16_t
construct:uint8_t
construct:variable
construct:visibility-modifiers
paradigm:imperative
paradigm:logical
paradigm:object-oriented
technique:boolean-logic
technique:looping

from c.

ErikSchierboom avatar ErikSchierboom commented on July 18, 2024

Exercise: all-your-base

Code

#include<stdint.h>
#include<stddef.h>
#include<math.h>
#include<stdlib.h>
size_t rebase(int8_t digits[], int16_t input_base, int16_t output_base, size_t input_length){
       
       if(input_base<1 || output_base <1 || digits[0] == 0)
        return 0;
       
       int num=0,r;
       size_t output_length = 0;
       //int digit_inverse[10];
       int *digit_inverse = malloc (sizeof (int8_t) * 10);
       unsigned int i=0;
       
       for(i=0;i<input_length;i++){
        if(digits[i]<0 || digits[i] >= input_base)
            return 0;
        num += digits[i]*pow(input_base,input_length-i-1);
       }
       i=0;
       while(num > 0){
        r = (num%output_base);
        digit_inverse[i++] = r;
        output_length ++;
        num = num/output_base;
       }
       
       for(i=0; i<output_length; i++){
        digits[i] = digit_inverse[output_length-i-1];
       }
       
       return output_length;
       
}

Tags:

construct:assignment
construct:boolean
construct:comment
construct:divide
construct:double
construct:for-loop
construct:floating-point-number
construct:function
construct:if
construct:implicit-conversion
construct:index
construct:int
construct:integral-number
construct:logical-or
construct:malloc
construct:parameter
construct:return
construct:size_t
construct:subtract
construct:variable
construct:visibility-modifier
construct:while-loop
paradigm:imperative
paradigm:procedural
technique:boolean-logic
technique:looping
technique:math
uses:malloc

from c.

ErikSchierboom avatar ErikSchierboom commented on July 18, 2024

Exercise: queen-attack

Code

#include "queen_attack.h"

#define MAX_SIZE 8

attack_status_t can_attack(position_t queen_1, position_t queen_2) {
    if((queen_1.row == queen_2.row && queen_1.column == queen_2.column) ||
        queen_1.row >= MAX_SIZE || queen_1.column >= MAX_SIZE ||
        queen_2.row >= MAX_SIZE || queen_2.column >= MAX_SIZE) {
        // Shares same position or out of bounds
        return INVALID_POSITION;
    }

    if(queen_1.row == queen_2.row || queen_1.column == queen_2.column) {
        // Shares same row or column
        return CAN_ATTACK;
    }

    double result = (double)(queen_2.row - queen_1.row) / 
                            (queen_2.column - queen_1.column);

    if(result == 1 || result == -1) {
        // Shares same diagonal
        return CAN_ATTACK;
    }

    return CAN_NOT_ATTACK;
}

Tags:

construct:boolean
construct:comment
construct:define
construct:double
construct:explicit-conversion
construct:floating-point-number
construct:if
construct:implicit-conversion
construct:include
construct:int
construct:integral-number
construct:logical-and
construct:logical-or
construct:number
construct:parameter
construct:return
construct:subtract
construct:variable
construct:visibility-modifiers
paradigm:imperative
paradigm:object-oriented
technique:boolean-logic
technique:type-conversion

from c.

ErikSchierboom avatar ErikSchierboom commented on July 18, 2024

Exercise: etl

Code

#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "etl.h"

enum {
   lettersInAlphabet = 26,
};

int convert(const legacy_map * input, const size_t input_len, new_map ** output)
{
   int assignedKeys[lettersInAlphabet] = {0};
   int keyCount = 0;
   int outputIndex = 0;

   for(size_t index = 0; index < input_len; index++)
   {
      int value = input[index].value;
      unsigned long length = strlen(input[index].keys);

      for(unsigned long charIndex = 0; charIndex < length; charIndex++)
      {
         char testChar = input[index].keys[charIndex];

         if(isalpha(testChar))
         {
            int assignedKeyIndex = tolower(testChar) - 'a';

            assignedKeys[assignedKeyIndex] = value;
            keyCount++;
         }
      }
   }

   *output = calloc(keyCount, sizeof(new_map));
   for(int index = 0; index < lettersInAlphabet; index++)
   {
      if(assignedKeys[index] > 0)
      {
         (*output)[outputIndex].key = 'a' + index;
         (*output)[outputIndex].value = assignedKeys[index];
         outputIndex++;
      }
   }
   return keyCount;
}

Tags:

construct:add
construct:assignment
construct:char
construct:const
construct:enum
construct:for-loop
construct:if
construct:implicit-conversion
construct:indexing
construct:int
construct:integral-number
construct:invocation
construct:long
construct:number
construct:parameter
construct:return
construct:size_t
construct:subtract
construct:typedef
construct:variable
construct:visibility-modifier
paradigm:imperative
paradigm:structured
technique:looping

from c.

ErikSchierboom avatar ErikSchierboom commented on July 18, 2024

Exercise: etl

Code

#include "etl.h"
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

int mapcmp(const void* a, const void* b);
int mapcmp(const void* a, const void* b) {
    char ca = ((new_map*)a)->key;
    char cb = ((new_map*)b)->key;
    return ca - cb;
}

void insert(new_map* input, int* len, new_map value);
void insert(new_map* input, int* len, new_map value) {
    for (int i = 0 ; i < *len ; ++i) {
        if (input[i].key == value.key)
            return;
    }

    input[*len].key = value.key;
    input[(*len)++].value = value.value;
}

int convert(const legacy_map * input, const size_t input_len, new_map ** output) {
    new_map* result = malloc(sizeof(new_map) * 26);
    int result_len = 0;

    for (size_t i = 0 ; i < input_len ; ++i) {
        for (size_t j = 0 ; j < strlen(input[i].keys) ; ++j) {
            insert(result, &result_len,
                   (new_map){ tolower(input[i].keys[j]), input[i].value} );
        }
    }

    qsort(result, result_len, sizeof(new_map), mapcmp);
    *output = result;
    return result_len;
}

Tags:

construct:assignment
construct:auto
construct:bitwise-or
construct:char
construct:constructor
construct:explicit-conversion
construct:for-loop
construct:function
construct:if
construct:initializer
construct:int
construct:integral-number
construct:invocation
construct:lambda
construct:logical-or
construct:malloc
construct:named-argument
construct:number
construct:parameter
construct:return
construct:size_t
construct:struct
construct:subtract
construct:typedef
construct:variable
construct:visibility-modifiers
paradigm:functional
paradigm:imperative
paradigm:object-oriented
technique:bit-manipulation
technique:bitwise-operators
technique:higher-order-functions
technique:looping
technique:type-conversion
uses:malloc

from c.

ErikSchierboom avatar ErikSchierboom commented on July 18, 2024

Exercise: say

Code

#include <stdlib.h>
#include <strings.h>
#include <stdio.h>

#define MAX_LEN 512

char *teens[] = { "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen",
    "sixteen", "seventeen", "eighteen", "nineteen" };
char *tens[] = { "", "ten", "twenty", "thirty", "forty", "fifty", "sixty",
    "seventy", "eighty", "ninty" };
char *ones[] = { "", "one", "two", "three", "four", "five", "six", "seven",
    "eight", "nine" };

char *powers[] = { "", " thousand", " million", " billion", " trillion" };

char *thousands(long digits) {
    char *tmp = calloc(sizeof(char), MAX_LEN);

    long one = digits % 10;
    long ten = (digits % 100) / 10;
    long hundered = (digits % 1000) / 100;

    if(hundered != 0 && ten == 0 && one == 0)
        sprintf(tmp, "%s hundred", ones[hundered]);
    else if(hundered != 0 && ten == 1)
        sprintf(tmp, "%s hundred %s", ones[hundered], teens[one]);
    else if(hundered != 0 && ten > 1 && one == 0)
        sprintf(tmp, "%s hundred %s", ones[hundered], tens[one]);
    else if(hundered != 0 && ten > 1 && one != 0)
        sprintf(tmp, "%s hundred %s-%s", ones[hundered], tens[ten], ones[one]);
    else if(hundered == 0 && ten == 1)
        sprintf(tmp, "%s", teens[one]);
    else if(hundered == 0 && ten > 1 && one != 0)
        sprintf(tmp, "%s-%s", tens[ten], ones[one]);
    else if(hundered == 0 && ten > 1 && one == 0)
        sprintf(tmp, "%s", tens[ten]);
    else if(hundered == 0 && ten == 0 && one != 0)
        sprintf(tmp, "%s", ones[one]);
    return tmp;
}

void strpre(char *dst, char *src) {
    char *tmp = calloc(sizeof(char), strlen(dst)+ strlen(src));
    strcpy(tmp, src);
    strcat(tmp, dst);
    strcpy(dst, tmp);
}

int say(long number, char **buffer) {
    *buffer = strdup("zero");
    if(number == 0) return 0;
    else if(number < 0 || 999999999999 < number) return -1;

    *buffer = calloc(sizeof(char), MAX_LEN);
    for(int p = 0; number > 0; number /= 1000, p++) {
        char *res = thousands(number % 1000);
        if(strlen(res) > 0) {
            strcat(res, powers[p]);
            if(strlen(*buffer) > 0)
                strcat(res, " ");
            strpre(*buffer, res);
        }
    }
    return 0;
}

Tags:

construct:add
construct:assignment
construct:bitwise-and
construct:boolean
construct:char
construct:define
construct:divide
construct:for-loop
construct:if
construct:implicit-conversion
construct:index
construct:int
construct:integral-number
construct:invocation
construct:logical-and
construct:logical-or
construct:long
construct:long-long
construct:macro
construct:nested-scope
construct:number
construct:parameter
construct:return
construct:string
construct:typedef
construct:variable
construct:visibility-modifiers
paradigm:imperative
paradigm:metaprogramming
paradigm:procedural
technique:bit-manipulation
technique:boolean-logic
technique:looping

from c.

ErikSchierboom avatar ErikSchierboom commented on July 18, 2024

Exercise: secret-handshake

Code

#include "secret_handshake.h"
#include <stdlib.h>
#include <stdbool.h>

void swap(char**, char**);
void swap(char** a, char** b) {
    char* temp = *b;
    *b = *a;
    *a = temp;
}

const char** commands(size_t number) {
    bool reverse = false;
    if (number >= 16) {
        reverse = true;
        number -= 16;
    }

    char** result = malloc(sizeof(char*) * 4);
    if (number == 0 || number == 16) {
        result[0] = NULL;
        return (const char**)result;
    }

    int idx = 0;
    if (number >= 8) {
        result[idx++] = "jump";
        number -= 8;
    }

    if (number >= 4) {
        result[idx++] = "close your eyes";
        number -= 4;
    }

    if (number >= 2) {
        result[idx++] = "double blink";
        number -= 2;
    }

    if (number >= 1) {
        result[idx++] = "wink";
        number -= 1;
    }

    if (!reverse) {
        for (int i = 0 ; i < idx/2 ; ++i)
            swap(&result[i], &result[idx-i-1]);
    }

    return (const char**)result;
}

Tags:

construct:assignment
construct:boolean
construct:char
construct:divide
construct:for-loop
construct:if
construct:implicit-conversion
construct:indexing
construct:int
construct:integral-number
construct:logical-or
construct:malloc
construct:number
construct:parameter
construct:return
construct:string
construct:subtract
construct:typedef
construct:variable
construct:visibility-modifiers
paradigm:imperative
paradigm:object-oriented
technique:boolean-logic
technique:looping
uses:malloc

from c.

ErikSchierboom avatar ErikSchierboom commented on July 18, 2024

Exercise: wordy

Code

#include "wordy.h"

#include <stdlib.h>
#include <string.h>

enum operator
{
  NONE,
  PLUS,
  MINUS,
  MULTIPLY,
  DIVIDE,
  RAISE
};

bool answer(const char *question, int *result)
{
  if (strncmp(question, "What is ", 8) != 0)
    return false;

  const char *startop1 = question + 8;
  char *endop1;
  long operand1 = strtol(startop1, &endop1, 0);
  if (endop1 == startop1)
    return false; // not a number

  do
  {
    enum operator op = NONE;
    const char *startop2;

#define COMP(str, operation)                         \
    if (strncmp(endop1, str, sizeof (str) - 1) == 0) \
    {                                                \
      op = operation;                                \
      startop2 = endop1 + sizeof (str) - 1;          \
    }
    COMP(" plus ", PLUS)
    COMP(" minus ", MINUS)
    COMP(" multiplied by ", MULTIPLY)
    COMP(" divided by ", DIVIDE)
    COMP(" raised to the ", RAISE);

    if (op == NONE)
      return false;

    char *endop2;
    long operand2 = strtol(startop2, &endop2, 0);
    if (endop2 == startop2)
      return false; // not a number

    if (op == RAISE && strncmp(endop2 + 2, " power", 6))
      endop2 += 6;

    switch (op)
    {
    case NONE:
      abort(); // Unreachable
    case PLUS:
      operand1 += operand2;
      break;
    case MINUS:
      operand1 -= operand2;
      break;
    case MULTIPLY:
      operand1 *= operand2;
      break;
    case DIVIDE:
      operand1 /= operand2;
      break;
    case RAISE:
      {
        long pow = 1;
        for (long i = 1; i < operand2; ++i)
          pow *= operand1;
        operand1 = pow;
      }
      break;
    }

    endop1 = endop2;
  }
  while (*endop1 != '?');

  *result = operand1;
  return true;
}

Tags:

construct:add
construct:assignment
construct:boolean
construct:break
construct:char
construct:comment
construct:const
construct:continue
construct:define
construct:do
construct:enum
construct:for-loop
construct:if
construct:include
construct:int
construct:integral-number
construct:logical-and
construct:long
construct:macro
construct:number
construct:parameter
construct:return
construct:sizeof
construct:string
construct:subtract
construct:switch
construct:variable
construct:visibility-modifiers
paradigm:imperative
paradigm:macro-expansion
paradigm:object-oriented
technique:boolean-logic
technique:looping

from c.

ErikSchierboom avatar ErikSchierboom commented on July 18, 2024

Exercise: diamond

Code

#include "diamond.h"
#include <stdlib.h>
#include <string.h>

char* reverse_string(char* str);
char* reverse_string(char* str) {
    size_t len = strlen(str);
    char* result = malloc(len+1);

    size_t idx = 0;
    for (size_t i = len ; i > 0 ; --i)
        result[idx++] = str[i-1];
    result[idx] = '\0';

    return result;
}

char **make_diamond(const char letter) {
    size_t size = (letter-'A')*2 + 1;
    char** result = malloc(size * sizeof(char*));

    for (size_t i = 0 ; i < size ; ++i)
        result[i] = malloc(size+1);

    char position = 'A';
    size_t diamond_idx = 0;
    size_t max_padding = size/2;

    while (position <= letter) {
        size_t idx = 0;
        size_t padding = letter-position;

        for (size_t i = 0 ; i < padding ; ++i)
            result[diamond_idx][idx++] = ' ';
        result[diamond_idx][idx++] = position;

        result[diamond_idx][idx] = '\0';
        char* reversed = reverse_string(result[diamond_idx]);

        size_t middle_len = (diamond_idx == 0) ? 0 : 2*diamond_idx-1;
        for (size_t i = 0 ; i < middle_len ; ++i)
            result[diamond_idx][idx++] = ' ';

        result[diamond_idx][idx] = '\0';
        strcat(result[diamond_idx], (diamond_idx == 0) ? (reversed+1) : reversed);
        free(reversed);

        diamond_idx++;
        position++;
    }

    position -= 2;

    while (position >= 'A') {
        size_t idx = 0;
        size_t padding = letter-position;

        for (size_t i = 0 ; i < padding ; ++i)
            result[diamond_idx][idx++] = ' ';
        result[diamond_idx][idx++] = position;

        for (size_t i = 0 ; i < (max_padding - padding) ; ++i)
            result[diamond_idx][idx++] = ' ';
        result[diamond_idx][idx] = '\0';

        char* reversed = reverse_string(result[diamond_idx]);
        strcat(result[diamond_idx], reversed+1);
        free(reversed);

        diamond_idx++;
        position--;
    }

    return result;
}

Tags:

construct:add
construct:assignment
construct:char
construct:divide
construct:for-loop
construct:free
construct:function
construct:function-declaration
construct:header
construct:if
construct:implicit-conversion
construct:indexing
construct:int
construct:integral-number
construct:invocation
construct:lambda
construct:malloc
construct:nested-function
construct:number
construct:parameter
construct:return
construct:size_t
construct:subtract
construct:ternary
construct:typedef
construct:variable
construct:visibility
construct:while-loop
paradigm:functional
paradigm:imperative
paradigm:object-oriented
technique:higher-order-functions
technique:looping
technique:memory-management

from c.

ErikSchierboom avatar ErikSchierboom commented on July 18, 2024

Exercise: linked-list

Code

#include "linked_list.h"

#include <stdlib.h>

struct list_item
{
  ll_data_t data;
  struct list_item *next;
};

struct list_item **new_list()
{
  struct list_item **list = malloc(sizeof (struct list_item *));
  *list = NULL;
  return list;
}

bool is_list_empty(struct list_item **list)
{
  return list == NULL || *list == NULL;
}

bool push(struct list_item **list, ll_data_t item_data)
{
  if (list == NULL)
    return false;

  while (*list != NULL)
    list = &((*list)->next);

  *list = malloc(sizeof (struct list_item));
  (*list)->data = item_data;
  (*list)->next = NULL;
  return true;
}

ll_data_t pop(struct list_item **list)
{
  if (list == NULL || *list == NULL)
    return 0;

  while ((*list)->next != NULL)
    list = &((*list)->next);

  ll_data_t ret = (*list)->data;
  free(*list);
  *list = NULL;
  return ret;
}

ll_data_t shift(struct list_item **list)
{
  if (list == NULL || *list == NULL)
    return 0;

  struct list_item *first = *list;
  *list = first->next;
  ll_data_t ret = first->data;
  free(first);
  return ret;
}

bool unshift(struct list_item **list, ll_data_t item_data)
{
  if (list == NULL)
    return false;
  struct list_item *new = malloc(sizeof (struct list_item));
  new->data = item_data;
  new->next = *list;
  *list = new;
  return true;
}

void delete_list(struct list_item **list)
{
  if (list == NULL)
    return;
  struct list_item *tofree = *list;
  while(tofree != NULL)
  {
    struct list_item *tmp = tofree->next;
    free(tofree);
    tofree = tmp;
  }
  free(list);
}

Tags:

construct:assignment
construct:boolean
construct:free
construct:header
construct:if
construct:include
construct:int
construct:integral
construct:logical-or
construct:malloc
construct:null
construct:null-pointer
construct:parameter
construct:return
construct:sizeof
construct:struct
construct:typedef
construct:variable
construct:while-loop
paradigm:imperative
paradigm:procedural
technique:boolean-logic
technique:looping
technique:memory-management

from c.

ErikSchierboom avatar ErikSchierboom commented on July 18, 2024

Exercise: rational-numbers

Code

#include "rational_numbers.h"
#include <math.h>

rational_t add(rational_t r1, rational_t r2) {
    int16_t n = r1.numerator * r2.denominator 
              + r2.numerator * r1.denominator;
    int16_t d = !n ? 1 : r1.denominator * r2.denominator;
    return reduce((rational_t) {n,d});
}

rational_t subtract(rational_t r1, rational_t r2) {
    int16_t n = r1.numerator * r2.denominator 
              - r2.numerator * r1.denominator;
    int16_t d = !n ? 1 : r1.denominator * r2.denominator;
    return reduce((rational_t) {n,d});
}

rational_t multiply(rational_t r1, rational_t r2) {
    int16_t n = r1.numerator   * r2.numerator;
    int16_t d = r1.denominator * r2.denominator;
    return reduce((rational_t) {n,d});
}

rational_t divide(rational_t r1, rational_t r2) {
    int16_t n = r1.numerator * r2.denominator;
    int16_t d = r2.numerator * r1.denominator;
    return reduce((rational_t) {n,d});
}

rational_t absolute(rational_t r) {
    int16_t n_sign = r.numerator   >> 15;
    int16_t d_sign = r.denominator >> 15;
    int16_t n = (r.numerator   + n_sign) ^ n_sign;
    int16_t d = (r.denominator + d_sign) ^ d_sign;
    return reduce((rational_t) {n,d});
}

rational_t exp_rational(rational_t r, uint16_t n) {
    if (!n)           return (rational_t) {1,1};
    if (!r.numerator) return (rational_t) {0,1};

    int16_t n1 = pow(r.numerator,   n);
    int16_t d1 = pow(r.denominator, n);
    return reduce((rational_t) {n1,d1});
}

static float nth_root(float x, float n) {
    return pow(x, 1.0 / n);
}

float exp_real(uint16_t n, rational_t r) {
    if (!r.numerator) return 1.0;
    r = reduce(r);
    float p = pow(n, r.numerator);
    return nth_root(p, r.denominator);
}

static int16_t gcd(int16_t x, int16_t y) {
    int16_t t;
    while (y) {
        t = y;
        y = x % y;
        x = t;
    }
    return x;
}

rational_t reduce(rational_t r) {
    if (!r.numerator) return (rational_t) {0,1};

    int16_t x = gcd(r.numerator, r.denominator);
    int16_t n = r.numerator   / x;
    int16_t d = r.denominator / x;

    return d < 0 ? (rational_t) {-n,-d} 
                 : (rational_t) { n, d};
}

Tags:

construct:assignment
construct:bitwise-xor
construct:divide
construct:explicit-conversion
construct:float
construct:floating-point-number
construct:if
construct:implicit-conversion
construct:include
construct:int
construct:integral-number
construct:initializer-list
construct:invocation
construct:lambda
construct:left-shift
construct:method
construct:multiply
construct:number
construct:parameter
construct:return
construct:right-shift
construct:static
construct:static-variable
construct:ternary
construct:typedef
construct:variable
construct:visibility-modifiers
construct:while-loop
paradigm:functional
paradigm:imperative
paradigm:object-oriented
technique:bit-manipulation
technique:bit-shifting
technique:higher-order-functions
technique:looping
technique:math

from c.

ErikSchierboom avatar ErikSchierboom commented on July 18, 2024

This is an automated comment

Hello ๐Ÿ‘‹ Next week we're going to start using the tagging work people are doing on these. If you've already completed the work, thank you! If you've not, but intend to this week, that's great! If you're not going to get round to doing it, and you've not yet posted a comment letting us know, could you please do so, so that we can find other people to do it. Thanks!

from c.

wolf99 avatar wolf99 commented on July 18, 2024

I had hoped to find time to make a start on this but have failed to do so.
If there are others that can do it, I'm happy for that to happen.
Otherwise it's still on my list to try to get to (new baby in the house so that may be some time!)

from c.

ErikSchierboom avatar ErikSchierboom commented on July 18, 2024

No problem. Congrats on the baby!

from c.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.