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!

Code: Select all

	for , l in List
		x:="abcd " l

Code: Select all

	for k in List
		x:="abcd " k
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,

Code: Select all

for , l in list
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

Code: Select all

for k, l in List
	x:=l
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:

Code: Select all

	for k, x in List
		continue

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 :wave:
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 :clap:. That is a point for you.

Thank you FanaticGuru for the explaination and sharing your function :thumbup:. 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,

Code: Select all

for k, x in List
	continue
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 :).

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 :) .

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 :wave: