Hi,
The following code fails to compile, but what do you think, should this work? Is there a reason not supporting this?
Thank you, Peter
var s = @[0,0,0]
for s[0] in 0..7:
#...
My intention was:
var s = @[0,0,0]
for tempVariable in 0..7:
s[0] = tempVariable
#...
I'd use:
var s = @[0,0,0]
for i, t in 0..7:
s[i] = t
And maybe list comprehension.
@Arrrrrrrrr: I think I want something different.
It is not so important. However, this feature would have made my solution 6 lines shorter to Ponder This https://www.research.ibm.com/haifa/ponderthis/challenges/September2015.html
Oh thats what you intended! Loops do not work that way. Its like for <what yields single value> in <iterator>. What you wanted is for <where to put single value> in <iterator>. And while we could do:
var s = @[0,0,0]
for s[0] in 0..7:
#...
we no longer could do:
for i in 0..7:
#...
Because here i is not declared explicitly. @rku: You are right.
So maybe this (like {.inject.} in macros)?
var s = @[0,0,0]
for s[0]{.reuse.} in 0..7:
#...
Again: this is not that important, I just miss the freedom what I have in C (for(alreadyExistingVar=0;alreadyExistingVar<8;...))@Araq
I was about to post the same and try to make one too. But that would not create a shorter version for his challenge.
Something like this probably?
for x[0] as 0..7:
...
OderWat: But that would not create a shorter version for his challenge.
I'm not sure that introducing language features solely for purposes of code-golfing would be a good idea.
@Jehan
I am pretty sure that it would be bad to do that for just this reason. We could solve the full problem in the standard library though ;-) Just kidding. I said that because developing a macro would be kinda useless if he had to include it.
@OderWat: Well, technically it can be a single line. :)
template iterate(v, r, b: untyped): auto = (for t in r: (v = t; b))
var s = @[0]
iterate(s[0], 0..7):
echo s[0]
It is October 1, we are after the deadline. Please see below my solution to September's Ponder this. I wanted to show you the motivation for this forum thread. There are several for loops with temporary variables, that's why I asked for something shorter:
var found = newSeq[bool](128)
proc check(s: seq[int], N: int) =
for x in 0..<N:
found[x] = false
var f = 0
for q0 in 0..1:
for q1 in 0..1:
for q2 in 0..1:
for q3 in 0..1:
for q4 in 0..1:
for q5 in 0..1:
for q6 in 0..1:
for q7 in 0..1:
let w = q0*s[0] + q1*s[1] + q2*s[2] + q3*s[3] + q4*s[4] + q5*s[5] + q6*s[6] + q7*s[7]
let e = q0 + q1 + q2 + q3 + q4 + q5 + q6 + q7
if w <= N and not found[e+N-w-1]:
f += 1
found[e+N-w-1] = true
if f == N:
echo N, " -> ", s
var s = newSeq[int](8)
s[0] = 2
for N in 70..128:
echo N
s[7] = N
for s1 in 2..3:
s[1] = s1
#for s[1]{.nodecl.} in 2..3: # would be nicer, right?
for s2 in s[1]..5:
s[2] = s2
for s3 in s[2]..9:
s[3] = s3
for s4 in s[3]..17:
s[4] = s4
for s5 in s[4]..33:
s[5] = s5
for s6 in s[5]..<N:
s[6] = s6
check(s, N)
@mora: What you're looking for is a proper library for this kind of loops. See, e.g., this one.
import combinatorics
var s = newSeq[int](8)
for q in tuples([0,1], 8):
var w = 0
var e = 0
for i in 0..q.high:
e += q[i]
w += q[i] * s[i]
...
Note that the library doesn't handle your second example, but there's no reason why it can't be extended accordingly. It's basically a variation of the multicombinations iterator except that individual elements can come from different ranges.
Not everything needs to be baked into a programming language. Even so, you can use a template to abbreviate this code (see above).
Where is this library? I tried nimble install combinatorics, but didn't work, and your link points back to this forum topic.
I would have used the tuples function if I had known about it. My all time favorite code is a 3 lines long python code which uses combinations(...) in itertools package and prints all the valid "8 queens on the board" solutions.
Oops, copy-and-paste fail. I didn't include a URL, and apparently the forum's reStructuredText processor fills in blank URLs with the current one. It should be fixed now.
It's not in the nimble list because (1) I wasn't sure when I wrote it if it was mature enough to be included and (2) because I don't use nimble much myself.
@Jehan Thanks, I love it! May I have some remarks? It is great that you are using iterators instead of returning a seq of the full solution. For permutations() I prefer a different order, I think that permutations(@[1,2,3]) should return the items in lexicographical order (@[1,2,3], @[1,3,2], ...), like itertools does in Python. I believe that your library should be part of the std library. I think that the tuples name is a little misleading since we have tuple as data type (I don't have a good candidate).
Currently combinations(@[1,2,3,4,5], 2) returns a seq[int], and this is good. I think that there should be a version which returns a tuple (in addition to the current function). So combinationsTuple(@[1,2,3,4,5], 2) would require that 2 is known at compile time and it would return (int, int). I believe that the more compile time check we have is the better. So for x, y in combinationsTuple(@[1,2,3,4,5], 2): ... would compile.
Sidenote: If you convert all the results to a seq with toSeq, then you can't preallocate the right size of the result. Rust have a size_hint trick to do this. I don't know how we could do the same without over-complicating the language.