--- /dev/null
+#!/bin/bash
+
+check_file() {
+ cat input.txt | while read line; do
+ password=${line#*: }
+ params=${line%: *}
+ min=${params%-*}
+ params=${params#*-}
+ max=${params% *}
+ char=${params#* }
+ count=0
+ for ((i=0; i<${#password}; i++)); do
+ if [ "${password:$i:1}" = "$char" ]; then
+ count=$((count+1))
+ fi
+ done
+ if [ $count -ge $min ] && [ $count -le $max ]; then
+ echo "Got valid line!"
+ fi
+ done
+}
+
+echo "Got $(check_file | wc -l) valid lines"
+
+exit 0
+#!/usr/bin/python3
+
+import regex
+
+total_lines=0
+valid_lines=0
+for line in open("input.txt", "r"):
+ total_lines += 1
+ (min_count, max_count, letter, password) = regex.match('([0-9]+)-([0-9]+) ([a-z]): ([a-z]*)', line).group(1,2,3,4)
+ min_count=int(min_count)
+ max_count=int(max_count)
+ count = 0
+ for x in password:
+ if x == letter:
+ count += 1
+ if count >= min_count and count <= max_count:
+ valid_lines += 1
+
+print(valid_lines, "valid lines of", total_lines)
--- /dev/null
+#!/bin/bash
+
+check_file() {
+ cat input.txt | while read line; do
+ password=${line#*: }
+ params=${line%: *}
+ min=${params%-*}
+ params=${params#*-}
+ max=${params% *}
+ char=${params#* }
+ count=0
+ min=$((min-1))
+ max=$((max-1))
+ if [ "${password:$min:1}" = "$char" ] || [ "${password:$max:1}" = "$char" ]; then
+ if [ "${password:$min:1}" != "${password:$max:1}" ]; then
+ echo "Got valid line! $line"
+ fi
+ fi
+ done
+}
+
+echo "Got $(check_file | wc -l) valid lines"
+
+exit 0
--- /dev/null
+#!/bin/bash
+
+start_letter=0
+line_number=0
+tree_count=0
+
+for line in $(<input.txt); do
+ line_number=$((line_number+1))
+ if [ $line_number -eq 1 ]; then
+ continue
+ fi
+ start_letter=$((start_letter+3))
+ if [ $start_letter -ge ${#line} ]; then
+ start_letter=$((start_letter - ${#line}))
+ fi
+ if [ "${line:$start_letter:1}" = "#" ]; then
+ tree_count=$((tree_count+1))
+ fi
+done
+
+echo "Hit $tree_count trees"
+
+exit 0
+
+#!/usr/bin/python3
+
+trees_count = 0
+position = 3 # forth square in, we moved 3 right from where we were, 0 + 3 -> 3
+on_first_line = True
+line_number = 0
+
+for line in open("input.txt", "r"):
+ line_number += 1
+ print("line: ", line_number)
+ line = line.rstrip()
+ print(line)
+ if on_first_line:
+ on_first_line = False
+ continue
+ print(line[position], position)
+ if line[position] == "#":
+ trees_count += 1
+ print("hit tree")
+ else:
+ print("missed tree")
+ # now add 3 to the position
+ position += 3
+ if position >= len(line):
+ position = position - len(line)
+
+print("There were", trees_count, "trees")
--- /dev/null
+#!/bin/bash
+
+moves=("1,1" "3,1" "5,1" "7,1" "1,2")
+
+count_trees() {
+ right=$1
+ down=$2
+ cur_down=-1 # we want to skip the very first line
+ pos=0
+ tree_count=0
+ for line in $(<input.txt); do
+ cur_down=$((cur_down+1))
+ if [ $cur_down -eq $down ]; then
+ cur_down=0
+ pos=$((pos + $right))
+ if [ $pos -ge ${#line} ]; then
+ pos=$((pos - ${#line}))
+ fi
+ if [ ${line:$pos:1} = "#" ]; then
+ tree_count=$((tree_count+1))
+ fi
+ fi
+ done
+ echo "$tree_count"
+}
+
+mult_total=1
+for move in ${moves[@]}; do
+ down=${move#*,}
+ right=${move%,*}
+ trees=$(count_trees $right $down)
+ echo "Move: $move has $trees trees"
+ mult_total=$((mult_total * $trees))
+done
+
+echo "Answer: $mult_total"
+
+exit 0
+
+#!/usr/bin/python3
+
+trees_count = []
+on_first_line = True
+line_number = 0
+
+move_types = ((1,1), (3,1), (5,1), (7,1), (1,2))
+
+for move in move_types:
+ line_offset = 0
+ tree_count = 0
+ position = move[0]
+ first_line = True
+ for line in open("input.txt", "r"):
+ line = line.rstrip()
+ print(move[1], line_offset)
+ if line_offset < move[1] or first_line:
+ line_offset += 1
+ if line_offset >= move[1]:
+ first_line = False
+ continue
+ line_offset = 1
+ if line[position] == "#":
+ tree_count += 1
+ position += move[0]
+ if position >= len(line):
+ position = position - len(line)
+ trees_count.append(tree_count)
+ tree_count = 0
+
+mult_result = 1
+for x in trees_count:
+ print(x)
+ mult_result *= x
+
+print("There were", mult_result, "trees")
--- /dev/null
+#!/bin/bash
+
+declare -a data
+cur_data=""
+seperator=""
+valid_count=0
+
+required_fields=(byr iyr eyr hgt hcl ecl pid)
+exec 3<input.txt
+
+while read -u 3 line; do
+ if [ "$line" = "" ]; then
+ data+=("$cur_data")
+ seperator=""
+ cur_data=""
+ continue
+ fi
+ cur_data="${cur_data}${seperator}$line"
+ seperator=" "
+done
+
+# on the last line, if cur_data isn't empty, add that to the array
+if [ "$cur_data" != "" ]; then
+ data+=("$cur_data")
+fi
+
+for (( i=0; i<${#data[@]}; i++ )); do
+ record="${data[$i]}"
+ declare -A kvp
+ for field in $record; do
+ key=${field%:*}
+ value=${field#*:}
+ kvp[$key]=$value
+ done
+ for field in ${required_fields[@]}; do
+ if ! [ ${kvp[$field]+a} ]; then
+ continue 2
+ fi
+ done
+ valid_count=$((valid_count+1))
+ unset kvp
+done
+
+echo "$valid_count valid entries"
--- /dev/null
+#!/bin/bash
+
+declare -a data
+cur_data=""
+seperator=""
+valid_count=0
+
+required_fields=(byr iyr eyr hgt hcl ecl pid)
+
+check_year() {
+ value=$1
+ min=$2
+ max=$3
+
+ if [ $value -ge $min ] && [ $value -le $max ]; then
+ exit 0
+ fi
+ exit 1
+}
+
+check_height() {
+ value=$1
+ units=${value:$((${#value}-2)):2}
+ value=${value:0:$((${#value}-2))}
+ case $units in
+ in)
+ if [ $value -ge 59 ] && [ $value -le 76 ]; then
+ exit 0
+ fi
+ ;;
+ cm)
+ if [ $value -ge 150 ] && [ $value -le 193 ]; then
+ exit 0
+ fi
+ ;;
+ *)
+ ;;
+ esac
+ exit 1
+}
+
+check_hair() {
+ value=$1
+
+ if [ ${value:0:1} != "#" ]; then
+ exit 1
+ fi
+
+ if [[ $value =~ /^[a-f0-9]{6}$/ ]]; then
+ exit 1
+ fi
+
+ exit 0
+}
+
+check_eyes() {
+ colour="$1"
+ case $colour in
+ amb|blu|brn|gry|grn|hzl|oth)
+ exit 0
+ ;;
+ *)
+ exit 1
+ ;;
+ esac
+ exit 1
+}
+
+check_data() {
+ local -n record=$1
+ for x in ${!record[@]}; do
+ value=${record[$x]}
+ case $x in
+ byr)
+ if ! ( check_year $value 1920 2002 ); then
+ exit 1
+ fi
+ ;;
+ iyr)
+ if ! ( check_year $value 2010 2020 ); then
+ exit 1
+ fi
+ ;;
+ eyr)
+ if ! ( check_year $value 2020 2030 ); then
+ exit 1
+ fi
+ ;;
+ hgt)
+ if ! ( check_height $value ); then
+ exit 1
+ fi
+ ;;
+ hcl)
+ if ! ( check_hair $value ); then
+ exit 1
+ fi
+ ;;
+ ecl)
+ if ! ( check_eyes $value ); then
+ exit 1
+ fi
+ ;;
+ pid)
+ value=${record[$x]}
+ if [ ${#value} -ne 9 ]; then
+ exit 1
+ fi
+ ;;
+ *)
+ ;;
+ esac
+ done
+
+ exit 0
+}
+
+exec 3<input.txt
+
+while read -u 3 line; do
+ if [ "$line" = "" ]; then
+ data+=("$cur_data")
+ seperator=""
+ cur_data=""
+ continue
+ fi
+ cur_data="${cur_data}${seperator}$line"
+ seperator=" "
+done
+
+# on the last line, if cur_data isn't empty, add that to the array
+if [ "$cur_data" != "" ]; then
+ data+=("$cur_data")
+fi
+
+for (( i=0; i<${#data[@]}; i++ )); do
+ record="${data[$i]}"
+ declare -A kvp
+ for field in $record; do
+ key=${field%:*}
+ value=${field#*:}
+ kvp[$key]=$value
+ done
+ for field in ${required_fields[@]}; do
+ if ! [ ${kvp[$field]+a} ]; then
+ continue 2
+ fi
+ done
+ if ( check_data kvp ); then
+ valid_count=$((valid_count+1))
+ fi
+ unset kvp
+done
+
+echo "$valid_count valid entries"