about summary refs log tree commit diff stats
path: root/cpp/.traces/subtract_literal
blob: a1a102500e65d34f7d0d5434e991e5c676349515 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
parse/0: instruction: 3
parse/0:   ingredient: {name: "5", value: 0, type: 0, properties: ["5": "literal"]}
parse/0:   ingredient: {name: "2", value: 0, type: 0, properties: ["2": "literal"]}
parse/0:   product: {name: "1", value: 0, type: 1, properties: ["1": "integer"]}
after-brace/0: recipe main
after-brace/0: subtract ...
run/0: instruction main/0
run/0: ingredient 0 is 5
run/0: ingredient 1 is 2
run/0: product 0 is 3
mem/0: storing 3 in location 1
ht: bold } /* Literal.Number.Integer.Long */
use Octans::Neighbors;
use Octans::RangeSearch;

# word-search walks the given grid & tries to find words in the
# dictionary. It walks in Depth-First manner (lookup Depth-First
# search).
sub word-search(
    # @dict holds the dictionary. @puzzle holds the puzzle.
    @dict, @puzzle,

    # $y, $x is the position of the current cell, we have to follow
    # this path. $str is the string we've looked up until now. If it's
    # not passed then assume that we're starting at $y, $x and take
    # @puzzle[$y][$x] as the string.
    #
    # $str should be passed in recursive calls, it's not required when
    # $y, $x is the starting position.
    Int $y, Int $x, $str? = @puzzle[$y][$x],

    # @visited holds the positions that we've already visited.
    @visited? is copy --> List
) is export {
    # If @visited was not passed then mark the given cell as visited
    # because it's the cell we're starting at.
    @visited[$y][$x] = True unless @visited;

    # neighbor block loops over the neighbors of $y, $x.
    neighbor: for neighbors(@puzzle, $y, $x).List -> $pos {
        # Move on to next neighbor if we've already visited this one.
        next neighbor if @visited[$pos[0]][$pos[1]];

        # Mark this cell as visited but only until we search this
        # path. When moving to next neighbor, mark it False.
        @visited[$pos[0]][$pos[1]] = True;

        # $word is the string that we're going to lookup in the
        # dictionary.
        my Str $word = $str ~ @puzzle[$pos[0]][$pos[1]];

        # range-starts-with returns a list of all words in the
        # dictionary that start with $word.
        with range-starts-with(@dict, $word) -> @list {
            if @list.elems > 0 {
                # If $word exist in the dictionary then it should be
                # the first element in the list.
                take @list[0], @visited if @list[0] eq $word;

                # Continue on this path because there are 1 or more
                # elements in @list which means we could find a word.
                word-search(
                    # Don't pass the whole dictionary for next search.
                    # Words that start with "ab" will always be a
                    # subset of words that start with "a", so keeping
                    # this in mind we pass the output of last
                    # range-starts-with (@list).
                    @list, @puzzle, $pos[0], $pos[1], $word, @visited
                );
            }
        }

        # We're done looking up this path, mark this cell as False &
        # move on to another neighbor.
        @visited[$pos[0]][$pos[1]] = False;
    }
}