Re: Haskell - Python
Ian Kelly ian.g.ke...@gmail.com wrote: On Fri, Nov 2, 2012 at 1:19 PM, foste...@gmail.com wrote: Is there anything anyone could recommend to make it more Pythonic or more functional. It looks clumsy next to the Haskell. def options(heaps): for i, heap in enumerate(heaps): head = heaps[:i] tail = heaps[i+1:] yield from (head + [x] + tail for x in range(heap)) yield from is Python 3.3 syntax. If you're not using Python 3.3, then that line could be replaced by: for x in range(heap): yield head + [x] + tail Cheers, Ian An alternative that is closer to foster63's original but still more Pythonic for some definitions of those words. def options(heaps): if not heaps: return [] head, *tail = heaps for h in range(head): yield [h]+tail for t in options(tail): yield [head]+t For a more 'functional' version there is also the Python 3.3 variant: def options(heaps): if not heaps: return [] head, *tail = heaps yield from ([h]+tail for h in range(head)) yield from ([head]+t for t in options(tail)) -- Duncan Booth http://kupuguy.blogspot.com -- http://mail.python.org/mailman/listinfo/python-list
Re: Haskell - Python
In article b19e3922-d86f-426f-afb8-1f75b793f...@googlegroups.com, foste...@gmail.com wrote: def options( heaps ): if heaps == []: return [] head, tail = heaps[:1], heaps[1:] # Calculate all possible moves which is the sum of # prepending all possible head moves to the tail # and appending all possible tail moves to the head return [ [h] + tail for h in range( head[0] ) ] \ + [ head + t for t in options( tail ) ] Is there anything anyone could recommend to make it more Pythonic or more functional. It looks clumsy next to the Haskell. If you want more Pythonic, follow PEP8 in your formatting. ;-) -- Aahz (a...@pythoncraft.com) * http://www.pythoncraft.com/ Normal is what cuts off your sixth finger and your tail... --Siobhan -- http://mail.python.org/mailman/listinfo/python-list
Haskell - Python
Hi All, As part of a Nim solver I'm playing around with I'm trying to code this Haskell snippet: options [x] = zero : [ [y] | y - [1..x - 1] ] options (x:xs) = map (++ xs) (options [x]) ++ map (x:) (options xs) in Python. So far I have this, which works OK, but somehow doesn't feel right: def options( heaps ): if heaps == []: return [] head, tail = heaps[:1], heaps[1:] # Calculate all possible moves which is the sum of # prepending all possible head moves to the tail # and appending all possible tail moves to the head return [ [h] + tail for h in range( head[0] ) ] \ + [ head + t for t in options( tail ) ] Is there anything anyone could recommend to make it more Pythonic or more functional. It looks clumsy next to the Haskell. Regards etc. -- http://mail.python.org/mailman/listinfo/python-list
Re: Haskell - Python
On 11/02/2012 03:19 PM, foste...@gmail.com wrote: Hi All, As part of a Nim solver I'm playing around with I'm trying to code this Haskell snippet: options [x] = zero : [ [y] | y - [1..x - 1] ] options (x:xs) = map (++ xs) (options [x]) ++ map (x:) (options xs) in Python. So far I have this, which works OK, but somehow doesn't feel right: def options( heaps ): if heaps == []: return [] head, tail = heaps[:1], heaps[1:] # Calculate all possible moves which is the sum of # prepending all possible head moves to the tail # and appending all possible tail moves to the head return [ [h] + tail for h in range( head[0] ) ] \ + [ head + t for t in options( tail ) ] Is there anything anyone could recommend to make it more Pythonic or more functional. It looks clumsy next to the Haskell. Regards etc. You'd save people a lot of time if you'd specify that the parameter heaps is a list of ints, perhaps initially [1,3,5,7] or [3, 4, 5] depending on which variation of Nim you're trying to. There are many. One variant is that some versions of Nim say the winner is the player who does NOT take the last piece. I'll assume that the goal is to end up with [0,0,0,0] My main problem with studying your code is that brute force is totally unnecessary; there's a fairly simple strategy for winning at Nim. Certainly it's simple enough to have perfect strategy without any computer. A good move is any one where the xor of all the items in the list ends up as zero. There is always at least one move for an ungood position that results in a good one. Thus the strategy is to go from good to good, with the opponent always stuck on an ungood one. -- DaveA -- http://mail.python.org/mailman/listinfo/python-list
Re: Haskell - Python
On 02/11/12 19:56, Dave Angel wrote: On 11/02/2012 03:19 PM, foste...@gmail.com wrote: Hi All, As part of a Nim solver I'm playing around with I'm trying to code this Haskell snippet: options [x] = zero : [ [y] | y - [1..x - 1] ] options (x:xs) = map (++ xs) (options [x]) ++ map (x:) (options xs) in Python. So far I have this, which works OK, but somehow doesn't feel right: def options( heaps ): if heaps == []: return [] head, tail = heaps[:1], heaps[1:] # Calculate all possible moves which is the sum of # prepending all possible head moves to the tail # and appending all possible tail moves to the head return [ [h] + tail for h in range( head[0] ) ] \ + [ head + t for t in options( tail ) ] Is there anything anyone could recommend to make it more Pythonic or more functional. It looks clumsy next to the Haskell. Regards etc. You'd save people a lot of time if you'd specify that the parameter heaps is a list of ints, perhaps initially [1,3,5,7] or [3, 4, 5] depending on which variation of Nim you're trying to. There are many. One variant is that some versions of Nim say the winner is the player who does NOT take the last piece. I'll assume that the goal is to end up with [0,0,0,0] My main problem with studying your code is that brute force is totally unnecessary; there's a fairly simple strategy for winning at Nim. Certainly it's simple enough to have perfect strategy without any computer. A good move is any one where the xor of all the items in the list ends up as zero. There is always at least one move for an ungood position that results in a good one. Thus the strategy is to go from good to good, with the opponent always stuck on an ungood one. Hi Dave, Thanks for the comments. Yes, I should have specified that the input is a list of ints giving the size of each heap, and the return value should be a list of all game positions reachable from the input position. At the moment I'm not concentrating on any particular Nim flavour, just trying to enumerate all possible moves from a given position. I know that there's an easier way to determine winning-losing positions, but my question was more about programming style than Nim strategy. My code to calculate the nim-value looks like this: def nim_val( heaps ): return functools.reduce( operator.xor, heaps, 0 ) Assuming that we're playing non-misere Nim then a zero nim-value is a lose for the player *about* to play. Regards Simon -- http://mail.python.org/mailman/listinfo/python-list
Re: Haskell - Python
On Fri, Nov 2, 2012 at 1:19 PM, foste...@gmail.com wrote: Is there anything anyone could recommend to make it more Pythonic or more functional. It looks clumsy next to the Haskell. def options(heaps): for i, heap in enumerate(heaps): head = heaps[:i] tail = heaps[i+1:] yield from (head + [x] + tail for x in range(heap)) yield from is Python 3.3 syntax. If you're not using Python 3.3, then that line could be replaced by: for x in range(heap): yield head + [x] + tail Cheers, Ian -- http://mail.python.org/mailman/listinfo/python-list
Re: Haskell - Python
On Fri, Nov 2, 2012 at 3:40 PM, Ian Kelly ian.g.ke...@gmail.com wrote: On Fri, Nov 2, 2012 at 1:19 PM, foste...@gmail.com wrote: Is there anything anyone could recommend to make it more Pythonic or more functional. It looks clumsy next to the Haskell. def options(heaps): for i, heap in enumerate(heaps): head = heaps[:i] tail = heaps[i+1:] yield from (head + [x] + tail for x in range(heap)) yield from is Python 3.3 syntax. If you're not using Python 3.3, then that line could be replaced by: for x in range(heap): yield head + [x] + tail In fact, the more that I look at it, the more that I think the latter might be preferable in any case. -- http://mail.python.org/mailman/listinfo/python-list
Re: Haskell - Python
On 11/02/2012 05:40 PM, Ian Kelly wrote: On Fri, Nov 2, 2012 at 1:19 PM, foste...@gmail.com wrote: Is there anything anyone could recommend to make it more Pythonic or more functional. It looks clumsy next to the Haskell. def options(heaps): for i, heap in enumerate(heaps): head = heaps[:i] tail = heaps[i+1:] yield from (head + [x] + tail for x in range(heap)) yield from is Python 3.3 syntax. If you're not using Python 3.3, then that line could be replaced by: for x in range(heap): yield head + [x] + tail Cheers, Ian Perhaps range(heap) should be replaced by range(len(heap)) -- DaveA -- http://mail.python.org/mailman/listinfo/python-list
Re: Haskell - Python
On Fri, Nov 2, 2012 at 4:24 PM, Dave Angel d...@davea.name wrote: Perhaps range(heap) should be replaced by range(len(heap)) heaps is a list of ints per the OP, so heap is an int. -- http://mail.python.org/mailman/listinfo/python-list
Re: Haskell - Python
On 11/02/2012 06:27 PM, Ian Kelly wrote: On Fri, Nov 2, 2012 at 4:24 PM, Dave Angel d...@davea.name wrote: Perhaps range(heap) should be replaced by range(len(heap)) heaps is a list of ints per the OP, so heap is an int. You're right of course blush. I was distracted by the fact that a heap is normally a collection of thing, and didn't notice that here it is a count of those things. -- DaveA -- http://mail.python.org/mailman/listinfo/python-list