• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

Betovsky

Tradutor Romano

17 mensagens neste tópico

Bem já que isto anda assim pro sossegado, aqui fica um problema simples.

Título:

- Tradutor Romano

Objectivo:

- Fazer um pequeno programa que traduza números arábicos para romanos e vice-versa.

- O utilizador terá que ter a capacidade para introduzir um número num dos 2 formatos disponíveis e o programa deverá responder com a representação do número no outro formato.

- Um número em formato arábico é constituído por 1 ou mais dígitos.

- Um número em formato romano é constituído por 1 ou mais letras em maiúsculas.

Pode-se considerar que todos os números introduzidos estão correctos no seu formato, ou seja, se for em romano é uma representação válida e o contrário o mesmo. Por especificações técnicas romanas, todos os números serão inteiros positivos, ou seja não há zero nem negativos.

Exemplo de Input/Output:

input: 119

output: CXIX

input: 2008

output: MMVIII

input: MMCCXXIX

output: 2229

Material de Apoio:

Não há muito a dizer. Para quem não souber numeração romana pode ver aqui.

Ou em português. Obrigada saunde  :D

Restrições:

Não se pode usar funções/bibliotecas que façam a tradução por nós.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Opá ainda ninguém deu uma solução  :P

Bem, como pelos vistos é provável que saia no futuro um tutorial de Haskell sobre Classes, decidi fazer um pouco de código a usar as ditas.

O código que se segue não valida o range dos números apresentados, portanto números maiores que 4000 irão ser representados com muitos M, já que não dá para por os traços por cima dos mesmos.

