Jump to content
thoga31

The Odd Words Problem (adaptado)

Recommended Posts

thoga31

Hoje trago-vos algo muito simples. Encontrei este desafio na web, e aparentemente foi um senhor de seu nome Edsger W. Dijkstra quem pela primeira vez o mencionou num livro, da sua autoria, no ano de 1972.

Título: The Odd Words Problem

Objectivo: (texto original adaptado e simplificado)

Seja dada uma String, S, constituída por palavras separadas por um espaço e que termina num ponto final. O objectivo é devolver a string em que as palavras ímpares aparecem revertidas. A primeira palavra é a nº 0, a segunda é a nº 1, e assim em diante.

Exemplo I/O:

INPUT: Frase exemplo teste pois claro ok.
OUTPUT: Frase olpmexe teste siop claro ko.  <-- atenção ao ponto final!

Have fun! ;)


Knowledge is free!

Share this post


Link to post
Share on other sites
HappyHippyHippo

/* inverter uma string */
revstring(StrWord, SolWord) :- string_to_list(StrWord, StrList),  /* converter a string numa array */
                              reverse(StrList, SolList),         /* inverter o array */
                              string_to_list(SolWord, SolList).  /* converter o array numa string */

/* predicado de entrada do problema (Frase original, Frase alterada) */
oddwords(Str, Sol) :- string_concat(AuxStr, '.', Str),            /* obter a string sem o ponto final */
                     atomic_list_concat(StrList, ' ', AuxStr),   /* separar as palavras */
                     oddwords(StrList, 0, SolList),              /* processamento da lista de palavras */
                     atomic_list_concat(SolList, ' ', AuxSol),   /* reconstruir a string final com a lista de palavras processado */
                     string_concat(AuxSol, '.', Sol).            /* adicinar o ponto final ao fim da frase processada */

/* predicado de fim do processamento recursivo */
oddwords([], _, []).                                                                   /* a hipótese e a solução são listas vazias */

/* predicado de processamento para o elemento par da lista, o elemento à cabeça das duas listas é igual (sem inversão) */
oddwords([Word|StrList], N, [Word|SolList]) :- N rem 2 =:= 0,                          /* verificação do N como par */
                                              oddwords(StrList, N+1, SolList).        /* processamento do resto da lista */

/* predicado de processamento para o elemento impar da lista */
oddwords([strWord|StrList], N, [solWord|SolList]) :- N rem 2 =\= 0,                    /* verificação do N como impar */
                                                    revstring(StrWord, SolWord),      /* o elemento à cabeça da solução é o inverso da elemento à cabeça da hipótese */
                                                    oddwords(StrList, N+1, SolList).  /* processamento do resto da lista */

é necessário comentários ?

Edited by HappyHippyHippo

IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
bioshock
string original = "Frase exemplo teste pois claro ok.";
		string nova = string.Empty;
		var tryIt = original.Split(' ');

		for (int i = 0; i <= tryIt.Length - 1; i++)
		{
			if (tryIt[i].ToString().Contains("."))
			{
				if (i % 2 == 0) { nova += tryIt[i] + " "; }
				else
				{
					nova += Reverse(tryIt[i].Substring(0, tryIt[i].IndexOf('.')).ToString()) + ".";
				}
				break;
			}
			else
			{
				if (i % 2 == 0) { nova += tryIt[i] + " "; } else { nova += Reverse(tryIt[i].ToString()) + " "; }
			}
		}
		MessageBox.Show(nova.ToString());

public static string Reverse(string s)
{
char[] charArray = s.ToCharArray();
Array.Reverse(charArray);
return new string(charArray);
}

Edited by bioshock

Share this post


Link to post
Share on other sites
thoga31

é necessário comentários ?

Se quiseres meter... com uns comentários até poderia perceber o teu código, que sou curioso :D

Meanwhile, uma solução rápida em Haskell, com certeza que deverá haver formas mais elegantes.

oddwords :: String -> String
oddwords xs = concats . f False $ words xs
 where
   f :: Bool -> [string] -> [string]
   f _ [] = []
   f cond (x:xs) = (if cond then reverse x else x) : f (not cond) xs

   -- o.m.q. "concat", mas dá espaço entre palavras e coloca o ponto final no fim caso pertença a uma palavra invertida
   concats :: [string] -> String
   concats [] = []
   concats (x:[]) = if head x == '.' then tail x ++ "." else x
   concats (x:xs) = x ++ " " ++ concats xs

main :: IO()
main = putStrLn $ oddwords "Frase exemplo teste pois claro ok."

http://ideone.com/BKzvFT

Edited by thoga31
Adicionado "main" para correr no Ideone

Knowledge is free!

Share this post


Link to post
Share on other sites
mogers

s = raw_input()
palavras = s[0:len(s)-1].split()  # remove o ponto final e separa em palavras
for i in range(1, len(palavras)):
if i % 2 == 1:
	palavras[i] = palavras[i][::-1]  # reverte as palavras em indice ímpar
print ' '.join(palavras) + '.'			  # junta o array numa string e adiciona o ponto final

Não sou grande conhecedor de python. Devem existir formas melhores de ir apenas aos indices impares.

Edited by mogers

"What we do for ourselves dies with us. What we do for others and the world, remains and is immortal.", Albert Pine

Blog pessoal : contém alguns puzzles, algoritmos e problemas para se resolver com programação.

Share this post


Link to post
Share on other sites
thoga31

Não sou grande conhecedor de python. Devem existir formas melhores de ir apenas aos indices impares.

Utiliza o próprio range para isso ;)

for i in range(1, len(palavras), 2):  # começa no índice 1 e anda de 2 em 2 -> 1,3,5,7...
       palavras[i] = palavras[i][::-1]


Knowledge is free!

Share this post


Link to post
Share on other sites
pwseo

Aqui vai a minha:

oddWords :: String -> String
oddWords s = unwords $ zipWith ($) funcs (words s)
 where
   funcs = cycle [ id, (fix . reverse) ]
   fix w | head w == '.' = tail w ++ "."
         | otherwise     = w

main :: IO ()
main = putStrLn $ oddWords "Frase exemplo teste pois claro ok."

ou então, assumindo que todas as frases terminam com um ponto final:

oddWords :: String -> String
oddWords s = (++ ".") . unwords $ zipWith ($) fs ws
 where
   fs = cycle [ id, reverse ]
   ws = words (init s)

main :: IO ()
main = putStrLn $ oddWords "Frase exemplo teste pois claro ok."

Edited by pwseo

Share this post


Link to post
Share on other sites
HappyHippyHippo

Se quiseres meter... com uns comentários até poderia perceber o teu código, que sou curioso :D

done


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
Rui Carlos

reverseOdd l = unwords (
   map
       (\(x,y) -> if odd$y then reverse$x else x)
       (zip (words.init$l) [0..])
   ) ++ "."

(Só me falta uma maneira de colocar aquele condicional em point-free, que estava na ideia que existia :\)

Share this post


Link to post
Share on other sites
pwseo

Rui Carlos,

Porque estás a fazer aplicação explícita das funções? (odd$y e reverse$x)

Share this post


Link to post
Share on other sites
mogers

Utiliza o próprio range para isso ;)

lol que fail da minha parte, obrigado x)

s = raw_input()
palavras = s[0:len(s)-1].split();
for i in range(1, len(palavras), 2):
palavras[i] = palavras[i][::-1]
print ' '.join(palavras) + '.'

Edited by mogers

"What we do for ourselves dies with us. What we do for others and the world, remains and is immortal.", Albert Pine

Blog pessoal : contém alguns puzzles, algoritmos e problemas para se resolver com programação.

Share this post


Link to post
Share on other sites
Rui Carlos

Rui Carlos,

Porque estás a fazer aplicação explícita das funções? (odd$y e reverse$x)

Eu tinha isto

\x -> if odd.snd$x then reverse.fst$x else fst$x

onde uso o $ para poupar nos parêntesis :D .

E depois evoluiu para isto

\(x,y) -> if odd$x then reverse$x else x

onde nem me lembrei de tirar o $ :D .

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.