Code Puzzle Thread

Discuss Autohotkey related topics here. Not a place to share code.
Forum rules
Discuss Autohotkey related topics here. Not a place to share code.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Code Puzzle Thread

25 Apr 2020, 09:07

Pzulze 13: Uamcsblrne!

A stiicnfiec sdtuy at an egisnlh uisitrveny has swhon that we can qitue elisay read text wehre all lrettes expcet the frist and the last in ecah word has been smeaclrbd. The oebijcvtes of tihs puzlze is to wrtie a fnitocun f, wchih unbcmlarses the enirte text of this psot. Ecah wrod, in odrer from first to last, in this txet has been scambreld by tihs fitcuonn,

slmarbce(wrod) {
lacol
wl := srlten(wrod) ; wl - wrod ltegnh
if (wl > 3) {
li := 2 ; li - lteetr iendx
count := wl - 2
loop %cuont% {
radonm np, 2, wl-1 ; np - new pisooitn
sl(word, li, np) ; sl - swap ltetres. You have to wrtie this fntioucn too, it swpas ltretes in wrod gievn by two psnooitis, li and np.
li++
}
}
rturen wrod
}

For rdoburiiatlcepy, Rdaonm,, 37 is uesd. Nruebms msut not be smacelbrd. Your code sulohd wrok for any simlriaily faotemrtd text. You can wrtie any aunmot of help fitunnocs. The fuicontn f msut be on the form,

out := f(str, fn)

wehre out is the poesrecsd text, str is the txet to pcseros, fn is a ftncioun objcet. It msut fiflul the flnwoolig citindoon

f(f(str, func("ucsrnlbmae")), fnuc("samrclbe")) == str

Bonus oicvetjbe, susgegt a sbtlaiue nmae for the ftinucon f, and epilaxn the bineetfs of the fn patremear.

Psaele sned yuor code (and bonus aesnwr) to me via PM but do not psot any stiolnous or hnits in tihs terahd. The fsrit one to copletme the task will rivecee two pniots, annoye who clteoemps the task aetfr taht but bofree a motnh from now, will recveie one ponit.

Dacilsiemr, the ogiianrl text mgiht cotiann silelpng eorrrs.

Crehes.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Code Puzzle Thread

04 May 2020, 10:34

We have a winner for Pzulze 13! boiler have submitted a great solution and will be awarded two points :clap:. Anyone who wants, can still send their solution to me for one point. The solution will be available around the 25th of May.

Cheers.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Code Puzzle Thread

25 May 2020, 10:03

This is boiler's solution for Pzulze 13,
boiler wrote:

Code: Select all

str =
(%
Pzulze 13: Uamcsblrne!

A stiicnfiec sdtuy at an egisnlh uisitrveny has swhon that we can qitue elisay read text wehre all lrettes expcet the frist and the last in ecah word has been smeaclrbd. The oebijcvtes of tihs puzlze is to wrtie a fnitocun f, wchih unbcmlarses the enirte text of this psot. Ecah wrod, in odrer from first to last, in this txet has been scambreld by tihs fitcuonn,

slmarbce(wrod) {
lacol
wl := srlten(wrod) ; wl - wrod ltegnh
if (wl > 3) {
li := 2 ; li - lteetr iendx
count := wl - 2
loop %cuont% {
radonm np, 2, wl-1 ; np - new pisooitn
sl(word, li, np) ; sl - swap ltetres. You have to wrtie this fntioucn too, it swpas ltretes in wrod gievn by two psnooitis, li and np.
li++
}
}
rturen wrod
}

For rdoburiiatlcepy, Rdaonm,, 37 is uesd. Nruebms msut not be smacelbrd. Your code sulohd wrok for any simlriaily faotemrtd text. You can wrtie any aunmot of help fitunnocs. The fuicontn f msut be on the form,

out := f(str, fn)

wehre out is the poesrecsd text, str is the txet to pcseros, fn is a ftncioun objcet. It msut fiflul the flnwoolig citindoon

f(f(str, func("ucsrnlbmae")), fnuc("samrclbe")) == str

Bonus oicvetjbe, susgegt a sbtlaiue nmae for the ftinucon f, and epilaxn the bineetfs of the fn patremear.

Psaele sned yuor code (and bonus aesnwr) to me via PM but do not psot any stiolnous or hnits in tihs terahd. The fsrit one to copletme the task will rivecee two pniots, annoye who clteoemps the task aetfr taht but bofree a motnh from now, will recveie one ponit.

Dacilsiemr, the ogiianrl text mgiht cotiann silelpng eorrrs.

Crehes.
)

