From 88930ee7cec32beac6b40869f65290bbf04caa68 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Thu, 14 Dec 2023 07:08:25 -0600 Subject: [PATCH] day 12 part 1, FINALLY ~250ms. Nailed the last nasty bug; now to see what part 2 brings. --- 2023/day12.m4 | 171 ++++++++++++++++++++-------------------------------------- 1 file changed, 58 insertions(+), 113 deletions(-) rewrite 2023/day12.m4 (62%) diff --git a/2023/day12.m4 b/2023/day12.m4 dissimilarity index 62% index 949dffa..2982e92 100644 --- a/2023/day12.m4 +++ b/2023/day12.m4 @@ -1,113 +1,58 @@ -divert(-1)dnl -*- m4 -*- -# Usage: m4 [-Dfile=day12.input] day12.m4 - -include(`common.m4')ifelse(common(12), `ok', `', -`errprint(`Missing common initialization -')m4exit(1)') - -# Assumes that the longest input line is a mask of 20 positions, followed -# by at most 6 groups within those positions. - -define(`input', translit((include(defn(`file'))), nl`.?# ,()', `;012//')) -define(`part1', 0) - -ifelse(` -# rshiftN(ignore, ignore, ignore, arg1, ...argn)->arg1, ...argn-1 -define(`rshift4', `') -define(`rshift5', ``$4'') -define(`rshift6', ``$4', `$5'') -define(`rshift7', ``$4', `$5', `$6'') -define(`rshift8', ``$4', `$5', `$6', `$7'') -define(`rshift9', ``$4', `$5', `$6', `$7', `$8'') -# last(arg1, ...argn)->argn -define(`last', `pushdef(`t', `popdef(`t')$$#')t($@)') -# eatl/r(amt, str, minargl, arg1, ...argn)->score w/o amt bytes and arg1/argn -define(`eatl', `ifelse(`$#', 4, 1, `score(trim(substr(`$2', $1)), eval($3-$4-1), - shift(shift(shift(shift($@)))))')') -define(`eatr', `ifelse(`$#', 4, 1, `score(trim(substr(`$2', 0, eval(len(`$2') - -$1))), eval($3-last($@)-1), rshift$#($@))')') -# brute(len(str), str, minarglen, arg1, ...argn)->int # brute force probes -define(`brute', `eatl(incr($4), shift($@))+score(trim(substr(`$2', 1)), - shift(shift($@)))') -# lone(len(str), str, arg1, arg1)->int # lone arg solution -define(`_lone', `ifelse(eval($1<$5), 1, 0, $3$4, -1-1, `eval($1-$5+1)', $4, -1, - `lone($3, substr(`$2', 0, $3), $5, $5)+lone(trim(substr(`$2', $3)), $5, $5)', - eval($3>=0&&$3<$4), 1, `lone(trim(substr(`$2', $3)), $5, $5)', eval($3>$1-$5), - 1, `lone(trim(substr(`$2', 0, $3)), $5, $5)', eval(index(substr(`$2', $5), - `*')>=0), 1, `lone(decr($1), substr($2, 1), $5, $5)', $3, -1, `eval($1-$5+1)', - `lone(trim(substr($2, ifelse(eval($3>$4), 1, `0,') $3)), $5, $5)')') -define(`lone', `_$0(`$1', `$2', index(`$2', `.'), index(`$2', `*'), `$3')') -# _score(len(str), str, minarglen, arg1, ...argn)->int # moderate probes -define(`_score', `ifelse($3, $4, `lone($@)', index(`$2', `?*').substr(`$2', $4, - 1), 0.*, `eatl(incr(incr($4)), shift($@))', index(`$2', `?*').substr(`$2', - incr($4), 1), 0.*, `eatl(incr($4), shift($@))', index(`..$2!', - `*?!').substr(`$2', eval($1-last($@)-1), 1), $1.*, `eatr(incr(incr(last($@))), - shift($@))', index(`..$2!', `*?!').substr(`$2', eval($1-last($@)-2), 1), - $1.*, `eatr(incr(last($@)), shift($@))', eval(index(`$2', `.')<$4&& - index(`$2', `.')>0), 1, `score(trim(substr(`$2', 1)), shift(shift($@)))', - substr(`$2', $4, 1), `*', `score(trim(substr(`$2', 1)), shift(shift($@)))', - `brute($@)')') -# score(len(str), str, minarglen, arg1, ...argn)->int # easy probes -define(`score', `ifelse(eval($3>$1), 1, 0, $3, 0, 1, $1, $3^, 1, - len(translit(`$2', `.')), eval($3-$#+4)^, 1, len(translit(`$2', `.?')), - eval($3-$#+4), 1, index(`$2', `*').substr(`$2', $4, 1), 0.*, 0, index(`$2', - `*'), 0, `eatl(incr($4), shift($@))', index(`$2!', `*!'), -1, `_$0($@)', - index(`.$2!', `*!').substr(`$2', eval($1-last($@)-1)), $1.*, 0, - `eatr(incr(last($@)), shift($@))')') -define(`_trim', `substr(`$1', 0, $2)substr(`$1', incr($2))') -define(`trim', `ifelse(index(`$1', `.'), 0, `$0(substr(`$1', 1))', eval(index( - `$1', `..')>0), 1, `$0(_$0(`$1', index(`$1', `..')))', index(`$1!', `.!'), - -1, `len($1), `$1'', `$0(substr(`$1', 0, decr(len(`$1'))))')') - -') - -define(`eatl', `ifelse(`$#', 4, `fatal(`oops')', `score(trim(substr(`$2', $1)), eval($3-$4-1), - shift(shift(shift(shift($@)))))')') - -# lone(len(str), str, arg1)->int # lone arg solution -define(`_lone', `ifelse(eval($1<$5), 1, 0, eval(index(translit(`$2', 1), - 202)>=0), 1, 0, $3$4, -1-1, `eval($1-$5+1)', $4, -1, `lone($3, substr(`$2', - 0, $3), $5)+lone(trim(substr(`$2', $3)), $5)', eval($4>=$5), 1, `lone(trim( - substr(`$2', eval($4-$5+1))), $5)', eval($3>=0&&$3<$4), 1, `lone(trim( - substr(`$2', $3)), $5)', eval($3>$1-$5), 1, `lone(trim(substr(`$2', - 0, $3)), $5)', eval(index(substr(`$2', $5), `2')>=0), 1, `ifelse(eval($4>0), - 1, `lone(decr($1), substr($2, 1), $5)', 0)', $4, 0, 1, $3, -1, `eval($1-$5+1)', - `lone(trim(substr($2, ifelse(eval($3>$4), 1, `0,') $3)), $5)')') -define(`lone', `_$0(`$1', `$2', index(`$2', `0'), index(`$2', `2'), `$3')') - -# score(len(str), str, minarglen, arg1, ...argn)->int # memoization -define(`hits', 0) -define(`_score', `ifelse($3, $4, `lone($@)', eval(index(`$2'0, 0)<$4), 1, - `ifelse(eval(index(`$2'2, 2)$1), 1, 0, `ifdef(`s$2_$4_$5_$6_$7_$8_$9', - `define(`hits', incr(hits))', `define(`s$2_$4_$5_$6_$7_$8_$9', - eval(_$0($@)))')s$2_$4_$5_$6_$7_$8_$9()')') - -# trim(str)->len, str -define(`_trim', `substr(`$1', 0, $2)substr(`$1', incr($2))') -define(`trim', `ifelse(index(`$1', `0'), 0, `$0(substr(`$1', 1))', index( - `$1'0, `00'), -1, `len($1), `$1'', `$0(_$0(`$1', index(`$1'0, `00')))')') -define(`_do', `score(trim(`$1'), eval(`$7 + $6 + $5 + $4 + $3 + $2 + $# - 2'), - shift($@))') -define(`Eval', `ifelse(eval($2>=10000), 1, `errprintn(`failed on $1')')eval( - part1+$2)') -define(`do', `define(`part1', Eval(`$1',_$0(translit(`$1', `/', `,'))))') - -ifdef(`__gnu__', ` - patsubst(defn(`input'), `\([^;]*\);', `do(`\1')') -', ` - define(`_chew', `do(substr(`$1', 0, index(`$1', `;')))define( - `tail', substr(`$1', incr(index(`$1', `;'))))ifelse(index(defn(`tail'), - `;'), -1, `', `$0(defn(`tail'))')') - define(`chew', `ifelse(eval($1 < 68), 1, `_$0(`$2')', `$0(eval($1/2), - substr(`$2', 0, eval($1/2)))$0(eval(len(defn(`tail')) + $1 - $1/2), - defn(`tail')substr(`$2', eval($1/2)))')') - chew(len(defn(`input')), defn(`input')) -') - -divert`'part1 -part2 +divert(-1)dnl -*- m4 -*- +# Usage: m4 [-Dfile=day12.input] day12.m4 + +include(`common.m4')ifelse(common(12), `ok', `', +`errprint(`Missing common initialization +')m4exit(1)') + +# Assumes that the longest input line is a mask of 20 positions, followed +# by at most 6 groups within those positions. + +define(`input', translit((include(defn(`file'))), nl`.?# ,()', `;012//')) +define(`part1', 0) +define(`min', `ifelse(eval($1<$2), 1, $1, $2)') + +# lone(len(str), str, arg1)->int # lone arg solution +define(`_lone', `ifelse(eval($1<$5), 1, 0, $3$4, $1-1, `eval($1-$5+1)', $4, -1, + `lone($3, substr(`$2', 0, $3), $5)+lone(trim(substr(`$2', $3)), $5)', eval( + $4>=$5), 1, `lone(trim(substr(`$2', eval($4-$5+1))), $5)', eval($3<$4), 1, + `lone(trim(substr(`$2', $3)), $5)', eval($3<$5), 1, 0, index(substr(`$2', $5), + `2'), -1, `1+min($4, $3-$5)', $4, 0, 0, `lone(decr($1), substr($2, 1), $5)')') +define(`lone', `_$0(`$1', `$2', index(`$2'0, `0'), index(`$2', `2'), `$3')') + +# score(len(str), str, minarglen, arg1, ...argn)->int # memoization +define(`hits', 0) +define(`_score', `ifelse($3, $4, `lone($@)', eval(index(`$2'0, 0)<$4), 1, + `ifelse(eval(index(`$2'2, 2)$1), 1, 0, `ifdef(`s$2_$4_$5_$6_$7_$8_$9', + `define(`hits', incr(hits))', `define(`s$2_$4_$5_$6_$7_$8_$9', + eval(_$0($@)))')s$2_$4_$5_$6_$7_$8_$9()')') + +# trim(str)->len, str +define(`_trim', `substr(`$1', 0, $2)substr(`$1', incr($2))') +define(`trim', `ifelse(index(`$1', `0'), 0, `$0(substr(`$1', 1))', index( + `$1'0, `00'), -1, `len($1), `$1'', `$0(_$0(`$1', index(`$1'0, `00')))')') +define(`_do', `score(trim(`$1'), eval(`$7 + $6 + $5 + $4 + $3 + $2 + $# - 2'), + shift($@))') +define(`Eval', `ifelse(eval($2>=10000), 1, `errprintn(`failed on $1')')eval( + part1+$2)') +define(`do', `define(`part1', Eval(`$1',_$0(translit(`$1', `/', `,'))))') + +ifdef(`__gnu__', ` + patsubst(defn(`input'), `\([^;]*\);', `do(`\1')') +', ` + define(`_chew', `do(substr(`$1', 0, index(`$1', `;')))define( + `tail', substr(`$1', incr(index(`$1', `;'))))ifelse(index(defn(`tail'), + `;'), -1, `', `$0(defn(`tail'))')') + define(`chew', `ifelse(eval($1 < 68), 1, `_$0(`$2')', `$0(eval($1/2), + substr(`$2', 0, eval($1/2)))$0(eval(len(defn(`tail')) + $1 - $1/2), + defn(`tail')substr(`$2', eval($1/2)))')') + chew(len(defn(`input')), defn(`input')) +') + +divert`'part1 +part2 -- 2.11.4.GIT