{-# OPTIONS_GHC -XTypeSynonymInstances #-}

import Data.List (isPrefixOf)
import Data.Char (isDigit)

lista = [ (1000, "M" )
        , (900 , "CM")
        , (500 , "D" )
        , (400 , "CD")
        , (100 , "C" )
        , (90  , "XC")
        , (50  , "L" )
        , (40  , "XL")
        , (10  , "X" )
        , (9   , "IX")
        , (5   , "V" )
        , (4   , "IV")
        , (1   , "I" )
        ]


class Convertivel a where
   converte :: a -> String

instance Convertivel Integer where
   converte 0 = ""
   converte x = valS ++ converte (x-valI)
      where (valI, valS) = head $ dropWhile ((x<).fst) lista

instance Convertivel String where
   converte = show . converteS

converteS [] = 0
converteS s  = valI + converteS s'
   where (valI, valS) = head $ dropWhile (not . (`isPrefixOf`s) . snd) lista
         s' = drop (length valS) s


main = getContents >>= mapM_ (putStrLn . proc) . lines
   where 
   proc s@(x:_) | isDigit x = converte $ toInteger $ read s
                | otherwise = converte s

Pode ser que agora mais alguém responda...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Epa... isto anda mesmo parado. Então ninguem respondeu a isto a nao ser o autor do desafio :S

Está aqui um bom exercicio para quando eu começar com Lisp.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Este é o meu primeiro post e espero que levem isso em conta na inexperiência neste tipo de foruns.

Tempos atrás precisei de um programa que operasse de forma parecida, cuja função era resolver isto:

http://projecteuler.net/index.php?section=problems&id=89

Não é exactamente o pedido pelo autor do tópico mas como aborda o tema pensei que outra pessoa pudesse achar útil.

O meu programa tem como objectivo a eficiência e minimiza números em romano para a sua forma mais curta possivel. Escrito em Pascal (Lib wincrt)

program prob89;
uses wincrt;
const
temp='dhssd';
maxlen=100;
var
redo: boolean;
ficheiro,ficheiro2: text;
cont1,cont2,tamanho,total,aux1,aux2: longint;
digit: array[0..maxlen] of char;
tempchar: char;
roman: string;
procedure block1;
begin
for cont1:=1 to maxlen-1 do digit[cont1]:=digit[maxlen];
redo:=false;
assign(ficheiro,temp);
rewrite(ficheiro);
write(ficheiro,roman);
close(ficheiro);
roman:='';
assign(ficheiro,temp);
reset(ficheiro);
cont1:=0;
while eoln(ficheiro)=false do begin
read(ficheiro,tempchar);
digit[cont1]:=upcase(tempchar);
cont1:=cont1+1;
end;
close(ficheiro);
tamanho:=cont1;
end;
begin
assign(ficheiro2,'roman.txt');
reset(ficheiro2);
repeat
cont2:=cont2+1;
readln(ficheiro2,roman);
block1;
aux1:=tamanho;
writeln(cont2,'.');
write('  INPUT = ');
for cont1:=0 to tamanho-1 do write(digit[cont1]);
writeln(' (',aux1,')');
write(' OUTPUT = ');
{ V }
repeat
for cont1:=0 to tamanho-1 do
if (digit[cont1]='I') and (digit[cont1+1]='I') and (digit[cont1+2]='I') and (digit[cont1+3]='I') and (digit[cont1+4]='I') then
begin
cont1:=cont1+4;
roman:=roman+'V';
redo:=true;
end else
roman:=roman+digit[cont1];
until redo=false;
{ IV }
repeat
block1;
for cont1:=0 to tamanho-1 do
if (digit[cont1]='I') and (digit[cont1+1]='I') and (digit[cont1+2]='I') and (digit[cont1+3]='I') then
begin
cont1:=cont1+3;
roman:=roman+'IV';
redo:=true;
end else
roman:=roman+digit[cont1];
until redo=false;
{ X }
repeat
block1;
for cont1:=0 to tamanho-1 do
if (digit[cont1]='V') and (digit[cont1+1]='V') then
begin
cont1:=cont1+1;
roman:=roman+'X';
redo:=true;
end else
roman:=roman+digit[cont1];
until redo=false;
{ IX }
repeat
block1;
for cont1:=0 to tamanho-1 do
if (digit[cont1]='V') and (digit[cont1+1]='I') and (digit[cont1+2]='V') then
begin
cont1:=cont1+2;
roman:=roman+'IX';
redo:=true;
end else
roman:=roman+digit[cont1];
until redo=false;
{ L }
repeat
block1;
for cont1:=0 to tamanho-1 do
if (digit[cont1]='X') and (digit[cont1+1]='X') and (digit[cont1+2]='X') and (digit[cont1+3]='X') and (digit[cont1+4]='X') then
begin
cont1:=cont1+4;
roman:=roman+'L';
redo:=true;
end else
roman:=roman+digit[cont1];
until redo=false;
{ XL }
repeat
block1;
for cont1:=0 to tamanho-1 do
if (digit[cont1]='X') and (digit[cont1+1]='X') and (digit[cont1+2]='X') and (digit[cont1+3]='X') then
begin
cont1:=cont1+3;
roman:=roman+'XL';
redo:=true;
end else
roman:=roman+digit[cont1];
until redo=false;
{ C }      
repeat
block1;
for cont1:=0 to tamanho-1 do
if (digit[cont1]='L') and (digit[cont1+1]='L') then
begin
cont1:=cont1+1;
roman:=roman+'C';
redo:=true;
end else
roman:=roman+digit[cont1];
until redo=false;
{ XC }
repeat
block1;
for cont1:=0 to tamanho-1 do
if (digit[cont1]='L') and (digit[cont1+1]='X') and (digit[cont1+2]='L') then
begin
cont1:=cont1+2;
roman:=roman+'XC';
redo:=true;
end else
roman:=roman+digit[cont1];
until redo=false;
{ D }
repeat
block1;
for cont1:=0 to tamanho-1 do
if (digit[cont1]='C') and (digit[cont1+1]='C') and (digit[cont1+2]='C') and (digit[cont1+3]='C') and (digit[cont1+4]='C') then
begin
cont1:=cont1+4;
roman:=roman+'D';
redo:=true;
end else
roman:=roman+digit[cont1];
until redo=false;
{ CD }
repeat
block1;
for cont1:=0 to tamanho-1 do
if (digit[cont1]='C') and (digit[cont1+1]='C') and (digit[cont1+2]='C') and (digit[cont1+3]='C') and (digit[cont1+4]='X') and
(digit[cont1+5]='C') then
begin
cont1:=cont1+5;
roman:=roman+'CD';
redo:=true;
end else
roman:=roman+digit[cont1];
until redo=false;
{ M }
repeat
block1;
for cont1:=0 to tamanho-1 do
if (digit[cont1]='D') and (digit[cont1+1]='D') then
begin
cont1:=cont1+1;
roman:=roman+'M';
redo:=true;
end else
roman:=roman+digit[cont1];
until redo=false;
{ CM }
repeat
block1;
for cont1:=0 to tamanho-1 do
if (digit[cont1]='D') and (digit[cont1+1]='C') and (digit[cont1+2]='D') then
begin
cont1:=cont1+2;
roman:=roman+'CM';
redo:=true;
end else
roman:=roman+digit[cont1];
until redo=false;
aux2:=tamanho;
writeln(roman,' (',aux2,')');
if aux2>aux1 then runerror(0);
total:=total+abs(aux2-aux1);
write('  SAVED = ',total);
if aux1<>aux2 then write(' (+',abs(aux2-aux1),')');
writeln;
writeln;
until eof(ficheiro2)=true;
close(ficheiro2);
end.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Não tinha visto o tópico não sei porquê...

Anyway, aqui fica uma resolução rápida do problema em Python. O processInt ficava mais curto se fosse recursivo, mas não me dei ao trabalho.

class roman:
    roman = {'M': 1000, 'D': 500, 'C': 100, 'L': 50, 'X': 10, 'V': 5, 'I': 1}
    pairs = [('M', 1000), ('D', 500), ('C', 100), ('L', 50), ('X', 10), ('V', 5), ('I', 1)]

    def main(self):
        tmp = raw_input("Input: ")
        try:
            tmp = int(tmp)
        except:
            print self.processRoman(tmp)
        else:
            print self.processInt(tmp)

    def processRoman(self, tmp):
        return sum([self.roman[char]*({True: -1, False: 1}[self.roman[char] < self.roman[tmp[min(len(tmp)-1,x+1)]]]) for x, char in zip(xrange(len(tmp)), tmp)[::-1]])

    def processInt(self, tmp):
        z = []
        curr = 0
        for x, y in self.pairs: #can't use self.roman because python doesn't iterate it in the order i declared it...
            z += [(tmp/y)*x]
            if (tmp/y) > 3 and x != 'M': #excepcao para poder ter 4000+
                z = z[:len(z)-2]
                z += [x+self.pairs[curr-2][0]]
            tmp %= y
            curr += 1
        return ''.join(z)

if __name__ == '__main__':
    roman().main()

Teste:

>>> roman().processRoman(roman().processInt(roman().processRoman(roman().processInt(1992))))

1992

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Está aqui uma versão em Ruby.

   2229.to_roman #=> "MMCCXXIX"
   "MMCCXXIX".from_roman #=> 2229
   2009.to_roman.from_roman #=> 2009

É um bocado de overkill com meta-programming, mas queria brincar um bocado (Código + Specs aqui).

require 'enumerator' 

module RomanTranslator

  def self.included(target)
    return if target != Fixnum && target != String
    
    func_name = 'to_roman'
    call_func = 'to_roman_from_number'
    func_name = 'from_roman' if target == String
    call_func = 'to_number_from_roman' if target == String
    
    target.class_eval <<-ruby_eval, __FILE__, __LINE__ + 1
      def #{func_name}
        #{call_func}(self)
      end
    ruby_eval
  end
  
private

  NUM_TO_ROM = { 
    1 => 'I', 4 => 'IV', 5 => 'V', 9 => 'IX', 10 => 'X', 40 => 'XL', 50 => 'L', 
    90 => 'XC', 100 => 'C', 400 => 'CD', 500 => 'D', 900 => 'CM', 1000 => 'M' 
  }
  
  ROM_TO_NUM = NUM_TO_ROM.invert
  
  def to_roman_from_number(num)
    numbers = NUM_TO_ROM.keys.sort.reverse
    str = num.to_s
    res = ""
    zeros = str.length - 1
    str.each_byte do |c|
      num = c.chr.to_i * (10 ** zeros)
      fill = 0
      numbers.each do |v|
        while ((fill + v) <= num) do
          fill += v
          res << NUM_TO_ROM[v]
          break if v == num
        end
      end
      zeros -= 1
    end
    res
  end

  def to_number_from_roman(roman)
    array = roman.split(//)
    lookahead = 1
    skip = false
    array.inject(0) do |result, char1|
      num1 = ROM_TO_NUM[char1]
      if skip
        skip = false
        next(result)
      end
      num2 = ROM_TO_NUM[array[lookahead]]
      if num2.nil? || num1 >= num2 then
        result += num1
      else
        result += num2 - num1
        skip = true
      end
      lookahead += 1
      result
    end
  end

end

class Fixnum
  include RomanTranslator
end

class String
  include RomanTranslator
end

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Estou a escrever um código em C++, a ver se consigo acaba-lo!

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Boas.

Aqui fica a minha contribuição.

Numbers = {'M' => 1000, 'CM' => 900, 'D' => 500, 'CD' => 400, 'C' => 100, 'XC' => 90,
                  'L' => 50, 'XL' => 40, 'X' => 10, 'IX' => 9, 'V' => 5, 'IV' => 4, 'I' => 1}

def toRoman num
 numConv = ""
 Numbers.each {|a,b|
   numConv += a * (num / b)
   num %= b
 }
 return numConv
end

def toInt num
 numConv = 0
 for a, b in Numbers
   while num.index(a) == 0
     numConv += b
     num.slice!(a)
   end
 end
 return numConv
end

print "Enter a number: "
num = gets
num.delete! "\n"
if num.to_i == 0
 puts toInt num.upcase
else
 puts toRoman num.to_i
end

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

djthyrax

Estive a testar o teu e está com um problema:

Input: 900
CM
Input: 400
CM
Input: 90
XC
Input: 40
XC
Input: 9
IX
Input: 4
IX

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Peço desculpa pela minha inactividade desde que postei uma resposta neste tópico, que foi na quinta feira penso eu, até hoje, mas estive ocupado com outras coisas e não podia trabalhar. Mas pronto, deixo aqui o meu código em C++. Duas classes, numero_romano e numero_arabe. Irei desenvolve-las mais criando operator= e operator+, por aí fora. Cumprimentos!

#include <iostream>

using namespace std;

class numero_romano
{
private:
string numero;

public:
numero_romano() {}
numero_romano(string novo): numero(novo) { normalizar(); }

string valor() const { return numero; }
void novo_valor(string novo) { numero = novo; normalizar(); }

int para_arabe();

void normalizar();
};

int numero_romano::para_arabe()
{
int i, res = 0;

for(i=0; i<numero.size(); i++)
{
	switch(numero[i])
	{
		case 'I':
			if(numero[i+1] == 'V')
			{
				res += 4;
				i++;
			}
			else if(numero[i+1] == 'X')
			{
				res += 9;
				i++;
			}
			else
				res += 1;
		break;

		case 'X':
			if(numero[i+1] == 'L')
			{
				res += 40;
				i++;
			}
			else if(numero[i+1] == 'C')
			{
				res += 90;
				i++;
			}
			else
				res += 10;
		break;

		case 'C':
			if(numero[i+1] == 'D')
			{
				res += 400;
				i++;
			}
			else if(numero[i+1] == 'M')
			{
				res += 900;
				i++;
			}
			else
				res += 100;
		break;

		case 'M':
			res += 1000;
			break;

		case 'V': res += 5; break;
		case 'L': res += 50; break;
		case 'D': res += 500; break;
	}
}

return res;
}

void numero_romano::normalizar()
{
for(int i=0; i<numero.size(); i++)
{
	if(numero[i] == 'i') numero[i] = 'I';
	if(numero[i] == 'v') numero[i] = 'V';
	if(numero[i] == 'x') numero[i] = 'X';
	if(numero[i] == 'l') numero[i] = 'L';
	if(numero[i] == 'c') numero[i] = 'C';
	if(numero[i] == 'd') numero[i] = 'D';
	if(numero[i] == 'm') numero[i] = 'M';
}
}

class numero_arabe
{
private:
int numero;

public:
numero_arabe() {}
numero_arabe(int novo): numero(novo) {}

int valor() const { return numero; }
void novo_valor(int novo) { numero = novo; }	

string para_romano();
};

string numero_arabe::para_romano()
{
int i;
string res;

while(numero > 0)
{
	if(numero >= 1000)
	{
		res += "M";
		numero -= 1000;
	}
	else if(numero >= 100)
	{
		if(numero >= 900 && numero <= 999)
		{
			res += "CM";
			numero -= 900;
		}
		else if(numero >= 400 && numero <= 499)
		{
			res += "CD";
			numero -= 400;
		}
		else if(numero >= 500)
		{
			res += "D";
			numero -= 500;
		}
		else
		{
			res += "C";
			numero -= 100;
		}
	}
	else if(numero >= 10)
	{
		if(numero >= 90 && numero <= 99)
		{
			res += "XC";
			numero -= 90;
		}
		else if(numero >= 40 && numero <= 49)
		{
			res += "XL";
			numero -= 40;
		}
		else if(numero >= 50)
		{
			res += "L";
			numero -= 50;
		}
		else
		{
			res += "X";
			numero -= 10;
		}
	}
	else if(numero >= 1)
	{
		if(numero >= 9 && numero <= 9)
		{
			res += "IX";
			numero -= 9;
		}
		else if(numero >= 4 && numero <= 4)
		{
			res += "IV";
			numero -= 4;
		}
		else if(numero >= 5)
		{
			res += "V";
			numero -= 5;
		}
		else
		{
			res += "I";
			numero -= 1;
		}
	}
}

return res;
}

int main(int argc, char *argv[])
{
//De arabe para romano
int num_arabe;
string res_romano;

cout << "Arabe: ";
cin >> num_arabe;
numero_arabe arabe(num_arabe);
res_romano = arabe.para_romano();
cout << endl << res_romano << endl;

//De romano para arabe	
string num_romano;
int res_arabe;

cout << "romano: ";
cin >> num_romano;
numero_romano romano(num_romano);
res_arabe = romano.para_arabe();
cout << endl << res_arabe << endl;

//----
return 0;
}

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

djthyrax

Estive a testar o teu e está com um problema:

Input: 900
CM
Input: 400
CM
Input: 90
XC
Input: 40
XC
Input: 9
IX
Input: 4
IX

Tens toda a razão. Tenho que refazer o for do processInt e percorrer apenas os pares M, C, X e I. Quando tiver tempo altero e meto aí. :D
0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Boas.

Aqui fica em C++.

#include <iostream>
#include <sstream>

#define LENGTH 13

using namespace std;

const string letters [13] = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};
const int numbers [13] = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};

bool StringToInt(const string &s, int &i)
{
  istringstream sStream(s);
    if (sStream >> i)
      return true;
    else
      return false;
}

string toRoman(int num)
{
  string numConv = "";
  int auxInt = 0;
  for (int i = 0; i < LENGTH; i++) {
    auxInt = num / numbers[i];
    for (int aa = 0; aa < auxInt; aa++) {
      numConv += letters[i];
    }
    num = num % numbers[i];
  }
  return numConv;
}

int toInt(string num)
{
  int numConv = 0;
  size_t found;
  for (int i = 0; i < LENGTH; i++) {
    while (num.find(letters[i]) == 0) {
      numConv += numbers[i];
      num.erase(0, letters[i].length());
    }
  }
  return numConv;
}

int main()
{
  string num;
  int res;

  cout << "Enter a number: ";
  cin >> num;

  if (StringToInt(num, res)) {
    cout << toRoman(res) << "\n";
  }
  else {
    cout << toInt(num) << "\n";
  }
  return 0;
}

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Aqui vai a minha solução em C pode não ser a melhor mas tentei.

 #include <stdio.h>
# include<stdlib.h>
   int main()   
{
  char c [20];
  int d,i,valor,r,numero;
  scanf("%s]",&c);
  r=isalpha(c[0]);
  d = strlen(c);
  valor=0;
numero=atoi(c);
  if (r==1)
     for (i=0;i<d;i++)
     {
        switch (c[i])
        {  
         case 'M' :valor=valor+1000; break;
         case 'D' :valor=valor+500;break;
         case 'L' :valor=valor+50;break;
         case 'V' :valor=valor+5;break;
         case 'C' :
              {
                if(c[i+1] =='M')
                   {
                      i++;
                      valor=valor+900;        
                   }  
                else if(c[i+1]=='D')
                   { 
                      i++;
                      valor=valor+400;
                   }  
                else
                      valor=valor+100;
                break;
              }
         case 'X' :
              {
                if(c[i+1] =='C')
                    {
                       i++;
                       valor=valor+90;        
                    }  
                else if(c[i+1]=='L')
                    { 
                      i++;
                      valor=valor+40;
                    } 
                else
                      valor=valor+10;
                  break;
               }
         case 'I' :
             {
                if(c[i+1] =='X')
                    {
                       i++;
                       valor=valor+9;        
                    }  
                else if(c[i+1]=='V')
                    { 
                       i++;
                       valor=valor+4;
                    }  
                else
                  valor=valor+1;
                  break;
              }
         }
     }   
  
  
    else
      
      while (numero != 0)
      {
      if (numero >=1000)
         {
         numero=numero-1000;
         printf("M");
         }      
       else
       if  (numero >=900)
       {numero=numero-900;
       printf("CM");
       }
         else
       if  (numero >=500)
       {numero=numero-500;
       printf("D");
       }
        else
       if  (numero >=400)
       {numero=numero-400;
       printf("CD");
       }
        else
       if  (numero >=100)
       {numero=numero-100;
       printf("C");
       }
        else
       if  (numero >=90)
       {numero=numero-90;
       printf("XC");
       }
        else
       if  (numero >=50)
       {numero=numero-50;
       printf("L");
       }
        else
       if  (numero >=40)
       {numero=numero-40;
       printf("Xl");
       }
        else
       if  (numero >=10)
       {numero=numero-10;
       printf("X");
       }
        else
       if  (numero >=9)
       {numero=numero-9;
       printf("IX");
       }
        else
       if  (numero >=5)
       {numero=numero-5;
       printf("V");
       }
        else
       if  (numero >=4)
       {numero=numero-4;
       printf("IV");
       }
        else
       if  (numero >=1)
       {numero=numero-1;
       printf("I");
       }
             
      }


if (r==1)
   printf(" o valor e %d ",valor); 





    
     
    
scanf("%d",&numero);     

}

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

