How to resolve the algorithm Spelling of ordinal numbers step by step in the C programming language

Published on 7 June 2024 03:52 AM
#C

How to resolve the algorithm Spelling of ordinal numbers step by step in the C programming language

Table of Contents

Problem Statement

Ordinal numbers   (as used in this Rosetta Code task),   are numbers that describe the   position   of something in a list. It is this context that ordinal numbers will be used, using an English-spelled name of an ordinal number.

The ordinal numbers are   (at least, one form of them): sometimes expressed as:

For this task, the following (English-spelled form) will be used:

Furthermore, the short scale numbering system (i.e. 2,000,000,000 is two billion) will be used here. wp:Long and short scales 2,000,000,000   is two billion,   not   two milliard.

Write a driver and a function (subroutine/routine ···) that returns the English-spelled ordinal version of a specified number   (a positive integer). Optionally, try to support as many forms of an integer that can be expressed:   123   00123.0   1.23e2   all are forms of the same integer. Show all output here.

Use (at least) the test cases of:

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Spelling of ordinal numbers step by step in the C programming language

The source code provided in C programming language is a program that calculates the ordinal or cardinal name of a given number. Here's a breakdown of what the code does:

  • Header Includes:

    • The program includes necessary header files like <stdbool.h>, <stdio.h>, <stdint.h>, and <glib.h> for various data types and functions.
  • Data Structures:

    • number_names: This data structure represents the names of numbers, both in cardinal and ordinal form.
    • named_number: This structure stores the names and values of named numbers like "hundred," "thousand," etc.
  • Constants:

    • small: An array of number_names structures representing the names of numbers from 0 to 19.
    • tens: An array of number_names structures representing the names of tens from 20 to 90.
    • named_numbers: An array of named_number structures representing named numbers like "hundred," "thousand," and their corresponding values.
  • Function Declarations:

    • get_small_name: Gets the name of a small number (0-19) in either cardinal or ordinal form.
    • get_big_name: Gets the name of a named number like "hundred" or "thousand" in either cardinal or ordinal form.
    • get_named_number: Finds the named number structure corresponding to a given integer.
    • append_number_name: Recursively appends the name of a number to a GString.
    • number_name: Returns a GString containing the name of the given number in either cardinal or ordinal form.
  • Test Function and Main Function:

    • test_ordinal: Tests the number_name function with various numbers and prints the results.
    • main: Calls the test_ordinal function for several test cases and prints the results, demonstrating the functionality of the program.
  • Functionality:

    • The number_name function constructs the name of a given number (up to quintillions) in either cardinal or ordinal form.
    • It recursively breaks down the number into small numbers (0-19), tens (20-90), and named numbers (hundred, thousand, etc.) and appends their corresponding names.
    • The test_ordinal function showcases the program's ability to handle various numbers and display their names in ordinal form.

In summary, this program demonstrates the conversion of numbers into their names, both in cardinal and ordinal form, using a combination of recursive functions, arrays of names, and named number structures.

Source code in the c programming language

#include <stdbool.h>
#include <stdio.h>
#include <stdint.h>
#include <glib.h>

typedef uint64_t integer;

typedef struct number_names_tag {
    const char* cardinal;
    const char* ordinal;
} number_names;

const number_names small[] = {
    { "zero", "zeroth" }, { "one", "first" }, { "two", "second" },
    { "three", "third" }, { "four", "fourth" }, { "five", "fifth" },
    { "six", "sixth" }, { "seven", "seventh" }, { "eight", "eighth" },
    { "nine", "ninth" }, { "ten", "tenth" }, { "eleven", "eleventh" },
    { "twelve", "twelfth" }, { "thirteen", "thirteenth" },
    { "fourteen", "fourteenth" }, { "fifteen", "fifteenth" },
    { "sixteen", "sixteenth" }, { "seventeen", "seventeenth" },
    { "eighteen", "eighteenth" }, { "nineteen", "nineteenth" }
};

const number_names tens[] = {
    { "twenty", "twentieth" }, { "thirty", "thirtieth" },
    { "forty", "fortieth" }, { "fifty", "fiftieth" },
    { "sixty", "sixtieth" }, { "seventy", "seventieth" },
    { "eighty", "eightieth" }, { "ninety", "ninetieth" }
};

typedef struct named_number_tag {
    const char* cardinal;
    const char* ordinal;
    integer number;
} named_number;

const named_number named_numbers[] = {
    { "hundred", "hundredth", 100 },
    { "thousand", "thousandth", 1000 },
    { "million", "millionth", 1000000 },
    { "billion", "billionth", 1000000000 },
    { "trillion", "trillionth", 1000000000000 },
    { "quadrillion", "quadrillionth", 1000000000000000ULL },
    { "quintillion", "quintillionth", 1000000000000000000ULL }
};

const char* get_small_name(const number_names* n, bool ordinal) {
    return ordinal ? n->ordinal : n->cardinal;
}

const char* get_big_name(const named_number* n, bool ordinal) {
    return ordinal ? n->ordinal : n->cardinal;
}

const named_number* get_named_number(integer n) {
    const size_t names_len = sizeof(named_numbers)/sizeof(named_numbers[0]);
    for (size_t i = 0; i + 1 < names_len; ++i) {
        if (n < named_numbers[i + 1].number)
            return &named_numbers[i];
    }
    return &named_numbers[names_len - 1];
}

void append_number_name(GString* gstr, integer n, bool ordinal) {
    if (n < 20)
        g_string_append(gstr, get_small_name(&small[n], ordinal));
    else if (n < 100) {
        if (n % 10 == 0) {
            g_string_append(gstr, get_small_name(&tens[n/10 - 2], ordinal));
        } else {
            g_string_append(gstr, get_small_name(&tens[n/10 - 2], false));
            g_string_append_c(gstr, '-');
            g_string_append(gstr, get_small_name(&small[n % 10], ordinal));
        }
    } else {
        const named_number* num = get_named_number(n);
        integer p = num->number;
        append_number_name(gstr, n/p, false);
        g_string_append_c(gstr, ' ');
        if (n % p == 0) {
            g_string_append(gstr, get_big_name(num, ordinal));
        } else {
            g_string_append(gstr, get_big_name(num, false));
            g_string_append_c(gstr, ' ');
            append_number_name(gstr, n % p, ordinal);
        }
    }
}

GString* number_name(integer n, bool ordinal) {
    GString* result = g_string_sized_new(8);
    append_number_name(result, n, ordinal);
    return result;
}

void test_ordinal(integer n) {
    GString* name = number_name(n, true);
    printf("%llu: %s\n", n, name->str);
    g_string_free(name, TRUE);
}

int main() {
    test_ordinal(1);
    test_ordinal(2);
    test_ordinal(3);
    test_ordinal(4);
    test_ordinal(5);
    test_ordinal(11);
    test_ordinal(15);
    test_ordinal(21);
    test_ordinal(42);
    test_ordinal(65);
    test_ordinal(98);
    test_ordinal(100);
    test_ordinal(101);
    test_ordinal(272);
    test_ordinal(300);
    test_ordinal(750);
    test_ordinal(23456);
    test_ordinal(7891233);
    test_ordinal(8007006005004003LL);
    return 0;
}


  

You may also check:How to resolve the algorithm Polyspiral step by step in the zkl programming language
You may also check:How to resolve the algorithm Remove duplicate elements step by step in the ECL programming language
You may also check:How to resolve the algorithm Primorial numbers step by step in the Julia programming language
You may also check:How to resolve the algorithm Constrained genericity step by step in the Icon and Unicon programming language
You may also check:How to resolve the algorithm Forward difference step by step in the Perl programming language