Napsal jsem jeste v noci treti verzi, kde jsem pouzil myslenku, ze nema cenu zjistovat (volat fci) pro kazdou hodnotu pole ktery ze tri registru HL,DE,BC se ma na tu hodnotu nastavit, kdyz uz u prvni hodnoty se to cele spocita az do konce. Takze pokud si nekam ulozim optimalni "cestu", tak usetrim cca 25% casu.
Cestu ukladam jako retezec cisel kde "1" znaci HL, "2" znaci DE a "3" BC. Musel jsem pro to napsat rekurzivni makro co to prevede na kod, to jsem pozdeji upravil tak ze to tiskne jen do zarazky "-".
Pomoci tisku toho retezce cesty jsem zjistil ze me v prubehu vypoctu najde nejlepsi reseni a pote ho zahodi a "cena" toho reseni je jina nez by mela byt. Takze jsem to postupne rucne krokoval, az nasel chybu mimo muj kod. Byla schovana v __LD_REG16(). Pokud je totiz pozadovano nacteni dat z pointeru tak to resi jina vetev kodu a tam jsem zapomel vynulovat __BYTES_16BIT a __CLOCKS_16BIT. Takze i kdyz to spravne generovalo kod tak pokud byl kod prazdny retezec, protoze registr uz drzel hodnotu tak cena byla stejna jako z predchoziho vypoctu... To me spravilo prvni funkci, uz generuje spravny kod, ale duvod proc se to lisilo od druhe stale nechapu. Mely byt chybne oba nebo ani jeden.
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH4(0,(10),0x1431,0x3333,0x1431,0x3333,0,(10)) __SHOW_TOKEN(1)'
; name: __TOKEN_PUSHS
; info: 0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
;items: 8
;param: (0,(10),0x1431,0x3333,0x1431,0x3333,0,(10))
;array1: >0<
;array2: >(10)<
;array3: >0x1431<
;array: 0,(10),0x1431,0x3333,0x1431,0x3333,0,(10)
push DE ; 1:11 0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
push HL ; 1:11 0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
ld HL, 0x0000 ; 3:10 0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
push HL ; 1:11 0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
ld HL, (10) ; 3:16 0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
push HL ; 1:11 0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
ld DE, 0x1431 ; 3:10 0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
push DE ; 1:11 0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
ld BC, 0x3333 ; 3:10 0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
push BC ; 1:11 0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
push DE ; 1:11 0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
push BC ; 1:11 0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
ld DE, 0x0000 ; 3:10 0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
;[23:144]
14 seconds
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH4(0,(10),0x1431,0x3333,0x1431,0,(10)) __SHOW_TOKEN(1)'
; name: __TOKEN_PUSHS
; info: 0 (10) 0x1431 0x3333 0x1431 0 (10)
;items: 7
;param: (0,(10),0x1431,0x3333,0x1431,0,(10))
;array1: >0<
;array2: >(10)<
;array3: >0x1431<
;array: 0,(10),0x1431,0x3333,0x1431,0,(10)
push DE ; 1:11 0 (10) 0x1431 0x3333 0x1431 0 (10)
push HL ; 1:11 0 (10) 0x1431 0x3333 0x1431 0 (10)
ld HL, 0x0000 ; 3:10 0 (10) 0x1431 0x3333 0x1431 0 (10)
push HL ; 1:11 0 (10) 0x1431 0x3333 0x1431 0 (10)
ld HL, (10) ; 3:16 0 (10) 0x1431 0x3333 0x1431 0 (10)
push HL ; 1:11 0 (10) 0x1431 0x3333 0x1431 0 (10)
ld DE, 0x1431 ; 3:10 0 (10) 0x1431 0x3333 0x1431 0 (10)
push DE ; 1:11 0 (10) 0x1431 0x3333 0x1431 0 (10)
ld BC, 0x3333 ; 3:10 0 (10) 0x1431 0x3333 0x1431 0 (10)
push BC ; 1:11 0 (10) 0x1431 0x3333 0x1431 0 (10)
push DE ; 1:11 0 (10) 0x1431 0x3333 0x1431 0 (10)
ld DE, 0x0000 ; 3:10 0 (10) 0x1431 0x3333 0x1431 0 (10)
;[22:133]
7 seconds
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$
Protoze i pres zrychleni ten vypocet zpomaluje exponencialne tak jsem napsal ctvrtou variantu, kde pouzivam kombinaci BruteForce rekurze a puvodniho algoritmu kde se testuje jak to pak sedi na konci.
Pro kazdou hodnotu se to vola se ctyrmi nasledujicimi parametry ke kterym se pridaji 2 koncove parametry a to co bylo mezitim se vynecha. Takove opakovane BF nad 6 hodnotama. Tim to dokaze odhalit to 0x1431, 0x3333, 0x1431, 0x3333, posledni_DE, posledni_HL. Proto jsem potreboval aby ta tisknouci funkce umela "-".
Problem byl stale vstup typu 0,0,0,0,0,0,0, ... 0,0,0,0x8765,0x4321. Generovalo se to prilis dlouho. Nakonec jsem pridal do BruteForce kodu pred zjistovanim ktery ze tri registru je nejlepsi varianta test na kazdy registr, zda uz nedrzi vyslednou hodnotu.
Kód:
__{}__{}__REG_HL,$3,{$0($1,$2{}1,shift(shift(shift($@))))},
__{}__{}__REG_DE,$3,{$0($1,$2{}2,shift(shift(shift($@))))},
__{}__{}__REG_BC,$3,{$0($1,$2{}3,shift(shift(shift($@))))},
Pokud drzi nema cenu zjistovat rekurzivne ktery je nejlepsi a rovnou vybrat ten co uz tu hodnotu ma. (Ma to drobnou chybku ze to delam pres porovnani retezcu a ne hodnot, takze pokud je to cislo zapsane jinak tak to nepozna, a kdyz bych pridal zase ze porovnavam hodnoty tak se to zase spomali, ale mozna ne o tolik, musim vyzkouset. Hmm.. ale zase nemusim resit zda neporovnavam jablka s hruskama, hodnotu a odkaz nebo jmeno promenne)
Tohle vylepseni me v podstate vygeneruje kod pro to cislo se spousty nul na zacatku okamzite a zrychli to i ten testovaci vypocet. Takze tam kde jsem mel cca 43 sekund puvodne, pak 14 sekund, to jsou ted 4 sekundy. (Je to shodne s verzi bez posledniho 0x3333)
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH4(0,(10),0x1431,0x3333,0x1431,0x3333,0,(10)) __SHOW_TOKEN(1)'
; name: __TOKEN_PUSHS
; info: 0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
;items: 8
;param: (0,(10),0x1431,0x3333,0x1431,0x3333,0,(10))
;array1: >0<
;array2: >(10)<
;array3: >0x1431<
;array: 0,(10),0x1431,0x3333,0x1431,0x3333,0,(10)
push DE ; 1:11 0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
push HL ; 1:11 0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
ld DE, 0x0000 ; 3:10 0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
push DE ; 1:11 0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
ld HL, (10) ; 3:16 0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
push HL ; 1:11 0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
ld DE, 0x1431 ; 3:10 0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
push DE ; 1:11 0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
ld BC, 0x3333 ; 3:10 0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
push BC ; 1:11 0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
push DE ; 1:11 0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
push BC ; 1:11 0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
ld DE, 0x0000 ; 3:10 0 (10) 0x1431 0x3333 0x1431 0x3333 0 (10)
;[23:144]
4 seconds
dworkin@dw-A15:~/Programovani/ZX/Forth/M4$ ../check_word.sh 'PUSH4(0,(10),0x1431,0x3333,0x1431,0,(10)) __SHOW_TOKEN(1)'
; name: __TOKEN_PUSHS
; info: 0 (10) 0x1431 0x3333 0x1431 0 (10)
;items: 7
;param: (0,(10),0x1431,0x3333,0x1431,0,(10))
;array1: >0<
;array2: >(10)<
;array3: >0x1431<
;array: 0,(10),0x1431,0x3333,0x1431,0,(10)
push DE ; 1:11 0 (10) 0x1431 0x3333 0x1431 0 (10)
push HL ; 1:11 0 (10) 0x1431 0x3333 0x1431 0 (10)
ld DE, 0x0000 ; 3:10 0 (10) 0x1431 0x3333 0x1431 0 (10)
push DE ; 1:11 0 (10) 0x1431 0x3333 0x1431 0 (10)
ld HL, (10) ; 3:16 0 (10) 0x1431 0x3333 0x1431 0 (10)
push HL ; 1:11 0 (10) 0x1431 0x3333 0x1431 0 (10)
ld DE, 0x1431 ; 3:10 0 (10) 0x1431 0x3333 0x1431 0 (10)
push DE ; 1:11 0 (10) 0x1431 0x3333 0x1431 0 (10)
ld BC, 0x3333 ; 3:10 0 (10) 0x1431 0x3333 0x1431 0 (10)
push BC ; 1:11 0 (10) 0x1431 0x3333 0x1431 0 (10)
push DE ; 1:11 0 (10) 0x1431 0x3333 0x1431 0 (10)
ld DE, 0x0000 ; 3:10 0 (10) 0x1431 0x3333 0x1431 0 (10)
;[22:133]
4 seconds
PS: Kdyz uz mam tu cestu tak by stalo za uvahu tam nejak implementovat ten trik s tim BC co se predpocita dopredu a pak umisti na zacatek. Tady to mohu vytahnout z te cesty. A nejen BC.
Kód:
define({__BRUTEFORCE_CHECK_PUSH_REC3},{dnl
__{}ifelse(dnl
__{}eval($1>=__CHECK_PUSH_BEST),1,{},
dnl __{}$#,3,{dnl
dnl __{}__{}__LD_REG16({HL},$3,{HL},__REG_HL,{DE},__REG_DE,{BC},__REG_BC){}dnl
dnl __{}__{}ifelse(eval(__CHECK_PUSH_BEST>($1+__PRICE_16BIT)),1,{dnl
dnl __{}__{}__{}define({__CHECK_PUSH_BEST},eval($1+__PRICE_16BIT)){}dnl
dnl __{}__{}__{}define({__CHECK_PUSH_BEST_PATH},$2){}dnl
dnl errprint({
dnl },__CHECK_PUSH_BEST:__CHECK_PUSH_BEST_PATH{}){}dnl
dnl __{}__{}}){}dnl
dnl __{}},
__{}$#,4,{dnl
__{}__{}__RESET_ADD_LD_REG16{}dnl
__{}__{}__ADD_LD_REG16({DE},$3,{HL},__REG_HL,{DE},__REG_DE,{BC},__REG_BC){}dnl
__{}__{}__ADD_LD_REG16({HL},$4,{HL},__REG_HL,{DE}, $3,{BC},__REG_BC){}dnl
__{}__{}ifelse(eval(__CHECK_PUSH_BEST>($1+__SUM_PRICE_16BIT)),1,{dnl
__{}__{}__{}define({__CHECK_PUSH_BEST},eval($1+__SUM_PRICE_16BIT)){}dnl
__{}__{}__{}define({__CHECK_PUSH_BEST_PATH},$2){}dnl
__{}__{}}){}dnl
__{}},
__{}{dnl
__{}__{}ifelse(dnl
__{}__{}__REG_HL,$3,{$0($1,$2{}1,shift(shift(shift($@))))},
__{}__{}__REG_DE,$3,{$0($1,$2{}2,shift(shift(shift($@))))},
__{}__{}__REG_BC,$3,{$0($1,$2{}3,shift(shift(shift($@))))},
__{}__{}{dnl
__{}__{}__{}__LD_REG16({HL},$3,{HL},__REG_HL,{DE},__REG_DE,{BC},__REG_BC){}dnl
__{}__{}__{}pushdef({__REG_HL}){}dnl
__{}__{}__{}define({__REG_HL},$3){}dnl
__{}__{}__{}$0(eval($1+__PRICE_16BIT),$2{}1,shift(shift(shift($@)))){}dnl
__{}__{}__{}popdef({__REG_HL}){}dnl
__{}__{}__{}dnl
__{}__{}__{}__LD_REG16({DE},$3,{HL},__REG_HL,{DE},__REG_DE,{BC},__REG_BC){}dnl
__{}__{}__{}pushdef({__REG_DE}){}dnl
__{}__{}__{}define({__REG_DE},$3){}dnl
__{}__{}__{}$0(eval($1+__PRICE_16BIT),$2{}2,shift(shift(shift($@)))){}dnl
__{}__{}__{}popdef({__REG_DE}){}dnl
__{}__{}__{}dnl
__{}__{}__{}__LD_REG16({BC},$3,{HL},__REG_HL,{DE},__REG_DE,{BC},__REG_BC){}dnl
__{}__{}__{}pushdef({__REG_BC}){}dnl
__{}__{}__{}define({__REG_BC},$3){}dnl
__{}__{}__{}$0(eval($1+__PRICE_16BIT),$2{}3,shift(shift(shift($@)))){}dnl
__{}__{}__{}popdef({__REG_BC}){}dnl
__{}__{}}){}dnl
__{}}){}dnl
}){}dnl
dnl
dnl
dnl
define({__PRINT_PUSH_REC3},{dnl
__{}ifelse(dnl
__{}$1,{},{dnl
__{}__{}__LD_REG16({DE},$2,{HL},__REG_HL,{DE},__REG_DE,{BC},__REG_BC){}dnl
__{}__{}__CODE_16BIT{}dnl
__{}__{}define({__REG_DE},$2){}dnl
__{}__{}__LD_REG16({HL},$3,{HL},__REG_HL,{DE},__REG_DE,{BC},__REG_BC){}dnl
__{}__{}__CODE_16BIT{}dnl
__{}__{}define({__REG_HL},$3){}dnl
__{}},
__{}substr($1,0,1),{-},{},
__{}substr($1,0,1),1,{dnl
__{}__{}__LD_REG16({HL},$2,{HL},__REG_HL,{DE},__REG_DE,{BC},__REG_BC){}dnl
__{}__{}__CODE_16BIT{}dnl
__{}__{}define({__REG_HL},$2)
__{}__{} push HL ; 1:11 __INFO{}dnl
__{}__{}$0(substr($1,1),shift(shift($@))){}dnl
__{}},
__{}substr($1,0,1),2,{dnl
__{}__{}__LD_REG16({DE},$2,{HL},__REG_HL,{DE},__REG_DE,{BC},__REG_BC){}dnl
__{}__{}__CODE_16BIT{}dnl
__{}__{}define({__REG_DE},$2)
__{}__{} push DE ; 1:11 __INFO{}dnl
__{}__{}$0(substr($1,1),shift(shift($@))){}dnl
__{}},
__{}substr($1,0,1),3,{dnl
__{}__{}__LD_REG16({BC},$2,{HL},__REG_HL,{DE},__REG_DE,{BC},__REG_BC){}dnl
__{}__{}__CODE_16BIT{}dnl
__{}__{}define({__REG_BC},$2)
__{}__{} push BC ; 1:11 __INFO{}dnl
__{}__{}$0(substr($1,1),shift(shift($@))){}dnl
__{}}){}dnl
}){}dnl
dnl
dnl
dnl
define({__BRUTEFORCE_PUSHS_REC3},{dnl
__{}define({__CHECK_PUSH_BEST},0x7FFFFFFF){}dnl
__{}__BRUTEFORCE_CHECK_PUSH_REC3(0,,$@){}dnl
__{}__PRINT_PUSH_REC3(__CHECK_PUSH_BEST_PATH,$@){}dnl
}){}dnl
dnl
dnl
dnl
define({__BRUTEFORCE_PUSHS_REC4},{dnl
__{}ifelse($#,0,{},
__{}$#,1,{
__{}__{} .error {$0}($@)},
__{}$#,2,{__BRUTEFORCE_PUSHS_REC3($@)},
__{}$#,3,{__BRUTEFORCE_PUSHS_REC3($@)},
__{}$#,4,{__BRUTEFORCE_PUSHS_REC3($@)},
__{}$#,5,{__BRUTEFORCE_PUSHS_REC3($@)},
__{}$#,6,{__BRUTEFORCE_PUSHS_REC3($@)},
__{}{dnl
__{}__{}define({__CHECK_PUSH_BEST},0x7FFFFFFF){}dnl
__{}__{}__BRUTEFORCE_CHECK_PUSH_REC3(0,,$1,$2,$3,$4,__LAST_REG_DE,__LAST_REG_HL){}dnl
__{}__{}__PRINT_PUSH_REC3(substr(__CHECK_PUSH_BEST_PATH,0,1){-},$@){}dnl
__{}__{}$0(shift($@)){}dnl
__{}}){}dnl
}){}dnl