A minha solução na linguagem nativa:

identification division.
program-id.	 roman.
date-written.   24 de agosto de 2012.
environment division.
configuration section.
special-names.
decimal-point is comma.
data division.
working-storage section.
01  variaveis.
05 numero	   pic 9(04).
05 romano	   pic x(80).
05 posicao	  pic 9(02).
05 numero-max   pic 9(04).
05 keep		 pic 9(02).
05 tecla		pic x.
01  tabela-interna.
05  n		   pic 9(02).
05  i.
	10 filler   pic x(07)   value '1000M 1'.
	10 filler   pic x(07)   value '0900XM2'.
	10 filler   pic x(07)   value '0500D 1'.
	10 filler   pic x(07)   value '0400CD2'.
	10 filler   pic x(07)   value '0100C 1'.
	10 filler   pic x(07)   value '0090XC2'.
	10 filler   pic x(07)   value '0050L 1'.
	10 filler   pic x(07)   value '0040XL2'.
	10 filler   pic x(07)   value '0010X 1'.
	10 filler   pic x(07)   value '0009IX2'.
	10 filler   pic x(07)   value '0005V 1'.
	10 filler   pic x(07)   value '0004IV2'.
	10 filler   pic x(07)   value '0001I 1'.
05  m redefines i occurs 13.
	10 num	  pic 9(04).
	10 rom	  pic x(02).
	10 len	  pic 9(01).
