* advent of code day 11 @ 2020-12-11 17:07 Stephen Leake 2020-12-11 18:24 ` John Perry 0 siblings, 1 reply; 10+ messages in thread From: Stephen Leake @ 2020-12-11 17:07 UTC (permalink / raw) mildly interesting; variation on Conway's Game of Life. -- -- Stephe ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: advent of code day 11 2020-12-11 17:07 advent of code day 11 Stephen Leake @ 2020-12-11 18:24 ` John Perry 2020-12-11 19:07 ` Jeffrey R. Carter ` (2 more replies) 0 siblings, 3 replies; 10+ messages in thread From: John Perry @ 2020-12-11 18:24 UTC (permalink / raw) On Friday, December 11, 2020 at 11:08:00 AM UTC-6, Stephen Leake wrote: > mildly interesting; variation on Conway's Game of Life. I recognized that, too. A solution should not be hard to parallelize, and I'd like to, but for now I have other tasks. (no pun intended, well, OK yes it was) Here's a couple of questions for the Ada experts. For each round I used two charts, a source and a result. These are arrays, defined like so: type Status is ( Floor, Empty, Occupied ); type Chart_Array is array( Positive range <> , Positive range <> ) of Status; Chart1, Chart2: Chart_Array; -- actually defined with appropriate dimensions A procedure named `Iterate_Seating` applies the given rules to a Chart_Array; an `if` statement determines which iterates into the other. I thought it would be clearer to use references to switch from one chart to the other, but I had trouble doing that last night. Now I can get it this way: Source: Chart_Array renames Chart1; Result: Chart_Array renames Chart2; while Changed loop Perform_Round( Source => Source , Result => Result , ... ); declare Tmp: Chart_Array renames Source; begin Source := Result; Result := Tmp; end; end loop; Does this technique swap references, or does it copy the arrays element-by-element? The run times are the same even if I compel a copy operation; I suppose it's because the arrays aren't large enough, and there aren't enough copies, to make a difference. thanks john perry ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: advent of code day 11 2020-12-11 18:24 ` John Perry @ 2020-12-11 19:07 ` Jeffrey R. Carter 2020-12-11 19:29 ` gautier...@hotmail.com 2020-12-12 20:27 ` Stephen Leake 2 siblings, 0 replies; 10+ messages in thread From: Jeffrey R. Carter @ 2020-12-11 19:07 UTC (permalink / raw) On 12/11/20 7:24 PM, John Perry wrote: > > Source: Chart_Array renames Chart1; > Result: Chart_Array renames Chart2; > > while Changed loop > > Perform_Round( Source => Source , Result => Result , ... ); > declare Tmp: Chart_Array renames Source; > begin > Source := Result; > Result := Tmp; Renaming simply creates an additional way to name something. This should be the same as Chart1 := Chart2; Chart2 := Chart1; -- Jeff Carter "[I]f we should ever separate, my little plum, I want to give you one little bit of fatherly advice. ... Never give a sucker an even break." Poppy 97 ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: advent of code day 11 2020-12-11 18:24 ` John Perry 2020-12-11 19:07 ` Jeffrey R. Carter @ 2020-12-11 19:29 ` gautier...@hotmail.com 2020-12-11 19:35 ` gautier...@hotmail.com ` (2 more replies) 2020-12-12 20:27 ` Stephen Leake 2 siblings, 3 replies; 10+ messages in thread From: gautier...@hotmail.com @ 2020-12-11 19:29 UTC (permalink / raw) > Perform_Round( Source => Source , Result => Result , ... ); > declare Tmp: Chart_Array renames Source; > begin > Source := Result; > Result := Tmp; > end; To complete Jeff's answer, what you are doing is not a swap: it's equivalent to Source := Result; Result := Source; Ooops. The ":=" makes a complete copy of the arrays. So you'd need above "Tmp : Chart_Array := Source" to have a correct swap with 3 copies. Of course it feels a bit heavy to make all those copies. And you understandably want to avoid playing with pointers. So a solution is to define: Map : array (0 .. 1) of Chart_Array; ... current := 0; loop next := 1 - current; Perform_Round( Source => Map (current), Result => Map (next) , ... ); current := next; end loop; ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: advent of code day 11 2020-12-11 19:29 ` gautier...@hotmail.com @ 2020-12-11 19:35 ` gautier...@hotmail.com 2020-12-11 22:40 ` Jeffrey R. Carter 2020-12-11 23:49 ` John Perry 2 siblings, 0 replies; 10+ messages in thread From: gautier...@hotmail.com @ 2020-12-11 19:35 UTC (permalink / raw) Full example in 2 flavours: https://github.com/zertovitch/hac/blob/master/exm/aoc/2020/aoc_2020_11_full_ada.adb (full Ada only) https://github.com/zertovitch/hac/blob/master/exm/aoc/2020/aoc_2020_11.adb (HAC & full Ada) ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: advent of code day 11 2020-12-11 19:29 ` gautier...@hotmail.com 2020-12-11 19:35 ` gautier...@hotmail.com @ 2020-12-11 22:40 ` Jeffrey R. Carter 2020-12-11 23:45 ` John Perry 2020-12-11 23:49 ` John Perry 2 siblings, 1 reply; 10+ messages in thread From: Jeffrey R. Carter @ 2020-12-11 22:40 UTC (permalink / raw) On 12/11/20 8:29 PM, gautier...@hotmail.com wrote: > > So you'd need above "Tmp : Chart_Array := Source" to have a correct swap with 3 copies. > Of course it feels a bit heavy to make all those copies. And you understandably want to avoid playing with pointers. So a solution is to define: > Map : array (0 .. 1) of Chart_Array; > ... > current := 0; > loop > next := 1 - current; > Perform_Round( Source => Map (current), Result => Map (next) , ... ); > current := next; > end loop; I don't see a need for a swap, or to avoid copying. I did Current : Floorplan := Read; Future : Floorplan := (others => (others => Floor) ); ... All_Rounds : loop for R in ... loop for S in ... loop if Current (R, S) /= Floor then -- It's a seat Future (R, S) := Next_State (Current (R, S), Num_Occupied (Current, R, S) ); end if; -- else Future (R, S) = Floor end loop; end loop; exit All_Rounds when Current = Future; Current := Future; end loop All_Rounds; which took 34 ms, well within the timing requirements for the problem. -- Jeff Carter "[I]f we should ever separate, my little plum, I want to give you one little bit of fatherly advice. ... Never give a sucker an even break." Poppy 97 ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: advent of code day 11 2020-12-11 22:40 ` Jeffrey R. Carter @ 2020-12-11 23:45 ` John Perry 0 siblings, 0 replies; 10+ messages in thread From: John Perry @ 2020-12-11 23:45 UTC (permalink / raw) On Friday, December 11, 2020 at 4:40:51 PM UTC-6, Jeffrey R. Carter wrote: > I don't see a need for a swap, or to avoid copying. I did > > Current : Floorplan := Read; > Future : Floorplan := (others => (others => Floor) ); > ... > > Current := Future; > end loop All_Rounds; > > which took 34 ms, well within the timing requirements for the problem. I agree it's not needed in this case. I raised the question simply because I'd like to know how it could be done in cases where it might well be important to save the time. I've sometimes shaved significant percentages of running time off programs by doing nothing more than avoiding copying arrays. ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: advent of code day 11 2020-12-11 19:29 ` gautier...@hotmail.com 2020-12-11 19:35 ` gautier...@hotmail.com 2020-12-11 22:40 ` Jeffrey R. Carter @ 2020-12-11 23:49 ` John Perry 2020-12-12 9:38 ` Maxim Reznik 2 siblings, 1 reply; 10+ messages in thread From: John Perry @ 2020-12-11 23:49 UTC (permalink / raw) On Friday, December 11, 2020 at 1:29:58 PM UTC-6, gautier...@hotmail.com wrote: > The ":=" makes a complete copy of the arrays. That's what I was afraid of. > Of course it feels a bit heavy to make all those copies. And you understandably want to avoid playing with pointers. Exactly! So a solution is to define: > Map : array (0 .. 1) of Chart_Array; > ... > current := 0; > loop > next := 1 - current; > Perform_Round( Source => Map (current), Result => Map (next) , ... ); > current := next; > end loop; This is a nice alternative, thanks. ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: advent of code day 11 2020-12-11 23:49 ` John Perry @ 2020-12-12 9:38 ` Maxim Reznik 0 siblings, 0 replies; 10+ messages in thread From: Maxim Reznik @ 2020-12-12 9:38 UTC (permalink / raw) Perhaps you might be interested in using generics for this solution https://github.com/reznikmm/ada-howto/blob/advent-2020/md/11/11.md ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: advent of code day 11 2020-12-11 18:24 ` John Perry 2020-12-11 19:07 ` Jeffrey R. Carter 2020-12-11 19:29 ` gautier...@hotmail.com @ 2020-12-12 20:27 ` Stephen Leake 2 siblings, 0 replies; 10+ messages in thread From: Stephen Leake @ 2020-12-12 20:27 UTC (permalink / raw) John Perry <john.perry@usm.edu> writes: > On Friday, December 11, 2020 at 11:08:00 AM UTC-6, Stephen Leake wrote: >> mildly interesting; variation on Conway's Game of Life. > > I thought it would be clearer to use references to switch from one > chart to the other, but I had trouble doing that last night. Now I can > get it this way: > > Source: Chart_Array renames Chart1; > Result: Chart_Array renames Chart2; A 'renames' declaration creates a _static_ name for the object that is the result of the expression; the expression is evaluated once when the 'renames' declaration is evaluated. When the name is used, it is the same as any other object name. > while Changed loop > > Perform_Round( Source => Source , Result => Result , ... ); > declare Tmp: Chart_Array renames Source; 'Tmp' is evaluated each time around the loop, but since the global Source is static, it always has the same value of Chart1. > begin Source := Result; This does not revaluate the expression for global Source; it uses the global Source name to determine where to store a copy of Result. -- -- Stephe ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2020-12-12 20:27 UTC | newest] Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2020-12-11 17:07 advent of code day 11 Stephen Leake 2020-12-11 18:24 ` John Perry 2020-12-11 19:07 ` Jeffrey R. Carter 2020-12-11 19:29 ` gautier...@hotmail.com 2020-12-11 19:35 ` gautier...@hotmail.com 2020-12-11 22:40 ` Jeffrey R. Carter 2020-12-11 23:45 ` John Perry 2020-12-11 23:49 ` John Perry 2020-12-12 9:38 ` Maxim Reznik 2020-12-12 20:27 ` Stephen Leake
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox