# [Advent Of Code 2022] Day 03 Discussion [SPOILERS]

That was a fun day!

The Exercism exercises Pangram and Sets helped me here Python Solution
``````    INPUT_TYPES = str

def part1(self, parsed_input: InputType) -> int:
"""Find the common element across the first and second half of each line."""
score = 0
for line in parsed_input:
middle = len(line) // 2
a, b = line[:middle], line[middle:]
common = set(a) & set(b)
assert len(common) == 1
score += SCORING.index(common.pop())

return score

def part2(self, parsed_input: InputType) -> int:
"""Find the common element across groups of three lines."""
score = 0
for lines in more_itertools.chunked(parsed_input, 3):
common = set(lines) & set(lines) & set(lines)
assert len(common) == 1
score += SCORING.index(common.pop())

return score
``````
3 Likes

Working with sets in Python is so great that I feel at a disadvantage by not solving problems with sets in Python Typescript Solution
``````type Backpack = string;

interface State {
backpacks: Backpack[];
}

export function parse(input: string): State {
return { backpacks: nonEmptyLines(input) };
}

export function part1(parsed: State): string {
const commonItems = parsed.backpacks.map(findCommonItemTypeInCompartiments);
const priorities = commonItems.map(getItemPriority);
return sumNumbers(priorities).toString();
}

export function part2(parsed: State): string {
const groups = chunkArray(parsed.backpacks, 3);

const badgesforGroups = groups.map((group) => {
const backpacks = group.map((backpack) => new Set(backpack));
return Array.from(intersectSets(...backpacks));
});

return sumNumbers(priorities).toString();
}

function findCommonItemTypeInCompartiments(backpack: Backpack): string {
const middle = backpack.length / 2;
const compartiments = [
new Set(backpack.slice(0, middle)),
new Set(backpack.slice(middle, backpack.length)),
];
return Array.from(intersectSets(...compartiments));
}

const LOWER_A = "a".charCodeAt(0);
const UPPER_A = "A".charCodeAt(0);

function getItemPriority(item: string): number {
const c = item.charCodeAt(0);
const diff = isUppercase(item) ? c - UPPER_A + 26 : c - LOWER_A;
return diff + 1;
}
``````
1 Like

I was also wondering if sets were the best approach. It is my longest-running problem so far. You think it would be better to get it done with some string magic?

Solution in Elixir
``````defmodule AdventOfCode.Day03 do
def part1(args) do
args
|> String.split()
|> Enum.map(&splitInHalf/1)
|> Enum.map(&findDuplicate/1)
|> Enum.map(&convertToPriority/1)
|> Enum.sum()
end

def splitInHalf(str), do: String.split_at(str, div(String.length(str), 2))

def findDuplicate({str1, str2}),
do:
MapSet.intersection(
MapSet.new(String.codepoints(str1)),
MapSet.new(String.codepoints(str2))
)
|> MapSet.to_list()
|> hd()

def findCommon([str1, str2, str3]),
do:
MapSet.intersection(
MapSet.new(String.codepoints(str1)),
MapSet.intersection(
MapSet.new(String.codepoints(str2)),
MapSet.new(String.codepoints(str3))
)
)
|> MapSet.to_list()
|> hd()

def convertToPriority(<<c::utf8, _::binary>>) when c <= ?z and c >= ?a, do: c - ?a + 1
def convertToPriority(<<c::utf8, _::binary>>) when c <= ?Z and c >= ?A, do: c - ?A + 27
def convertToPriority(_), do: :error

def part2(args) do
args
|> String.split()
|> Stream.chunk_every(3)
|> Enum.map(&findCommon/1)
|> Enum.map(&convertToPriority/1)
|> Enum.sum()
end
end
``````

@iHiD Can we have some nice syntax highlighting in Elixir code snippets?

1 Like

I need to learn to read directions more carefully. I thought part 2 required you to find the sets of 3 instead of just evaluating progressive groups of three.

I am still a relatively newbie, and feedback is welcome.

go Solution
``````func part1(lines []string) (res int) {
for _, line := range lines {
split := len(line) / 2
res += decodeBinary(encodeBinary(line[:split]) & encodeBinary(line[split:]))
}
return res
}

func part2(lines []string) (res int) {
for i := 0; i < len(lines); i += 3 {
set := ^uint64(0)
for _, line := range lines[i : i+3] {
set &= encodeBinary(line)
}
res += decodeBinary(set)
}
return res
}

func decodeBinary(b uint64) (res int) {
for b >>= 1; b > 0; res++ {
b >>= 1
}
return res
}

func encodeBinary(line string) (res uint64) {
for _, char := range line {
res |= (1 << priority(char))
}
return res
}

func priority(char rune) int {
switch {
case unicode.IsLower(char):
return int(char-'a') + 1
default:
return int(char-'A') + 27
}
}
``````
1 Like

This went a lot easier than Day 2, and I’ll have some fun cleaning this one up later I think.

Julia Solution

module day03
priorities = Dict(char => v for (char , v) in zip([‘a’:‘z’; ‘A’:‘Z’], 1:52))
compartments(rucksack) = [rucksack[1:div(end,2)], rucksack[div(end,2)+1:end]]

``````function part01()
score = 0
if length(l) != 0
left, right = compartments(l)
uniq = intersect(left, right)
score += priorities[uniq]
end
end
score
end

function part02()
score = 0
for group in Iterators.partition(groups, 3)
uniq = intersect(group...)
score += priorities[uniq]
end
score
end
``````

end
println(“P01: (day03.part01())") println("P02: (day03.part02())”)

Ruby Solution
``````PRIORITIES = [nil, *'a'..'z', *'A'..'Z'].freeze

def priority(item_types) = PRIORITIES.index(item_types.map(&:chars).reduce(:&).first)