MsgBox, % out := f(str, func("unscramble")) ; unscramble the input
MsgBox, % out2 := f(out, func("scramble")) ; scramble the previous unscrambled output
MsgBox, % f(out2, func("unscramble")) ; re-unscramble the previous scrambled output
MsgBox, % (f(f(str, func("unscramble")), func("scramble")) == str) ? "Success!" : "Failed :("
return

f(str, fn)
{
	Random,, 37
	index := 1
	loop {
		if RegExMatch(SubStr(str, index), "^[a-zA-Z]+", word) {
			newStr .= %fn%(word)
			index := index + StrLen(word)
		} else {
			newStr .= SubStr(str, index, 1)
			index++
		}
	} until index > StrLen(str)
return newStr
}

scramble(word) {
	local
	wl := strlen(word) ; wl - word length
	if (wl > 3) {
		li := 2 ; li - letter index
		count := wl - 2
		loop %count% {
			random np, 2, wl-1 ; np - new position
			sl(word, li, np) ; sl - swap letters. You have to write this function too, it swaps letters in word given by two positions, li and np.
			li++
		}
	}
	return word
}

unscramble(word) {
	local
	swaps := []
	wl := strlen(word) ; wl - word length
	if (wl > 3) {
		li := 2 ; li - letter index
		count := wl - 2
		loop %count% {
			random np, 2, wl-1 ; np - new position
			swaps.Push({pos1: li, pos2: np})
			li++
		}
		loop, %count%
			sl(word, swaps[swaps.Count() - A_Index + 1].pos1, swaps[swaps.Count() - A_Index + 1].pos2)
	}
	return word
}

sl(ByRef word, li, np) {
	t := SubStr(word, li, 1)
	word := SubStr(word, 1, li - 1) . SubStr(word, np, 1) . SubStr(word, li + 1)
	word := SubStr(word, 1, np - 1) . t . SubStr(word, np + 1)
}
And the bonus questions,
Boiler wrote: My suggested name for the function f is processWords, because it will perform a process on each of the words in a string, and that process can be anything that the identified function might perform on those words. In this case, it scrambles and unscrambles them, but it could also be provided a function encrypt, decrypt, reverse or capitalize or any number of other processes. This is the benefit of the fn parameter. It makes the function f very flexible in that it is set up to process all words in the provided string with the provided process.
Well done and thanks for participating :clap: :thumbup:. It is now boiler's privilege to submit the next puzzle, if boiler wants.

Cheers.
User avatar
boiler
Posts: 16774
Joined: 21 Dec 2014, 02:44

Re: Code Puzzle Thread

25 May 2020, 10:23

Thanks, Helgef. I do have a new puzzle:

Puzzle 14: Earn your stripes by being first to find the hidden message, and your fellow puzzle solvers will be green with envy. Add the missing function HiddenMsg to the script below. A correct function will result in the message appearing in the GUI.

Code: Select all

Gui, -Caption
Gui, Margin, 0, 0
Gui, Add, Picture, x0 y0, ahk.png
Gui, Add, Progress, xm w217 h26 BackgroundD4D4D4
Gui, Add, Progress, xp+2 yp+2 wp-4 hp-4 Background202020
Gui, Font, cWhite
Gui, Add, Text, xp hp wp hp Center +0x200 vMsg BackgroundTrans
Gui, Show
GuiControl,, Msg, % HiddenMsg()
return

Esc::ExitApp
ahk.png
ahk.png (16.04 KiB) Viewed 7038 times
User avatar
boiler
Posts: 16774
Joined: 21 Dec 2014, 02:44

Re: Code Puzzle Thread

09 Jun 2020, 09:27

Since we haven’t seen any solutions to Puzzle 14 yet, I thought perhaps I should make my hints a little more obvious:

Earn your stripes by being first to find the hidden message, and your fellow puzzle solvers will be green with envy.

And I’ll add:

If you’re able to solve it, you’ll reveal an important component of your character.

It’s really not complicated code to extract the info from the image. I hope to see someone solve it!
User avatar
boiler
Posts: 16774
Joined: 21 Dec 2014, 02:44

Re: Code Puzzle Thread

10 Jun 2020, 08:34

Congratulations to Helgef for providing the solution to Puzzle 14! :bravo:

Helgef has won two points for being first with the solution. Anyone who also sends the correct solution by June 25th will be awarded one point. Please PM me with your proposed solution.
User avatar
boiler
Posts: 16774
Joined: 21 Dec 2014, 02:44

Re: Code Puzzle Thread

26 Jun 2020, 08:02

Here is Helgef's solution to Puzzle 14:

Code: Select all

HiddenMsg() {
	coordmode pixel, window
	x := 156
	y := 20
	s := ""
	loop 9 {
		pixelgetcolor col, x,y
		green := (col & 0x0000ff00) >> 8
		s .= chr(green)
		y += 10
	}
	return s
}
When added to the main script and run with the image in the folder, it produces this, including the hidden message displayed at the bottom:
Puzzle 14 solution output.png
Puzzle 14 solution output.png (16.87 KiB) Viewed 6740 times
It may be a little cheesy, but it's hard to fit a profound message into a few stripes. :D

Good job, Helgef! :thumbup: I'm looking forward to seeing what you come up with for Puzzle 15, if you choose to create one.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Code Puzzle Thread

26 Jun 2020, 12:19

Thank you @boiler, great puzzle :thumbup:. I'll put it in my mental stack of todos to come up with a new puzzle :shock: .

Cheers.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Code Puzzle Thread

05 Apr 2022, 04:39

Send in your solution as a private message to me, so that everyone gets a chance to consider the problem before solutions are posted.
Puzzle 15 - A critical mistake
Puzzle description: You have written a program in which a number (N) of timers need to run and their callback objects need to be deleted before your program can continue. In your test code every thing works fine when N := 5, but for your actual needs you set N := 10000 but now your program isn't working as you expected.
Puzzle objective: Explain what goes wrong when N is increased, why and how you realised. Also provide a fix for the program.
Puzzle rules: You can change the code below to help you understand what happens. But you should consider all parts of it essential for the program so a fix cannot simply be to remove the loop or remove the use of timers or similar. When the program is fixed, the msgbox should display pretty quickly (a few seconds) for N := 10000. If the code below works if you set N := 10000, increase it until it doesn't.
Code:

Code: Select all

; The test case:
N := 5 ; 10000 ; <- not working
loop % N 
	new c

while c.i < N ; Must wait for all timers to finnish and all objects to be released!
	continue
	
msgbox done

esc::exitapp

class c {
	static i := 0
	__delete(){
		critical	 ; Must not be interrupted
		c.i++ 
	}
	call(){
	}
	__new(){
		settimer % this, -1
		return this
	}
}
Cheers.
Last edited by Helgef on 08 Apr 2022, 02:35, edited 1 time in total.
iseahound
Posts: 1434
Joined: 13 Aug 2016, 21:04
Contact:

Re: Code Puzzle Thread

05 Apr 2022, 19:30

I have no idea. Even though I found the bug that inspired your puzzle. Spent about half an hour thinking this trough - I bet it's something very obvious.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Code Puzzle Thread

06 Apr 2022, 03:39

You shouldn't be led astray by the similarities with the code in your bug report, it only served as a good template to demonstrate this is issue. It could be demonstrated and manifest in many other ways.

I'm glad you thought it through :thumbup:. But it isn't obvious, obviously :P

Cheers.
User avatar
TheDewd
Posts: 1508
Joined: 19 Dec 2013, 11:16
Location: USA

Re: Code Puzzle Thread

07 Apr 2022, 11:25

Removed solution. PM'ing Helgef instead.
Last edited by TheDewd on 07 Apr 2022, 12:24, edited 1 time in total.
User avatar
boiler
Posts: 16774
Joined: 21 Dec 2014, 02:44

Re: Code Puzzle Thread

07 Apr 2022, 12:14

Just a reminder...
Helgef wrote:
05 Apr 2022, 04:39
PM me your solution so that everyone gets a chance to consider the problem before solutions are posted.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Code Puzzle Thread

08 Apr 2022, 02:37

Thank you @boiler for reading through the entire instruction :thumbup:. I have moved that part to the top of my post now.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Code Puzzle Thread

01 Oct 2022, 08:08

