#!/usr/bin/python "Telegram problem, aka fmt." import sys words = lambda line: line.split() width = lambda buf: sum(len(word) for word in buf) + len(buf) - 1 def telegram_generator_1(infile, maxwidth): """A purely procedural version that doesn't use generators internally. This is what you get if you're writing a conventional procedural program to solve the problem by imperatively producing output lines. """ buf = [] for line in infile: buf.extend(words(line)) while width(buf)> maxwidth: n = len(buf) while width(buf[:n])> maxwidth: n -= 1 yield ' '.join(buf[:n]) buf[:n] = [] yield ' '.join(buf) # XXX what to do if a word is wider than the line? def telegram_super_cool(infile, maxwidth): """Here's a totally generator-oriented version.""" buf = [] for word in (word for line in lines for word in words(line)): buf.append(word) if width(buf)> maxwidth: yield ' '.join(buf[:-1]) buf[:-1] = [] yield ' '.join(buf) class IteratorBase: def __iter__(self): return self class telegram_super_cool_explicit_cps(IteratorBase): """Here's an explicit iterator implementation. I wrote this from telegram_super_cool above, twiddling it a little to reduce excess complexity. It's remarkable how much excess complexity still remains. """ def __init__(self, infile, maxwidth): self.infile, self.maxwidth = iter(infile), maxwidth self.buf = [] self.done = False self.buf2 = [] def next_word(self): while not self.buf2: self.buf2 = words(self.infile.next()) return self.buf2.pop(0) def next(self): if self.done: raise StopIteration while True: try: self.buf.append(self.next_word()) except StopIteration: self.done = True return ' '.join(self.buf) if width(self.buf)> self.maxwidth: rv = ' '.join(self.buf[:-1]) self.buf[:-1] = [] return rv if __name__ == '__main__': for line in telegram_super_cool_explicit_cps(sys.stdin, 72): print line

AltStyle によって変換されたページ (->オリジナル) /