screen section.
01  screen-input.
05  accept-screen.
	10  line 01 col 01  value 'Introduza um número (1-3999): '.
	10  a-numero		entry-field using
		numero		  auto reverse required
						pic zzz9
						after procedure valida-input.
05  display-screen.
	10  line 02 col 01  value 'Em numeração romana é '.
	10  a-romano		using
		romano		  pic x(80).
procedure division.
inicio.
display accept-screen.
accept  accept-screen.
display display-screen.
accept  tecla.
perform varying numero-max from 1 by 1 until numero-max > 3999
	move numero-max to numero
	perform valida-input
	if posicao > keep
	   move keep to posicao
	   display romano, keep
	end-if
end-perform.  
stop run.
valida-input.
evaluate numero
	when 1 thru 3999
		move 1 to posicao
		perform until numero < 1 or posicao > 80
			perform varying n from 1 by 1 until n > 13
				if numero not < num (n)
				   move	 rom (n) to   romano (posicao:)
				   add	  len (n) to   posicao
				   subtract num (n) from numero
				end-if
			end-perform
		end-perform
	when other
		move '#Fora do limite...' to romano
end-evaluate.

Apenas traduz até 3999, já que a partir do 4000, começa a usar aqueles traços por cima das letras, e isso é mais complicado de fazer...

:thumbsup:

1

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

date-written.   24 de agosto de 2012.

Gostei!

O Cobol não morre este mês :)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Gostei!

O Cobol não morre este mês :)

Enquanto houver uma instituição bancária ou seguradora no mundo, o Cobol estará cá para durar!

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora