day 6
a calm (before the storm)
much easier parsing today, no need to even bother reading seperate lines!
clean solutions galore as well
lets get on with it
click to view my solution
given the sample input:
mjqjpqmgbljsphdztnvjfqwrcgsmlb
assuming input
is the above as one big string,
packets = input |> String.graphemes()
split input into its characters
i say characters, but the [underlying function] is named graphemes, since it is splitting on unicode graphemes
["m", "j", "q", "j", "p", "q", "m", "g", "b", "l", "j", "s", "p", "h", "d", "z", "t", "n", "v", "j",
"f", "q", "w", "r", "c", "g", "s", "m", "l", "b"]
we are left with list of… i’m gonna call them charcaters again its easier to write
defmodule CommunicationDevice do
def find_first_duplicate(packets, chunk_size) do
index =
packets
|> Enum.chunk_every(chunk_size, 1, :discard)
|> Enum.map(&MapSet.new(&1))
|> Enum.with_index()
|> Enum.find(fn {set, _index} -> MapSet.size(set) == chunk_size end)
|> elem(1)
index + chunk_size
end
end
nice little single function module here!
find_first_duplicate/2
accepts our list of packets, and a chunk_size parameter
# ...
packets
|> Enum.chunk_every(chunk_size, 1, :discard)
# ...
this solution relies on [Enum.chunk_every/4] quite a bit, it basically acts as a sliding window
say i was given the list [1,2,3,4]
, and used this chunk_every function
with the firt argument the list, the second the chunk size (2), and the
third being the step, (with the :discard atom), we would get the following enumerable:
[[1,2], [2,3], [3,4]]
(the :discard atom is used to ensure we don’t get a [4]
show up in
this list, if any returned enumerable is less than the size of the chunk,
it is discarded)
back to the function,
# ...
|> Enum.map(&MapSet.new(&1))
|> Enum.with_index()
# ...
then, we map over each one of these chunks into MapSet
s
and we include the index (what step we are on) by mapping
the resulting MapSet
s enumerable with Enum.with_index
[
{MapSet.new(["j", "m", "q"]), 0},
{MapSet.new(["j", "p", "q"]), 1},
{MapSet.new(["j", "p", "q"]), 2},
{MapSet.new(["j", "m", "p", "q"]), 3},
{MapSet.new(["g", "m", "p", "q"]), 4},
# ...
]
we are left with this, the first three MapSet
s with a length less
than 4 characters, even though 4 characters (we are using part 1 as the example
here) were used to generate them, but the 4th item in this list having
a MapSet
with a size of 4, implies no duplicates in the characters used to
produce this one!
# ...
|> Enum.find(fn {set, _index} -> MapSet.size(set) == chunk_size end)
|> elem(1)
# ...
pluck out the first tuple with a MapSet
the size of our chunk size, and pluck
the second item out of the tuple, since we are concerned with the index and not
the actual MapSet
itself
# ...
index + chunk_size
then, with this index, return it plus the chunk_size
, since the value on
the end of the window would be the first non-duplicate we run into in the
devices stream, and if we just returned the index, it would be incorrectly
offset
part 1
CommunicationDevice.find_first_duplicate(packets, 4) # -> 7
with our new fangled device module, use it, with a chunk size of 4
part 2
CommunicationDevice.find_first_duplicate(packets, 14) # -> 19
and, do it again, but with a chunk size of 14
nice
the full solution can be found [here]
others
there’s going to be lots of inline code today
[Mudkip/AdventOfCode] python src/data/aoc/2022/data[briannamcdonald/advent-of-code-2022] python src/data/aoc/2022/datadef solve(n): input = open("6.in", "r").read().strip() return next(i+n for i in range(len(input)) if len(set(input[i:i+n])) == n) print(f"Part 1: {solve(4)}") print(f"Part 2: {solve(14)}")
super clean, but also not crazy busy? maybe i’ve just read too many of your list comprehensions and grown to not hate them :D
i really like the usage of
next
here to find the first valid item that matches the conditonal bit of the list comp.as usual, compact and epic
[krbarter/Advent-Of-Code-2022] python src/data/aoc/2022/dataa solution, could probably be compacted quite a bit though
chars_unique
could early return false instead of continually iterating after settingunique
to false
[nint8835/AdventOfCode2022] f# & python src/data/aoc/2022/dataline = open("input.txt", "r").readlines()[0] def solve(line, length): for x in range(0, len(line) - (length - 1)): if len(set([line[x + y] for y in range(0, length)])) == length: return (x + length) print("Part1: ", solve(line, 4), "Part2: ", solve(line, 14))
nice
a compact python solution
yeah
[hamzahap/AdventOfCode2022] sheets src/data/aoc/2022/datalet inputData = (System.IO.File.ReadAllText "Day6/input.txt") let findMarker (size: int) (input: string) : int = input |> Array.ofSeq |> Array.windowed size |> Array.map (fun window -> (window |> Set.ofArray |> Set.count)) |> Array.findIndex (fun uniqueCount -> uniqueCount = size) |> (+) size printfn $"%A{findMarker 4 inputData}" printfn $"%A{findMarker 14 inputData}"
first riley solution included fully inline, and its clean
quite similar conceptually to my solution, but i do like converting the array to a set, and then just counting the number of values in the set, since the find statement is then just comparing between the length of the chunks and how many items were in the set
also the
(+) size
is nice, i should look to see how i would do this in elixir :)
[TheCrypticCanadian/advent-of-code-2022] python src/data/aoc/2022/data=IF(COUNTUNIQUE(B1427:B1430)=4,"You reached my guy","You no reach noob")
you reached my guy
[STollenaar/AdventOfCode2022] golang src/data/aoc/2022/dataok so to begin with, how dare you [change your folder naming structure] without consulting me first
i kid, i have [the tools] to update this in one spot, and have every link from here to your solution automagically update
your solution though, is nice, although you could have defined a cell above with a function to make your part 1 & 2 reusable :)
good job gump
[emilydormody/advent-of-code] src/data/aoc/2022/dataclean go
not compact enough to include inline, but i don’t think a go solution will ever be that? it feels like it goes against the language design if it does
but still, clean go
[zcvaters/adventofcode2022] swift src/data/aoc/2022/datawoooaaahhh a little queue
this is nice, fill up the queue, check for dups, and if dupes move on, but always be poppin’ one off of the queue to keep it with a length of 4 / 14
nice
you could probably do your part 1 & 2 in one file since, like most, the only thing seperating them is putting a 1 infront of the 4 in part one to make it 14
[chadmroberts88/advent-of-code-2022] typescript src/data/aoc/2022/datanice
this also gives the vibes of emilys queue solution, but uses a set to do the duplication finding, therefore no need for a utility function
nice
[devthedevel/advent_of_code] typescript src/data/aoc/2022/datainteresting solution here, reaching for a regular expression
/(.).*\1/.
i put this into [regexr.com] to get a better understanding of it (since my regex-fu is lacking)
i sort of get it, but i don’t really understand the magic going on with capture group backreferencing here
Chad Roberts: Love it when you can use one function to solve both parts! (Full Disclosure: I Googled the RegEx!)
i feel like this is the response of most people who say “where did you get this regex?”
still neat to think of this as a possible solution method!
[mathieuboudreau/advent] python notebook src/data/aoc/2022/datadev from the clouds, has duplicated code between part 1 and 2
are the clouds to be trusted?
i thought i should ask lord poseidon about this, via [ChatGPT], here is his response:
Dear Devin,
I, Lord Poseidon, have noticed that your code is quite impressive. However, I must point out that you have included duplicated code in your solutions. As a wise programmer, you should know that it is best practice to break out your code into utility functions to avoid repetition and make your code more organized and efficient.
Please consider this advice and continue to strive for excellence in your coding endeavors.
Best regards,
Lord Poseidon
[ajhynes7/advent-of-code-2022] julia src/data/aoc/2022/datanice
could probably cut out
num_chars
by iterating over a range and then breaking once you get to the valueand because python will keep the value you iterate over in-scope you can just print it at the end
for x in range(5): if x == 3: break print(x) # -> 3
^ an example of what i’m talking about, a sneaky pythonism
[RyanBrushett/adventofcode2022] ruby src/data/aoc/2022/datanice, very nice
the usage of [CircularDeque] is cool, a more sensible data structure to use since yeah the only operation you need to do if you are doing it the listy way is enqueue and dequeue
and also the function here acting directly on the file, but still remaining super clean
also
allunique
being a top-level function???julia is good for this stuff wow
[joel1842/advent-of-code-2022] python src/data/aoc/2022/datatest cases! nice
def run input_data.each_char.with_index do |x, i| if packet.length < signal_length packet << x next end return i if packet & packet == packet (packet << x).shift end end
clean, i always like seeing
&
being used for set operations
[canetoads.ca] javascript src/data/aoc/2022/datai can tell by your file path you are on linux, nice
but, this is because your full fat file path is in the file :P
stop that
interesting approach though, basically calculating both at the same time
it would technically add a line, but i would break from the for loop when startOfPacket and startOfMessage are both defined
also, [preferably you’d be using
snake_case
] instead ofcamelCase
[apreynolds1989/AdventOfCode2022] typescript src/data/aoc/2022/datai don’t think there will ever be a nathan solution without a horizontal scroll bar :P
console.log( fs .readFileSync(io) .toString() .split("") .map((x, i, a) => new Set(a.slice(i - 14, i))) .map(function (x, i) { if (x.size == 14) return { x, i }; }) .filter((x) => x) .map((x) => x.i) );
now, i know this isn’t as compact, but this is a bit nicer to grok
also this is technically only a part 2 solution since 14 is hard coded, could be broken out into a util function and invoked twice below to get 1 & 2
but hey, i am not your mum
[EthanDenny/AdventOfCode2022] c++ src/data/aoc/2022/dataREDUCER
even i didn’t pull out a reducer today, nice
good set usage as well
epic
[lilmert/aoc] rust src/data/aoc/2022/dataa c++ solution
pretty nice and simple
yeah
[bjbemister19/AdventOfCode] rust src/data/aoc/2022/data:clean:
itertools usage with windowing and unique counting
but whats this
unwrap usage
marty please, think of the children
[M-ArafatZaman/AdventOfCode] python & c++ src/data/aoc/2022/datano unwraps in this rust code, phew
feels quite similar logically to the c++ solution, but more crustacean-like
[SheldonT/AdventOfCode2022] java src/data/aoc/2022/datanice c++ solution
you read the input twice though, could read once and pass to both solve calls, or just put it in a global variable because there are no rules
a java solution!
quite decent
this is a nitpiq, but i’d run your code through the [google-java-format] utility (or some other java formatter) to clean it up a bit, a little too much in the way of newlines here
if you want to have your repo added for me to make a note of / talk about here (or have you repo removed), reach out:
email -> me@jackharrhy.com
discord -> <i>jack arthur null</i>#7539