DEV Community

loading...

AoC: 2020 Day 06 AWK

Christopher Nilsson
Full-stack enthusiast working currently on next.js/React/Typescript/Node.
・2 min read

⚠️ SPOILER ALERT ⚠️
This is a post with my solutions and learning from the puzzle. Don't continue reading if you haven't tried the puzzle on your own yet.

If you want to do the puzzle, visit adventofcode.com/2020/day/6.

AWK

AWK is an useful tool in the command-line when processing text-files. It has it's own "programming language" which makes it quite powerful.

Prerequisite understandings

Built-in variables:
There are built-in variables in AWK. These are useful to know when doing more complex calculations. In this code I will use FS and NF.

  • FS: Field seperator. It defaults to blank space " ".
  • NF: Number of fields. A counter for number of fields in current line.

No initialize required:
You don't need to initialize variables in AWK. Running var1++ is a valid statement. It will initialize var1 to 0 and then add one. The same principle applies to arrays.

array['X']++ initializes an empty array and then set the key-value. Will equal: { "X": 1 }

Structure:

pattern1 { ACTIONS; }
pattern2 { ACTIONS; }
pattern3 { ACTIONS; }
Enter fullscreen mode Exit fullscreen mode

The pattern is usually a regex for matching lines. For example: /name/ { print $1}. There are two built-in patterns BEGIN and END. They run at the beginning and end of the program. They are good for initializing variables and output results.

Fetching fields:
In an action the fields are accessed by $1 notation. $0 is the whole line. $1 is the first field, $2 is the second field and so on. It is allowed to use variables:

echo "Hello! My name is Christopher." | awk '{ i=5; print $i }'
# Output: Christopher.
Enter fullscreen mode Exit fullscreen mode

Solution

BEGIN {
  # Field separator. Sets each character as an own field
  FS="" 
}
{ # Matches all lines.
  if (NF == 0){ # NF - Number of fields. 0 means empty line
    # Part 1
    total = total + length(group)

    # Part 2
    for(letters in group) {
      if (group[letters] >= person_count) {
        total2 += 1
      }
    }

    # Reset values
    delete group
    person_count = 0
  } else {
    person_count += 1
    for(i=1; i <= NF; i++){ # Iterate through fields
      group[$i]++ 
    }
  }
}
END {
  printf "Solution part 1: " total "\n"
  printf "Solution part 2: " total2 "\n"
}
Enter fullscreen mode Exit fullscreen mode

Save this file as 06.awk and then you can run it this way:

cat 06.input | awk -f 06.awk
Enter fullscreen mode Exit fullscreen mode

Good reads about AWK

Discussion (0)