diff --git a/alib2data/src/std/hexavigesimal.cpp b/alib2data/src/std/hexavigesimal.cpp index 3a750e2621283c324d5a0d96c58a249ba667c3f4..cc544a4400cda79b83c39bc174f97d6d4b0238e9 100644 --- a/alib2data/src/std/hexavigesimal.cpp +++ b/alib2data/src/std/hexavigesimal.cpp @@ -2,38 +2,55 @@ * Hexavigesimal.cpp * * Created on: 19. 4. 2014 - * Author: Tomas Pecka + * Author: Tomas Pecka */ #include "hexavigesimal.h" +#include <stdexcept> namespace std { unsigned fromBase26( string rep ) { - // http://en.wikipedia.org/wiki/Hexavigesimal - unsigned n = 0; for(char repSymbol : rep ) { unsigned remainder = repSymbol - 'A'; if(remainder > 26) - throw 1; //("Invalid argument"); //TODO fix + throw std::invalid_argument(rep); n = n * 26 + remainder; } return n; } -string toBase26( unsigned id ) { - // http://en.wikipedia.org/wiki/Hexavigesimal - +string toBase26( unsigned n ) { string name; do { - unsigned remainder = id % 26; - name += ( char )( remainder + 'A' ); - id = (id - remainder) / 26; - } while (id > 0); + name += ( char )( n % 26 + 'A' ); + n = n / 26; + } while (n > 0); return string( name.rbegin( ), name.rend( ) ); } +unsigned bijectiveFromBase26(string rep) { + unsigned n = 0; + for (char repSymbol : rep ) { + unsigned remainder = repSymbol - 'A'; + if(remainder > 26) + throw std::invalid_argument(rep); + n = n * 26 + remainder + 1; + } + return n; +} + +string bijectiveToBase26(unsigned n) { + string name; + while(n > 0) { + --n; + name += (char) (n % 26 + 'A'); + n /= 26; + } + return string(name.rbegin(), name.rend()); +} + } /* namespace conversions */ diff --git a/alib2data/src/std/hexavigesimal.h b/alib2data/src/std/hexavigesimal.h index 36147c76c0c8aeb4b8f84a79aa681882d661dac4..1d3be3bcfe27a1d16424baaaa472aed5db80246d 100644 --- a/alib2data/src/std/hexavigesimal.h +++ b/alib2data/src/std/hexavigesimal.h @@ -13,10 +13,28 @@ namespace std { /** - * Maps 1 -> A, 2 -> B, ..., AA, AB, AC, ... , AAA, AAB, ... + * Maps 0 -> A, 1 -> B, ..., 25 -> Z, 26 -> AB, 27 -> AC, ..., 675 -> ZZ, 676 -> BAA, ... * http://en.wikipedia.org/wiki/Hexavigesimal - *///FIXME opravdu to mapuje takhle? -std::string toBase26( unsigned n ); + */ +string toBase26( unsigned n ); + +/** + * Maps A -> 0, B -> 0, ..., Z -> 25, AB -> 26, AC -> 27, ..., ZZ -> 675, BAA -> 676, ... + * http://en.wikipedia.org/wiki/Hexavigesimal + */ +unsigned fromBase26( string rep ); + +/** + * Maps 1 -> A, 2 -> B, ..., 26 -> Z, 27 -> AA, 28 -> AB, ..., 675 -> ZZ, 676 -> BAA, ... + * http://en.wikipedia.org/wiki/Hexavigesimal + */ +string bijectiveToBase26( unsigned n ); + +/** + * Maps 1 -> A, 2 -> B, ..., 26 -> Z, 27 -> AA, AB -> 28, ..., ZZ -> 675, BAA -> 676, ... + * http://en.wikipedia.org/wiki/Hexavigesimal + */ +unsigned bijectiveFromBase26( string rep ); } /* namespace std */ diff --git a/alib2data/test-src/std/StdTestHexavigesimal.cpp b/alib2data/test-src/std/StdTestHexavigesimal.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e2898dc08596a52f5e838ec39a57a19850f0f013 --- /dev/null +++ b/alib2data/test-src/std/StdTestHexavigesimal.cpp @@ -0,0 +1,44 @@ +#include "StdTestHexavigesimal.h" +#include "std/hexavigesimal.h" + +CPPUNIT_TEST_SUITE_REGISTRATION( StdTestHexavigesimal ); + +void StdTestHexavigesimal::setUp() { +} + +void StdTestHexavigesimal::tearDown() { +} + +void StdTestHexavigesimal::test1() { + CPPUNIT_ASSERT_EQUAL(std::string("A") , std::toBase26(0)); + CPPUNIT_ASSERT_EQUAL(std::string("B") , std::toBase26(1)); + CPPUNIT_ASSERT_EQUAL(std::string("Z") , std::toBase26(25)); + CPPUNIT_ASSERT_EQUAL(std::string("BA") , std::toBase26(26)); + CPPUNIT_ASSERT_EQUAL(std::string("BB") , std::toBase26(27)); + CPPUNIT_ASSERT_EQUAL(std::string("ZZ") , std::toBase26(675)); + CPPUNIT_ASSERT_EQUAL(std::string("BAA"), std::toBase26(676)); + + CPPUNIT_ASSERT_EQUAL(0u , std::fromBase26("A")); + CPPUNIT_ASSERT_EQUAL(1u , std::fromBase26("B")); + CPPUNIT_ASSERT_EQUAL(25u , std::fromBase26("Z")); + CPPUNIT_ASSERT_EQUAL(26u , std::fromBase26("BA")); + CPPUNIT_ASSERT_EQUAL(27u , std::fromBase26("BB")); + CPPUNIT_ASSERT_EQUAL(675u, std::fromBase26("ZZ")); + CPPUNIT_ASSERT_EQUAL(676u, std::fromBase26("BAA")); + + CPPUNIT_ASSERT_EQUAL(std::string("") , std::bijectiveToBase26(0)); + CPPUNIT_ASSERT_EQUAL(std::string("A") , std::bijectiveToBase26(1)); + CPPUNIT_ASSERT_EQUAL(std::string("Z") , std::bijectiveToBase26(26)); + CPPUNIT_ASSERT_EQUAL(std::string("AA") , std::bijectiveToBase26(27)); + CPPUNIT_ASSERT_EQUAL(std::string("AB") , std::bijectiveToBase26(28)); + CPPUNIT_ASSERT_EQUAL(std::string("ZZ") , std::bijectiveToBase26(702)); + CPPUNIT_ASSERT_EQUAL(std::string("AAA"), std::bijectiveToBase26(703)); + + CPPUNIT_ASSERT_EQUAL(0u , std::bijectiveFromBase26("")); + CPPUNIT_ASSERT_EQUAL(1u , std::bijectiveFromBase26("A")); + CPPUNIT_ASSERT_EQUAL(26u , std::bijectiveFromBase26("Z")); + CPPUNIT_ASSERT_EQUAL(27u , std::bijectiveFromBase26("AA")); + CPPUNIT_ASSERT_EQUAL(28u , std::bijectiveFromBase26("AB")); + CPPUNIT_ASSERT_EQUAL(702u, std::bijectiveFromBase26("ZZ")); + CPPUNIT_ASSERT_EQUAL(703u, std::bijectiveFromBase26("AAA")); +} diff --git a/alib2data/test-src/std/StdTestHexavigesimal.h b/alib2data/test-src/std/StdTestHexavigesimal.h new file mode 100644 index 0000000000000000000000000000000000000000..8e313dbdd999b961b53ef99e4458a7fe9e7acb8d --- /dev/null +++ b/alib2data/test-src/std/StdTestHexavigesimal.h @@ -0,0 +1,19 @@ +#ifndef HEXAVIGESIMAL_TEST_H_ +#define HEXAVIGESIMAL_TEST_H_ + +#include <cppunit/extensions/HelperMacros.h> + +class StdTestHexavigesimal : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE( StdTestHexavigesimal ); + CPPUNIT_TEST( test1 ); + CPPUNIT_TEST_SUITE_END(); + +public: + void setUp(); + void tearDown(); + + void test1(); +}; + +#endif // HEXAVIGESIMAL_TEST_H_