Page 4 of 8
Re: Code Puzzle Thread
Posted: 07 Dec 2017, 15:27
by rommmcek
Thanks for incentive!
Don't know if this is allowed, but it certainly doesn't break given rules and yields desired result!
P.s.: I got it already before, but I didn't think to this concatenation:
"abcd "
Re: Code Puzzle Thread
Posted: 07 Dec 2017, 16:37
by rommmcek
O.k., maybe I cheated (came in through not secured back door).
If so, let's go non plus ultra:
Code: Select all
for k in List
!x ? x:="abcd " A_Index-99 : ""
This is ~74% faster!
P.s.: I got it already before, but I didn't think to this concatenation!
Re: Code Puzzle Thread
Posted: 07 Dec 2017, 18:51
by Helgef
These methods break the function. Regarding,
it probably doesn't do what you think.
Cheers.
Re: Code Puzzle Thread
Posted: 08 Dec 2017, 02:26
by rommmcek
I know something is wrong, since it works only if I know the content of the
List.
Yes, you are right! I actually even don't understand why this
works! I just have a hunch that the function must somehow process the
x and
l in order to make comparison.
P.s.: I'm desperately waiting for the right solution and at least raw explanation, but of course let's wait if somebody else has an idea. Meanwhile I'll give a try now and then.
Re: Code Puzzle Thread
Posted: 08 Dec 2017, 13:03
by rommmcek
This is my best till now:
Re: Code Puzzle Thread
Posted: 11 Dec 2017, 08:04
by just me
Hi Helgef,
do you think about something like
Code: Select all
Min(List*)
{ ; https://autohotkey.com/boards/viewtopic.php?f=6&t=40898 by FanaticGuru
!(X := List[List.MaxIndex()]) ? List._NewEnum().Next( , X) : ""
for
the special case?
Edit: Modified to match the rules.
Re: Code Puzzle Thread
Posted: 11 Dec 2017, 08:24
by Helgef
Hello
just me, I'm happy to see you participate
I'm on the phone so I can't test, but it looks like it will achieve the goal, but it doesn't follow the rules, specifically
pop will modify the object refered to by the variable
list.
Cheers.
Re: Code Puzzle Thread
Posted: 11 Dec 2017, 08:28
by just me
Hi,
I missed that. I modified my post.
Re: Code Puzzle Thread
Posted: 11 Dec 2017, 13:59
by FanaticGuru
Here is my solution.
Code: Select all
Min(List*)
{ ; https://autohotkey.com/boards/viewtopic.php?f=6&t=40898 by FanaticGuru
Enum := List._NewEnum(), Enum.Next(Y), Enum.Next(,X)
for key, element in List ; This line is not allowed to be modified.
if (element < X) ; This line is not allowed to be modified.
X := element ; This line is not allowed to be modified.
return X
}
Basically you don't want X to be the first element in the List array because the first element is a huge string and you want to avoid comparing the first element to itself as that will be the comparision of two huge strings. This solution makes X the second element in the array which pretty much cuts the time by about 50% in this special case but has little impact plus or minus in most cases.
Here is a superior solution:
Code: Select all
Min(X:="�", List*) ; X := chr(0xffff)
{ ; https://autohotkey.com/boards/viewtopic.php?f=6&t=40898 by FanaticGuru
for key, element in List ; This line is not allowed to be modified.
if (element < X) ; This line is not allowed to be modified.
X := element ; This line is not allowed to be modified.
return X
}
This deletes one line entirely and changes the function parameters so that X is defined right from the get go. This cuts the time by about 75% in this special case and cuts the time significantly in all cases.
That X default is a special character. Basically a very high special character so that all characters and numbers are lower than the initial X. You need to save your file in an unicode encoding that will allow that special character. I use UTF-16 Little Endian but any UTF should work. The special character is a little bit of a pain but worth the universal improvement in the functions performance.
The superior solution is pretty much entirely the work of Helgef with my imput only being maybe inspiration.
FG
Re: Code Puzzle Thread
Posted: 11 Dec 2017, 14:17
by Helgef
Very good
just me ![Clapping :clap:](./images/smilies/icon_clap.gif)
. That is a point for you.
Thank you
FanaticGuru for the explaination and sharing your function
![Thumbup :thumbup:](./images/smilies/icon_thumbup.gif)
. Although it is implied by your explaination, I would like to emphasise that the huge compairsion also comes with the burden of making one huge string copy, which takes time.
Another example, showing the time spent on copying the data is, using
just me's solution as an example,
Code: Select all
Min(List) ; Removed *
{ ; https://autohotkey.com/boards/viewtopic.php?f=6&t=40898 by FanaticGuru
!(X := List[List.MaxIndex()]) ? List._NewEnum().Next( , X) : ""
for key, element in List ; This line is not allowed to be modified.
if (element < X) ; This line is not allowed to be modified.
X := element ; This line is not allowed to be modified.
return X
}
Min(p) ; Removed *
Here we aviod copying the string entirely, this breaks the rules ofc.
@ rommmcek, you where close, for example, this,
avoids the huge compairson, but does the copy. You could have done,
Code: Select all
for k in List
if (A_Index == 2)
break
X := List[k]
Finally, it is now
just me's privilige to provide the next puzzle, if
just me so pleases within some reasonable time frame.
Cheers.
Re: Code Puzzle Thread
Posted: 12 Dec 2017, 04:05
by rommmcek
Awesome tractates!
One think I still don't understand. Why count to two? Why not just simply use X:=List[2] instead?, knowing what is at the second place. And then why would X:="abcd 1" break the function? Any way I do understand this things a bit better now.
Bye!
P.s.: In FG's superior solution Min(X:="�", List*) for me works if I assign anything to X even X:=""?
Re: Code Puzzle Thread
Posted: 12 Dec 2017, 04:28
by just me
Hi Helgef,
I don't think I deserve the point. I didn't expect that copying a large string would cost so much time. I thought it was caused by the additional List._NewEnum() so i tried to avoid it, if possible. I was wrong. So my "solution" is pure coincidence.
Re: Code Puzzle Thread
Posted: 12 Dec 2017, 06:41
by Helgef
If anything, your honesty would award you an additional point
just me, the puzzle rules didn't demand an explaination, you have been added to the scoreboard. You will get one more if you supply the next puzzle
![Smile :)](./images/smilies/icon_e_smile.gif)
.
Also, you have an good point about the additional enumerator, it is a wasteful, it is possible to continue the for loop with the same enumerator, but any such solutions will probably come with a higher price than making a new.
@ rommmcek
Why not just simply use X:=List[2] instead?
The function must work for any input the original does, eg,
Min(1) will return blank if you do that. If you do
X:="abcd 1" and call the function like this,
Min("x","y") you will get back
"abcd 1" instead of
x.
works if I assign anything to X even X:=""?
The default value is not used when
X is assigned a value from the call, hence in those cases, it can be anything. When you call the function like
Min(AssociativeArray*) , and
AssociativeArray doesn't only have numeric keys like
1,2,... and lacks a key named
X, the
X parameter's default value is used, example,
Min({a:1,b:2}*) and
Min({a:1, x:0}*).
Cheers.
Re: Code Puzzle Thread
Posted: 12 Dec 2017, 14:01
by FanaticGuru
rommmcek wrote:Awesome tractates!
One think I still don't understand. Why count to two? Why not just simply use X:=List[2] instead?, knowing what is at the second place. And then why would X:="abcd 1" break the function? Any way I do understand this things a bit better now.
Bye!
P.s.: In FG's superior solution Min(X:="�", List*) for me works if I assign anything to X even X:=""?
As Helgef touched on the tricky part is associative arrays.
For example:
Code: Select all
List := {one:1, two:2}
MsgBox % List[2] ; this does not work as there is no key equal to "2", the only keys are "one" and "two"
This is the whole rigmarole with
_NewEnum(). How to get the second element of an array when you don't know the keys.
The
X:="�" is only to deal with associative arrays.
This might help to understand how the parameters are assigned values.
Code: Select all
Func1(1,2)
Func1(X:="�", List*)
{
MsgBox % X "`n" List[1]
}
Data := {one:1}
Func2(Data*)
Func2(X:="�", List*)
{
MsgBox % X "`n" List["one"]
}
In the first function, 1 goes into X as a simple variable and 2 goes into List as a simple array.
In the second function, Data associative array does not assign to X as it is not set up to accept an array so X defaults to � and all the passed info from Data gets assigned to List as an associative array.
In both functions no matter what List is going to be an array of information even if it ends up
List := {} with nothing in it.
FG
Re: Code Puzzle Thread
Posted: 13 Dec 2017, 16:18
by rommmcek
Thanks Helgef and special acknowledgment this time to FG!
Maybe these were still not the last stones in my array mosaic, but very precious ones for sure!
Re: Code Puzzle Thread
Posted: 05 Jan 2018, 14:44
by Helgef
Puzzle 9: Release the bug.
In this puzzle we shall look at a benchmarking script which contains a significant error, which causes incorrect results for the last test snippet. The test measures the time it takes to free
count := 50000 instances of the class
Task. All instances are stored
internally in the array
Task.List, hence in order to invoke
__delete they must be removed from this array.
Puzzle objectives: Correct the significant mistake in the benchmarking script in the code box below.
Puzzle rules: You are not allowed to modify the class
Task. You must be able to explain the mistake, hence, why your solution works.
Puzzle hint: When you correct the mistake, you can expect the last test snippet to be significantly faster. Edit: When you correct the mistake, you can expect the last test to work as intended.
Code:
The code comes from this discussion:
[BUG]Associative Arrays, you are not required to read the discussion to solve the problem. Reading others' code and debug it can be very challenging, I consider that part of this puzzle and therefore I have not removed any noise from the code.
Code: Select all
; https://autohotkey.com/boards/viewtopic.php?f=37&t=42328
; [BUG]Associative Arrays
setbatchlines,-1
#noenv
class Task {
static time:= 0
static tick:= 0
static List:= []
__new(name, mode:= 0x13) {
this.mode:= mode
this.name:= name
Task.List[this]:= "" ;no value for key
}
end() { ;initate destruct
if !Task.time
Task.time:= A_TickCount
Task.List.Delete(this) ;self kill
}
;Task.List.Delete(this)
;Task.List:= ""
__delete() { ;destruct idea by Helgef
if !Task.time
Task.time:= A_TickCount
this.name:= ""
Task.tick:= A_TickCount - Task.time
}
}
result:= ""
count:= 50000
; SLOW -----------------------------------------------
loop % count
new Task("name" A_Index)
Task.time:= ""
SLOW:
for key in Task.List {
key.end()
goto SLOW
}
key:=""
msgBOX(result.= "SLOW`t:= " Task.tick "`n")
; FAST -----------------------------------------------
array:= []
loop % count
new Task("name" A_Index)
Task.time:= ""
for key in Task.List
array[A_Index]:= key
loop % array.length()
array[A_Index].end()
array:= ""
key:=""
msgBOX(result.= "FAST`t:= " Task.tick "`n")
; ENUM -----------------------------------------------
loop % count
new Task("name" A_Index)
Task.time:= ""
while (_enum:= Task.List._newEnum()).Next(key, val) {
loop {
key.end()
} until !_enum.Next(key, val)
}
key:=""
msgBOX(result.= "ENUM`t:= " Task.tick "`n")
; LOOP -----------------------------------------------
loop % count
new Task("name" A_Index)
Task.time:= ""
loop {
isEmpty:= 1
for key in Task.List {
key.end()
isEmpty:= 0
}
} until isEmpty
key:="" ; <-- edit: conversion mistake fixed
msgBOX(result.= "LOOP`t:= " Task.tick "`n")
; Helgef ---------------------------------------------
loop % count
new Task("name" A_Index)
Task.time:= ""
Task.List:= [] ;Task.List:= "" change type from Array to string if further use
msgBOX("Wait for Helgef",, "2") ;this 2 seconds is out of tick (destruction in background)
msgBOX(result.= "HELL`t:= " Task.tick "`n")
msgBOX(a,b:="",c:=""){
msgbox,,,% a, % c
}
The code has been converted from v2 to v1, if you spot a mistake in that regard please tell.
Good luck.
Re: Code Puzzle Thread
Posted: 06 Jan 2018, 06:44
by just me
Hi Helgef,
I'd say
Puzzle hint: When you correct the mistake, you can expect the last test to work as intended.
Re: Code Puzzle Thread
Posted: 06 Jan 2018, 06:53
by Helgef
Hello
just me, that is correct
![Smile :)](./images/smilies/icon_e_smile.gif)
.
Cheers.
Re: Code Puzzle Thread
Posted: 08 Jan 2018, 07:16
by just me
Another hint: If you compare the results of the LOOP and Helgef sections, you'll see that they are always equal.
Re: Code Puzzle Thread
Posted: 08 Jan 2018, 13:58
by Helgef
How is it going
just me? I thought you had solved it when you corrected my hint. Your new hint is correct, but is it a good hint?
Anyways, I have corrected a small
conversion error, it is not significant for the puzzle though. I also updated the first post to indicate the current puzzle.
Good luck, have fun
![Waving :wave:](./images/smilies/icon_wave.gif)