Hi Helgef,
yes, I think I solved it, but I'm waiting for others who might jump in (because I won't contribute a new puzzle).
My last hint has been my personal key to solve the problem.
Code Puzzle Thread
Forum rules
Discuss Autohotkey related topics here. Not a place to share code.
Discuss Autohotkey related topics here. Not a place to share code.
Re: Code Puzzle Thread
. submitting new puzzles aren't mandatory, you are welcome to submit your solution whenever you like.
Cheers .
Cheers .
Re: Code Puzzle Thread
And the answer is: 42!
Athough it should always be true, it's obviously not true in this case. I tried without success. After that I noticed, that the LOOP and the Helgef sections always give the same result, regardless of the value in Count. So I added Task.tick := 0 above Task.List:= []. The Helgef section was indeed 'significant faster' after doing this: 0 ms for 50,000 Task instances, WOW!
This seemed to be a little too fast. I realized that Task.tick isn't touched by Task.List:= [] at all. From this follows that Task.__delete() is not called. The only reason for this behaviour is: The objects are not released because 'something' still holds a reference. Some thoughts later I found this 'something'. It's the enumerator object created by while (_enum:= Task.List._newEnum()) in the ENUM section. So the real answer is:
Due to my limited knowledge about OOP and the AHK implementation details my explanation might be technically imprecise, but the solution is working.
Cheers .
Athough it should always be true, it's obviously not true in this case. I tried without success. After that I noticed, that the LOOP and the Helgef sections always give the same result, regardless of the value in Count. So I added Task.tick := 0 above Task.List:= []. The Helgef section was indeed 'significant faster' after doing this: 0 ms for 50,000 Task instances, WOW!
This seemed to be a little too fast. I realized that Task.tick isn't touched by Task.List:= [] at all. From this follows that Task.__delete() is not called. The only reason for this behaviour is: The objects are not released because 'something' still holds a reference. Some thoughts later I found this 'something'. It's the enumerator object created by while (_enum:= Task.List._newEnum()) in the ENUM section. So the real answer is:
Code: Select all
; 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:=""
_enum := "" ; <<<<< added
msgBOX(result.= "ENUM`t:= " Task.tick "`n")
Cheers .
Re: Code Puzzle Thread
You are spot on just me, both in regards to reasoning, explaination and solution, great job . You will be rewarded a point.
Since just me already declined the offer to submit a new puzzle, it is free for anyone who likes to, to do so.
Cheers.
Since just me already declined the offer to submit a new puzzle, it is free for anyone who likes to, to do so.
Cheers.
Re: Code Puzzle Thread
Yep my mistake.just me wrote:_enum := "" ; <<<<< added
Cheers .
Code: Select all
class Task {
static time:= 0
static tick:= 0
static List:= []
__new(name, mode:= 0x13) {
this.mode:= mode
this.name:= name
Task.List[this]:= ""
}
static end:= func("__Task_end")
__delete() { ;destruct idea by Helgef
if !Task.time
Task.time:= A_TickCount
if this.mode != "" { ;prevent second run
;on destruct actions <<< ---------------------------------- ;
this.mode:= this.name:= "" ;clear to prevent second run ;
} ;
Task.tick:= A_TickCount - Task.time ;
} } ;
__Task_end(byRef this) { ;
if !Task.time ;
Task.time:= A_TickCount ;
this.__delete() ; forced call on destruct actions <<< --- ;
Task.List.Delete(this) ; remove reference from Task.List
this:= "" ;if no more references <<< destruct
}
result:= ""
count:= 50000
;count:= 20
; LOOP -----------------------------------------------
loop count
new Task("name" A_Index)
Task.time:= ""
while !isEmpty { ;just less code but the same
isEmpty:= 0
for key in Task.List {
key.end()
isEmpty:= 1
} }
msgBOX(result.= "LOOP`t:= " Task.tick "`n") ;<<< 1391
; Helgef ---------------------------------------------
loop count
new Task("name" A_Index)
Task.time:= "" ;Task.time:= 0 (the same)
Task.List:= []
;next line is needed to become destruction ready
;there count times calling of Task.__delete()
;but the fastest way
msgBOX("Wait for Helgef",, "T1") ;1 seccond enough
msgBOX(result.= "HELL`t:= " Task.tick "`n") ;<<< 234 (fastest)
AHKv2.0 alpha forever.
-
- Posts: 1
- Joined: 24 Jan 2018, 01:57
- Contact:
Re: Code Puzzle Thread
I was also waiting for the 3D formula to apply in the game.
Re: Code Puzzle Thread
Puzzle:
Goals:
Disconnect the Proxy from the Target
Restrictions:
You may not edit the underlying object in memory with numput/get or similar.
You may only add new code in the marked area.
Goals:
Disconnect the Proxy from the Target
Restrictions:
You may not edit the underlying object in memory with numput/get or similar.
You may only add new code in the marked area.
Code: Select all
;add code here
;don't edit the code below
class Proxy {
__New() {
static init := new Proxy()
if init
return init
Proxy := this
}
__Call( fn, p* ){
return Target[fn]( p* )
}
__Set( p* ) {
value := p.pop()
return Target[p*] := value
}
__Get( p* ){
return Target[p*]
}
}
class Target {
__New() {
static init := new Target()
if init
return init
Target := this
this.val := 13
}
test() {
Msgbox Hello World!
}
}
Recommends AHK Studio
Re: Code Puzzle Thread
Thank you nnnik, I will mark this as the current puzzle. You will get one point for submitting a new puzzle.
Cheers.
Cheers.
Re: Code Puzzle Thread
This puzzle strikes my interest, but only in that I would like to learn more about classes. So I can't solve it :(
try it and see
...
...
Re: Code Puzzle Thread
It seems nnnik's puzzle remains unsolved, great . Maybe it is time for a hint?
I have posted a bonus puzzle here, if someone wants to ponder it, it assumes some understanding of c/c++ so it is not fit for this thread.
Cheers
I have posted a bonus puzzle here, if someone wants to ponder it, it assumes some understanding of c/c++ so it is not fit for this thread.
Cheers
Re: Code Puzzle Thread
I think it is time for a new puzzle, I leave it open to anyone who likes to submit one to do so, please see the rules in the first post and do not hesitate to ask me (via pm) if you have any questions.
This is my (pre-1.1.29.00) suggestion for a solution to nnnik's puzzle,
Cheers.
This is my (pre-1.1.29.00) suggestion for a solution to nnnik's puzzle,
Code: Select all
;add code here
objrawset(f(), "__set", "")
objrawset(f(), "__get", "")
objrawset(f(), "__call", "")
f(){
static b := proxy
return b
}
;don't edit the code below
Re: Code Puzzle Thread
Well I really searched for a solution myself for quite a while as it was a problem that I couldnt solve myself.
I was rather impressed at the speed he came up with the solution.
Also while Helgefs solution solves this riddle but does not solve the underlying problem for me since the underlying problem does not allow the addition of a static initialisation by writing a new function.
In AHK v1.1.29.00 you can use ObjGetBase and ObjSetBase to solve this.
I was rather impressed at the speed he came up with the solution.
Also while Helgefs solution solves this riddle but does not solve the underlying problem for me since the underlying problem does not allow the addition of a static initialisation by writing a new function.
In AHK v1.1.29.00 you can use ObjGetBase and ObjSetBase to solve this.
Recommends AHK Studio
Re: Code Puzzle Thread
Puzzle 11
Puzzle objectives:
Recreate the built in functions numget and numput. The important point is to be able to correctly write and read any of the number types the built-in functions can, you do not need to consider parameter validation and you can assume all parameters are passed if you like.
Puzzle rules:
You are not allowed to call any external API functions other than this,
You are not allowed to use a file object. You may give your answer in either v1 or v2 code. You may write any number of help functions. Your functions should work on both 32 bit and 64 bit.
For reference, this question was asked here: read byte via DllCall. This topic is not supposed to be a hint.
Edit, hint .
Update:
jeeswg gave a partial solution here. I still accept other solutions, see comments here.
Cheers.
Puzzle objectives:
Recreate the built in functions numget and numput. The important point is to be able to correctly write and read any of the number types the built-in functions can, you do not need to consider parameter validation and you can assume all parameters are passed if you like.
Puzzle rules:
You are not allowed to call any external API functions other than this,
Code: Select all
memcpy(dest, src, count){
/*
void *memcpy(
void *dest,
const void *src,
size_t count
);
url: https://msdn.microsoft.com/en-us/library/dswaw1wk.aspx (memcpy)
*/
return dllcall("MSVCRT.dll\memcpy", "ptr", dest, "ptr", src, "ptr", count, "cdecl")
}
For reference, this question was asked here: read byte via DllCall. This topic is not supposed to be a hint.
Edit, hint .
Update:
jeeswg gave a partial solution here. I still accept other solutions, see comments here.
Cheers.
Last edited by Helgef on 04 Feb 2019, 04:23, edited 3 times in total.
Re: Code Puzzle Thread
I forgot to tell you cannot use file objects.
Re: Code Puzzle Thread
Hello .
Did someone attempt to solve puzzle 11? Please comment if something is unclear. I will give a hint, the solution does not need to involve very much code, actually, quite few lines are needed.
I came up with a (quite simple) puzzle, it requires some basic knowledge of C so this just a bonus puzzle, solving it rewards you only with a bonus point . Also, the one which writes the fastest version will get a point.
Bonus puzzle.
Description: You are working on a computation heavy application and need to improve performance, your computations involve large amounts of calls to this function,
You ask your friend John for advice and he tells you about a function which approximates this result sufficiently well, which he have used in one of his project with good result, he gives you this C function: Q_rsqrt.
Puzzle objectives: Implement the function Q_rsqrt in AHK and optimise it as much as you can with all tricks you know. Compare the (speed) performance to the more accurate function rsqrt and report your code, test results and conclusions. You are welcome to use both v1 and v2.
Edit, edited wrong post...
Cheers.
Did someone attempt to solve puzzle 11? Please comment if something is unclear. I will give a hint, the solution does not need to involve very much code, actually, quite few lines are needed.
I came up with a (quite simple) puzzle, it requires some basic knowledge of C so this just a bonus puzzle, solving it rewards you only with a bonus point . Also, the one which writes the fastest version will get a point.
Bonus puzzle.
Description: You are working on a computation heavy application and need to improve performance, your computations involve large amounts of calls to this function,
Code: Select all
rsqrt(x) {
return 1/sqrt(x)
}
Puzzle objectives: Implement the function Q_rsqrt in AHK and optimise it as much as you can with all tricks you know. Compare the (speed) performance to the more accurate function rsqrt and report your code, test results and conclusions. You are welcome to use both v1 and v2.
Edit, edited wrong post...
Cheers.
Last edited by Helgef on 27 Jan 2019, 05:00, edited 2 times in total.
Re: Code Puzzle Thread
Re. Puzzle 11. Something like this? Cheers.
Code: Select all
;AHK v1 script
;'PuzGet'/'PuzPut' - recreate NumGet/NumPut functionality (minus Float/Double functionality)
;where 'Puz' refers to 'Code Puzzle Thread'
w:: ;test PuzPut and PuzGet functions
VarSetCapacity(vData1, 8, 0)
VarSetCapacity(vData2, 8, 0)
NumPut(-12345678, &vData1, "Int")
PuzPut(-12345678, &vData2, "Int")
MsgBox, % NumGet(&vData1, "Int")
MsgBox, % NumGet(&vData2, "Int")
MsgBox, % PuzGet(&vData1, "Int")
return
q:: ;test PuzPut and PuzGet functions
oType := StrSplit("Char,Short,Int,Int64,Ptr,UChar,UShort,UInt,UInt64,UPtr", ",")
VarSetCapacity(vData1, 8)
VarSetCapacity(vData2, 8)
Loop, 10000
{
Random, vNum, -2147483648, 2147483647
vNum *= 256**3
Random, vTemp, 1, % oType.Length()
vType := oType[vTemp]
NumPut(vNum, &vData1, vType)
PuzPut(vNum, &vData2, vType)
vNum1 := NumGet(&vData1, vType)
vNum2 := NumGet(&vData2, vType)
vNum1X := PuzGet(&vData1, vType)
vHex1 := Format("0x{:X}", vNum1)
vHex2 := Format("0x{:X}", vNum2)
vHex1X := Format("0x{:X}", vNum1X)
;if 0
if !(vNum1 = vNum2)
;if !InStr(vType, "Int64")
MsgBox, % "put`r`n" "index: " A_Index "`r`n" vType "`r`n" vNum1 "`r`n" vNum2 "`r`n" vHex1 "`r`n" vHex2
;if 0
if !(vNum1 = vNum1X)
MsgBox, % "get`r`n" "index: " A_Index "`r`n" vType "`r`n" vNum1 "`r`n" vNum1X "`r`n" vHex1 "`r`n" vHex1X
}
MsgBox, % "done"
return
;==================================================
PuzGet(vAddr, vType:="UPtr")
{
local
static oChar, oType := {Char:1, Short:2, Int:4, Int64:8, Ptr:A_PtrSize=8?8:4}
static vIsReady := 0
if !vIsReady
{
oChar := {0:0}
VarSetCapacity(vData, 1, 0)
Loop, 255
PuzPut(A_Index, &vData, "UChar")
, vOrd := Ord(StrGet(&vData, 1, "CP0"))
, oChar[vOrd] := A_Index
vIsReady := 1
}
vIsSigned := !RegExMatch(vType, "i)^U")
vSize := oType[RegExReplace(vType, "i)^U")]
vNum := 0
Loop, % vSize
vNum |= oChar[Ord(StrGet(vAddr+A_Index-1, 1, "CP0"))] << (A_Index*8-8)
if vIsSigned
if (vSize = 1) && (vNum >= 128)
return vNum - 256
else if (vSize = 2) && (vNum >= 32768)
return vNum - 65536
else if (vSize = 4) && (vNum >= 2147483648)
return vNum - 4294967296
return vNum
}
PuzPut(vNum, vAddr, vType:="UPtr")
{
local
static oChar, oType := {Char:1, Short:2, Int:4, Int64:8, Ptr:A_PtrSize=8?8:4}
static vIsReady := 0, vDataNull := 0
if !vIsReady
{
;oChar := {0:""}
oChar := {}
VarSetCapacity(vDataNull, 1, 0)
Loop, 255
oChar[A_Index] := Chr(A_Index)
vIsReady := 1
}
vSize := oType[RegExReplace(vType, "i)^U")]
Loop, % Min(vSize, 7)
vTemp := vNum & (0xFF << (A_Index*8-8))
, vTemp >>= (A_Index*8-8)
, (vTemp=0) ? memcpy(vAddr+A_Index-1, &vDataNull, 1) : memcpy(vAddr+A_Index-1, oChar.GetAddress(vTemp), 1)
;0xFF00000000000000 (UInt64) = (0xFF00000000000000 - 0x10000000000000000) (Int64) = -0x100000000000000 (Int64)
if (vSize = 8)
vTemp := SubStr(Format("0x{:016X}", vNum & -0x100000000000000), 1, 4)
, (vTemp=0) ? memcpy(vAddr+7, &vDataNull, 1) : memcpy(vAddr+7, oChar.GetAddress(vTemp), 1)
}
memcpy(dest, src, count){
/*
void *memcpy(
void *dest,
const void *src,
size_t count
);
url: https://msdn.microsoft.com/en-us/library/dswaw1wk.aspx (memcpy)
*/
return dllcall("MSVCRT.dll\memcpy", "ptr", dest, "ptr", src, "ptr", count, "cdecl")
}
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Re: Code Puzzle Thread
Hello jeeswg . Thank you for participating. Your code seems fine for your test cases, well done, but float and double are also required.
Great function names .
Cheers.
Great function names .
Cheers.
Re: Code Puzzle Thread
I will specify a little on the hint for puzzle 11, my v2 solution is 21 lines, without parameter verification, and without trying to make it short, also not counting memcpy. V1 will require just a few lines more. You can make it as long as you like though.
Re: Code Puzzle Thread
- I've added support for Floats and Doubles.
- Note: the script is now for AHK v2.
- Haha cheers re. the function names.
- Note: the script is now for AHK v2.
Code: Select all
;AHK v2 script
;'PuzGet'/'PuzPut' - recreate NumGet/NumPut functionality
;where 'Puz' refers to 'Code Puzzle Thread'
;note: when converting from/to Floats,
;the fractions could be *fractionally* different,
;although the tests show the expected accuracy
;note: the maths of handling the raw binary data
;of the Floats is very fiddly, so errors are possible
;AHK v2 is used because you can convert from/to Doubles
;by using the address of a variable
w:: ;test PuzPut and PuzGet functions
VarSetCapacity(vData1, 8, 0)
VarSetCapacity(vData2, 8, 0)
NumPut(-12345678, &vData1, "Int")
PuzPut(-12345678, &vData2, "Int")
MsgBox(NumGet(&vData1, "Int"))
MsgBox(NumGet(&vData2, "Int"))
MsgBox(PuzGet(&vData1, "Int"))
return
q:: ;test PuzPut and PuzGet functions
;oType := StrSplit("Char,Short,Int,Int64,Ptr,UChar,UShort,UInt,UInt64,UPtr", ",")
;oType := StrSplit("Char,Short,Int,Int64,Ptr,UChar,UShort,UInt,UInt64,UPtr,Float,Double", ",")
oType := StrSplit("Float,Double", ",")
VarSetCapacity(vData1, 8)
VarSetCapacity(vData2, 8)
Loop 10000
{
vNum := Random(-2147483648, 2147483647)
vNum *= 256**3
vTemp := Random(1, oType.Length())
vType := oType[vTemp]
NumPut(vNum, &vData1, vType)
PuzPut(vNum, &vData2, vType)
vNum1 := NumGet(&vData1, vType)
vNum2 := NumGet(&vData2, vType)
vNum1X := PuzGet(&vData1, vType)
vHex1 := Format("0x{:X}", vNum1)
vHex2 := Format("0x{:X}", vNum2)
vHex1X := Format("0x{:X}", vNum1X)
;if 0
if !(vNum1 = vNum2)
;if !InStr(vType, "Int64")
MsgBox("put`r`n" "index: " A_Index "`r`n" vType "`r`n" vNum1 "`r`n" vNum2 "`r`n" vHex1 "`r`n" vHex2)
;if 0
if !(vNum1 = vNum1X)
MsgBox("get`r`n" "index: " A_Index "`r`n" vType "`r`n" vNum1 "`r`n" vNum1X "`r`n" vHex1 "`r`n" vHex1X)
}
MsgBox("done")
return
;==================================================
PuzGet(vAddr, vType:="UPtr")
{
local
static oChar, oType := {Char:1, Short:2, Int:4, Int64:8, Ptr:A_PtrSize=8?8:4}
static vIsReady := 0
if !vIsReady
{
oChar := {0:0}
VarSetCapacity(vData, 1, 0)
Loop 255
PuzPut(A_Index, &vData, "UChar")
, vOrd := Ord(StrGet(&vData, 1, "CP0"))
, oChar[vOrd] := A_Index
vIsReady := 1
}
if (vType = "Double")
{
vData := 0.0
memcpy(&vData, vAddr, 8)
return vData
}
if (vType = "Float")
{
vNum := PuzGet(vAddr+0, "UInt")
vSign := !!(vNum & 0x80000000)
vPow := ((vNum & 0x7F800000) >> 23)
vNum := vNum & 0x7FFFFF
if (vPow = 255)
vPow := 2047
else if (vPow > 0)
vPow := (vPow - 127 + 1023)
;else if (vPow = 0)
; vPow := 0
vNum <<= (52-23)
vTemp := (vSign ? -0x8000000000000000 : 0) | (vPow << 52) | vNum
VarSetCapacity(vData, 8)
PuzPut(vTemp, &vData, "Int64")
return PuzGet(&vData, "Double")
}
vIsSigned := !RegExMatch(vType, "i)^U")
vSize := oType[RegExReplace(vType, "i)^U")]
vNum := 0
Loop vSize
vNum |= oChar[Ord(StrGet(vAddr+A_Index-1, 1, "CP0"))] << (A_Index*8-8)
if vIsSigned
if (vSize = 1) && (vNum >= 128)
return vNum - 256
else if (vSize = 2) && (vNum >= 32768)
return vNum - 65536
else if (vSize = 4) && (vNum >= 2147483648)
return vNum - 4294967296
return vNum
}
PuzPut(vNum, vAddr, vType:="UPtr")
{
local
static oChar, oType := {Char:1, Short:2, Int:4, Int64:8, Ptr:A_PtrSize=8?8:4}
static vIsReady := 0, vDataNull := 0
if !vIsReady
{
;oChar := {0:""}
oChar := {}
VarSetCapacity(vDataNull, 1, 0)
Loop 255
oChar[A_Index] := Chr(A_Index)
vIsReady := 1
}
if (vType = "Double")
{
vData := vNum + 0.0
memcpy(vAddr, &vData, 8)
return
}
if (vType = "Float")
{
vData := vNum + 0.0
vNum := PuzGet(&vData, "Int64")
;0x8000000000000000 (UInt64) = 0x8000000000000000 - 0x10000000000000000 (Int64) = -0x8000000000000000 (Int64)
vSign := !!(vNum & -0x8000000000000000)
vPow := ((vNum & 0x7FF0000000000000) >> 52)
vNum := vNum & 0xFFFFFFFFFFFFF
if (vPow = 2047)
vPow := 255
else if (vPow > 0)
vPow := (vPow - 1023 + 127) & 0xFF
;else if (vPow = 0)
; vPow := 0
vNum >>= (52-23)
vTemp := (vSign << 31) | (vPow << 23) | vNum
PuzPut(vTemp, vAddr+0, "UInt")
return
}
vSize := oType[RegExReplace(vType, "i)^U")]
Loop Min(vSize, 7)
vTemp := vNum & (0xFF << (A_Index*8-8))
, vTemp >>= (A_Index*8-8)
, (vTemp=0) ? memcpy(vAddr+A_Index-1, &vDataNull, 1) : memcpy(vAddr+A_Index-1, oChar.GetAddress(vTemp), 1)
;0xFF00000000000000 (UInt64) = (0xFF00000000000000 - 0x10000000000000000) (Int64) = -0x100000000000000 (Int64)
if (vSize = 8)
vTemp := SubStr(Format("0x{:016X}", vNum & -0x100000000000000), 1, 4)
, vTemp := Integer(vTemp)
, (vTemp=0) ? memcpy(vAddr+7, &vDataNull, 1) : memcpy(vAddr+7, oChar.GetAddress(vTemp), 1)
}
memcpy(dest, src, count){
/*
void *memcpy(
void *dest,
const void *src,
size_t count
);
url: https://msdn.microsoft.com/en-us/library/dswaw1wk.aspx (memcpy)
*/
return dllcall("MSVCRT.dll\memcpy", "ptr", dest, "ptr", src, "ptr", count, "cdecl")
}
Last edited by jeeswg on 27 Jan 2019, 14:45, edited 3 times in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Re: Code Puzzle Thread
You call numput / numget in your puz functions. I guess that is a mistake. Please correct and I will look at your code later this week.
Cheers.
Cheers.
Return to “General Discussion”
Who is online
Users browsing this forum: No registered users and 4 guests