Hmm interesting. Thanks for all replies. That was very educational.
On Wednesday, December 16, 2015 at 3:33:32 PM UTC-8, [email protected] wrote: > > > > On Thursday, December 17, 2015 at 4:07:37 AM UTC+10, Josh Langsfeld wrote: >> >> Using mutables in a Set or as keys in a Dict is not necessarily bad; it's >> changing them after they've been inserted that causes the chaos. Your 1785 >> "distinct" elements are all references to a single array object that is >> being continually mutated by the santa function. >> >> I'm not sure why there would be randomness in the number of elements, but >> would guess that something is being hashed on its memory location instead >> of its contents. I don't know what that would be though since hashes on >> arrays are a function of their values only. >> > > The Set contains only references to the array values, not copies, thats > why mutating them after adding them to the set screws things up. You can > see that by printing your resulting set, all the entries will have the same > value, the last one. So any new value compared to the value of an entry > with == will always succeed, its comparing the same array after all. > Therefore a value will only be added to the set if the hash of the new > value happens to fall on an empty slot in the underlying array, if it falls > on a used slot it will always compare equal and not be added. > > So the "randomness" depending on input just shows that hash is doing a > good job :) > > >> >> On Wednesday, December 16, 2015 at 12:22:06 AM UTC-5, Jan Strube wrote: >>> >>> So now we have Tomas saying that two arrays are not equal, even though >>> their contents are equal. >>> Kristoffer is saying that changing a mutable doesn't update the hash. >>> It looks like these two effects are competing when inserting into a Set. >>> In the game the input was 8192 directions. >>> Of those 2592 were distinct - the result of the string solution. >>> The version with arrays gave 1785 distinct elements in the Set. >>> >>> So sometimes, the hash definitely did get updated (most of the time in >>> fact). >>> I'm fine with the lesson that using mutables in a Set (or Dict) is a bad >>> idea, but I'd still like to understand what's going on here. In fact, the >>> array solution is not reproducible on my machine. Two runs give two >>> different numbers. >>> Where does this randomness come from? >>> >>> >>> >>> On Tuesday, December 15, 2015 at 1:09:54 PM UTC-8, Kristoffer Carlsson >>> wrote: >>>> >>>> The set is built as a number of key-value pairs of the hash and the >>>> object. When you modify the object the key that contains the hash does not >>>> get updated. A good reason not to put mutables in sets. >>>> >>>> On Tuesday, December 15, 2015 at 5:17:00 PM UTC+1, Josh Langsfeld wrote: >>>>> >>>>> I played with it a bit more and am seeing some unexpected behavior. If >>>>> you add a mutable element, change it, and then add another equal one, the >>>>> set gets two elements. But if you don't mutate the element, it stays at >>>>> one. >>>>> >>>>> julia> s = Set{Vector{Int}}() >>>>> Set{Array{Int64,1}}() >>>>> >>>>> julia> el = [1,2,3]; push!(s, el) >>>>> Set([[1,2,3]]) >>>>> >>>>> julia> push!(s, [1,2,3]) #Pushing a new array object, but the length >>>>> stays at 1. >>>>> Set([[1,2,3]]) >>>>> >>>>> julia> s = Set{Vector{Int}}() >>>>> Set{Array{Int64,1}}() >>>>> >>>>> julia> el = [1,2,3]; push!(s, el) >>>>> Set([[1,2,3]]) >>>>> >>>>> julia> el[1] = 10; @show s; #Mutate the set element from the outside >>>>> s = Set([[10,2,3]]) >>>>> >>>>> julia> push!(s, [10,2,3]) >>>>> Set([[10,2,3],[10,2,3]]) >>>>> >>>>> julia> length(s) >>>>> 2 >>>>> >>>>> julia> els = collect(s); els[1] == els[2] >>>>> true >>>>> >>>>> Is something buggy going on here? >>>>> >>>>> On Tuesday, December 15, 2015 at 10:57:31 AM UTC-5, Josh Langsfeld >>>>> wrote: >>>>>> >>>>>> It's not array equality that's the issue here. Arrays with the same >>>>>> elements are '==' (but not '==='). If you manually test pushing the same >>>>>> array to a Set you'll see it works fine. >>>>>> >>>>>> Jan, what happened is that your 'santa' function modifies and returns >>>>>> the same array that was passed in instead of creating a new one. So the >>>>>> only array that ever gets created is the first 'start = [0 0]' and it >>>>>> just >>>>>> gets continually modified, both in the santa function and in the set. >>>>>> Switching to a tuple works because you are forced to create a new tuple >>>>>> to >>>>>> change one of the elements. >>>>>> >>>>>> On Tuesday, December 15, 2015 at 3:32:40 AM UTC-5, Tomas Lycken wrote: >>>>>>> >>>>>>> Probably because the arrays will not be equal even if their contents >>>>>>> are equal (this is true of most mutable types in Julia). >>>>>>> >>>>>>> If you try representing a position as a tuple `(0,0)` instead of as >>>>>>> an array `[0,0]`, you'll find that it works as expected. >>>>>>> >>>>>>> // T >>>>>>> >>>>>>> On Tuesday, December 15, 2015 at 8:28:36 AM UTC+1, Jan Strube wrote: >>>>>>>> >>>>>>>> That's not a problem at all. In fact that's the very reason why I'm >>>>>>>> using a Set in the first place. >>>>>>>> >>>>>>>> My question is: Why is the number of entries in the set different >>>>>>>> when I add Arrays vs. adding ASCIIStrings? >>>>>>>> >>>>>>>> >>>>>>>> On Monday, December 14, 2015 at 10:57:57 PM UTC-8, [email protected] >>>>>>>> wrote: >>>>>>>>> >>>>>>>>> I think your problem is that Sets cannot contain duplicate >>>>>>>>> entries, so if Santa ever passes the same point twice it won't be >>>>>>>>> added. >>>>>>>>> >>>>>>>>> Cheers >>>>>>>>> Lex >>>>>>>>> >>>>>>>>> On Tuesday, December 15, 2015 at 4:23:19 PM UTC+10, Jan Strube >>>>>>>>> wrote: >>>>>>>>>> >>>>>>>>>> I'm trying to learn a bit more Julia by solving the puzzles over >>>>>>>>>> on http://adventofcode.com >>>>>>>>>> On day 3, the problem is to follow a number of directions and >>>>>>>>>> figure out how many new places you end up. >>>>>>>>>> http://adventofcode.com/day/3 >>>>>>>>>> >>>>>>>>>> I thought I can solve this simply by defining a set of [x y] >>>>>>>>>> positions, each time adding a new grid position to the set, so I'd >>>>>>>>>> end up >>>>>>>>>> with a Set{ Array{Int64,2}} of the right length. >>>>>>>>>> However, this doesn't work as expected. I get the wrong number >>>>>>>>>> (it's too low). >>>>>>>>>> >>>>>>>>>> Wrapping each grid position into a string() call, however, gives >>>>>>>>>> me the right answer. >>>>>>>>>> The explanation is a bit convoluted. To avoid spoilers I've put >>>>>>>>>> the code up at >>>>>>>>>> https://gist.github.com/jstrube/3d54e15f7d051b72032b >>>>>>>>>> >>>>>>>>>> I don't quite understand this. Is this expected? >>>>>>>>>> >>>>>>>>>>
