954,504 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

Practice Problem: Mapping

Just for exercise, if people want to give it a go; see how creative one can be.

Problem Statement: Given a list of data from a file( or user input which ever) as such:

char 1
char 2
char 26 
char 27
char 52
char 53


output the mapping of the number like so:

char 1 => 'a'
char 2 => 'b'
char 26 = 'z'
char 27 => 'A'
char 52 => 'Z'
char 53 => 'aa'


If you don't see the pattern then here it is:

[1...26] gets mapped to ['a'...'z']
[27...52] gets mapped to ['A'...'Z']


any thing after 52, ex 53 getswrapped back. For example 53 gets wrapped to 'aa' or 54 gets wrapped to 'bb' or 79 gets wrapped to 'AA'
Free to use any language paradigm....blah...blah...blah, just make sure its understandable.

Difficulty: 2.0f/5.0f

firstPerson
Senior Poster
3,923 posts since Dec 2008
Reputation Points: 841
Solved Threads: 608
 

make a simple array container add 2 functios such as add() and operator[]
witch knows the number ranges :)

cppgangster
Junior Poster in Training
86 posts since Oct 2010
Reputation Points: 9
Solved Threads: 5
 

Something along the lines of:

string alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
	string input;
	getline(cin,input);
	stringstream ss(input);
	unsigned int value = 0;
	ss >> value;
	if(value <= 0)
	{
		cerr << "Program encountered an unexpected error and will now exit. (Mwuahahaha!)" << endl; 
		return 1;
	}
	cout << "value = " << value << endl;

	//j is the current index into "alphabet"
	//r is the number of times it has wrapped around.
	//i is simply used by the loop as the "loop-control" variable.
	string::size_type i = 0, j = 0, r = 0;
	for( ; i < value; i++, j++)
	{
		 if(j == alphabet.size()) { j = 0; r++; }
	}

	string output;
	for( string::size_type k = 0; k < (r+1); k++ )
	{
		output += alphabet[j-1];
	}
	cout << "Output = " << output << endl;
pseudorandom21
Practically a Posting Shark
890 posts since Jan 2011
Reputation Points: 216
Solved Threads: 111
 

Or maybe something along the lines of:

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main() {
  ifstream infile("input.txt");
  ofstream outfile("output.txt");
  int value;
  while(infile >> value) {
    char mod_val = (--value) % 52;
    outfile << string(value / 52 + 1, 
                      (mod_val < 26 ? mod_val + 'a' : (mod_val - 26) + 'A')) 
            << endl;
  };
  return 0;
};
mike_2000_17
Posting Virtuoso
Moderator
2,139 posts since Jul 2010
Reputation Points: 1,634
Solved Threads: 457
 

Or maybe something along the lines of:

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main() {
  ifstream infile("input.txt");
  ofstream outfile("output.txt");
  int value;
  while(infile >> value) {
    char mod_val = (--value) % 52;
    outfile << string(value / 52 + 1, 
                      (mod_val < 26 ? mod_val + 'a' : (mod_val - 26) + 'A')) 
            << endl;
  };
  return 0;
};


The only problem being the assumption of adjacent letters in the character set. Only digits are guaranteed to be contiguous. But great minds think alike, because my solution is different from yours only in that I used a custom alphabet:

#include <type_traits>

namespace jsw {
    /**
     * @brief Subtract y from x
     * @remarks Moves in an absolute negative direction while preserving sign
     */
    template <typename T>
    T subtract(T x, T y, typename std::enable_if<std::is_integral<T>::value>::type* = 0)
    {
        return (x >= 0) ? x - y : x + y;
    }
    
    /**
     * @brief Calculates the remainder of x / y
     * @remarks Behavior is sign agnostic (equivalent regardless of sign)
     */
    template <typename T>
    T mod(T x, T y, typename std::enable_if<std::is_integral<T>::value>::type* = 0)
    {
        return (x % y + y) % y;
    }
}

#include <cstdlib>
#include <iostream>
#include <string>

int main()
{
    std::string const buf = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    int value;

    while (std::cin >> value) {
        value = jsw::subtract(value, 1);
        
        int const n_wrap = std::abs(value) / buf.size() + 1;
        int const index = jsw::mod(value, (int)buf.size());
        
        std::cout << std::string(n_wrap, buf[index]) << '\n';
    }
}
Narue
Bad Cop
Administrator
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
 

Yeah now I'm depressed I didn't do the modulus thing. I was thinking about it I swear!

pseudorandom21
Practically a Posting Shark
890 posts since Jan 2011
Reputation Points: 216
Solved Threads: 111
 

This isn't much of a challenge as it is now, so I decided to do the interesting stuff during compilation.

EDIT: A boost preprocessor array can't have more than 25 elements. That's why I had to split the letters like that.

#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/comparison/less.hpp>
#include <boost/preprocessor/arithmetic/add.hpp>
#include <boost/preprocessor/arithmetic/sub.hpp>
#include <boost/preprocessor/arithmetic/div.hpp>
#include <boost/preprocessor/arithmetic/mod.hpp>
#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/array/elem.hpp>
#include <boost/preprocessor/control/if.hpp>

#define LETTERS_a_m (13, ("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m"))
#define LETTERS_n_z (13, ("n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"))
#define LETTERS_A_M (13, ("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M"))
#define LETTERS_N_Z (13, ("N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"))

#define LETTER_LOWER(n) \
BOOST_PP_IF(BOOST_PP_LESS(n, 13), \
    BOOST_PP_ARRAY_ELEM(n, LETTERS_a_m), \
    BOOST_PP_ARRAY_ELEM(BOOST_PP_SUB(n, 13), LETTERS_n_z))

#define LETTER_UPPER(n) \
BOOST_PP_IF(BOOST_PP_LESS(n, 13), \
    BOOST_PP_ARRAY_ELEM(n, LETTERS_A_M), \
    BOOST_PP_ARRAY_ELEM(BOOST_PP_SUB(n, 13), LETTERS_N_Z))

#define LETTER(z, n, letter_id) \
BOOST_PP_IF(BOOST_PP_LESS(letter_id, 27), \
    LETTER_LOWER(BOOST_PP_SUB(letter_id, 1)), \
    LETTER_UPPER(BOOST_PP_SUB(letter_id, 27)))

#define PRINT_LETTER(r, unused, n) \
BOOST_PP_REPEAT(BOOST_PP_ADD(BOOST_PP_DIV(n, 52), 1), LETTER, BOOST_PP_MOD(n, 52)) "\n"

#include <cstdio>

#define INPUT (1)(2)(4)(8)(16)(32)(50)(64)(100)(128)(150)

int main()
{
    const char * output = BOOST_PP_SEQ_FOR_EACH(PRINT_LETTER, ~, INPUT);

    printf(output);
    fflush(stdout);

    return 0;
}

Compiler output: .file "main.cpp"
.def ___main; .scl 2; .type 32; .endef
.section .rdata,"dr"
LC0:
.ascii <strong>"a\12b\12d\12h\12p\12F\12X\12ll\12VV\12xxx\12TTT\0"</strong>
.text
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $16, %esp
call ___main
movl $LC0, (%esp)
call _puts
movl __imp___iob, %eax
addl $32, %eax
movl %eax, (%esp)
call _fflush
xorl %eax, %eax
leave
ret
.def _puts; .scl 2; .type 32; .endef
.def _fflush; .scl 2; .type 32; .endef

m4ster_r0shi
Posting Whiz in Training
230 posts since Mar 2010
Reputation Points: 154
Solved Threads: 31
 

This isn't much of a challenge as it is now, so I decided to do the interesting stuff during compilation.

EDIT: A boost preprocessor array can't have more than 25 elements. That's why I had to split the letters like that.

#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/comparison/less.hpp>
#include <boost/preprocessor/arithmetic/add.hpp>
#include <boost/preprocessor/arithmetic/sub.hpp>
#include <boost/preprocessor/arithmetic/div.hpp>
#include <boost/preprocessor/arithmetic/mod.hpp>
#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/array/elem.hpp>
#include <boost/preprocessor/control/if.hpp>

#define LETTERS_a_m (13, ("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m"))
#define LETTERS_n_z (13, ("n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"))
#define LETTERS_A_M (13, ("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M"))
#define LETTERS_N_Z (13, ("N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"))

#define LETTER_LOWER(n) \
BOOST_PP_IF(BOOST_PP_LESS(n, 13), \
    BOOST_PP_ARRAY_ELEM(n, LETTERS_a_m), \
    BOOST_PP_ARRAY_ELEM(BOOST_PP_SUB(n, 13), LETTERS_n_z))

#define LETTER_UPPER(n) \
BOOST_PP_IF(BOOST_PP_LESS(n, 13), \
    BOOST_PP_ARRAY_ELEM(n, LETTERS_A_M), \
    BOOST_PP_ARRAY_ELEM(BOOST_PP_SUB(n, 13), LETTERS_N_Z))

#define LETTER(z, n, letter_id) \
BOOST_PP_IF(BOOST_PP_LESS(letter_id, 27), \
    LETTER_LOWER(BOOST_PP_SUB(letter_id, 1)), \
    LETTER_UPPER(BOOST_PP_SUB(letter_id, 27)))

#define PRINT_LETTER(r, unused, n) \
BOOST_PP_REPEAT(BOOST_PP_ADD(BOOST_PP_DIV(n, 52), 1), LETTER, BOOST_PP_MOD(n, 52)) "\n"

#include <cstdio>

#define INPUT (1)(2)(4)(8)(16)(32)(50)(64)(100)(128)(150)

int main()
{
    const char * output = BOOST_PP_SEQ_FOR_EACH(PRINT_LETTER, ~, INPUT);

    printf(output);
    fflush(stdout);

    return 0;
}

Compiler output: .file "main.cpp" .def ___main; .scl 2; .type 32; .endef .section .rdata,"dr" LC0: .ascii <strong>"a\12b\12d\12h\12p\12F\12X\12ll\12VV\12xxx\12TTT\0"</strong> .text .globl _main .def _main; .scl 2; .type 32; .endef _main: pushl %ebp movl %esp, %ebp andl $-16, %esp subl $16, %esp call ___main movl $LC0, (%esp) call _puts movl __imp___iob, %eax addl $32, %eax movl %eax, (%esp) call _fflush xorl %eax, %eax leave ret .def _puts; .scl 2; .type 32; .endef .def _fflush; .scl 2; .type 32; .endef

Thats so not fair, I still have no complete idea what the hell is going on. Mainly because I never gave enough time to learn metaprogramming and boost metaprogramming. Anyways I'll take your word for it to work. Thats pretty cool.

firstPerson
Senior Poster
3,923 posts since Dec 2008
Reputation Points: 841
Solved Threads: 608
 
Thats pretty cool.


Haha, thanks! :D

There is a bug in the code above though...  It won't work for some edge cases
(e.g. 52 is mapped to "aa" (as is 53) instead of "Z"). I realised it too late to edit
it and correct it (BTW, what's this thing with the 30 minute limit to editing? Why
can't I edit my posts whenever I want?).   PRINT_LETTER should look like this: #define PRINT_LETTER(r, unused, n) \
BOOST_PP_REPEAT(BOOST_PP_ADD(BOOST_PP_DIV(BOOST_PP_SUB(n, 1), 52), 1), \
LETTER, BOOST_PP_ADD(BOOST_PP_MOD(BOOST_PP_SUB(n, 1), 52), 1)) "\n"
I never gave enough time to learn metaprogramming
In this case, I think I'll seize the opportunity to show off a little bit more :P

I'll do the same thing using just  template  metaprogramming  (no boost  preprocessor  tricks). Note that the end
result won't be the same.  What I got using  preprocessor  metaprogramming  was a literal constant just the way
I wanted it. I can't do that using just template  metaprogramming  (AFAIK). The best I can do in this case is fill an
existing array with values generated during compilation. The filling itself will still be made while the program runs.

Let's begin with something simple. A template that generates code that prints the numbers 0 ... 9.

#include <cstdio>

template <int MAX_I, int CUR_I = 0>
struct PrintLoop
{
    static void RUN()
    {
        printf("%c\n", CUR_I + '0');

        PrintLoop<MAX_I, CUR_I + 1>::RUN();
    }
};

template <int MAX_I>
struct PrintLoop<MAX_I, MAX_I>
{
    static void RUN() {}
};

int main()
{
    PrintLoop<10>::RUN();

    fflush(stdout);
}

Compiler output (note that I compile everything using -Os (code size optimization)): .file "main.cpp"
.def ___main; .scl 2; .type 32; .endef
.section .rdata,"dr"
LC0:
.ascii "%c\12\0"
.text
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $16, %esp
call ___main
movl $48, 4(%esp)
movl $LC0, (%esp)
call _printf
movl $49, 4(%esp)
movl $LC0, (%esp)
call _printf
movl $50, 4(%esp)
movl $LC0, (%esp)
call _printf
movl $51, 4(%esp)
movl $LC0, (%esp)
call _printf
movl $52, 4(%esp)
movl $LC0, (%esp)
call _printf
movl $53, 4(%esp)
movl $LC0, (%esp)
call _printf
movl $54, 4(%esp)
movl $LC0, (%esp)
call _printf
movl $55, 4(%esp)
movl $LC0, (%esp)
call _printf
movl $56, 4(%esp)
movl $LC0, (%esp)
call _printf
movl $57, 4(%esp)
movl $LC0, (%esp)
call _printf
movl __imp___iob, %eax
addl $32, %eax
movl %eax, (%esp)
call _fflush
xorl %eax, %eax
leave
ret
.def _printf; .scl 2; .type 32; .endef
.def _fflush; .scl 2; .type 32; .endef

It's good, but not good enough. There's something I don't like. There are too many printf calls. Let's see if I can do better...

#include <cstdio>

char output[100] = { 0 };
int output_index = 0;

template <int MAX_I, int CUR_I = 0>
struct FillBufferLoop
{
    static void RUN()
    {
        output[output_index++] = CUR_I + '0';
        output[output_index++] = '\n';

        FillBufferLoop<MAX_I, CUR_I + 1>::RUN();
    }
};

template <int MAX_I>
struct FillBufferLoop<MAX_I, MAX_I>
{
    static void RUN() {}
};

int main()
{
    FillBufferLoop<10>::RUN();

    printf("%s", output);
    fflush(stdout);
}

Compiler output: .file "main.cpp"
.def ___main; .scl 2; .type 32; .endef
.section .rdata,"dr"
LC0:
.ascii "%s\0"
.text
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $16, %esp
call ___main
movl _output_index, %eax
movb $48, _output(%eax)
movb $10, _output+1(%eax)
movb $49, _output+2(%eax)
movb $10, _output+3(%eax)
movb $50, _output+4(%eax)
movb $10, _output+5(%eax)
movb $51, _output+6(%eax)
movb $10, _output+7(%eax)
movb $52, _output+8(%eax)
movb $10, _output+9(%eax)
movb $53, _output+10(%eax)
movb $10, _output+11(%eax)
movb $54, _output+12(%eax)
movb $10, _output+13(%eax)
movb $55, _output+14(%eax)
movb $10, _output+15(%eax)
movb $56, _output+16(%eax)
movb $10, _output+17(%eax)
movb $57, _output+18(%eax)
movb $10, _output+19(%eax)
addl $20, %eax
movl %eax, _output_index
movl $_output, 4(%esp)
movl $LC0, (%esp)
call _printf
movl __imp___iob, %eax
addl $32, %eax
movl %eax, (%esp)
call _fflush
xorl %eax, %eax
leave
ret
.globl _output
.bss
.align 4
_output:
.space 100
.globl _output_index
.align 4
_output_index:
.space 4
.def _printf; .scl 2; .type 32; .endef
.def _fflush; .scl 2; .type 32; .endef

Yeap, that's more like it. Now, let's see how this can be applied to the problem at hand.

I'll  need  two  loops  for  this.  An  outer  one, that  will  iterate  over the input
data, and an inner one, that will  generate  the string  mapped  to the current
integer.  Also, note that neither  the  int -> letter  mapping  nor the input data
can be arrays if I want to be able to use them as template arguments (AFAIK).

#include <cstdio>

template <int N>
struct Letters;

#define DEF_LETTER(index, value) \
template <> struct Letters<index> \
{ static const char VAL = value; };

DEF_LETTER( 0, 'a') DEF_LETTER( 1, 'b') DEF_LETTER( 2, 'c') DEF_LETTER( 3, 'd')
DEF_LETTER( 4, 'e') DEF_LETTER( 5, 'f') DEF_LETTER( 6, 'g') DEF_LETTER( 7, 'h')
DEF_LETTER( 8, 'i') DEF_LETTER( 9, 'j') DEF_LETTER(10, 'k') DEF_LETTER(11, 'l')
DEF_LETTER(12, 'm') DEF_LETTER(13, 'n') DEF_LETTER(14, 'o') DEF_LETTER(15, 'p')
DEF_LETTER(16, 'q') DEF_LETTER(17, 'r') DEF_LETTER(18, 's') DEF_LETTER(19, 't')
DEF_LETTER(20, 'u') DEF_LETTER(21, 'v') DEF_LETTER(22, 'w') DEF_LETTER(23, 'x')
DEF_LETTER(24, 'y') DEF_LETTER(25, 'z') DEF_LETTER(26, 'A') DEF_LETTER(27, 'B')
DEF_LETTER(28, 'C') DEF_LETTER(29, 'D') DEF_LETTER(30, 'E') DEF_LETTER(31, 'F')
DEF_LETTER(32, 'G') DEF_LETTER(33, 'H') DEF_LETTER(34, 'I') DEF_LETTER(35, 'J')
DEF_LETTER(36, 'K') DEF_LETTER(37, 'L') DEF_LETTER(38, 'M') DEF_LETTER(39, 'N')
DEF_LETTER(40, 'O') DEF_LETTER(41, 'P') DEF_LETTER(42, 'Q') DEF_LETTER(43, 'R')
DEF_LETTER(44, 'S') DEF_LETTER(45, 'T') DEF_LETTER(46, 'U') DEF_LETTER(47, 'V')
DEF_LETTER(48, 'W') DEF_LETTER(49, 'X') DEF_LETTER(50, 'Y') DEF_LETTER(51, 'Z')

template <int N>
struct Input;

#define DEF_INPUT(index, value) \
template <> struct Input<index> \
{ static const int VAL = value; };

const int input_size = 15;

DEF_INPUT( 0,  1) DEF_INPUT( 1,   3) DEF_INPUT( 2,  25) DEF_INPUT( 3,  26) DEF_INPUT( 4,  27)
DEF_INPUT( 5, 30) DEF_INPUT( 6,  51) DEF_INPUT( 7,  52) DEF_INPUT( 8,  53) DEF_INPUT( 9,  59)
DEF_INPUT(10, 80) DEF_INPUT(11, 103) DEF_INPUT(12, 104) DEF_INPUT(13, 105) DEF_INPUT(14, 110)

const int output_size = 100;

char output[output_size] = { 0 };

int output_index = 0;

template <char CUR_C, int MAX_I, int CUR_I = 0>
struct InnerLoop
{
    static void RUN()
    {
        output[output_index++] = CUR_C;

        InnerLoop<CUR_C, MAX_I, CUR_I + 1>::RUN();
    }
};

template <char CUR_C, int MAX_I>
struct InnerLoop<CUR_C, MAX_I, MAX_I>
{
    static void RUN() {}
};

template <int MAX_I, int CUR_I = 0>
struct OuterLoop
{
    static void RUN()
    {
        InnerLoop<Letters<(Input<CUR_I>::VAL - 1) % 52 >::VAL, (Input<CUR_I>::VAL - 1) / 52 + 1>::RUN();

        output[output_index++] = '\n';

        OuterLoop<MAX_I, CUR_I + 1>::RUN();
    }
};

template <int MAX_I>
struct OuterLoop<MAX_I, MAX_I>
{
    static void RUN() {}
};

int main()
{
    OuterLoop<input_size>::RUN();

    printf("%s", output);
    fflush(stdout);
}

Compiler output: .file "main.cpp"
.def ___main; .scl 2; .type 32; .endef
.section .rdata,"dr"
LC0:
.ascii "%s\0"
.text
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $16, %esp
call ___main
movl _output_index, %eax
movb $97, _output(%eax)
movb $10, _output+1(%eax)
movb $99, _output+2(%eax)
movb $10, _output+3(%eax)
movb $121, _output+4(%eax)
movb $10, _output+5(%eax)
movb $122, _output+6(%eax)
movb $10, _output+7(%eax)
movb $65, _output+8(%eax)
movb $10, _output+9(%eax)
movb $68, _output+10(%eax)
movb $10, _output+11(%eax)
movb $89, _output+12(%eax)
movb $10, _output+13(%eax)
movb $90, _output+14(%eax)
movb $10, _output+15(%eax)
movb $97, _output+16(%eax)
movb $97, _output+17(%eax)
movb $10, _output+18(%eax)
movb $103, _output+19(%eax)
movb $103, _output+20(%eax)
movb $10, _output+21(%eax)
movb $66, _output+22(%eax)
movb $66, _output+23(%eax)
movb $10, _output+24(%eax)
movb $89, _output+25(%eax)
movb $89, _output+26(%eax)
movb $10, _output+27(%eax)
movb $90, _output+28(%eax)
movb $90, _output+29(%eax)
movb $10, _output+30(%eax)
movb $97, _output+31(%eax)
movb $97, _output+32(%eax)
movb $97, _output+33(%eax)
movb $10, _output+34(%eax)
movb $102, _output+35(%eax)
movb $102, _output+36(%eax)
movb $102, _output+37(%eax)
movb $10, _output+38(%eax)
addl $39, %eax
movl %eax, _output_index
movl $_output, 4(%esp)
movl $LC0, (%esp)
call _printf
movl __imp___iob, %eax
addl $32, %eax
movl %eax, (%esp)
call _fflush
xorl %eax, %eax
leave
ret
.globl _output
.bss
.align 4
_output:
.space 100
.globl _output_index
.align 4
_output_index:
.space 4
.def _printf; .scl 2; .type 32; .endef
.def _fflush; .scl 2; .type 32; .endef

Program output: a
c
y
z
A
D
Y
Z
aa
gg
BB
YY
ZZ
aaa
fff

m4ster_r0shi
Posting Whiz in Training
230 posts since Mar 2010
Reputation Points: 154
Solved Threads: 31
 

Well, while m4ster_r0shi is going at it, I might flex my C++ muscles too...

I just wanted to make the point that doing things at compile-time with meta-programming techniques doesn't have to be really complex and elaborate like m4ster_r0shi's example, especially with C++0x support. For this problem, you could simply do:

#include <iostream>
#include <string>

const char alphabet[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

template <unsigned int Size, unsigned int Index>
struct decoding {
  static constexpr std::string value(const int (&arr)[Size]) {
    return std::string( (arr[Index] - 1) / 52 + 1,
                        alphabet[(arr[Index] - 1) % 52] ) 
           + "\n" 
           + decoding<Size, Index + 1>::value(arr);
  };
};

template <unsigned int Size>
struct decoding<Size, Size> {
  static constexpr std::string value(const int (&)[Size]) {
    return "";
  };
};

template <unsigned int Size>
constexpr std::string decode(const int (&arr)[Size]) { return decoding< Size, 0 >::value(arr); };

int main() {
  constexpr int input[] = {1, 3, 25, 26, 27, 30, 51, 52, 53, 59, 80, 103, 104, 105, 110};

  std::cout << decode(input) << std::endl;

  return 0;
};
mike_2000_17
Posting Virtuoso
Moderator
2,139 posts since Jul 2010
Reputation Points: 1,634
Solved Threads: 457
 

Damn. I really have to start to familiarize myself with the upcoming standard.

m4ster_r0shi
Posting Whiz in Training
230 posts since Mar 2010
Reputation Points: 154
Solved Threads: 31
 

Are we in the assembly forums or something?

iamthwee
Posting Expert
5,950 posts since Aug 2005
Reputation Points: 1,543
Solved Threads: 439
 

This article has been dead for over three months

Post: Markdown Syntax: Formatting Help
You