Hacker News new | past | comments | ask | show | jobs | submit login
Interrupted Loops (leancrew.com)
43 points by tosh on Oct 11, 2020 | hide | past | favorite | 22 comments



You can of course always do it with a list comprehension, also:

    [ seq 
      for seq in permutations(range(1,10)) 
      if all(x + y in primes 
             for x, y in zip(seq, islice(seq, 1, None))) ]
This has the same short-circuiting behaviour as the loop-based solution (i.e. it will break out of the inner loop appropriately).


Agree.

The sort of python user who regularly writes stuff like zip(seq, islice(seq, 1, None)))

may enjoy the `itertoolz` library

    https://github.com/pytoolz/toolz
which (among many other handy functions) has a sliding_window function:

    def sliding_window(n, seq):
      """ A sequence of overlapping subsequences
      >>> list(sliding_window(2, [1, 2, 3, 4]))
      [(1, 2), (2, 3), (3, 4)]
      """
      return zip(*(collections.deque(itertools.islice(it, i), 0) or it
                 for i, it in enumerate(itertools.tee(seq, n))))


You could use the all function instead of the inner loop in the for-loop solution as well, which would solve the problem without any of the kludges described in the article. But I like the list comprehension better since it is more declarative.


I wonder how an array based language would fit the problem, would short-circuiting be possible or even matter?


Well, in Julia you can use good old goto :)

  using Combinatorics
  
  # Initialization
  numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
  primes = [3, 5, 7, 11, 13, 17]
  winners = []
  
  # Loop though the permutations, collecting only prime pairs
  for p in permutations(numbers)
      for i in 2:9
          if !(p[i-1] + p[i] in primes)
              @goto nextpermutation
          end
      end
      push!(winners, p)
      @label nextpermutation
  end
  
If I were to use a non-brute force approach I would consider computing all the hamiltonian paths of a graph where each vertex is a number and two vertices are connected only if their sum is a prime number


Gotos can be so useful in situations like this. I do not like the trend in new languages of not allowing goto and instead make the programmer do gymnastics to implement relatively straightforward logic.


This isn't even the limit on fun you can have with the for-else. Check out the 'beautiful' else-continue-break ladder: https://stackoverflow.com/a/3150107


This is a feature of posix shells, the status of `while ...` outside the loop is zero unless the loop never executed.


In older languages, you could have used goto

Somehow it went out of favor but it is actually really nice to break out of something


After looking at the comments I wonder how many permutations there are to solve this problem.


Infinitely many?


Exceptions?


Don't use exceptions for flow control


Agreed! except a) python does exactly this (which I disagree with but whatever, it's considered acceptable https://softwareengineering.stackexchange.com/questions/1124...) and b) in this case it may be cleanest.


Well, the Right Answer is surely to filter on a generator, rather than this ghastly mutable state - which points firmly towards what the author calls the "function" solution.


Arguably the Right Answer wouldn't filter on a generator of all permutations but would generate the permutations in a way that didn't include invalid ones to begin with.

Something like:

    def extend(perm):
        for k in range(1,11):
            if k not in perm and isprime(k + perm[-1]):
               yield [*perm, k]
        
    perms = [[]]
    for _ in range(10):
       perms = [extend(perm) for perm in perms]
(This is just a draft, but you get the gist)


Oh, absolutely, but the article is predicated on using the most naive brute force.


Don't want to be rude but I'm getting really fed up with the state = bad mindset that's now becoming a dogma. State is there to be used appropriately. There's nothing wrong with state, gotos or whatever, and there's nothing right about functional or OO. It's how you use them.


In this instance, I'm pretty confident the generator version is just a better phrasing. It's shorter, contains no mutable state to get wrong, is Pythonic, and can instantly be made lazy by replacing the square brackets with round ones.

`[p for p in permutations(numbers) if primePairs(p)]`


This would have been a better original comment than just calling the solution in the blog post "ghastly".


I retract what I said. You were right.


> state = bad mindset that's now becoming a dogma.

You must be very young. State = bad has been a guiding principle for many decades.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: