Skip to content

Instantly share code, notes, and snippets.

@mattmc3
Last active December 9, 2021 15:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mattmc3/a058c1870fd61ed0de20693687161a89 to your computer and use it in GitHub Desktop.
Save mattmc3/a058c1870fd61ed0de20693687161a89 to your computer and use it in GitHub Desktop.
Advent of Code 2021 - Day 8
function day8 \
--description "https://adventofcode.com/2021/day/8 - usage: day8 part1 datafile.dat" \
--argument-names part datafile
test -f "$datafile"; or echo >&2 "file expected" && return 1
set part (string match --regex '.$' $part)
day8part$part $datafile
end
function day8part1 \
--argument-names datafile
set --local data (cat $datafile)
set --local digit_lengths
for row in $data
set --local left_right (string split ' | ' $row)
set --local digits (string split ' ' $left_right[2])
# 1:=2 4:=4 7:=3 8:=7
set digit_lengths $digit_lengths (string length $digits | string match --regex '2|4|3|7')
end
count $digit_lengths
end
function day8part2 \
--argument-names datafile
# logic path:
# - diff 7&1 to find seg a
# - diff 4&1, and see which remaining segment is in 0/6/9 which gets seg b&d
# - we now have 3 segments, so we can distinguish 5 from the 2/3/5 set
# - diff 5&1 to identify segments c&f
# - use segment f to distinguish 2 from 3
# - use 3 to identify remaining segments e&g
set --local data (cat $datafile)
set --local result 0
for row in $data
set --local top_horiz # a
set --local top_left_vert # b
set --local top_right_vert # c
set --local mid_horiz # d
set --local bottom_left_vert # f
set --local bottom_right_vert # f
set --local bottom_horiz # g
set --local left_right (string split ' | ' $row)
set --local codex (string split ' ' $left_right[1])
set --local one (string match --regex '^.{2}$' $codex)
set --local seven (string match --regex '^.{3}$' $codex)
set --local four (string match --regex '^.{4}$' $codex)
set --local two_three_five (string match --all --regex '^.{5}$' $codex)
set --local six_nine_zero (string match --all --regex '^.{6}$' $codex)
# we can determine the top horizontal by comparing the 1 and the 7
for char in (string split '' $seven)
if not contains $char (string split '' $one)
set top_horiz $char
break
end
end
# the 4 matches the 1 on the top right vert and bottom right vert
# the remaining two segments are the horiz middle and top left vert
# we can get the horiz middle by comparing with the six_nine_zero
set --local possibilities
for char in (string split '' $four)
if not contains $char (string split '' $one)
set --append possibilities $char
end
end
for char in $possibilities
if test (count (string match --all '*'$char'*' $six_nine_zero)) -eq 2
set mid_horiz $char
else
set top_left_vert $char
end
end
# now, we have 3 segments, and they all appear in "5", but not 2&3
# we can identify the codex for 5
#set --local codex5
for digit in $two_three_five
contains $top_horiz (string split '' $digit) || continue
contains $mid_horiz (string split '' $digit) || continue
contains $top_left_vert (string split '' $digit) || continue
set codex5 $digit && break
end
set --local two_three (string match --invert $codex5 $two_three_five)
# now that we have the codex for 5 we can determine which segment is which
# for the number 1, since 5 has only one of those two segs
for char in (string split '' $one)
if contains $char (string split '' $codex5)
set bottom_right_vert $char
else
set top_right_vert $char
end
end
# the number 2 is missing vert bottom right, so we can identify codex2&3
for digit in $two_three
if contains $bottom_right_vert (string split '' $digit)
set codex3 $digit
end
end
# now we can easily identify the final two segments
for char in a b c d e f g
if test $char != $top_horiz && \
test $char != $top_left_vert && \
test $char != $top_right_vert && \
test $char != $mid_horiz && \
test $char != $bottom_right_vert
if contains $char (string split '' $codex3)
set bottom_horiz $char
else
set bottom_left_vert $char
end
end
end
# now that we have the segments identified, let's sum up the output values
set --local output
for digit in (string split ' ' $left_right[2])
set --append output (
segment-repr-to-digit \
$top_horiz \
$top_left_vert \
$top_right_vert \
$mid_horiz \
$bottom_left_vert \
$bottom_right_vert \
$bottom_horiz \
$digit
)
end
string join '' $output
set result (math $result + (string join '' $output))
end
echo $result
end
function segment-repr-to-digit \
--argument-names a b c d e f g repr
set len (string length $repr)
set chars (string split '' $repr)
switch $len
case 2
echo 1
case 3
echo 7
case 4
echo 4
case 5
if not contains $c $chars
echo 5
else if not contains $e $chars
echo 3
else
echo 2
end
case 6
if not contains $d $chars
echo 0
else if not contains $c $chars
echo 6
else
echo 9
end
case 7
echo 8
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment