Skip to main content
added 47 characters in body
Source Link
Dwayne Robinson
  • 2.6k
  • 1
  • 31
  • 44
  • Non-pangram count: 429819
  • Imperfect pangram count: 488132
  • Perfect pangram count: 8349
  • Total pangram count: 571181 (perfect + imperfect)
#include <iostream>
#include <fstream>
#include <print>
#include <chrono>
#include <algorithm>
#include <string>
#include <cassert>

const char* defaultFileName = "List of 1000 strings.json";

enum class PangramType
{
    NotAPangram,
    ImperfectPangram,
    PerfectPangram,
};

char const* PangramTypeNames[3] = {"Not a pangram", "Pangram", "Perfect pangram"};

std::string ReadTextFile(const char* fileName);
std::string ReadTextFile(std::basic_istream<char, std::char_traits<char>>& inputStream);
std::string_view GetNextString(std::string_view text);
PangramType DeterminePangramType(std::string_view text);


int main()
{
    int pangramCounts[3 /*PangramType total*/] = {};

    std::string fileText = ReadTextFile(defaultFileName);
    std::string_view fileTextRange = fileText;
    auto fileTextRangeEnd = fileTextRange.data() + fileTextRange.size(); // Can't use end() because of debug iterator bogus warning.

    while (true)
    {
        std::string_view stringRange = GetNextString(fileTextRange);
        if (stringRange.empty())
            break;

        PangramType pangramType = DeterminePangramType(stringRange);
        ++pangramCounts[size_t(pangramType)];

        std::println("{} - {}", stringRange, PangramTypeNames[size_t(pangramType)]);

        auto stringRangeEnd = stringRange.data() + stringRange.size() + 1;
        fileTextRange = std::string_view{stringRangeEnd, fileTextRangeEnd};
    }

    std::println();
    std::println("Non-pangram count: {}", pangramCounts[size_t(PangramType::NotAPangram)]);
    std::println("Imperfect pangram count: {}", pangramCounts[size_t(PangramType::ImperfectPangram)]);
    std::println("Perfect pangram count: {}", pangramCounts[size_t(PangramType::PerfectPangram)]);
    std::println("Total pangram count: {} (perfect + imperfect)", pangramCounts[size_t(PangramType::ImperfectPangram)] + pangramCounts[size_t(PangramType::PerfectPangram)]);

    return EXIT_SUCCESS;
}

std::string_view GetNextString(std::string_view text)
{
    auto startPosition = text.find('"');
    if (startPosition == std::string::npos)
        return {};

    auto endPosition = text.find('"', startPosition + 1);
    if (endPosition == std::string::npos)
        return {};

    auto range = std::string_view(text).substr(startPosition + 1, endPosition - startPosition - 1);
    return range;
}

std::string ReadTextFile(std::basic_istream<char, std::char_traits<char>>& inputStream)
{
    std::string dataBuffer;

    // Avoid unnecessary zeroing of the buffer which will just be overwritten anyway.
    // The transient indeterminate values between resize_and_overwrite and read are irrelevant.
    inputStream.seekg(0, std::ios_base::end);
    std::size_t fileSize = inputStream.tellg();
    inputStream.seekg(0, std::ios_base::beg);
    auto dummyResize = [](char* buffer, std::size_t fileSize) noexcept -> size_t { return fileSize;};
    dataBuffer.resize_and_overwrite(fileSize, dummyResize);
    inputStream.read(dataBuffer.data(), fileSize);

    return dataBuffer;
}

std::string ReadTextFile(const char* fileName)
{
    std::ifstream inputStream(fileName, std::ios::binary);
    if (!inputStream.is_open())
    {
        std::cerr << "Could not open the file - '" << fileName << "'" << std::endl;
        return {};
    }

    std::string dataBuffer = ReadTextFile(inputStream);
    inputStream.close();
    return dataBuffer;
}

PangramType DeterminePangramType(std::string_view text)
{
    bool lettersSeen[26] = {};
    int letterCount = 0;
    int uniqueLetterCount = 0;

    for (char c : text)
    {
        c &= ~0x20; // Convert to uppercase.
        if (c >= 'A' && c <= 'Z')
        {
            if (!lettersSeen[c - 'A'])++letterCount;
            {
 int letterIndex = c - 'A';
          ++uniqueLetterCount;
  uniqueLetterCount += !lettersSeen[letterIndex];
            lettersSeen[c]lettersSeen[letterIndex] = true;
            }
        }
    }

    if (uniqueLetterCount ==< sizeof(lettersSeen))
    {
        return PangramType::PerfectPangram;NotAPangram;
    }
    else if (uniqueLetterCountletterCount <== sizeof(lettersSeen))
    {
        return PangramType::NotAPangram;PerfectPangram;
    }
    else
    {
        return PangramType::ImperfectPangram;
    }
}
  • Non-pangram count: 429
  • Imperfect pangram count: 488
  • Perfect pangram count: 83
  • Total pangram count: 571 (perfect + imperfect)
#include <iostream>
#include <fstream>
#include <print>
#include <chrono>
#include <algorithm>
#include <string>
#include <cassert>

const char* defaultFileName = "List of 1000 strings.json";

enum class PangramType
{
    NotAPangram,
    ImperfectPangram,
    PerfectPangram,
};

char const* PangramTypeNames[3] = {"Not a pangram", "Pangram", "Perfect pangram"};

std::string ReadTextFile(const char* fileName);
std::string ReadTextFile(std::basic_istream<char, std::char_traits<char>>& inputStream);
std::string_view GetNextString(std::string_view text);
PangramType DeterminePangramType(std::string_view text);


int main()
{
    int pangramCounts[3 /*PangramType total*/] = {};

    std::string fileText = ReadTextFile(defaultFileName);
    std::string_view fileTextRange = fileText;
    auto fileTextRangeEnd = fileTextRange.data() + fileTextRange.size(); // Can't use end() because of debug iterator bogus warning.

    while (true)
    {
        std::string_view stringRange = GetNextString(fileTextRange);
        if (stringRange.empty())
            break;

        PangramType pangramType = DeterminePangramType(stringRange);
        ++pangramCounts[size_t(pangramType)];

        std::println("{} - {}", stringRange, PangramTypeNames[size_t(pangramType)]);

        auto stringRangeEnd = stringRange.data() + stringRange.size() + 1;
        fileTextRange = std::string_view{stringRangeEnd, fileTextRangeEnd};
    }

    std::println();
    std::println("Non-pangram count: {}", pangramCounts[size_t(PangramType::NotAPangram)]);
    std::println("Imperfect pangram count: {}", pangramCounts[size_t(PangramType::ImperfectPangram)]);
    std::println("Perfect pangram count: {}", pangramCounts[size_t(PangramType::PerfectPangram)]);
    std::println("Total pangram count: {} (perfect + imperfect)", pangramCounts[size_t(PangramType::ImperfectPangram)] + pangramCounts[size_t(PangramType::PerfectPangram)]);

    return EXIT_SUCCESS;
}

std::string_view GetNextString(std::string_view text)
{
    auto startPosition = text.find('"');
    if (startPosition == std::string::npos)
        return {};

    auto endPosition = text.find('"', startPosition + 1);
    if (endPosition == std::string::npos)
        return {};

    auto range = std::string_view(text).substr(startPosition + 1, endPosition - startPosition - 1);
    return range;
}

std::string ReadTextFile(std::basic_istream<char, std::char_traits<char>>& inputStream)
{
    std::string dataBuffer;

    // Avoid unnecessary zeroing of the buffer which will just be overwritten anyway.
    // The transient indeterminate values between resize_and_overwrite and read are irrelevant.
    inputStream.seekg(0, std::ios_base::end);
    std::size_t fileSize = inputStream.tellg();
    inputStream.seekg(0, std::ios_base::beg);
    auto dummyResize = [](char* buffer, std::size_t fileSize) noexcept -> size_t { return fileSize;};
    dataBuffer.resize_and_overwrite(fileSize, dummyResize);
    inputStream.read(dataBuffer.data(), fileSize);

    return dataBuffer;
}

std::string ReadTextFile(const char* fileName)
{
    std::ifstream inputStream(fileName, std::ios::binary);
    if (!inputStream.is_open())
    {
        std::cerr << "Could not open the file - '" << fileName << "'" << std::endl;
        return {};
    }

    std::string dataBuffer = ReadTextFile(inputStream);
    inputStream.close();
    return dataBuffer;
}

PangramType DeterminePangramType(std::string_view text)
{
    bool lettersSeen[26] = {};
    int uniqueLetterCount = 0;

    for (char c : text)
    {
        c &= ~0x20; // Convert to uppercase.
        if (c >= 'A' && c <= 'Z')
        {
            if (!lettersSeen[c - 'A'])
            {
                ++uniqueLetterCount;
                lettersSeen[c] = true;
            }
        }
    }

    if (uniqueLetterCount == sizeof(lettersSeen))
    {
        return PangramType::PerfectPangram;
    }
    else if (uniqueLetterCount < sizeof(lettersSeen))
    {
        return PangramType::NotAPangram;
    }
    else
    {
        return PangramType::ImperfectPangram;
    }
}
  • Non-pangram count: 819
  • Imperfect pangram count: 132
  • Perfect pangram count: 49
  • Total pangram count: 181 (perfect + imperfect)
#include <iostream>
#include <fstream>
#include <print>
#include <chrono>
#include <algorithm>
#include <string>
#include <cassert>

const char* defaultFileName = "List of 1000 strings.json";

enum class PangramType
{
    NotAPangram,
    ImperfectPangram,
    PerfectPangram,
};

char const* PangramTypeNames[3] = {"Not a pangram", "Pangram", "Perfect pangram"};

std::string ReadTextFile(const char* fileName);
std::string ReadTextFile(std::basic_istream<char, std::char_traits<char>>& inputStream);
std::string_view GetNextString(std::string_view text);
PangramType DeterminePangramType(std::string_view text);


int main()
{
    int pangramCounts[3 /*PangramType total*/] = {};

    std::string fileText = ReadTextFile(defaultFileName);
    std::string_view fileTextRange = fileText;
    auto fileTextRangeEnd = fileTextRange.data() + fileTextRange.size(); // Can't use end() because of debug iterator bogus warning.

    while (true)
    {
        std::string_view stringRange = GetNextString(fileTextRange);
        if (stringRange.empty())
            break;

        PangramType pangramType = DeterminePangramType(stringRange);
        ++pangramCounts[size_t(pangramType)];

        std::println("{} - {}", stringRange, PangramTypeNames[size_t(pangramType)]);

        auto stringRangeEnd = stringRange.data() + stringRange.size() + 1;
        fileTextRange = std::string_view{stringRangeEnd, fileTextRangeEnd};
    }

    std::println();
    std::println("Non-pangram count: {}", pangramCounts[size_t(PangramType::NotAPangram)]);
    std::println("Imperfect pangram count: {}", pangramCounts[size_t(PangramType::ImperfectPangram)]);
    std::println("Perfect pangram count: {}", pangramCounts[size_t(PangramType::PerfectPangram)]);
    std::println("Total pangram count: {} (perfect + imperfect)", pangramCounts[size_t(PangramType::ImperfectPangram)] + pangramCounts[size_t(PangramType::PerfectPangram)]);

    return EXIT_SUCCESS;
}

std::string_view GetNextString(std::string_view text)
{
    auto startPosition = text.find('"');
    if (startPosition == std::string::npos)
        return {};

    auto endPosition = text.find('"', startPosition + 1);
    if (endPosition == std::string::npos)
        return {};

    auto range = std::string_view(text).substr(startPosition + 1, endPosition - startPosition - 1);
    return range;
}

std::string ReadTextFile(std::basic_istream<char, std::char_traits<char>>& inputStream)
{
    std::string dataBuffer;

    // Avoid unnecessary zeroing of the buffer which will just be overwritten anyway.
    // The transient indeterminate values between resize_and_overwrite and read are irrelevant.
    inputStream.seekg(0, std::ios_base::end);
    std::size_t fileSize = inputStream.tellg();
    inputStream.seekg(0, std::ios_base::beg);
    auto dummyResize = [](char* buffer, std::size_t fileSize) noexcept -> size_t { return fileSize;};
    dataBuffer.resize_and_overwrite(fileSize, dummyResize);
    inputStream.read(dataBuffer.data(), fileSize);

    return dataBuffer;
}

std::string ReadTextFile(const char* fileName)
{
    std::ifstream inputStream(fileName, std::ios::binary);
    if (!inputStream.is_open())
    {
        std::cerr << "Could not open the file - '" << fileName << "'" << std::endl;
        return {};
    }

    std::string dataBuffer = ReadTextFile(inputStream);
    inputStream.close();
    return dataBuffer;
}

PangramType DeterminePangramType(std::string_view text)
{
    bool lettersSeen[26] = {};
    int letterCount = 0;
    int uniqueLetterCount = 0;

    for (char c : text)
    {
        c &= ~0x20; // Convert to uppercase.
        if (c >= 'A' && c <= 'Z')
        {
            ++letterCount;
            int letterIndex = c - 'A';
            uniqueLetterCount += !lettersSeen[letterIndex];
            lettersSeen[letterIndex] = true;
        }
    }

    if (uniqueLetterCount < sizeof(lettersSeen))
    {
        return PangramType::NotAPangram;
    }
    else if (letterCount == sizeof(lettersSeen))
    {
        return PangramType::PerfectPangram;
    }
    else
    {
        return PangramType::ImperfectPangram;
    }
}
added 290 characters in body
Source Link
Dwayne Robinson
  • 2.6k
  • 1
  • 31
  • 44
  • PangramNon-pangram count: 488429
  • Non-pangramImperfect pangram count: 429488
  • Perfect pangram count: 83
  • Total pangram count: 571 (perfect + imperfect)
#include <iostream>
#include <fstream>
#include <print>
#include <chrono>
#include <algorithm>
#include <string>
#include <cassert>

const char* defaultFileName = "List of 1000 strings.json";

enum class PangramType
{
    NotAPangram,
    PangramImperfectPangram,
    PerfectPangram,
};

char const* PangramTypeNames[3] = {"Not a pangram", "Pangram", "Perfect pangram"};

std::string ReadTextFile(const char* fileName);
std::string ReadTextFile(std::basic_istream<char, std::char_traits<char>>& inputStream);
std::string_view GetNextString(std::string_view text);
PangramType DeterminePangramType(std::string_view text);


int main()
{
    int pangramCounts[3 /*PangramType total*/] = {};

    std::string fileText = ReadTextFile(defaultFileName);
    std::string_view fileTextRange = fileText;
    auto fileTextRangeEnd = fileTextRange.data() + fileTextRange.size(); // Can't use end() because of debug iterator bogus warning.

    while (true)
    {
        std::string_view stringRange = GetNextString(fileTextRange);
        if (stringRange.empty())
            break;

        PangramType pangramType = DeterminePangramType(stringRange);
        ++pangramCounts[size_t(pangramType)];

        std::println("{} - {}", stringRange, PangramTypeNames[size_t(pangramType)]);

        auto stringRangeEnd = stringRange.data() + stringRange.size() + 1;
        fileTextRange = std::string_view{stringRangeEnd, fileTextRangeEnd};
    }

    std::println("Pangram);
    std::println("Non-pangram count: {}", pangramCounts[size_t(PangramType::PangramNotAPangram)]);
    std::println("Non-"Imperfect pangram count: {}", pangramCounts[size_t(PangramType::NotAPangramImperfectPangram)]);
    std::println("Perfect pangram count: {}", pangramCounts[size_t(PangramType::PerfectPangram)]);
    std::println("Total pangram count: {} (perfect + imperfect)", pangramCounts[size_t(PangramType::ImperfectPangram)] + pangramCounts[size_t(PangramType::PerfectPangram)]);

    return EXIT_SUCCESS;
}

std::string_view GetNextString(std::string_view text)
{
    auto startPosition = text.find('"');
    if (startPosition == std::string::npos)
        return {};

    auto endPosition = text.find('"', startPosition + 1);
    if (endPosition == std::string::npos)
        return {};

    auto range = std::string_view(text).substr(startPosition + 1, endPosition - startPosition - 1);
    return range;
}

std::string ReadTextFile(std::basic_istream<char, std::char_traits<char>>& inputStream)
{
    std::string dataBuffer;

    // Avoid unnecessary zeroing of the buffer which will just be overwritten anyway.
    // The transient indeterminate values between resize_and_overwrite and read are irrelevant.
    inputStream.seekg(0, std::ios_base::end);
    std::size_t fileSize = inputStream.tellg();
    inputStream.seekg(0, std::ios_base::beg);
    auto dummyResize = [](char* buffer, std::size_t fileSize) noexcept -> size_t { return fileSize;};
    dataBuffer.resize_and_overwrite(fileSize, dummyResize);
    inputStream.read(dataBuffer.data(), fileSize);

    return dataBuffer;
}

std::string ReadTextFile(const char* fileName)
{
    std::ifstream inputStream(fileName, std::ios::binary);
    if (!inputStream.is_open())
    {
        std::cerr << "Could not open the file - '" << fileName << "'" << std::endl;
        return {};
    }

    std::string dataBuffer = ReadTextFile(inputStream);
    inputStream.close();
    return dataBuffer;
}

PangramType DeterminePangramType(std::string_view text)
{
    bool lettersSeen[26] = {};
    int uniqueLetterCount = 0;

    for (char c : text)
    {
        c &= ~0x20; // Convert to uppercase.
        if (c >= 'A' && c <= 'Z')
        {
            if (!lettersSeen[c - 'A'])
            {
                ++uniqueLetterCount;
                lettersSeen[c] = true;
            }
        }
    }

    if (uniqueLetterCount == sizeof(lettersSeen))
    {
        return PangramType::PerfectPangram;
    }
    else if (uniqueLetterCount < sizeof(lettersSeen))
    {
        return PangramType::NotAPangram;
    }
    else
    {
        return PangramType::Pangram;ImperfectPangram;
    }
}
  • Pangram count: 488
  • Non-pangram count: 429
  • Perfect pangram count: 83
#include <iostream>
#include <fstream>
#include <print>
#include <chrono>
#include <algorithm>
#include <string>
#include <cassert>

const char* defaultFileName = "List of 1000 strings.json";

enum class PangramType
{
    NotAPangram,
    Pangram,
    PerfectPangram,
};

char const* PangramTypeNames[3] = {"Not a pangram", "Pangram", "Perfect pangram"};

std::string ReadTextFile(const char* fileName);
std::string ReadTextFile(std::basic_istream<char, std::char_traits<char>>& inputStream);
std::string_view GetNextString(std::string_view text);
PangramType DeterminePangramType(std::string_view text);


int main()
{
    int pangramCounts[3 /*PangramType total*/] = {};

    std::string fileText = ReadTextFile(defaultFileName);
    std::string_view fileTextRange = fileText;
    auto fileTextRangeEnd = fileTextRange.data() + fileTextRange.size(); // Can't use end() because of debug iterator bogus warning.

    while (true)
    {
        std::string_view stringRange = GetNextString(fileTextRange);
        if (stringRange.empty())
            break;

        PangramType pangramType = DeterminePangramType(stringRange);
        ++pangramCounts[size_t(pangramType)];

        std::println("{} - {}", stringRange, PangramTypeNames[size_t(pangramType)]);

        auto stringRangeEnd = stringRange.data() + stringRange.size() + 1;
        fileTextRange = std::string_view{stringRangeEnd, fileTextRangeEnd};
    }

    std::println("Pangram count: {}", pangramCounts[size_t(PangramType::Pangram)]);
    std::println("Non-pangram count: {}", pangramCounts[size_t(PangramType::NotAPangram)]);
    std::println("Perfect pangram count: {}", pangramCounts[size_t(PangramType::PerfectPangram)]);

    return EXIT_SUCCESS;
}

std::string_view GetNextString(std::string_view text)
{
    auto startPosition = text.find('"');
    if (startPosition == std::string::npos)
        return {};

    auto endPosition = text.find('"', startPosition + 1);
    if (endPosition == std::string::npos)
        return {};

    auto range = std::string_view(text).substr(startPosition + 1, endPosition - startPosition - 1);
    return range;
}

std::string ReadTextFile(std::basic_istream<char, std::char_traits<char>>& inputStream)
{
    std::string dataBuffer;

    // Avoid unnecessary zeroing of the buffer which will just be overwritten anyway.
    // The transient indeterminate values between resize_and_overwrite and read are irrelevant.
    inputStream.seekg(0, std::ios_base::end);
    std::size_t fileSize = inputStream.tellg();
    inputStream.seekg(0, std::ios_base::beg);
    auto dummyResize = [](char* buffer, std::size_t fileSize) noexcept -> size_t { return fileSize;};
    dataBuffer.resize_and_overwrite(fileSize, dummyResize);
    inputStream.read(dataBuffer.data(), fileSize);

    return dataBuffer;
}

std::string ReadTextFile(const char* fileName)
{
    std::ifstream inputStream(fileName, std::ios::binary);
    if (!inputStream.is_open())
    {
        std::cerr << "Could not open the file - '" << fileName << "'" << std::endl;
        return {};
    }

    std::string dataBuffer = ReadTextFile(inputStream);
    inputStream.close();
    return dataBuffer;
}

PangramType DeterminePangramType(std::string_view text)
{
    bool lettersSeen[26] = {};
    int uniqueLetterCount = 0;

    for (char c : text)
    {
        c &= ~0x20; // Convert to uppercase.
        if (c >= 'A' && c <= 'Z')
        {
            if (!lettersSeen[c - 'A'])
            {
                ++uniqueLetterCount;
                lettersSeen[c] = true;
            }
        }
    }

    if (uniqueLetterCount == sizeof(lettersSeen))
    {
        return PangramType::PerfectPangram;
    }
    else if (uniqueLetterCount < sizeof(lettersSeen))
    {
        return PangramType::NotAPangram;
    }
    else
    {
        return PangramType::Pangram;
    }
}
  • Non-pangram count: 429
  • Imperfect pangram count: 488
  • Perfect pangram count: 83
  • Total pangram count: 571 (perfect + imperfect)
#include <iostream>
#include <fstream>
#include <print>
#include <chrono>
#include <algorithm>
#include <string>
#include <cassert>

const char* defaultFileName = "List of 1000 strings.json";

enum class PangramType
{
    NotAPangram,
    ImperfectPangram,
    PerfectPangram,
};

char const* PangramTypeNames[3] = {"Not a pangram", "Pangram", "Perfect pangram"};

std::string ReadTextFile(const char* fileName);
std::string ReadTextFile(std::basic_istream<char, std::char_traits<char>>& inputStream);
std::string_view GetNextString(std::string_view text);
PangramType DeterminePangramType(std::string_view text);


int main()
{
    int pangramCounts[3 /*PangramType total*/] = {};

    std::string fileText = ReadTextFile(defaultFileName);
    std::string_view fileTextRange = fileText;
    auto fileTextRangeEnd = fileTextRange.data() + fileTextRange.size(); // Can't use end() because of debug iterator bogus warning.

    while (true)
    {
        std::string_view stringRange = GetNextString(fileTextRange);
        if (stringRange.empty())
            break;

        PangramType pangramType = DeterminePangramType(stringRange);
        ++pangramCounts[size_t(pangramType)];

        std::println("{} - {}", stringRange, PangramTypeNames[size_t(pangramType)]);

        auto stringRangeEnd = stringRange.data() + stringRange.size() + 1;
        fileTextRange = std::string_view{stringRangeEnd, fileTextRangeEnd};
    }

    std::println();
    std::println("Non-pangram count: {}", pangramCounts[size_t(PangramType::NotAPangram)]);
    std::println("Imperfect pangram count: {}", pangramCounts[size_t(PangramType::ImperfectPangram)]);
    std::println("Perfect pangram count: {}", pangramCounts[size_t(PangramType::PerfectPangram)]);
    std::println("Total pangram count: {} (perfect + imperfect)", pangramCounts[size_t(PangramType::ImperfectPangram)] + pangramCounts[size_t(PangramType::PerfectPangram)]);

    return EXIT_SUCCESS;
}

std::string_view GetNextString(std::string_view text)
{
    auto startPosition = text.find('"');
    if (startPosition == std::string::npos)
        return {};

    auto endPosition = text.find('"', startPosition + 1);
    if (endPosition == std::string::npos)
        return {};

    auto range = std::string_view(text).substr(startPosition + 1, endPosition - startPosition - 1);
    return range;
}

std::string ReadTextFile(std::basic_istream<char, std::char_traits<char>>& inputStream)
{
    std::string dataBuffer;

    // Avoid unnecessary zeroing of the buffer which will just be overwritten anyway.
    // The transient indeterminate values between resize_and_overwrite and read are irrelevant.
    inputStream.seekg(0, std::ios_base::end);
    std::size_t fileSize = inputStream.tellg();
    inputStream.seekg(0, std::ios_base::beg);
    auto dummyResize = [](char* buffer, std::size_t fileSize) noexcept -> size_t { return fileSize;};
    dataBuffer.resize_and_overwrite(fileSize, dummyResize);
    inputStream.read(dataBuffer.data(), fileSize);

    return dataBuffer;
}

std::string ReadTextFile(const char* fileName)
{
    std::ifstream inputStream(fileName, std::ios::binary);
    if (!inputStream.is_open())
    {
        std::cerr << "Could not open the file - '" << fileName << "'" << std::endl;
        return {};
    }

    std::string dataBuffer = ReadTextFile(inputStream);
    inputStream.close();
    return dataBuffer;
}

PangramType DeterminePangramType(std::string_view text)
{
    bool lettersSeen[26] = {};
    int uniqueLetterCount = 0;

    for (char c : text)
    {
        c &= ~0x20; // Convert to uppercase.
        if (c >= 'A' && c <= 'Z')
        {
            if (!lettersSeen[c - 'A'])
            {
                ++uniqueLetterCount;
                lettersSeen[c] = true;
            }
        }
    }

    if (uniqueLetterCount == sizeof(lettersSeen))
    {
        return PangramType::PerfectPangram;
    }
    else if (uniqueLetterCount < sizeof(lettersSeen))
    {
        return PangramType::NotAPangram;
    }
    else
    {
        return PangramType::ImperfectPangram;
    }
}
Source Link
Dwayne Robinson
  • 2.6k
  • 1
  • 31
  • 44

Results

  • Pangram count: 488
  • Non-pangram count: 429
  • Perfect pangram count: 83

Code

#include <iostream>
#include <fstream>
#include <print>
#include <chrono>
#include <algorithm>
#include <string>
#include <cassert>

const char* defaultFileName = "List of 1000 strings.json";

enum class PangramType
{
    NotAPangram,
    Pangram,
    PerfectPangram,
};

char const* PangramTypeNames[3] = {"Not a pangram", "Pangram", "Perfect pangram"};

std::string ReadTextFile(const char* fileName);
std::string ReadTextFile(std::basic_istream<char, std::char_traits<char>>& inputStream);
std::string_view GetNextString(std::string_view text);
PangramType DeterminePangramType(std::string_view text);


int main()
{
    int pangramCounts[3 /*PangramType total*/] = {};

    std::string fileText = ReadTextFile(defaultFileName);
    std::string_view fileTextRange = fileText;
    auto fileTextRangeEnd = fileTextRange.data() + fileTextRange.size(); // Can't use end() because of debug iterator bogus warning.

    while (true)
    {
        std::string_view stringRange = GetNextString(fileTextRange);
        if (stringRange.empty())
            break;

        PangramType pangramType = DeterminePangramType(stringRange);
        ++pangramCounts[size_t(pangramType)];

        std::println("{} - {}", stringRange, PangramTypeNames[size_t(pangramType)]);

        auto stringRangeEnd = stringRange.data() + stringRange.size() + 1;
        fileTextRange = std::string_view{stringRangeEnd, fileTextRangeEnd};
    }

    std::println("Pangram count: {}", pangramCounts[size_t(PangramType::Pangram)]);
    std::println("Non-pangram count: {}", pangramCounts[size_t(PangramType::NotAPangram)]);
    std::println("Perfect pangram count: {}", pangramCounts[size_t(PangramType::PerfectPangram)]);

    return EXIT_SUCCESS;
}

std::string_view GetNextString(std::string_view text)
{
    auto startPosition = text.find('"');
    if (startPosition == std::string::npos)
        return {};

    auto endPosition = text.find('"', startPosition + 1);
    if (endPosition == std::string::npos)
        return {};

    auto range = std::string_view(text).substr(startPosition + 1, endPosition - startPosition - 1);
    return range;
}

std::string ReadTextFile(std::basic_istream<char, std::char_traits<char>>& inputStream)
{
    std::string dataBuffer;

    // Avoid unnecessary zeroing of the buffer which will just be overwritten anyway.
    // The transient indeterminate values between resize_and_overwrite and read are irrelevant.
    inputStream.seekg(0, std::ios_base::end);
    std::size_t fileSize = inputStream.tellg();
    inputStream.seekg(0, std::ios_base::beg);
    auto dummyResize = [](char* buffer, std::size_t fileSize) noexcept -> size_t { return fileSize;};
    dataBuffer.resize_and_overwrite(fileSize, dummyResize);
    inputStream.read(dataBuffer.data(), fileSize);

    return dataBuffer;
}

std::string ReadTextFile(const char* fileName)
{
    std::ifstream inputStream(fileName, std::ios::binary);
    if (!inputStream.is_open())
    {
        std::cerr << "Could not open the file - '" << fileName << "'" << std::endl;
        return {};
    }

    std::string dataBuffer = ReadTextFile(inputStream);
    inputStream.close();
    return dataBuffer;
}

PangramType DeterminePangramType(std::string_view text)
{
    bool lettersSeen[26] = {};
    int uniqueLetterCount = 0;

    for (char c : text)
    {
        c &= ~0x20; // Convert to uppercase.
        if (c >= 'A' && c <= 'Z')
        {
            if (!lettersSeen[c - 'A'])
            {
                ++uniqueLetterCount;
                lettersSeen[c] = true;
            }
        }
    }

    if (uniqueLetterCount == sizeof(lettersSeen))
    {
        return PangramType::PerfectPangram;
    }
    else if (uniqueLetterCount < sizeof(lettersSeen))
    {
        return PangramType::NotAPangram;
    }
    else
    {
        return PangramType::Pangram;
    }
}