Odd word problem: Difference between revisions

From Rosetta Code
Content added Content deleted
m (→‎{{header|Python}}: edit conflict error)
(→‎{{header|Python}}: correct solution with closure)
Line 183: Line 183:
def char_out(c): stdout.write(c)
def char_out(c): stdout.write(c)


def odd(n = 0):
def odd(prev = None):
a = char_in()
a = char_in()
if not a.isalpha(): return a
if not a.isalpha():
if prev: prev()
char_out(a)
return a != '.'


# delay action until later, in the shape of a closure
b = odd(1)
char_out(a)
def clos():
if not n: char_out(b)
char_out(a)
if prev: prev()
return b

return odd(clos)


def even():
def even():
while True:
c = char_in()
c = char_in()
char_out(c)
char_out(c)
return even() if c.isalpha() else c
if not c.isalpha(): return c != '.'


c, e = 'x', 0
c, e = 1, 0
while c != '.':
while c:
c = odd() if e else even()
c = odd() if e else even()
e = not e</lang>
e = not e</lang>

Revision as of 22:23, 3 November 2011

Odd word problem is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

Write a program that solves the odd word problem.

Description: You are promised an input stream consisting of English letters and punctuations. It is guaranteed that

  • the words (sequence of consecutive letters) are delimited by one and only one punctuation; that
  • the stream will begin with a word; that
  • the words will be at least one letter long; and that
  • a full stop (.) appears after, and only after, the last word.

For example, what,is,the;meaning,of:life. is such a stream with six words. Your task is to reverse the letters in every other word while leaving punctuations intact, producing e.g. "what,si,the;gninaem,of:efil.", while observing the following restrictions:

  1. Only I/O allowed is reading or writing one character at a time, which means: no reading in a string, no peeking ahead, no pushing characters back into the stream, and no storing characters in a global variable for later use;
  2. You are not to explicitly save characters in a collection data structure, such as arrays, strings, hash tables, etc, for later reversal;
  3. You are allowed to use recursions, closures, continuations, threads, coroutines, etc.

Test case: work on both the "life" example given above, and the text we,are;not,in,kansas;any,more.

Go

<lang go>package main

import (

   "bytes"
   "fmt"
   "io"
   "os"
   "unicode"

)

func main() {

   owp(os.Stdout, bytes.NewBufferString("what,is,the;meaning,of:life."))
   fmt.Println()
   owp(os.Stdout, bytes.NewBufferString("we,are;not,in,kansas;any,more."))
   fmt.Println()

}

func owp(dst io.Writer, src io.Reader) {

   b := make([]byte, 1)
   var odd func(s byte) byte
   odd = func(s byte) byte {
       if unicode.IsPunct(rune(s)) {
           return s
       }
       src.Read(b)
       b[0] = odd(b[0])
       s, b[0] = b[0], s
       dst.Write(b)
       return s
   }
   for {
       for {
           src.Read(b)
           dst.Write(b)
           if b[0] == '.' {
               return
           }
           if unicode.IsPunct(rune(b[0])) {
               break
           }
       }
       src.Read(b)
       b[0] = odd(b[0])
       dst.Write(b)
       if b[0] == '.' {
           return
       }
   }

}</lang> Output:

what,si,the;gninaem,of:efil.
we,era;not,ni,kansas;yna,more.

Java

This example is incorrect. Please fix the code and remove this message.

Details: Peeking ahead is not allowed

This is translated from the first C version on the solutions page. <lang java>import java.io.BufferedReader; import java.io.IOException; import java.io.StringReader;

public class OddWord { public static void processStream(BufferedReader in) throws IOException{ if(checkEnd(in))return; while(true){ forward(in); if(checkEnd(in))return; reverse(in); if(checkEnd(in))return; } }

private static boolean checkEnd(BufferedReader in) throws IOException{ if(peek(in) == '.'){ System.out.println((char)in.read()); return true; }else{ System.out.print((char)in.read()); return false; } }

private static char peek(BufferedReader in) throws IOException{ in.mark(1); char retVal = (char)in.read(); in.reset(); return retVal; }

private static void forward(BufferedReader in) throws IOException{ while(Character.isLetter(peek(in))){ System.out.print((char)in.read()); } }

private static void reverse(BufferedReader in) throws IOException{ if(Character.isLetter(peek(in))){ char character = (char)in.read(); reverse(in); System.out.print(character); } }

public static void main(String[] args) throws IOException{ processStream(new BufferedReader(new StringReader("what,is,the;meaning,of:life."))); processStream(new BufferedReader(new StringReader("we,are;not,in,kansas;any,more."))); processStream(new BufferedReader(new StringReader(";what,is,the;meaning,of:life."))); processStream(new BufferedReader(new StringReader("'we,are;not,in,kansas;any,more."))); } }</lang> Output:

what,si,the;gninaem,of:efil.
we,era;not,ni,kansas;yna,more.
;what,si,the;gninaem,of:efil.
'we,era;not,ni,kansas;yna,more.

Pike

This example is incorrect. Please fix the code and remove this message.

Details: not single char I/O; res and out arrays; "in[1..]" is effectively peeking.

<lang pike>string even(string in) {

   string out = ""; 
   if (in == "." || in == "")
       return in;
   out += in[0..0];  
   if( (<',',';',':'>)[in[0]] )
   {
       array res = odd(in[1..]);
       out += res[0];
       out += res[1][0..0];
       out += even(res[1][1..]);
   }
   else
       out += even(in[1..]); 
   return out; 

}

array odd(string in) {

   string out = "";
   if( (<',',';',':','.'>)[in[0]] )
   { 
         return ({ "", in });
   }
   array res = odd(in[1..]);
   out = res[0]+in[0..0];
   return ({ out, res[1] });

}

void main() {

   string input = "what,is,the;meaning,of:life.";
   string output = even(input);
   write(output+"\n");
   input = "we,are;not,in,kansas;any,more.";
   output = even(input);
   write(output+"\n");

}</lang>

Output:

what,si,the;gninaem,of:efil.
we,era;not,ni,kansas;yna,more.

Python

<lang python>from sys import stdin, stdout

def char_in(): return stdin.read(1) def char_out(c): stdout.write(c)

def odd(prev = None): a = char_in() if not a.isalpha(): if prev: prev() char_out(a) return a != '.'

# delay action until later, in the shape of a closure def clos(): char_out(a) if prev: prev()

return odd(clos)

def even(): while True: c = char_in() char_out(c) if not c.isalpha(): return c != '.'

c, e = 1, 0 while c: c = odd() if e else even() e = not e</lang> Running:<lang>$ echo "what,is,the;meaning,of:life." | python odd.py what,si,the;gninaem,of:efil. $ echo "we,are;not,in,kansas;any,more." | python odd.py we,era;not,ni,kansas;yna,more.