Feedback on AoC Solution

16 views
Skip to first unread message

umma...@gmail.com

unread,
Dec 31, 2020, 12:17:48 AM12/31/20
to pure-lang
Hello!

It's been a while since my first message last October. I was going to probably be writing more as I planned to do Advent of Code 2020 in Pure but decided to use C to destress with some nostalgia programming instead, and that's been great.

A conversation with coworkers, however, on how they solved Day 18 made me realize it would be neat to try and use Pure for a second time (the problem involves changing the precedence of arithmetic among + and * -- my colleague used JavaScript's .replace method of string objects).

Here's my Pure solution to the problem. Part one is to just have + and * have equal precedence but with left associativity. Part two is to have + bind tighter than *. If you have a few moments, could you please tell me how this could be better in a Pure idiomatic / style sense. Thanks!

using system, regex ;

leftFirst = reduce with a + b * c = (a + b) * c end ;
addFirst = reduce with
  a * b + c = prod(a, b + c) ;
  a + b * c = dorp(a + b, c) ;
  prod(a, b) + c = prod(a, b + c) ;
  a + dorp(b, c) = dorp(a + b, c) ;
  dorp(a, b) = prod(a, b) ;
  'prod(a, b) = prod(a, b) ;
  prod(prod(a, b), c) = prod(a * b, c) ;
  prod(a, prod(b, c)) = prod(a, b * c) ;
  prod(a, b) = a * b ;
end ;

fixed f a = loop a (f a) with
  loop b bb = b if same b bb ;
            = loop bb (f bb) otherwise ;
end ;

quoted s = regsub (cst "'(") "(" 0 s 0 ; // can these two be done more idiomatically?
toLong s = regsub (\s -> s!1 + "L") "[[:digit:]][[:digit:]]*" 0 s 0 ;
let input = map val . filter ("" ~=) . split "\n" . toLong . quoted . fget $ fopen "input.raw" "r" ;
run r = init . str . foldl (+) 0L . map (fixed eval . r) $ input ;
printf "Part 1: %s\nPart 2: %s\n" (run leftFirst, run addFirst) ;

umma...@gmail.com

unread,
Dec 31, 2020, 12:20:10 AM12/31/20
to pure-lang
Additionally, the "input.raw" file has lines of the following form (just simple expressions):

9 + 4 + (3 + (6 * 5 + 9 * 2 * 4) * 9)
((7 + 6) + 2 * 6 + 4 * 2 + 9) * 6 + 5
7 * 3 * 9 * 6 + (4 + 2 + 4 * 9) + 7
9 + (9 * 3 * 3 * (9 + 5 + 4) + 4)
(8 * 5 + (7 + 5 + 3 + 6) * 9 + 7 * (9 * 8 + 7 * 2)) * 8
3 + (6 * 2 * (9 + 2 + 5) * (9 * 2 * 6 + 8 * 5) * (2 + 2 + 3 + 7 * 9)) + 4 * 4 + (6 * 4 * (9 + 4) + 8 * 3 * (5 + 3)) * 5
2 * 8 * (8 * 2 * 4) + (9 * 3 * 6) * 9
2 + (8 * 4 * 9 * 3 + 8 * 2) + 4 * 9 * 6
((6 * 4 + 9 + 5 * 7 + 3) * 4 + 8 * (3 + 6 + 9 * 9) + 9 * 6) + (7 * 7) + 6 * 2 * 2
2 + 5 * 3

And, as shown in the code, answer is given as the sum of the evaluation of all lines.

umma...@gmail.com

unread,
Dec 31, 2020, 5:54:05 PM12/31/20
to pure-lang
I simplified the reduce a lot and have the following. Just updating so that no one unnecessarily types out a long email.

Happy Holidays.

using system, regex ;

leftFirst = reduce with a + b * c = (a + b) * c end ;
addFirst = reduce with
  a * b + c = prod(a, b + c) ;
  a + b * c = prod(a + b, c) ;
Reply all
Reply to author
Forward
0 new messages