Fixup day18 and add second part
[advent-of-code-2020.git] / day13 / get_bus.sh
1 #!/bin/bash
2
3 read_file() {
4     local filename="$1"
5     local IFS=","
6     declare -g earliest_leave_time
7     declare -g -a buses
8     exec 3<"$filename"
9     read -u 3 earliest_leave_time
10     read -u 3 -a buses
11 }
12
13 filename=${1:-p1_295.txt}
14
15 read_file "$filename"
16
17 echo "Earliest leave_time: $earliest_leave_time"
18 echo "Buses: ${buses[@]}"
19
20 bus_to_catch=0
21 time_difference=-1
22
23 for bus in ${buses[@]}; do
24     if [ "$bus" == "x" ]; then
25         continue
26     fi
27     # work out how many times this goes in
28     # to earliest time stamp
29     multiplier=$(($earliest_leave_time / $bus))
30     while [ $((bus * $multiplier)) -lt $earliest_leave_time ]; do
31         multiplier=$((multiplier+1))
32     done
33     if [ $(((bus*multiplier)-$earliest_leave_time)) -lt $time_difference ] || [ $time_difference -eq -1 ]; then
34         time_difference=$(((bus*$multiplier)-$earliest_leave_time))
35         bus_to_catch=$bus
36     fi
37 done
38
39 echo "Part 1:"
40 echo "  Bus to catch: $bus_to_catch"
41 echo "  Gotta wait: $time_difference"
42 echo "  Answer: $((bus_to_catch * $time_difference))"
43
44 echo "Part 2:"
45
46 # screw it, we've got prime bus numbers, lets
47 # just loop a bit, and make the step the multiple
48
49 loop=1
50 offset=0
51 step=${buses[0]}
52 for a in "${buses[@]:1}"; do
53     count=0
54     if [ $a == "x" ]; then
55         loop=$((loop+1))
56         continue
57     fi
58     # we need to check a multiple of steps past the offset
59     while [ $((((($offset*${buses[0]}) + ($count*$step)) + $loop) % $a)) -ne 0 ]; do
60         count=$((count+1))
61     done
62     offset=$(($offset + (($count*$step)/${buses[0]})))
63     step=$((step*$a)) # our steps are going to be a product of what we had
64     loop=$((loop+1))
65 done
66
67 echo "  Timestamp: $((offset*${buses[0]}))"
68