新增的需求是在字符串中有don’t()和do()开关,如:xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5)),位于don’t()后面,下一个do()之前的mul(x,y)不参与计算。
我的解答是
先将整个文件拆成按don’t()分隔的行,再拆成按do()分隔的列表,因为第一个元素是don’t()控制的,所以从第二个元素开始取数,在字符串开头插入一个多余的add do(),第一行就能和后续行统一处理了。
with t as(select content a from read_text('2403-input.txt'))
,b as(select unnest(string_split('add do()'||a,'don''t()'))b from t)
,c as(select string_split(b, 'do()')c from b)
,t1 as(select c, listagg(c[2:],'') z from c group by c)
,t2 as(select regexp_extract_all(z, 'mul\(*(\d+),*(\d+)\)', 1) l ,regexp_extract_all(z, 'mul\(*(\d+),*(\d+)\)', 2) r from t1)
select sum(l*r)from (select unnest(l)::int l,unnest(r)::int r from t2);
另一种写法是,不插入多余字符串,利用行号和instr(line, ‘do()’)判断某行是否有需要计算的表达式
with t as(select content a from read_text('2403-input.txt'))
,b as(select unnest(string_split(a,'don''t()'))b from t)
,c as(select row_number()over()rn, instr(b, 'do()')pos,b c from b)
,t1 as(select c, case when rn=1 then c when pos>0 then substr(c,pos::int)end z from c)
,t2 as(select regexp_extract_all(z, 'mul\(*(\d+),*(\d+)\)', 1) l ,regexp_extract_all(z, 'mul\(*(\d+),*(\d+)\)', 2) r from t1)
select sum(l*r)from (select unnest(l)::int l,unnest(r)::int r from t2);

849

被折叠的 条评论
为什么被折叠?