Send in your solution as a private message to me, so that everyone gets a chance to consider the problem before solutions are posted.
Edit: This puzzle must not use changes made in beta 12 since these makes the unsetting part of the puzzle trivial :thumbup:
Puzzle 16 - The unliner
Puzzle description: In AHK v2, variables which has not been assigned a value are considered uninitalised and trying to read them will cause an error message to display. This is useful to help detect mistakes. However, once a variable has been assigned a value, there is no obvious way to make it uninitialised again, which could be helpful to avoid mistakes when reusing variables.
Puzzle objective: Write a function _unset(v*), which for any number of variable references causes each one of them to be uninitialised after the call. Example,

Code: Select all

a:=b:=1
msgbox 	isset(a) isset(b)	; 11
_unset &a,&b
msgbox 	isset(a) isset(b)	; 00
Puzzle rules:Your solution must consist of only one line, i.e., write _unset(v*) => .... You can assume that v.has(n) is true for n = 1,..,v.length. Edit: you may not call _unset from within _unset.
Disclaimer: I wrote this puzzle (about) six months ago, and didn't follow the changes since closely, so perhaps this is trivial or obsolete now.

Note: Puzzle 15 is still unsolved, please consider it too :)

Cheers.
Last edited by Helgef on 09 Oct 2022, 07:34, edited 1 time in total.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Code Puzzle Thread

07 Oct 2022, 11:49

Regarding Puzzle 16. @Emile HasKey has provided an excellent recursive solution and will be awarded one point for this. For two points the solution should be non-recursive.

Working around the you may not call _unset from within _unset. rule by defining a method or other function which is then called recursively is not considered a non-recursive solution, as it will also not satisfy the for any number of variable references objective very well.

Solutions should also be supported by documented behaviour.

Great job @Emile HasKey, cheers :bravo:
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Code Puzzle Thread

08 Oct 2022, 13:26

This post is a follow up to Puzzle 11

In this puzzle we tried to recreate the numput/get functions. The accepted solution was made by lexikos, but before that jeeswg attemped a different approach which ultimately contained some errors. Jeeswg was given one point for a good effort and partial solution, and I left it open for anyone to try to fix his version for one additional point. At the time I wrote a fix for his script,

Code: Select all

;slightly improved PuzPut function which handles rounding
;the MsgBox indicating a slight discrepancy now appears less frequently
;before: e.g. 2381/10000 = 0.2381 [24%]
;after: e.g. 67/10000 = 0.0067 [0.7%]

;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
double_to_float_to_double(d){
	local
	static inf := 1.0e400
	if (d == 0 || instr(d, "n") || instr(d, "i"))	; no need to do anything in these cases, -0.0, 0.0, NaN or inf
		return d
	
	d := d * 1.0								; Ensure double
	
	; Write the double to an address from where we can get it as an int64
	varsetcapacity(dd, 8)
	puzput(d, &dd, "double")
	i := puzget(&dd, "int64")					; The double as int64
	
	; Split the int64 into sign, exponenent and fraction
	sign_bit := i < 0							; get sign bit
	i &= ~(1 << 63)								; remove sign bit
	exp := ( i >> 52 ) - 1023 + 127				; get exponenent and convert it to "float exponent"
	fraction := (i & (2**52-1) ) >> (52 - 23)	; get fraction and convert it to "float fraction"
	
	if (exp  >= 0xff)							; it is inf, NaN was detected above
		return inf * (sign_bit ? -1 : 1)
	
	
	; When converting a double to float, the result might be either larger or smaller than the original number (or equal but that is covered here too).
	; Pick the one closest to the original. If there is a tie, choose the one which doesn't have its most significant bit set.
	loop 2 {
		uint_%a_index% := ( sign_bit << 31 ) | ( exp << 23 ) | fraction			; assemble the sign, exponenent and fraction as a uint
		puzput( ( sign_bit << 31 ) | ( exp << 23 ) | fraction, &dd, "uint" )	; interpret this uint as a float, reusing dd.
		d%a_index% := PuzGet(&dd, "float") 										; interpret this float as a double
		fraction += 1															; next float
	}
	
	; Now check which float is the closest to the original double, and pick it.
	diff1 := abs(d-d1)
	diff2 := abs(d-d2)
	
	if (diff1 == diff2) {
		; tie! pick the one which doesn't have its most significant bit set.
		if !(uint_1 & 1)	
			return d1
		return d2
	}
	if (diff1 < diff2)
		return d1
	return d2
	
}
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)
vCount := 0
Loop 10000
{
try
{
	vNum := Random(-2147483648, 2147483647)
	vNum *= 256**3
	;vTemp := Random(1, oType.Length())
	vType := "float" ;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)
}
catch
	continue
