with open("04_input.txt") as file:
data = file.read().splitlines()
total_lines_contained = 0
total_lines_overlapping = 0
for line in data:
assignment_1, assignment_2 = (tuple(map(int, interval.split("-"))) for interval in line.split(","))
interval_1, interval_2 = set(range(assignment_1[0], assignment_1[1] + 1)), set(range(assignment_2[0], assignment_2[1] + 1))
if interval_1 & interval_2 in (interval_1, interval_2):
total_lines_contained += 1
if interval_1 & interval_2:
total_lines_overlapping += 1
print(total_lines_contained)
print(total_lines_overlapping)
#AoC 2022 | Day 4 | Solutions & Spoilers
1508 messages · Page 2 of 2 (latest)
Super difficult pt. 1 and then... surprise even more difficult pt 2 no Christmas rest for you
oh right, 2019 25 was an intcode text adventure
- that's not a CLI that's a script interface
- how is 'a' and 'b' more clear than '1' and '2'? Literally 'the first part' and 'the second part'
- okay fair
- Just subjectively, things like 1a is clearer than 1-1 or whatever IMO, but again, subjective
(you can do either one in the script interface, I checked)
Nothing that can save characters unfortunately
#d4p1
def d4p1(text):
lines = text.splitlines()
func = lambda x:any([all([c in list(range(int(x.replace('-',' ').replace(',',' ').split()[0]),int(x.replace('-',' ').replace(',',' ').split()[1])+1)) for c in list(range(int(x.replace('-',' ').replace(',',' ').split()[2]),int(x.replace('-',' ').replace(',',' ').split()[3])+1))]),all([z in list(range(int(x.replace('-',' ').replace(',',' ').split()[2]),int(x.replace('-',' ').replace(',',' ').split()[3])+1)) for z in list(range(int(x.replace('-',' ').replace(',',' ').split()[0]),int(x.replace('-',' ').replace(',',' ').split()[1])+1))])])
#func = lambda x:[x.replace('-',' ').replace(',',' ').split()]
for i in lines:
yield func(i)
#d4p2
def d4p2(text):
lines = text.splitlines()
func = lambda x:any([any([c in list(range(int(x.replace('-',' ').replace(',',' ').split()[0]),int(x.replace('-',' ').replace(',',' ').split()[1])+1)) for c in list(range(int(x.replace('-',' ').replace(',',' ').split()[2]),int(x.replace('-',' ').replace(',',' ').split()[3])+1))]),any([z in list(range(int(x.replace('-',' ').replace(',',' ').split()[2]),int(x.replace('-',' ').replace(',',' ').split()[3])+1)) for z in list(range(int(x.replace('-',' ').replace(',',' ').split()[0]),int(x.replace('-',' ').replace(',',' ').split()[1])+1))])])
for i in lines:
yield func(i)
```d4 solve almost one line solution
actually i can make it less
return map(lambda x ...., text.splitlines())
sum(anyfunc for i in text.splitlines()) you don't need the lambda
def d4p1(text):
return sum([any([all([c in list(range(int(x.replace('-',' ').replace(',',' ').split()[0]),int(x.replace('-',' ').replace(',',' ').split()[1])+1)) for c in list(range(int(x.replace('-',' ').replace(',',' ').split()[2]),int(x.replace('-',' ').replace(',',' ').split()[3])+1))]),all([z in list(range(int(x.replace('-',' ').replace(',',' ').split()[2]),int(x.replace('-',' ').replace(',',' ').split()[3])+1)) for z in list(range(int(x.replace('-',' ').replace(',',' ').split()[0]),int(x.replace('-',' ').replace(',',' ').split()[1])+1))])]) for x in text.splitlines()])
def d4p2(text):
return sum([any([any([c in list(range(int(x.replace('-',' ').replace(',',' ').split()[0]),int(x.replace('-',' ').replace(',',' ').split()[1])+1)) for c in list(range(int(x.replace('-',' ').replace(',',' ').split()[2]),int(x.replace('-',' ').replace(',',' ').split()[3])+1))]),any([z in list(range(int(x.replace('-',' ').replace(',',' ').split()[2]),int(x.replace('-',' ').replace(',',' ').split()[3])+1)) for z in list(range(int(x.replace('-',' ').replace(',',' ').split()[0]),int(x.replace('-',' ').replace(',',' ').split()[1])+1))])]) for x in text.splitlines()])
here we go
Had to write it on mobile, it was painful
import re
from operator import methodcaller
from pathlib import Path
data = Path("input.txt").read_text().split("\n")
pattern = re.compile(r"(\d+)-(\d+),(\d+)-(\d+)")
print(sum((x1<=y1<=x2 and x1<=y2<=x2) or (y1<=x1<=y2 and y1<=x2<=y2) for x1, x2, y1, y2 in map(lambda g: map(int, g), map(methodcaller("groups"), (map(pattern.match, data))))))
print(sum((x1<=y1<=x2 or x1<=y2<=x2 or y1<=x1<=y2) for x1, x2, y1, y2 in map(lambda g: map(int, g), map(methodcaller("groups"), (map(pattern.match, data))))))
Is there a more interesting way to check overlap? Besides creating the full range
x2 >= y1 and y2 >= x1
I tend to think of this as if they don't overlap, that means either the first one takes place entirely before the second (first ending before second start) or the second one takes place entirely before the first (second ending before first start)
the negated version is more obvious to reason about imo
Wrote mine in the comfort of my desk.
def parse_sections(s: str):
start, end = map(int, s.split("-"))
return set(range(start, end + 1))
def main(data: str):
redudnant_count = 0
overlapping_count = 0
for line in data.splitlines():
# e - elf
e1, e2 = map(parse_sections, line.split(","))
if e1.issubset(e2) or e1.issuperset(e2):
redudnant_count += 1
if e1.intersection(e2):
overlapping_count += 1
print("Part 1:", redudnant_count)
print("Part 2:", overlapping_count)
not (r1 < l2 or r2 < l1)
That's pretty good yeah
That is the version I used in my solution, though I think you have the first set flipped, they need to be endings < beginnings for each
Which is actually a mistake I made during my solve too, where I had one flipped
I see, r1 is an end. Zig was using x1,x2,y1,y2 so the 2's were the endings
ah, right
I've implemented this solution a lot at work checking for overlapping date ranges
ideally you would abstract this away since the logic generalizes
like, this works for any intervals where the endpoints can be compared with <
106
print(sum(1-(a>c<=d<b or d>b>=a<c)+1j*(a<=d>=c<=b)for a,b,c,d in[eval(l.replace(*'-,'))for l in open(0)]))```
78 with encoding
```py
exec(bytes('牰湩⡴畳⡭ⴱ愨挾㴼㱤牯搠戾㴾㱡⥣ㄫ⩪愨㴼㹤挽㴼⥢潦ⱡⱢⱣ湩敛慶⡬敲汰捡⡥✪Ⱝ⤧昩牯氠椠灯湥〨崩⤩','u16')[2:])```
new best
it's a 106
import re
with open('input.txt') as f:
data = f.read().splitlines()
part_1_matches = 0
part_2_matches = 0
for line in data:
a1, a2, b1, b2 = map(int, re.findall(r'\d+', line))
set_a, set_b = set(range(a1, a2+1)), set(range(b1, b2+1))
if len(set_a | set_b) == len(set_a) or len(set_a | set_b) == len(set_b):
part_1_matches += 1
if set_a & set_b:
part_2_matches += 1
print(part_1_matches) #Part 1
print(part_2_matches) #Part 2
Why using regex?
78 with shenanigans
exec(bytes('牰湩⡴畳⡭ⴱ愨挾㴼㱤牯搠戾㴾㱡⥣ㄫ⩪愨㴼㹤挽㴼⥢潦ⱡⱢⱣ湩敛慶⡬敲汰捡⡥✪Ⱝ⤧昩牯氠椠灯湥〨崩⤩','u16')[2:])```
!e ```py
print(bytes('牰湩⡴畳⡭ⴱ愨挾㴼㱤牯搠戾㴾㱡⥣ㄫ⩪愨㴼㹤挽㴼⥢潦ⱡⱢⱣ湩敛慶⡬敲汰捡⡥✪Ⱝ⤧昩牯氠椠灯湥〨崩⤩','u16')[2:])
@neat mountain :white_check_mark: Your 3.11 eval job has completed with return code 0.
b"print(sum(1-(a>c<=d<b or d>b>=a<c)+1j*(a<=d>=c<=b)for a,b,c,d in[eval(l.replace(*'-,'))for l in open(0)]))"
and this is why we count bytes
yeah
185 bytes
you don't have 76 bytes though 😛
@kind niche this. noice!
Good ol demorgans strikes again
yep
I read that as demagorgons and was confused lol
I am оωo "sets are cool" #4962 py def day4(inp: str) -> tuple[int, int]: cnt = 0 tcnt = 0 for i in inp.strip().split("\n"): (af, at), (bf, bt) = map(lambda i: map(int, i.split("-")), i.split(",")) if set(range(af, at + 1)) & set(range(bf, bt + 1)) in [set(range(af, at + 1)), set(range(bf, bt + 1))]: cnt += 1 if set(range(af, at + 1)) & set(range(bf, bt + 1)): tcnt += 1 return (cnt, tcnt)
Sets probably easier to read but checking boundaries faster to compute
wanna try some custom input? 😛
This puzzle is easy for most compute. Thinking scaling:)
nononono
here 
still, only 1k lines lol
number of lines isn't the issue
I like doing this for fun 🤷♂️
the size of the interval is
I'm not bothered about a hypothetical production implementation of a small fun little puzzle
For sure. Just talking:)
what I'm sad about is having a puzzle with a nice lesson (doing fast operations on ranges) that is trivially bruteforce-able
yeah
If that was interview question, that would be next q probably:)
as I stated before, we need more lanternfish
I originally solved #1 without sets lol
Oh no! I broke my brain on this one 🙂
When difficult puzzles start,?
(when does the first puzzle that makes me take >1ms in rust come)
Wow, now I can doing 1d line collision detection
🎉
pandas rocks again
# Part 1
print(pd.read_csv("day_4.input", header=None).apply(lambda c: c.str.split("-")).explode([0, 1], ignore_index=1).astype(int).mask(lambda fr: pd.DataFrame([fr.index % 2] * 2).T.astype(bool), lambda fr: fr.add(1)).groupby(lambda idx: idx // 2).agg(list).applymap(lambda v: {*range(*v)}).agg(lambda r: r[0] | r[1] in (r[0], r[1]), 1).sum())
# Part 2
print(pd.read_csv("day_4.input", header=None).apply(lambda c: c.str.split("-")).applymap(lambda v: pd.Interval(*map(int, v), "both")).agg(lambda r: r[0].overlaps(r[1]), 1).sum())
with open("4.txt") as f:
pairs = [i.replace("\n", "") for i in f]
pairs = [i.split(",") for i in pairs]
overlaps = 0
with open("4.txt") as f:
pairs = [i.strip() for i in f]
pairs = [i.split(",") for i in pairs] # divides each pair into sub-lists e.g.([[1-2, 2-3], [2-3, 4-5]]
overlaps = 0
for i in pairs:
l1 = [i for i in range(int(i[0].split("-")[0]), int(i[0].split("-")[1]) + 1)] # makes 1 list for the first pair range
l2 = [i for i in range(int(i[1].split("-")[0]), int(i[1].split("-")[1]) + 1)] # makes other list for the second pair
l3 = set(l1).intersection(l2) # makes a set with only the intersecting items
if set(l1) == l3 or set(l2) == l3: # checks if the set == any of the two pairs...
overlaps += 1 # ...if so, they are intersecting
print(overlaps)
What do you guys think of my code for part 1?
l1 = [i for i in range(int(i[0].split("-")[0]), int(i[0].split("-")[1]) + 1)]
this can just be
l1 = list(range(int(i[0].split("-")[0]), int(i[0].split("-")[1]) + 1))
but also, I think you should just turn them into sets right away
l1 = set(range(int(i[0].split("-")[0]), int(i[0].split("-")[1]) + 1))
l2 = set(range(int(i[1].split("-")[0]), int(i[1].split("-")[1]) + 1))```
since you're doing that multiple times later on anway
I did a similar thing, so here's how I did mine
count = 0
count2 = 0
for x in re.findall(r'(\d+)-(\d+),(\d+)-(\d+)', raw):
a, b, c, d = map(int, x)
s1 = set(range(a, b + 1))
s2 = set(range(c, d + 1))
if len(s1.union(s2)) == max(len(s1), len(s2)):
count += 1
if len(s1 & s2) > 0:
count2 += 1
with open("4.txt") as f:
pairs = [i.replace("\n", "") for i in f]
pairs = [i.split(",") for i in pairs]
can I make this part better? I'm really confused since I learned about list comprehension just yesterday
i.replace("\n", "") instead of this you can just do i.strip() to remove the whitespace at the beginning and end of the line
ngl I dont understand much about the code, but I find interesting how you used regex
with open("4.txt") as f:
pairs = [i.split(",") for i in f.readlines()]```
I think readlines() gives you each line without the newline character
np
readlines keeps the line endings
ah, well then you'll need to i.strip().split(',')
lets go custom data types and loops + 1 for the win
i usually go with f.read().splitlines()
I'm wondering if there's a fleshed-out Interval Class for Python
I don't think there is one for the standard library
But someone should have done one for pypi by now
I like to think my code is still readable. 🙂 pure golfing is more like write once, read never.
i'm surprised by the people that come up with a golfing solution in the first 8 minutes of the puzzle being released
why?
like, I assumed most people would just write a short solution and then make it shorter from there
that's what they do
yea
but there are some very common tricks to make it shorter
the first 8 minutes
i could probably do these problems in 2 minutes with sloppy code
then use the remaining 6 to golf
8 mins is fast but not surprising
at least not for the first few days
can someoone explain me why i don't get the wright answer ? I can figure it out
"2" > "13"
if you post your code I can copy/paste and show you things. I'm not retyping anything from an image though.
oops yeah, next time
i will compile the code in my head
not too sure what's wrong here, this should be right unless I didn't fully understand the overlapping (FOR PART 2)
input = open("input.txt").read().split("\n")
newList = []
for x in input:
z = x.split(",")
newList.append([z[0].split("-"), z[1].split("-")])
pairsList = []
count = 0
for x in newList:
fp1 = int(x[0][0])
fp2 = int(x[0][1])
sp1 = int(x[1][0])
sp2 = int(x[1][1])
if fp1 >= sp1 or fp2 >= sp1:
count += 1
print(count)
3-4,1-2
the overlapping is for any range that overlaps in any way (like 2-4, 4-5, wich overlaps in 4)
thanks for example! I was searching for a wrong answer in the correct output lists couldn't stumble on 1 thats incorrect but didn't think about that ^^
Why does this not work.... ```py
def convert_range_to_list(x: str) -> str:
x = x.split('-')
x = list(map(int, x))
x = list(range(x[0], x[1]+1))
x = ','.join(map(str, x))
return x
with open(os.path.dirname(sys.argv[0]) + "/input.txt", 'r') as f:
data = f.read()
data = data.split('\n')
data = [d.split(',') for d in data]
counter = 0
for n, d in enumerate(data):
elf1 = convert_range_to_list(d[0])
elf2 = convert_range_to_list(d[1])
if elf1 in elf2 or elf2 in elf1:
counter += 1
print(counter)
It gives me an answer that is too high
Use Rust
This is pt 1, I am creating a string for each of the tasks and then comparing with in. It works on the sample input, but it doesnt on my problem input
I don't know if you noticed but this is the pyhton discord server.....
use rust regardless
where is the main function?
there isnt a main function
that's your problem
No its not - you dont need a main function
1-1,11-11
elf1 in elf2 but 1-1 is not a subset of 11-11
the counter should be a += 0.5
np
This is a horrible solution but it worked. Such a niche edge case, I would have spent forever looking for that.
y = lambda x: '.' + str(x) + '.'
x = ','.join(map(y, x))
def parse_raw():
with open('input.txt') as f:
data = f.read().strip().split('\n')
data = [pair.split(',') for pair in data]
data = [[pair[0].split('-'), pair[1].split('-')] for pair in data]
for idx, pair in enumerate(data):
elf_1_start = int(pair[0][0])
elf_1_stop = int(pair[0][1])
elf_2_start = int(pair[1][0])
elf_2_stop = int(pair[1][1])
elf_1_range = range(elf_1_start, elf_1_stop + 1)
elf_2_range = range(elf_2_start, elf_2_stop + 1)
data[idx] = [set(elf_1_range), set(elf_2_range)]
return data
data = parse_raw()
def part_one():
count = 0
for pair in data:
if (pair[0].issubset(pair[1]) or pair[1].issubset(pair[0])):
count += 1
print(count)
def part_two():
count = 0
for pair in data:
if (len(pair[0] & pair[1]) > 0):
count += 1
print(count)
part_one()
part_two()
``` I like how clean / simple the actual solutions are, but I wish I knew a less obtuse way to format the input that would still result in the same data structure
frfr look at how clean and simple my solution is
print(sum(1-(a>c<=d<b or d>b>=a<c)+1j*(a<=d>=c<=b)for a,b,c,d in[eval(l.replace(*'-,'))for l in open(0)]))```
Sets feel a bit overkill for these imo
It’s the easiest way to deal with it, no faffing around with the range boundaries, just do set operations. Obv won’t work for large inputs though
perhaps, but sets were still fresh in my mind from day_03
Oh day three was solved by chatGPT for me
bruh
coming up with the solution myself is part of the fun for me, but to each their own
as long as youre not trying to place on leaderboards with it i dont see the issue
for the first few days, it's not too fun to come up with solutions, since they're trivial
golfing is where it's at
everyone is at different levels of experience tho 🙂 i dont consider myself that advanced, so the early days are still good practice for me
Yeah using AI for it was fun way to learn that it can solve it with 1:1 copy of puzzle instructions. Crazy
the top on the lb for both d1p1 and d3p1 were both ai 
i know 😦
i might try ai for d5
pretty disappointing in my opinion
Today part 1 was taken by GPT3
im nowhere close to being competitive enough to be on the leaderboards. but i feel bad for the people who are, yet lose out on spots due to others using AI
yup ive seen all the drama on twitter / AoC subreddit
like yeah its cool that it can solve it in 16 seconds, its very impressive. but its lame to take away spots from humans actually trying to compete
Huge progress on one end.
lame but there's almost nothing that can be done to enforce it
agreed. it is cool and very impressive that these language models are so advanced they can solve it in 16 seconds. i just feel bad for the people trying to compete to get on the leaderboards
they'll get their chance in later days
Most of the time is handling input output i would imagine
just my 2 cents, everyone is entitled to their own opinion 🙂
Solving is instant i would guess
no
Yeah probably
Maybe rules should prevent it. Sure making sure it doesn't happen is different story
what lang?
assembly
then 7.3ms feels kinda slow 
probably inefficient code
Depends on the machine:)
true
hard to imagine a >1000x increase based on hardware alone though
I have <20μs including file read and parsing
Unless it's Atarii 1200 😆
if their cpu clock frequency is measured in khz instead of ghz…
do they have an actual clock?
Hey @obsidian snow!
You either uploaded a .txt file or entered a message that was too long. Please use our paste bin instead.
A clock generator is an electronic oscillator that produces a clock signal for use in synchronizing a circuit's operation. The signal can range from a simple symmetrical square wave to more complex arrangements. The basic parts that all clock generators share are a resonant circuit and an amplifier.
The resonant circuit is usually a quartz piezo...
idk if this counts
the assembly is too long
can you not use the pastebin?
too big
I guess you miss out on compiler optimizations
I feel like at this point a compiled Nim or C version would be faster
because of the optimizations
man's getting skill diffed by compilers 😔
Maybe you could use the -S flag and look at the output assembly by the compiler
and find some good tips
*it might be another flag I forget which
@sleek python yes 
though maybe the approach is also different
If you really want to be extreme you could embed the file input in the data of your assembly
Or use extreme parallelization on the GPU
this seems like something that could be parallelized
can you even send data to the gpu in <20μs?
that is the only issue
m1 mac? 👀
if you really want to be extreme, you could embed the expected output in the data of your assembly
It might be possibly to use some sort of async file access
😎
where you are reading and operating at the same time
I know it's possible in C (I think it's in the Boost library) and you could get ~2700 more operations while reading the file
boost::asio::async_read(s, boost::asio::buffer(data, size), handler);
or just accept that GPU isn't going to be helpful for this tiny size
simd is a better bet for speedups
The GPU + Parallelization will be slower for tiny input but will speed up significantly for a ridiculously large input I would guess
this is AoC
but because we have a small input it's probably better not to use GPU
no input is that huge
Is there a neater way of doing this kind of assignment in python:
if len_range(a) < len_range(b):
sub_list = a
mainlist = b
else:
sub_list = b
mainlist = a
sub_list, mainlist = a, b
if len_range(a) < len_range(b):
mainlist, sub_list = sub_list, main_list
is one way that is shorter
not sure about neater
I would at least use the comma assignment though
because it is neater
sub_list = a
mainlist = b
becomes
sub_list, mainlist = a, b
imo that's much more annoying to read
Ah yeah thats an idea, I guess you could even do it like this:
mainlist, sub_list = (b, a) if len_range(a) < len_range(b) else (a, b)```
we don't need to golf his solution lol
wtf is golf? 😂
mainlist,sub_list=((b,a),(a,b))[len_range(a)<len_range(b)]
making the shortest code possible
if you don't mind keeping the old names, then
if ...:
a, b = b, a
How about a weirder way 🥴
main_list = max(a, b, key=len_range)
sub_list = min(a, b, key=len_range)
if not in expected order, swap
ahh I like the min max 😝
sorted
true
like yesterday we golfed the solution to:
# LF (144)
*z,=open(0,'rb');u=sum;print(u((u({*a[(l:=len(a)//2):]}&{*a[:l]})-96)%58for a in z),u((u({*b}&{*c}&{*d})-106)%58for b,c,d in zip(*3*[iter(z)])))
# CR (144)
*z,=open(0,'rb');u=sum;print(u((u({*a[(l:=len(a)//2):]}&{*a[:l]})-96)%58for a in z),u((u({*b}&{*c}&{*d})-109)%58for b,c,d in zip(*3*[iter(z)])))
# CRLF (146)
*z,=open(0,'rb');u=sum;print(u((u({*a[(l:=len(a)//2-1):]}&{*a[:l]})-96)%58for a in z),u((u({*b}&{*c}&{*d})-119)%58for b,c,d in zip(*3*[iter(z)])))
# xplatform (156)
z=open(0,'rb').read().split();u=sum;print(u((u({*a[(l:=len(a)//2):]}&{*a[:l]})-96)%58for a in z),u((u({*b}&{*c}&{*d})-96)%58for b,c,d in zip(*3*[iter(z)])))
# xplatform one loop (161)
u=sum;print(u(u((u({*a[(l:=len(a)//2):]}&{*a[:l]})-96)%58for a in(b,c,d))+(u({*b}&{*c}&{*d})-96)%58*1j for b,c,d in zip(*3*[iter(open(0,'rb').read().split())])))
# encoded
# LF (97)
exec(bytes("稪㴬灯湥〨✬扲⤧画猽浵瀻楲瑮用⠨⡵⩻孡氨㴺敬⡮⥡⼯⤲崺♽⩻孡氺絝㘹┩㠵潦湩稠Ⱙ⡵用笨截♽⩻絣符搪⥽ㄭ㘰┩㠵潦ⱢⱣ湩稠灩⨨⨳楛整⡲⥺⥝⤩",'u16')[2:])
# CR (97)
exec(bytes("稪㴬灯湥〨✬扲⤧画猽浵瀻楲瑮用⠨⡵⩻孡氨㴺敬⡮⥡⼯⤲崺♽⩻孡氺絝㘹┩㠵潦湩稠Ⱙ⡵用笨截♽⩻絣符搪⥽ㄭ㤰┩㠵潦ⱢⱣ湩稠灩⨨⨳楛整⡲⥺⥝⤩",'u16')[2:])
# CRLF (98)
exec(bytes('稪㴬灯湥〨✬扲⤧画猽浵瀻楲瑮用⠨⡵⩻孡氨㴺敬⡮⥡⼯ⴲ⤱崺♽⩻孡氺絝㘹┩㠵潦湩稠Ⱙ⡵用笨截♽⩻絣符搪⥽ㄭ㤱┩㠵潦ⱢⱣ湩稠灩⨨⨳楛整⡲⥺⥝⤩','u16')[2:])
# xplatform (103)
exec(bytes("㵺灯湥〨✬扲⤧爮慥⡤⸩灳楬⡴㬩㵵畳㭭牰湩⡴⡵用笨愪⡛㩬氽湥愨⼩㈯㨩絝符愪㩛嵬⥽㤭⤶㔥昸牯愠椠⥺甬⠨⡵⩻絢符挪♽⩻絤㘹┩㠵潦ⱢⱣ湩稠灩⨨⨳楛整⡲⥺⥝⤩",'u16')[2:])
# xplatform one loop (106)
exec(bytes("㵵畳㭭牰湩⡴⡵⡵用笨愪⡛㩬氽湥愨⼩㈯㨩絝符愪㩛嵬⥽㤭⤶㔥昸牯愠椠⡮ⱢⱣ⥤⬩用笨截♽⩻絣符搪⥽㤭⤶㔥⨸樱映牯戠挬搬椠楺⡰㌪嬪瑩牥漨数⡮ⰰ爧❢⸩敲摡⤨献汰瑩⤨崩⤩
",'u16')[2:])
exactly
What if they are equal length
Oh dear god
this is why we should measure bytes, not characters
Then it doesnt matter which way around it uses them
this is also why exec should be banned in most cases
Still need to assign main sub not?
the min max one could end up with the same list twice
Ah thats true
then do min(b, a) just in case
I think exec is fine, for example the eval trick for parsing today's input was cool. But yeah, golf for bytes not characters.
i know someone who did day 1 and day 2 in futhark
Obviously, the code should include everything it needs to run, don't open another file or fetch from the internet and exec that
I said exec not eval, but I can agree that if you're doing something fancy like running .replace() on a string you are executing to shorten it then I can see that being valid
Something like:
# xplatform one loop (106)
exec(bytes("㵵畳㭭牰湩⡴⡵⡵用笨愪⡛㩬氽湥愨⼩㈯㨩絝符愪㩛嵬⥽㤭⤶㔥昸牯愠椠⡮ⱢⱣ⥤⬩用笨截♽⩻絣符搪⥽㤭⤶㔥⨸樱映牯戠挬搬椠楺⡰㌪嬪瑩牥漨数⡮ⰰ爧❢⸩敲摡⤨献汰瑩⤨崩⤩
",'u16')[2:])
Kind of ruins the point tbh
You can replace exec with eval in that if the original was a single print call or whatever and it will work. Doesn't make sense to differentiate between the two when it comes to code golf really
that's 268 bytes
that's why we shouldn't measure characters
"Optimal" solution for every problem ever:
print(eval(input()))
# and
exec(input())
When "input can be given in any convenient format"
I mean you can put any valid code and it will work fine
the only things that are shorter than that
are like
print(5)
or something small
exec(input())
print(123456)
you can print a maximum of a 5 character expression
before beating that
Love to see situations where part 2 require 3 more lines of code
def puzzle():
crossovers = 0
anyCrossOver = 0
for pair in pairs:
order1 = set(range(pair[0][0], pair[0][1] + 1))
order2 = set(range(pair[1][0], pair[1][1] + 1))
if order1.intersection(order2) == order1 or order1.intersection(order2) == order2:
crossovers += 1
elif not order1.isdisjoint(order2):
anyCrossOver += 1
return crossovers + anyCrossOver
with open('input.txt', 'r') as file:
data = file.read().split("\n")
pairs = [[[int(i) for i in hyphen.split('-')] for hyphen in row.split(',')] for row in data]
puzzle()
finished!
I got to use sets for this too
def part_1(ranges: list[Iterator[int]]) -> int:
r = [
i
for i in ranges
if (a := set(range(next(i), next(i) + 1))).issubset(
b := set(range(next(i), next(i) + 1))
)
or b.issubset(a)
]
return len(r)
def part_2(ranges: list[Iterator[int]]) -> int:
r = [
i
for i in ranges
if set(range(next(i), next(i) + 1)) & set(range(next(i), next(i) + 1))
]
return len(r)
``` was my solution
hmm, the second thing for an intersection doesn't have to be a set, does it
ah, yeah, if you use .intersection you can pass any iterable
eh whatever, & is cleaner
where ranges was ranges = [map(abs, extract_ints(l)) for l in raw_input]
O(😔)
i'm surprised y'all actually constructed ranges
What the fuck
i did at first when i thought you could do range in range
my pc crashed when I tried to create two huge sets for an intersection with timeit
but bounds checking is so much easier
lol, I tried that at first too
(and faster)
but muh sets
new feature for 3.12, range.intersect
PRing immediately
this idea isn't horrible actually
but they would probably just say convert to set
lmfao i was expecting someone to pr Range::overlaps and Range::covers to rust
surprised it hasn't happened yet
surely they wouldn't. that's such a poor way to do it
turning a O(1) time and memory to O(n) time and meemory
I suppose so
Is intersection O(1)?
ranges can do trivial bounds checking, they don't calculate everything beforehand
Yes
I see
as i found out quite recently in #algos-and-data-structs !
I'm a JS user :)
oh yes, steps exist
differing step sizes would be nightmarish
completely forgot about those
same step sizes wouldn't change anything
at least intersect for general ranges would still be a range
(afaik)
err...I guess negative steps makes the direction weird
just error on steps 😤
what's the intersection between range(10) and range(9, -1, -1)?
you could just default to a >0 step
!e ```py
a = set(range(10))
b = set(range(9, -1, -1))
print(a)
print(b)
print(a&b)
:O sets are ordered??? /j
@sleek python :white_check_mark: Your 3.11 eval job has completed with return code 0.
001 | {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
002 | {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
003 | {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
no lol
Replace the two ranges to test what the intersection should be
now do range(10000000000000000)
!e ```py
a = set(range(100000000))
b = set(range(9, -1, -1))
print(a)
print(b)
print(a&b)
@sleek python :warning: Your 3.11 eval job timed out or ran out of memory.
[No output]
Skill issue
yeah that's unsuprising
we were talking about intersection of ranges producing new ranges
the output is the range
it would be equivalent to the set() of the range
I think
but I haven't tested like anything so I'm probably wrong
what would the logic be though for every case
random shit
it's a linear diophantine equation
you can solve it
yes, the step might be least common multiple
the answer is a range
is it O(1) to solve though? Cause if not then set() solution is easier
you need to compute a gcd, but that's about it
gcd is what? log(n)?
alright
Yeah I'm pretty sure its log(n)
Worst case is
log10(min(x,y))
where x, y are the inputs
for the most optimized algorithm
!d math.gcd
another example
a = range(1, 100, 3)
b = range(0, 100, 5)
a&b could be range(10, 15, 100)
hm. what is gcd good for in this case? 
solving a "linear diophantine equation"
In mathematics, a Diophantine equation is an equation, typically a polynomial equation in two or more unknowns with integer coefficients, such that the only solutions of interest are the integer ones. A linear Diophantine equation equates to a constant the sum of two or more monomials, each of degree one. An exponential Diophantine equation is ...
I'm unfamilar with the term "diophantine" at all but I'm gonna trust fiery on this one
a diophantine equation is just an equation with only integers allowed
this is a particularly easy one
oh this seems way easier then
we would have to write a solution in C and add it to the range class
but as mentioned, it's a bit ill-defined
I'll see if I can find the source for range
e.g. for a mix of negative and positive step sizes
@ember junco :x: Your 3.11 eval job has completed with return code 1.
001 | File "<string>", line 1
002 | raise raise raise
003 | ^^^^^
004 | SyntaxError: invalid syntax
found the definition
of PyRange_Type
A little late to the party because I wasn't there this wk:
def all_overlapping(parts):
first = list(map(int, parts[0].split("-")))
second = list(map(int, parts[1].split("-")))
return (first[0] <= second[0] and first[-1] >= second[-1]) \
or (second[0] <= first[0] and second[-1] >= first[-1])
def some_overlapping(parts):
first = list(map(int, parts[0].split("-")))
second = list(map(int, parts[1].split("-")))
return (first[0] <= second[0] and first[1] >= second[0]) or \
(second[0] <= first[0] and second[1] >= first[0])
def part1(content):
return sum([all_overlapping(line.split(",")) for line in content.split("\n")])
def part2(content):
return sum([some_overlapping(line.split(",")) for line in content.split("\n")])
content = read_file("input.txt").strip()
print(part2())
with open('day4\input.txt', 'r') as f:
inputlist = f.read().split('\n')
total = 0
def formula(x):
return {num for num in range(int(x[0]), int(x[1]) + 1)}
for line in inputlist:
a, b = [half.split('-') for half in line.split(',')]
seta, setb = formula(a), formula(b)
if seta.intersection(setb) != set():
total += 1
print(total)```
Solution for part 2, lmk if you spot any obvious optimizations that can be made!
set(range(int(x[0]), int(x[1]) + 1))
also technically if seta.intersection(setb): is enough, but maybe you were trying to be verbose
Ah, I was not :P because python treats empty stuff as false?
if you're looking for optimization, then comparing the boundaries will be more efficient than generating the entire set for each pair of integers
Yeah I did find out about that when I saw other peoples solutions but decided to keep with how I solved it and try to look for simple optimizations since I'm only a beginner
Ah, ty, I didn't know range could be used like that outside of for loops
range is just a function (technically a class), it can be used anywhere
Also question, why can't I replace the line
if seta.intersection(setb) != set():```
with
```py
if seta.isdisjoint(setb):```
It seems like they should be the same thing
you want to know if they're not disjoint
ah, yeah I thought it might be something like that, how would I write that?
if not seta...
tysm
ig i don't get a pin 😦
seta.intersection(setb)
seta.intersection(setb) is the same as not seta.isdisjoint(setb) in truthyness
I was actually surprised that part 2 was not specifically about adding enough scale that comparing sets would not work.
Too early I guess. Might return in a future puzzle
Seems likely.
im guessing 60-90% of people would compare ranges though
and for those people scale doesn't pose that much of an issue
I'll be honest, I was also surprised to see so many people using sets instead of just comparing the end points.
And here I thought I was cool because I thought outside the box and came up with this cool idea for sets...
sets are cool. I love sets. didn't use them this time. =/
for some reason comparisons always mess me up
Laughably unoptimised this time, but I was lazy lol
def day_4():
def part_one():
return len([1 for pair in DATA.splitlines() if all([n in range(int(pair.split(",")[1].split("-")[0]), int(pair.split(",")[1].split("-")[1]) + 1) for n in range(int(pair.split(",")[0].split("-")[0]), int(pair.split(",")[0].split("-")[1]) + 1)]) or all([n in range(int(pair.split(",")[0].split("-")[0]), int(pair.split(",")[0].split("-")[1]) + 1) for n in range(int(pair.split(",")[1].split("-")[0]), int(pair.split(",")[1].split("-")[1]) + 1)])])
def part_two():
return len([1 for pair in DATA.splitlines() if any([n in range(int(pair.split(",")[1].split("-")[0]), int(pair.split(",")[1].split("-")[1]) + 1) for n in range(int(pair.split(",")[0].split("-")[0]), int(pair.split(",")[0].split("-")[1]) + 1)]) or any([n in range(int(pair.split(",")[0].split("-")[0]), int(pair.split(",")[0].split("-")[1]) + 1) for n in range(int(pair.split(",")[1].split("-")[0]), int(pair.split(",")[1].split("-")[1]) + 1)])])
return part_one()
i got the logic right yesterday in my submission, but it took me about 15 minutes to mentally work through it when helping someone this morning
I tried to do it that way, but it was too early in the morning xd
I did that at first but it just wasn't working. It wasn't till after I started another approach that I realized I was using < and > on strings XD
This might have been the problem for me too... xD
wow
uh
:= is your friend
i used all and any for the first time
I've never had to use it @frank sleet
no kidding
Agreed
Here's mine for part one
# Checks if any range fully contains the other
def fully_contains(range_one, range_two):
one_fully_contains_two = range_one[0] <= range_two[0] and range_one[1] >= range_two[1]
two_fully_contains_one = range_two[0] <= range_one[0] and range_two[1] >= range_one[1]
return one_fully_contains_two or two_fully_contains_one
def main():
# Opens input file in read mode
with open("problem_4_input.txt", "r") as input_file:
# Number of ranges that fully contains the other
num_fully_contains = 0
for line in input_file.readlines():
# Split line into two ranges
line = line.rstrip("\n")
ranges = line.split(",")
# Split both ranges into two integer strings
range_one = ranges[0].split("-")
range_two = ranges[1].split("-")
# List versions of both ranges
range_one_list = [int(range_one[0]), int(range_one[1])]
range_two_list = [int(range_two[0]), int(range_two[1])]
# If either range fully contains the other, increase number of ranges that fully contains the other
if fully_contains(range_one_list, range_two_list):
num_fully_contains += 1
# Print result
print(num_fully_contains)
if __name__ == "__main__":
main()
Tips and suggestions are welcome
with open("the.txt","r") as f:
ko = f.read().split("\n")
count = 0
for i in ko:
k, l = i.split(",")
do,xo = k.split("-")
fo,go = l.split("-")
do = int(do)
xo = int(xo)
fo = int(fo)
go = int(go)
if do >= fo and xo >= go:
count += 1
elif fo >= do and go >= xo:
count += 1
print(count)```
What's wrong exactly?
1-6,5-7
5 >= 1 and 7 >= 6, but neither interval contains the other
Ty I fixed it
I don't think I really understand part 2
first part is to count the amount of fully contained assignments, part 2 is to count the amount of assignments with at least 1 overlap
like in this case, there would be an overlap between the two (in 5 and 6)
Ah
cleaned up my solution a bit
def part1(section_ids):
set_a = set(range(section_ids[0], section_ids[1] + 1))
set_b = set(range(section_ids[2], section_ids[3] + 1))
smallest_set = set_a if len(set_a) < len(set_b) else set_b
return set_a & set_b == smallest_set
def part2(section_ids):
set_a = set(range(section_ids[0], section_ids[1] + 1))
set_b = set(range(section_ids[2], section_ids[3] + 1))
return not len(set_a & set_b) == 0
with open("../inputs/day4.txt") as file:
sections = list(map(lambda s: list(map(int, s)),
[ids.replace('-', ',').split(',') for ids in file.read().splitlines()]))
print("Part 1:", len(list(filter(part1, sections))))
print("Part 2:", len(list(filter(part2, sections))))
can someone explain what i am doing wrong?
def range_to_string(lower, upper):
return "".join([str(x) for x in range(int(lower), int(upper) + 1)])
def main() -> int:
contains_count = 0
with open("input.txt", "r", encoding="UTF-8") as f:
for line in f:
line = line.strip("\n")
e1_range, e2_range = line.split(",")
e1_lower, e1_upper = e1_range.split("-")
e2_lower, e2_upper = e2_range.split("-")
elf_1 = range_to_string(e1_lower, e1_upper)
elf_2 = range_to_string(e2_lower, e2_upper)
if (elf_1 in elf_2) or (elf_2 in elf_1):
contains_count += 1
print(contains_count)
return 0
this outputs 2 for the example they gave but when i try it on my own puzzle input it is wrong apparently
d4a = sum(a<=c<=d<=b or c<=a<=b<=d for a,b,c,d in (map(int, line.replace(",","-").split("-")) for line in in4a.splitlines()))
My single-liner :3
You're converting them to a string of numbers, which may have false-positives. Like first elf having 1-2 and second having 12-whatever
The task specifically says they used single digits there so they could nicely show the overlap and that real task will have multiple digit numbers
just to clarify, does 50-55 mean 50, 51, 52, 53, 54, 55 ?
Yes. The example specifically showed that both ends are inclusive. You're doing that one part correctly, the only bad part is the string and false-positives stemming from that
Okay, second part finished:
d4a = sum(a<=c<=d<=b or c<=a<=b<=d for a,b,c,d in (map(int, line.replace(",","-").split("-")) for line in in4a.splitlines()))
d4b = sum((min(b,d)+1-max(a,c))>0 for a,b,c,d in (map(int, line.replace(",","-").split("-")) for line in in4a.splitlines()))
with open('advent4.txt', 'r') as txtfile:
from re import split
txtlst = [list(map(int, split(r',|-', line.strip()))) for line in txtfile]
#print(txtlst)
This is how I'm parsing. So I didn't use the read() or readline() but it still works? Is there a reason to use read() over looping. Please don't comment about the parsing method yet I'm going to try to do it my way first
Sometimes you might want the whole text in one go, rather than line by line
I agree, but I mean I did it without using the read methods
I guess read() is what you mean
and readline() same as looping?
what I did
*iterating
Close, though I think readline() might preserve the \n at the end
Yes that is what I was referring to
Gotcha gotcha ty
def parttwo(loloi):
counter = 0
for item in loloi:
rge1, rge2 = set(range(item[0], item[1] + 1)), set(range(item[2], item[3] + 1))
#if not rge1 - rge2 or not rge2 - rge1:
if rge2 & rge1:
counter += 1
return counter
with open('advent4.txt', 'r') as txtfile:
from re import split
txtlst = [list(map(int, split(r',|-', line.strip()))) for line in txtfile]```
This is my incorrect solution for parttwo. I would like to be given a hint.
It seems to me a simple intersection should do the trick.
EDIT: input was wrong. Solution works
Did you try testing against the test input?
I did
I got the same answer of 4 as here
I'm thinking there must be an edge case I'm missing.
seems to work for my input for some reason
😭
Let me double-check my input file.
yeah, maybe just redownload it
🙄 I failed to copy paste last line. My answer was one off.
💀
Thank you for testing in your input
solution (not python)```ruby
aoc problem 4
class Range
def overlap?(other)
self.end >= other.begin or self.begin > other.begin and self.begin <= other.end
end
end
def input
File.read('4.txt').lines.map do |l|
l.split(/,/).map do |r|
start, stop = r.split(/-/)
start.to_i..stop.to_i
end
end
end
return unless FILE == $0
part 1 solution
puts input.count {|r0, r1| r0.cover? r1 or r1.cover? r0}
part 2 solution
puts input.count {|r0, r1| r0.overlap? r1}
ok now yes python ```py
aoc problem 4
def getinput():
acc = []
with open('4.txt') as f:
for l in f.read().splitlines():
(r0start, r0stop), (r1start, r1stop) = [r.split('-') for r in l.split(',')]
acc.append((set(range(int(r0start), int(r0stop) + 1)),
set(range(int(r1start), int(r1stop) + 1))))
return acc
def full_contains(rangepairs):
acc = 0
for r0, r1 in rangepairs:
if (r0 | r1) == r0 or (r0 | r1) == r1:
acc += 1
return acc
def overlaps(rangepairs):
acc = 0
for r0, r1 in rangepairs:
if (r0 & r1) != set():
acc += 1
return acc
def main():
inpt = getinput()
print(full_contains(inpt)) # part 1 solution
print(overlaps(inpt)) # part 2 solution
if name == 'main':
main()
sets are cool
ruby?
yeah that's rb
yeah its ruby
input_file = "4.txt"
with open(input_file) as f:
data = f.read().split("\n")
score = 0
for line in data:
one, two = line.split(",")
one_range = one.split("-")
two_range = two.split("-")
one_range = list(range(int(one_range[0]), int(one_range[1])+1))
two_range = list(range(int(two_range[0]), int(two_range[1])+1))
if any(x in two_range for x in one_range) or any(x in one_range for x in two_range):
score += 1
print(score)
# for part 1, just change the `any` functions to `all`
I keep getting a wrong answer for the part 1 (my input is fine). It works for the test values. Could someone help me out? Thanks
f = open("inputday4.txt",'r')
filecontents=f.read().replace('\n',',').replace('-',',').split(',')
filecontents = [filecontents[x:x+4] for x in range(0,len(filecontents),4)]
assignments1 = []
assignments2 = []
for x in filecontents:
assignments1.append([z for z in range (int(x[0]),int(x[1])+1)])
for x in filecontents:
assignments2.append([z for z in range (int(x[2]),int(x[3])+1)])
assignments1 = [','.join([str(z) for z in x])for x in assignments1]
assignments2 = [','.join([str(z) for z in x])for x in assignments2]
assignments_containing_the_other = 0
for x in range(len(assignments1)):
if assignments1[x] in assignments2[x] or assignments2[x] in assignments1[x]:
assignments_containing_the_other+=1
print(assignments_containing_the_other)
f.close()
if you have
x1 x2
y1 y2
your if statement is true because y1 is in between x1 and x2, but it should be false because the whole range (y1, y2) isn't inside (x1, x2) (or vice versa)
hello
i am facing some awkward issue with this problem
8
2 6 4 8
True False False True
2 4 3 5
True False False True
5 7 7 9
True False False True
2 3 8 7
True True False False
['2', '8'] ['3', '7']
6 4 6 6
False True True True
['6', '6'] ['4', '6']
2 4 6 8
True False False True
5 5 5 5
True True True True
['5', '5'] ['5', '5']
13 8 98 13
True True False False
['13', '98'] ['8', '13']
4
here, my condition was
so you see for the last experimental input which is 13-98,8-13
the program shouldn't count this pair as it doesn't fulfill the condition
but the program somehow counts it
here in this part s_point_1st_elf <= s_point_2nd_elf s_point_1st_elf is 13 and s_point_2nd_elf is 8, so 13 <=8 should have been False but when printed the result for this input it is True
13 8 98 13
True True False False
['13', '98'] ['8', '13']
x1 = 13 and x2 = 8
y1 = 98 and y2 = 13
so for the first condition
13 <= 8 is False and 98 >= 13 is True which results False so it shouldn't count
as for the second condition
8 <= 13 is True and 13 >= 98 is False which also results False and won't count
so this pair shouldn't count at all
but how come my program is counting it?
the worst thing is i am not seeing any wrong with my program but if we read the program it shouldn't count this pair but it does anyway
#Advent of code
#Problem 4
#--- Day 4: Camp Cleanup ---
with open("day4exp.txt") as f:
inp = f.read()
li1 = [list(map(str, i.split("\n"))) for i in inp.strip().split("\n\n")]
li2 = []
for i in li1[0]:
str1 = i.split(",")
li2.append(str1)
cnt = 0
for j in li2:
temp_li1 = j[0].split("-")
temp_li2 = j[1].split("-")
x1 = temp_li1[0]
y1 = temp_li1[1]
x2 = temp_li2[0]
y2 = temp_li2[1]
if (x1 <= x2) and (y1 >= y2):
cnt += 1
elif (x2 <= x1) and (y2 >= y1):
cnt +=1
print(cnt)
here's my program and idk why it doesn't work
it works on the example input
but like i said this program count some pair which it shouldn't count
that's why i get wrong answer in the part 1
You're not converting them to integers are you?
You're probably doing string comparison here
Which isn't right
ahh damn! okay let me try after converting them to integer
ohh it worked now! thanks!
idk why this thought didn't cross my mind, tried every way to find the bug except this.
Happens to the best of us 😅
It's easier to find certain bugs when you have a fresh pair of eyes
my brain is not working today at all lol
yeah true
You've probably just been looking at it too long, and think it does what you want, not what it says
Been there done that
yeah sorry! learned my lesson today 