;vCount++
	vIsErr := 0
	;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)
		, vIsErr := 1
	;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)
		, vIsErr := 1
	if vIsErr
		vCount++
}
MsgBox("done " vCount)
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
		vData := double_to_float_to_double(vData)
		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
		vBit := (vNum >> (52-24)) & 0x1 ;truncate number, but if bit is 1, round up
		vNum >>= (52-23)
;MsgBox vBit
;if (vBit)
;throw
		;handle rounding:
		;if 0
		if vBit
		{
			vTemp := 1
			Loop 22
			{
				if !(vNum & vTemp)
				{
					vNum |= vTemp
					vNum ^= vTemp-1
					break
				}
				vTemp <<= 1
			}
			if (vTemp = 2**22)
				vNum := 0, vPow += 1
		}

		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")
}

;prepend Z to MsgBox, and it becomes a NoOp
ZMsgBox(oParams*)
{
}
It requires an older v2 alpha version, it seems ok with a100. I added a function double_to_float_to_double which correctly converts double to float (and back to double), which is the part which jeeswg didn't get quite right.

Also, you need to press q to start the script, and it has no exitapp hotkey so you have to manually close it from the tray :)

Cheers.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Code Puzzle Thread

20 Nov 2022, 09:54

@Emile HasKey har provided a complete solution for :arrow: puzzle 16, please enjoy,

Code: Select all

; for Puzzle 16 - The unliner (2nd attempt)
; link: https://www.autohotkey.com/boards/viewtopic.php?p=484863#p484863
; by Emile HasKey
; when the Sort comparison function returns 0, the number of comparisons is approximately v.Length*2

#Requires AutoHotkey v2.0-beta.7

_unset(v*) => (str := StrReplace(Format("{:" v.Length "}", ""), " ", "0,") "0", Sort(str, "D,", (a, b, c) => v.Length && ([,0].__Enum(1))(v.Pop()) && 0))

a:=b:=1
msgbox 	isset(a) isset(b)	; 11
_unset &a,&b
msgbox 	isset(a) isset(b)	; 00

a:=b:=c:=d:=e:=1
msgbox 	isset(a) isset(b) isset(c) isset(d) isset(e)	; 11111
_unset &a,&b,&c,&d,&e
msgbox 	isset(a) isset(b) isset(c) isset(d) isset(e)	; 00000
The unsetting part is identical to the way I had in mind, but the one-liner part is not. However, the solution is creative and does the job according to specification, so it will reward @Emile HasKey two points. Well done :dance:.

Cheers.
teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Re: Code Puzzle Thread

17 Jan 2023, 00:25

What a pity I just saw this thread. :)
IMO, the less sophisticated way:

Code: Select all

_unset(v*) => (e := v.__Enum(1), c := (*) => (e(&a), !%a% := unset), StrGet(Buffer(v.Length*2, 1)) ~= '.(?Cc)')

a:=b:=1
msgbox 	isset(a) isset(b)	; 11
_unset &a,&b
msgbox 	isset(a) isset(b)	; 00

a:=b:=c:=d:=e:=1
msgbox 	isset(a) isset(b) isset(c) isset(d) isset(e)	; 11111
_unset &a,&b,&c,&d,&e
msgbox 	isset(a) isset(b) isset(c) isset(d) isset(e)	; 00000
Also, forEach() one-liner:

Code: Select all

forEach(arr, fn) => (e := arr.__Enum(2), c := (*) => (e(&k, &v), arr[k] := fn(v), 1), StrGet(Buffer(arr.Length*2, 1)) ~= '.(?Cc)')

arr := [1, 2, 3]
forEach(arr, (el) => el**2)
MsgBox Format('[{}, {}, {}]', arr*) ; [1, 4, 9]
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Code Puzzle Thread

21 Jan 2023, 05:15

Hello @teadrinker, glad to see you participate :)

The oneliner part of the puzzle should utilise the * operator, which provides non-hackish ways to loop in an expression.

Cheers.

Return to “General Discussion”

Who is online

Users browsing this forum: No registered users and 22 guests