#AoC 2022 | Day 10 | Solutions & Spoilers
1841 messages · Page 2 of 2 (latest)
You have a moving pointer and a theoretically infinite strip (if you make the width more than 40) though.
doesn't make it turing complete
Yes but you can't read or loop
exactly
True I guess

If you could read though I don't think you'd have to have a dedicated loop here for it to be turing complete
As it resets its position at the end of the screen each time anyway
as long as you can't create a finite program with an infinite runtime, it's not turing complete
There's no looping or branching, it's not turing complete
impossible, as you can not disable the first pixel, no matter what you do. X is 1 at the start, and it takes at least 2 ops to change that, in that time, this pixel is already drawn.
my conclusion, might be faulty
@hollow void
yes, youa re right
I'd argue there is looping, just no branching
but if you ignore the frst 4 pixels?
can't exceed 40 columns, so still not every image
good question. will play with that tomorrow 👋
every image as in any combination of pixels on the screen
The counter essentially sets itself to 0 every 40 cycles, that sounds like a form of looping to me.
uh that's not looping
But the PC doesn't loop
why would the counter reset?
fr just read the wiki page on turing machines 
To draw the next row
we can't discuss turing completeness if you don't know what it means
but part 1 relies on the counter not resetting
in that case, yes
it's possible
i could even write a program that generates the instructions for any given image (excluding starting pixels)
proof
set the sprite to somewhere away from the beam or at the beam 2 cycles ahead
not that hard
I'd prove it in this way:
I can freely update x every 2 pixels.
This way, I need to be able to draw all 4 combinations every 2 cycles
yeah, and you can position the sprite for any combo of the 2 pixels
#., .., .# and ##
yep
But is it possible if width isn't divisible by 2 though
yes
you can just use a noop
wait
actually maybe not
I don't think it is
(some rows, so you can choose the value of X)
# # # # #
# # # # #
I don't think it's possible to render that pattern
Without a dedicated blanking period anyway
yeah i think you're right
I tried writing a thing to generate the code for a given output string, and well my brain hurts i am giving up
rip
Just caught up on all my AoC - did all Day 9 and Day 10 today
Day 10 probably my fave day, though the off-by-one errors are not fun
QQ - in the Python match-case syntax, is there a way to cast a matched value to a different type from within the case statement? Or do you have to cast afterwards
I think you have to cast after binding
me too
me3
my solution had 0 
mine had 1 function
java user spotted
cast afterwards
Actually, true story, the first time I learned Java, I was lying on my bed reading the first chapter of a Java book, and fell asleep reading it
Lmao
What the cat??
Look at the tests for trying to cast in a case -
I would have expected it to be a syntax error - But it's actually changing the results...
https://github.com/shenanigansd/scratchpad/commit/0c20735eba3fc0031de1b7b773290e640e271a8c
https://github.com/shenanigansd/scratchpad/actions/runs/3665655477/jobs/6196870308
=================================== FAILURES ===================================
_______________________________ test_run_cycles ________________________________
def test_run_cycles() -> None:
cycles = run_cycles(EXAMPLE_INPUT)
> assert cycles[20] * 20 == 420
E assert (1 * 20) == 420
2022/10/python/test_day10.py:156: AssertionError
=========================== short test summary info ============================
FAILED 2022/10/python/test_day10.py::test_run_cycles - assert (1 * 20) == 420
========================= 1 failed, 36 passed in 0.17s =========================
amazon: "often bought together: Data Structures in Java - rope - stepladder"
Python 3.10.8 locally and CPython (3.11.0) in CI
Every time I tried to use a cast in a case statement, Pytest freaked the fuck out
it did NOT like me doing that
How so?
Huh
For me all it's doing is making it to where x is always 1, and stopping after 35 cycles for some reason
I would have guessed that int was a constraint, not a cast 
def day10(inp: str) -> tuple[int, str]:
xhist = [1]
for i in inp.strip().split("\n"):
match i.split(" "):
case "noop",:
xhist.append(xhist[-1])
case "addx", val:
xhist.append(xhist[-1])
xhist.append(xhist[-1] + int(val))
gsm = 0
for i in [20, 60, 100, 140, 180, 220]:
gsm += i * xhist[i - 1]
data = []
for i, j in enumerate(xhist):
data.append((i % 40 - j) in (0, 1, -1))
for j, i in enumerate(data):
print("\u2588\u2588" if i else " ", end = "")
if j % 40 == 39:
print()
deeta = input("\b\bWhat can you read?\n> ").strip().upper()
if deeta.isalpha() and deeta.isascii() and len(deeta) == 8:
return (gsm, deeta)
print("Misinput, aborting...")
raise ValueError("Invalid input")```

In [5]: a = ["addx", "3"]
In [6]: match a:
...: case ["addx", int(x)]:
...: print('int')
...: case ["addx", x]:
...: print('other')
...:
other
seems to be a constraint, yeah
makes sense
@hollow void :white_check_mark: Your 3.11 eval job has completed with return code 0.
4
Anyone else's solution missing seemingly one pixel?
I mean clearly this is legible but that first Z is killing me
Ok figured it out. x at this point is -1, so my x % 40 check is yielding 39 which causes the pixel not to be drawn
This is perhaps too high-resolution
(it's not even done encoding yet)
190M lines, 1.4G
Yikes
>>> match 4:
... case int():
... print("it's an int.")
... case _:
... print("it's not.")
it's an int.
It can be both
had this exact same issue
my robust unit testing caught this for me though :)
I have poked at mine a bit and I can't get the little errors to go away
today is really easy for off by one errors
I had to really think about exactly the error I was getting and what I needed to do
I just can't see it 😅
If you'd like, I'd be happy to have a look at your code once I finish polishing my unit tests :)
Sure
It's only four pixels that are wrong as far as I can see
(spoilered for answer)
Everyone has a different answer
guys what is tricky about this task because i think im missing out on sth that is important
An understanding of crt beams is important
For me, it helped just being very regimented in coding part 1
Do you know how ticks work?
My understanding is that the puzzle inputs are not unique to an individual, there's just an assortment of them
you really have to read part 1, IMO. It's not difficult, but getting the precise details just right can be tricky
everytime there is addx i add the value to the "queue"
that has to wait 2 cycles to be added to the x
The 'tricky' bit in part 1 is that the updating register operation takes two cycles
I just realized our "communication device" is a pager
then it goes onto the next value in the queue
so you might have to read the answer in the middle of it
I made this mistake too. There is no queue. It simply takes 2 cycles before you go to the next input
so if there is something waiting to be added i dont read the values from addx?
When do we get the challenge that becomes O(n^x) if we do it wrong?
read input
cycle
if input is noop, start over
if input is addx
cycle
update x
I implemented mine using lots of generators.
what do you mean by start over
get next input
so forget about what was before?
noop is no op aka no operation.
basically pass
I did mine kind of like this. ```py
registers = {"X": 1}
def noop():
yield
def addx(value):
yield
yield
registers["X"] += value
opcodes = {
"noop": noop,
"addx": addx,
}
def run(data):
counter = 0
for line in data.splitlines():
oc, *args = line.split()
args = [*map(int, args)]
for _ in opcodesoc:
counter += 1
I just did a for loop.
for cycles in range(2)
if noop break
else
update x
noop is short for no operation
i dont understand what does it change
noop does nothing.
it's 1 of the 2 things you can get in the puzzle input.
ye i know
but i get correct answer for the example
up to 20 cycles
then i get the wrong value of x on other cycles
it's from the puzzle:
noop takes one cycle to complete. It has no other effect.
x = 1
cycles_to_register = [20+(x * 40) for x in range(6)]
addx = []
num_of_cycles = 0
for cycle in file:
num_of_cycles += 1
cycle = cycle.strip().split(" ")
if cycle[0].startswith("a"):
v = int(cycle[1])
addx.append([v,2])
addx[0][1] -= 1
if addx[0][1] == 0:
x += addx.pop(0)[0]
if num_of_cycles in cycles_to_register:
print(x*num_of_cycles)
maybe you can take a look
that seems odd. are you using the test input to verify your code?
I made the mistake of using the actual input
why do you have a list addx ?
that's good, is 40 correct?
addx is my so called queue
which some1 said doesnt have a place here
i store every value from addx there
there is no queue. it's 2 cycles and then add.
no need to queue anything, your queue will never have more than 1 item
well maybe if you never take anything off of the queue it will act as a history.
so for example
if i have
addx2
noop
noop
addx 3
addx 5
noop
what should the x be
4?
but it will be:
queue is empty
cycle
read input
if addx: add to queue
cycle
remove from queue
queue is empty
1 +2 +3 +5 is 10, and you used 2 + 1 +1 + 2 +2 +1 = 9 cycles
ohhhh
i think i get it
so just correct me if im wrong now
when i read addx 2
i add 2 to cycles count
and add 2 to the x
and then move on to the next line
sort of
haha
it's impoartnt that you understand that it's:
if addx:
+1cycle
+1cycle
and not:
if addx:
+2cycle
⬆️
there is stuff happening during each cycle.
and 1 thing happening after both cycles, but not during the cycle. 🙂
there is the option of replacing the 2 cycle addx with a noop + 1 cycle addx
Like the issue I suspect is that at some point one of the points you have to read at happens in the middle of an addx
and the register is only changed on the second cycle of the addx
on after
yes, sorry
so whats the difrence in
for _ in range(2):
num_of_cycles += 1
from
if cycle[0].startswith("a"):
num_of_cycles += 2
if after reading addx 3
i have to wait 2 cycles for the 3 to be addex to x
what can happen during this 2 cycles that addx 3 takes to complete
what is your objective? What number are you trying to turn in for your puzzle? think about how that number is calculated and when.
ok i think i got it
thanks a lot ;d
i know why it mattered
at least i think so
because while addx is happening it may be cycle 20 that i have to register
and if i just added 2 cycles i may never be on cycle 20
Dumb question, but im trying to figure out my loop condition, we need to read through every command in the list, but we also need to keep going until we read through all the cycles right?
how the hell do i get correct signal strengths on all cycles except 220
I used a queue, when it's noop I just add a noop to the queue, when it's addx I add both a noop and an addx
oof, that hurts
i got it
thank you to every1 who helped me
hopefully i get part2 without problems XD
Just finished my code and test refactoring for today
Tests have 673 lines 👀
My code for today:
import collections
from collections.abc import Iterator, Container
import dataclasses
import enum
import itertools
class CycleState(enum.Enum):
START = enum.auto()
DURING = enum.auto()
AFTER = enum.auto()
@dataclasses.dataclass(frozen=True)
class Cycle:
no: int
state: CycleState
@dataclasses.dataclass
class Instr:
cycle_no: int
add_val: int
def decrement_cycle(self) -> None:
self.cycle_no -= 1
class CathodeRayTube:
def __init__(self, program: str, watch_cycles: Container[Cycle] = ()) -> None:
self.program = collections.deque(program.splitlines())
self.register = 1
self._cycle_gen = self._cycle_gen_fn()
self.cycle: Cycle
self.instr: Instr | None = None
self._watch_cycles = watch_cycles
self.watched_cycles: dict[Cycle, int] = {}
self.screen = ""
@classmethod
def read_file(cls, watch_cycles: Container[Cycle] = ()) -> "CathodeRayTube":
with open("input.txt") as f:
return cls(f.read(), watch_cycles=watch_cycles)
@staticmethod
def _cycle_gen_fn() -> Iterator[Cycle]:
for x in itertools.count(1):
for y in CycleState:
yield Cycle(x, y)
def _increment_cycle(self) -> None:
self.cycle = next(self._cycle_gen)
def _parse_instr(self, instr_text: str) -> None:
match instr_text.split():
case ["noop"]:
instr = Instr(cycle_no=1, add_val=0)
case ["addx", add_val]:
instr = Instr(cycle_no=2, add_val=int(add_val))
case _:
raise Exception("Unexpected instruction")
self.instr = instr
def _execute_pre_cycle(self) -> None:
if self.instr is None:
try:
instr_txt = self.program.popleft()
except IndexError as exc:
raise StopIteration from exc
self._parse_instr(instr_txt)
def _execute_mid_cycle(self) -> None:
if ((self.cycle.no - 1) % 40) in (
self.register - 1,
self.register,
self.register + 1,
):
self.screen += "#"
else:
self.screen += "."
if self.cycle.no % 40 == 0:
self.screen += "\n"
def _execute_post_cycle(self) -> None:
assert self.instr
self.instr.decrement_cycle()
if self.instr.cycle_no == 0:
self.register += self.instr.add_val
self.instr = None
@property
def signal_strength(self) -> int:
return self.cycle.no * self.register
def __iter__(self) -> "CathodeRayTube":
return self
def __next__(self) -> int:
self._increment_cycle()
cycle_fns = {
CycleState.START: self._execute_pre_cycle,
CycleState.DURING: self._execute_mid_cycle,
CycleState.AFTER: self._execute_post_cycle,
}
cycle_fns[self.cycle.state]()
if self.cycle in self._watch_cycles:
self.watched_cycles[self.cycle] = self.signal_strength
return self.signal_strength
def main() -> None:
key_cycles = [
Cycle(no=20, state=CycleState.DURING),
Cycle(no=60, state=CycleState.DURING),
Cycle(no=100, state=CycleState.DURING),
Cycle(no=140, state=CycleState.DURING),
Cycle(no=180, state=CycleState.DURING),
Cycle(no=220, state=CycleState.DURING),
]
crt = CathodeRayTube.read_file(watch_cycles=key_cycles)
for _ in crt:
pass
print(
"Sum of interesting signal strengths:",
sum(crt.watched_cycles.values()),
end="\n\n",
)
print("Screen:\n")
print(crt.screen)
if __name__ == "__main__":
import timeit
print(timeit.timeit(main, number=1))
And my unit tests, which is multiple times larger than that:
https://github.com/Fiddle-N/advent-of-code-2022/blob/master/day_10/test.py
😭
when your tests are longer than your actual program.
I think I'm missing the first column but well it worked
I think they mean why did you have to make it that long lol
I had to make it that long to fit all the test cases
I want to be able to assert every detail given in the problem description about the test inputs
Part 2 has a crap ton of test cases though
20 cycles * 3 cycle stages (before, during, after) leads to around 60 cases to assert just for part 2
I still don't even understand how it works
I'm opening up the docs just to figure out what a Container is
I had a weird solution for dealing with part 1, but otherwise my dist code is straightforward
fn solve(input: &[Command]) -> AocResult<(i32, String)> {
use Command::*;
let mut res = 0;
let mut cycle = 0;
let mut x = 1;
let mut display = vec![];
let mut draw = |pos, x| {
display.push(pos - 1 <= x && x <= pos + 1);
};
for cmd in input {
let prev_cycle = cycle;
let prev_x = x;
match cmd {
Noop => {
draw(cycle % 40, x);
cycle += 1;
}
Addx(arg) => {
draw(cycle % 40, x);
cycle += 1;
draw(cycle % 40, x);
cycle += 1;
x += arg;
}
}
if (20 + prev_cycle) % 40 > (20 + cycle) % 40 {
let aligned = cycle - cycle % 20;
res += aligned * prev_x;
}
}
let display = display
.chunks_exact(40)
.map(|row| {
row
.iter()
.map(|b| if *b { '#' } else { '.' })
.collect::<String>()
})
.join("\n");
Ok((res, format!("\n{display}")))
}
parsing code left out, it's not too interesting
Jeebs.
just parses the thing into commands, rust enums are neat
pub enum Command {
Addx(i32),
Noop,
}
So that’s based off the fact that all I’m doing with that parameter is doing an “in” check on it
I pass in a list in one place, and dict.keys() in another, both of which support doing an “in” check
That means they both use __contains__, so they are both a Container
why use a deque for the instructions?
Just so I can pop left . It’s a bit gratuitous I admit
https://github.com/Fiddle-N/advent-of-code-2022/blob/master/day_10/process.py#L136-L142
Why do you get two blank lines at the end in two different ways?
https://github.com/Fiddle-N/advent-of-code-2022/blob/master/day_10/test.py#L5
https://github.com/Fiddle-N/advent-of-code-2022/blob/master/day_10/test.py#L157
Why is one a constant and one is not?
That's all I got because I don't understand the code
day_10/process.py lines 136 to 142
print(
"Sum of interesting signal strengths:",
sum(crt.watched_cycles.values()),
end="\n\n",
)
print("Screen:\n")
print(crt.screen)```
`day_10/test.py` line 5
```py
LONG_PROGRAM = """\```
`day_10/test.py` line 157
```py
program = """\```
I didn’t have to use end for the first print, that much is true
And the constant is just because I have that long program in two test functions and didn’t want a copy paste of it
And hey, my code is understandable! XD
More than the golf courses that’s for sure
It's very nice and clean
I'm just not a very good dev
||and verbose||
I am verbose I admit
That's not bad though
it can be
nah, this is fine
using the test input, for some reason mine gets the first two but thats it
cycle, val, cycle*x
20 21 420
60 19 1140
100 17 1700
140 30 4200
180 16 2880
220 18 3960
Well, actually, no
Instr is bad
Don't shorten variable names
Not verbose enough
the vals are wrong as well
Naming things is unironically difficult
There's only two hard things in computer science, cache invalidation, naming things, and off-by-one errors
You too!?
With all the testing I did, I still got an off by one error afterwards 😂
But I quickly found it
and this was an off by one error lol
to interject
Have you worked out the error or still trying to figure it out?
i got it
i init'ed my cycle count at 1 for some reason
def check_cycle(cycle, x):
if cycle % 40 == 20:
return cycle * x
return 0
def part_one():
with open("day10/instructions.txt", "r") as f:
instructions = f.read().split('\n')
x = 1
cycle = 0
strength = 0
for i in instructions:
if 'addx' in i.split():
_, val = i.split()
cycle += 1
strength += check_cycle(cycle, x)
cycle += 1
strength += check_cycle(cycle, x)
x += int(val)
else:
cycle += 1
strength += check_cycle(cycle, x)
print(strength)
to give some criticism, I see a bunch of methods that are used once and do trivial work
e.g. _increment_cycle should just be inlined in the one place it's called imo
read_file is a paper thin wrapper around the constructor with a file hard coded, why not just read the file and pass the string to the constructor in main?
make sure you check during every cycle, and not skipping cycles, or after cycles.
Lmao that'll do it
So, the increment_cycle I have as a separate function just because it reads nicer. self._increment_cycle is IMO clearer than next(self._cycle_gen()) as to what it does
And yes, read_file absolutely doesn’t have to be a class method, it could be a separate one
But I like alternative initialisers :)
@wispy topaz thanks a lot at part 2 i understood even more why making it 2 seperate cycles is that important
but you made me really understand this problem
alternative initializers are fine, but having one that just reads from a hard coded file is very weird from a usability standpoint
Wow, your code is the antithesis of mine. it's impressive in it's level of detail, but I would get lost in it.
yw! glad to help!
something like this would make more sense
def make_crt_from file(fname):
...
(though I would call also that overkill, but that's more in opinion land)
It’s a fair point. For sure if I had the need to read in from different files I’d do that
I just have it hardcoded cos I know I’ll only read from one file ever in this case
you don't run the samples from file?
What, you don't read your testdata from different input files and test the testdata as well? 🙂
I get lost in the golf courses 😂
If you're not careful, you might get some business logic in with those tests!
Yeah, I think the golf is a fun experiment, but I don't think it's how people should be coding typically.
but there's quite a difference between "minimal readable code" and "unreadable golf"
Could also make the center part a for loop to clean it up
Oh yeah for sure! Totally agree
You have the same couple of lines duplicated in 3 places. There might be a logical way to remove the duplicates.
I tend to opt to keep things as simple as possible, no extravagant structures unless they are obviously good ideas from the beginning
During writing patterns tend to emerge and you can factor pieces out
^
People spout DRY but they need to consider WET
('Write Everything Twice', the principle that your code is actually fairly likely to diverge if you've only had to write it twice)
I am definitely overengineering my code for these puzzles, that’s for sure
Oh, I do try to follow DRY, but things that repeat tend to become very obvious as you write code
But the reason that the structures are there are so the unit tests work nicely
I follow DRY as/where it makes sense
I.E. if the code has the same structure and purpose
There's also the concept of reasonable numbers. The only reasonable numbers in computer science are 0, 1 and inf. 🙂
If the code is for two different things that just look similar, that's where WET applies
Well, that’s part of it. The other part is that I like named attributes for things
me too.
I do find the fact that iter steps partway through steps a bit weird as well, but that could just be me. There could still be a split internally for unit testing purposes "execute_pre_cycle/execute_mid_cycle/execute_post_cycle", but a lot of the cruft seems to be to try to accommodate the iterator part
a
with open("Inputs/10.txt") as f:
ops = f.readlines()
# Cycle: value
graph: dict[int, int] = {}
cycle = 0
x = 1
for op in ops:
op = op.strip()
if op == "noop":
cycle += 1
graph[cycle] = x
else:
to_add = int(op.split(" ")[-1])
graph[cycle] = x
graph[cycle+1] = x
x += to_add
graph[cycle+2] = x
cycle+=2
from pprint import pprint
pprint(graph)
and yes I did call that variable graph....
I couldnt think of a better name lol
i think you did your cycles wrong
alright lemme try it again then
I don't see how tho
but I can't say my attributes always have great names during aoc, see my day8, lot's of them:
# create an empty class
class Tree(namedtuple('Tree', 'x y h')): v=0;s=1
#read the data into a dictionary
data = open(filename).read().splitlines()
forest = {(x,y):Tree(x,y,h) for y,row in enumerate(data) for x,h in enumerate(row)}
H,W = max(forest)
# loop over each tree
for t in forest.values():
# loop over the 4 directions
for z,d in [
(list(zip( range(0,t.x)[::-1], repeat(t.y))), t.x),
(list(zip( range(t.x+1,W+1), repeat(t.y))), W-t.x),
(list(zip( repeat(t.x), range(0,t.y)[::-1])), t.y),
(list(zip( repeat(t.x), range(t.y+1,H+1))), H-t.y)]:
t.v |= all(t.h>forest[x,y].h for x,y in z)
t.s *= next((c for c,e in enumerate(z,1) if t.h<=forest[e].h),d)
print('part1', sum(t.v for t in forest.values()))
print('part2', max(forest.values(),key=lambda t:t.s).s)
day7 at least had better names:
class File(namedtuple('File', 'name fsize folders files parent')):
@property
def size(self):
return self.fsize + sum(d.size for d in [*self.folders.values(),*self.files])
As you say, it’s really for the unit testing. If I didn’t have to care about unit testing then I’d definitely make it be one iteration per full cycle. But testing the intermediary steps is really the key thing IMO, as it’s the place one is most likely to slip up on
what you're doing looks really weird, are you starting your cycle count at 0 or 1
0
Any reason to use namedtuples over dataclasses btw?
if the first instruction is noop then your graph should look like {0: 1} no?
1 liner class definition. That's about it really.
Fair
no
why
its cycle:value, not the other way around
also useful if you want attributes whose value cannot be changed.
yeah, i know
so 1 cycle, 0 value
I'm also curious why _parse_instr isn't a free function that returns an Instr, it doesn't really have any business being part of the class. It doesn't depend on anything in the class at all
def parse_instr(self, instr_text: str) -> Instr:
match instr_text.split():
case ["noop"]:
instr = Instr(cycle_no=1, add_val=0)
case ["addx", add_val]:
instr = Instr(cycle_no=2, add_val=int(add_val))
case _:
raise Exception("Unexpected instruction")
return instr
class ...:
# ...
def _execute_pre_cycle(self) -> None:
if self.instr is None:
try:
instr_txt = self.program.popleft()
except IndexError as exc:
raise StopIteration from exc
self.instr = parse_instr(instr_txt)
Dataclasses has a frozen parameter
oh wait reg starts at 1
on the end of the 0th cycle (which is your first cycle) . . .
so it would be 1:1
Since dataclasses came out, namedtuples have basically been dead to me
That's like having milk on your poptarts, you might as well cook at that point. 🙂
if you're doing 1:1 then why does your dict look like {0:1, 1:1, 2:2} if there's an addx 1
For actual non-aoc coding I do really enjoy dataclasses a lot.
Friendship ended with namedtuple
Now dataclasses is my best friend
Dataclasses and enums are my favourite for my over engineered AOC code :)
um, 0:1 is 0th cycle and value has 1. 1:1 is first cycle, but value wont increase yet. and in 2nd cycle value will finally be increased. I'm sorry what am I missing
they are very much not first class citizens in python
This could be a free function definitely. My unofficial rule of thumb is that if it’s a helper function only used in the one class, I keep it in that class. But if it were to be used across classes I’d bump it out of the class
if it doesn't depends on the state of the class, it for sure shouldn't be a member function
I guess you could make a case for a staticmethod or classmethod
Definitely staticmethod
okay got it!
Definitely not classmethod
my starting cycle was wrong @tidal forum. Thank you
(I keep forgetting the exact difference, I know staticmethod is the one you usually want)
I dont really understand what we are doing in part 2. X is the position of the middle of our sprite? And that somehow relates to what gets drawn?
ah classmethod takes class as an arg
Class method is really mostly for alternative initialisers
If I ever feel the need to type @staticmethod. I stop and write a free function instead.
If it doesn't need an instance and doesn't need the class, it has nothing to do with the class and shouldn't be there.
I don't mind the odd static method. Though at the moment I'm standing at 2 static methods having edited my code, which is definitely the upper limit I'd be comfortable with
If it's a function only used by a class, even if it doesn't need self, I'm ok with it as long as it's sparingly used
tbh if it's basically a helper to another method I have no issue with it just being a method. regardless if you use self or not.
Otherwise, there's no room at the inn!
is the gist of part 2?
if cycle in range(x-1,x+3): return '#'
return '.'
I have a similar line of code in my solution... so it's not a terrible idea
wrong range, but basically
oh yeah x+2
because we still need inclusive
and then like print newline at cycle % 40
tbh I just went with in (x-1, x, x+1)
I just dumped true/false into a list and built the actual string afterwards
like a list of bools and #/. based on the truth value?
I would do x-1 <= cycle <= x+1
feels like it describes the intent better
Dunno, is the beam in one of these 3 positions feels better to me.
I'll see what my senior says at code review 😛
I did enjoy the code review of my code just now. Usually I'm the one rigorously reviewing people's code, not the other way around XD
hopefully it comes off as constructive criticism rather than just ranting 😛
Nah it's all good :)
And a slots parameter too!
wait, how are you guys printing the drawing as a contiguous block? I put everything into a list and was just going to iterate over it but that just prints down the terminal lol
and i couldnt just print the list because of the newlines
nvm i can see the data is wrong anyways
oh i had the wrong dataset loaded
long day
nah either way this is wrong lol
but the test input matches what is shown
i just build up the solution as a string
i print with end=""
day 10 part 2 done!
isnt it actually cycle % 40 in [x-1,x,x+1]? because my cycle counter keeps going up to 240 and the x obviously never goes that high
1-based indeximg go brrr
cycle % 41
(cycle + 1) % 40?
or that
I was pretty happy with my solution today
I didnt think the problem itself was that hard, working out what you really had to do was quite challenging though
it was definitely easier than day 9
I feel day 9 was easier
the difference between part 2 and part 1 today is a couple variables and an if
Day 9 wasnt too tough either - I just got stuck on a silly bug for ages
day 9 I at least knew what I was doing. day 10 I was literally changing the order of the lines to make it work
noop was causing issues
i couldn't figure out how part 2 worked in day 9
If you kept a history of the register for each cycle then pt 2 was incredibly easy
how the loop worked idk
this is the loop you had to add https://github.com/Chiggy-Playz/AdventOfCode/blob/master/2022/Python/day9.py#L42
2022/Python/day9.py line 42
for i in range(1, len(rope)):```
well
Oh this is the rope one
not very helpful
not the forrest trees one
yeah
me too
basically "take pt 1, make it work for n dimensions"
I couldnt believe when my code ran first try and was correct
Yeah, the answer somewhat fell out on me too
agreed
where to add?
you expect me to read that? :kekw:
You really need to layout your code in a more human friendly way 😂
that's literally the first thing that comes to my mind
what do you expect me to do in a rush
I always find that if you rush and dont take the time to make it readable you will never fix the bugs you come up against
that's only an issue if you have bugs
why rush
to be faster
eh
i can read it all right
but the only thing i can't figure out is the bug
how does part 2 work
what you're doing for head and tail, you gotta apply for current knot and previous knot
Formatting usually comes second... sometimes third... because when I see what Part 2 is I usually need/want to refactor Part 1 to make it nicer code. Then I will format it. 😄
and loop over all knots
I do follow this too. Part 1 is just "throw anything at it" 😂
the U 8 in the test case gives me ```
H
1
2
3
4
98765
i did
it worked for part 1
rewrite it with better names and I might just look at it 🙃
I do get lucky sometimes and I correctly predict Part 2 well enough that my P1 code is mostly still suitable 😄
wrong day ?
or you can just see how my code works and compare. You say you are doing this, so it should be comparable
yep happened to me on treehouse
idk we're just talking about the difficulty of day 9
perhaps this is linked to your message above
I don't like that this one is nearly impossible to complete programmatically
I thought this was Advent of Code, not Advent of Reading
my part 1 worked something like ```py
if abs(head - tail) > sqrt(2):
tail = previous_head
yeah lmao
reminds me a bit of the cursed picoCTF 2022 challenge Wizardlike where it was nearly impossible to read the (ASCII art) flag and actually complete the challenge
when I read What eight capital letters appear on your CRT? I was like wtf
things like this have shown up before, to be fair
that is EXACTLY what I did for part 1
but as you can see from my github, I ditched that
come on
is this spoilers for day 9
you all are not talking about day 10 right?
if so why
maybe we should move
probably
I was just confused more than anything, but yeah
did you use Euclidian distance or something?
I'm getting spoiled for day 9 lol I should wait to go to this channel
what type of distance is the thing where you don't square because that's exactly what i did
how are you on day 10 without 9 ignore, me stupid
riiiiiiiiiight
Please move Day 9 chat to #1050641552524976129
there's no need to do all of them
yeah
Manhattan?
I forget only I try to lol
nvm it does
okk
see this is the reason i don't leave this chat
i keep getting pinged
😂
for Day 10 Part 2 I just add dummy array item before every addx, this is easiest way
assuming register start point is 1
and i have addx 15
cycle 1: register = 1
cycle 2: register = 16
any updates during cycle 2 must use X=1
you will only get X=16 effectively in 3rd cycle
im part 2
to be fair even in part 2, the drawing to screen is based on during-value
well, part 2 as well, if we are talking about setting pixels on the screen
lets go
[(1, 1), (2, 1), (3, 16), (4, 16), (5, 5), (6, 5), (7, 11), (8, 11), (9, 8), (10, 8), (11, 13), (12, 13), (13, 12), (14, 12), (15, 4), (16, 4), (17, 17), (18, 17), (19, 21), (20, 21), (21, 21), (22, 20), (23, 20), (24, 25), (25, 25), (26, 24), (27, 24), (28, 29), (29, 29), (30, 28), (31, 28), (32, 33), (33, 33), (34, 32), (35, 32), (36, 37), (37, 37), (38, 36), (39, 36), (40, 1), (41, 1), (42, 2), (43, 2), (44, 26), (45, 26), (46, 7), (47, 7), (48, 8), (49, 8), (50, 24), (51, 24), (52, 13), (53, 13), (54, 13), (55, 13), (56, 34), (57, 34), (58, 19), (59, 19), (60, 19), (61, 19), (62, 16), (63, 16), (64, 25), (65, 25), (66, 26), (67, 26), (68, 23), (69, 23), (70, 31), (71, 31), (72, 32), (73, 32), (74, 37), (75, 37), (76, 37), (77, 37), (78, 37), (79, 37), (80, 37), (81, 1), (82, 1), (83, 1), (84, 2), (85, 2), (86, 9), (87, 9), (88, 9), (89, 9), (90, 9), (91, 11), (92, 11), (93, 17), (94, 17), (95, 17), (96, 17), (97, 17), (98, 17), (99, 17), (100, 18), (101, 18), (102, 18), (103, 18), (104, 25), (105, 25), (106, 26), (107, 26), (108, 26), (109, 13), (110, 13), (111, 26), (112, 26), (113, 33), (114, 33), (115, 33), (116, 34), (117, 34), (118, 1), (119, 1), (120, 1), (121, 1), (122, 1), (123, 3), (124, 3), (125, 3), ]
back on track
so i have this
why do you have this
ayy nice
cycle 1/2 sprite is at X=1
I will be honest I couldnt figure out how to get the newlines working so i just used a library
print(textwrap.fill(''.join(drawing), 40))
lol
because it's 3 characters wide
the leftmost character is at X=1
but it covers columns 1,2,3
Yeah first 2 should be ## because you can't move the sprite until 3rd cycle
at cycle 38 it seems like the sprite is at X=36, so it covers 36,37,38, so you should get a #
str(map(lambda x:"\n"+x[1]if x[0]%40 else x[1], drawing))[1:]
``` should work
That better be a language barrier
octothorpe
pound!
WTF is that?
and on cycle 42 will it be
...................................###..```
or will it be
.......................................#```
o c t o t h o r p e
which one of these is correct
hash
is octothorpe
tag
octothorpe is overly fancy name for it lol
It's a hashtag you dummy
it is, I like being that guy
i forgot its hashtag
no just hash
but it's not a hashable value
pls anyone
xd
Why not?
It's a str
is the hash. A hashtag is the hash plus some text, like #python
i don't want to count the dots lol
stop bringing logic into this
its not about counting dots
its about will the thing go into the edge
or will it return
the moment the 3 hash touch the right side
*reverse
is an octothorpe
wth
so it will be
..XXX....
i thought it moves like
first 40 cycles = 1st row
is not a hash, a hash is 334359b90efed75da5f0ada1d5e6b256f4a6bd0aee7eb39c0f90182a021ffc8b
second 40 cycles = 2nd row
you get the "column" by cycle % 40
You're right, I'm sorry, I forgot we're on Twitter
I'll now proceed with normal Twitter posting -
@vernal urchin is fired for wanting to use Python instead of Rust BTW
no, rust has no garbage collection
C is better it's much simpler
haha
best programming language is aecor
boehm ftw
and dumped into the pile of idk
only reason java is not dead is because of my minecraft channel
Does it have more than one user yet?
100% of the people who have used it have loved it
Can't argue with that
i made rope simulation with it how bad can it be
string
everything gets implicitly converted to string IIRC if js doesn't know what to do
string
a bunch of operators need to behave as if it converts to string even if it's not implemented that way (for performance reasons)
actually some security exploits came like this
The only reason java is not dead is because Oracle spends more money on lawyers than programmers.
(I kid, java is widely distributed and will remain relevant for many years to come in some form or another)
i would like to learn it for android
but i also dont want to learn it
Unfortunately
I almost put laughing emoji, but actually this is unironically true
i want to learn rust or c++
Learn Rust BTW!!
Join us in the future of the developed world!!
Yesterday took me the entire day
Today took me an hour
learn Rust! 🦀🚀
I did today's first than yesterday, because today looks easy
should I do yesterday's
this one second part is almost identical to first part
what does entire day mean
how fast did you do today?
Like 7 hours of working on the problem
Just under an hour and a half
i did the first part in 20min
and now i sit on second part
1 hour
because i cannot understand the task
it feels frightening(?) because its syntax is like c++s so much more difficult than python imo
Yeah I'll admit I had to look at this channel for a second before I completely understood the problem
Today is a bit like reading a datasheet and building up a simple circuit based on it. It's all about precision, timing, and reading comprehension
Day 9 included a food break in between because i kinda got annoyed after seeing part 2 lmao
i remember it being midnight and I was about to go to bed because I was expecting this one to be harder like day 9, but then I quickly read through it and went "man I could do that pretty quickly"
"08:44"
Takes me longer than that just to understand the problem
day9 was nice for brain imo
some other moderator/helper had a animation that looked cool
salt-die
yes
here
mine's more of an inspiration to continuous rather than discrete blocks
thats cool
I also did a discrete version in python like salt-die but that wasn't as cool as this
why is at the end when you have let go of it already
some movement still happening?
because you can move more than 1 pixel in every frame, so I make everything go closer over time
rather than just snapping instantly
basically each node goes closer to its parent at a speed proportional to how far away it is from the expected position
takes a few frames for it to converge
it's not completely rigid, basically, similar to how in the 2d version there was some "leeway" before the child snaps
i meant for part 2, part 1 was pretty straightforward
Day 4 is my proudest achievement
###...##..#..#..##..####.###..####.####.
#..#.#..#.#.#..#..#.#....#..#.#.......#.
###..#....##...#..#.###..#..#.###....#..
#..#.#.##.#.#..####.#....###..#.....#...
#..#.#..#.#.#..#..#.#....#.#..#....#....
###...###.#..#.#..#.####.#..#.####.####.```
i get this
am i done finaly?
😭
Here is my dreadful looking code for part 2
with open('day10\input.txt','r') as f:
data = f.read().split('\n')
cycle = 0
x = 1
screenline = ''
screen = []
pixel = -1
def add_line(cycle):
global pixel
global screenline
if cycle in [40, 80, 120, 160, 200, 240]:
screen.append(screenline)
screenline = ''
pixel = -1
def draw_pixel(x):
global pixel
global screenline
pixel += 1
add_line(cycle)
if pixel in (x+1,x-1,x):
print(x, pixel, '#')
screenline += '#'
else:
print(x, pixel)
screenline += '.'
for line in data:
if 'noop' in line:
cycle += 1
draw_pixel(x)
else:
line = line.strip('addx ')
cycle += 1
draw_pixel(x)
cycle += 1
draw_pixel(x)
x += int(line)
for i in screen:
print(i)```
As always, lmk if you see any obvious improvements
if you replace . with a space it's easier to read the characters @junior coyote
If you think about it, there could be a possibility that someone's random letters spelled out some word
just don't sleep
i spent a few hours today morning trying to reverse engineer an input for a custom word, but I gave up lol
global 👀
here's my cleaned up implementation:
res = 0
screen = ""
X = 1
cycles = 0
def tick():
global cycles,res,screen
cycles += 1
if cycles % 40 == 20:
res += X * cycles
if cycles % 40 == 0:
screen += "\n"
else:
screen += " #"[X <= cycles % 40 < X+3]
for line in lines:
if line == "noop":
tick()
elif line.startswith("addx"):
tick()
tick()
X += int(line[4:])
print("Part 1:", res)
print("Part 2:")
print(screen)
lol your advice with " " instead of "."
finally can read
I'm not against hardcoding but it's just... more work in this case
ay
Try running this program. You'll need to increase the number of rows to 24 though: https://paste.pythondiscord.com/elutisiwex
i don't have a number of rows harcoded, it just stops when the program stops 😛
Ah nice. Robust!
lmao this is exactly what i was trying to do
with the rick roll
how did you generate this?
Erm, I'll send you the function, one sec...
if you want to see the golfed solution we have all been optimizing in the other channel:
R=c=X=0
S=n="\n"
T='c+=1;W=c%40;R-=~X*c*(W==20);S+=n[W:]or" #"[X<W<X+4];'
for L in open(0):exec(T+(T>L)*f"{T}X+=int(L[4:])")
print(R,S)
it's so horrible I love it
i go out of my way to say today was harder than all other ones
my english reading comprehension is horrible ig
🥴
I didn't do anything fancy to generate the ascii art itself 😄
I looked up pixel fonts but got bored.
It just looks two pixels ahead at each step, and always uses addx. There are probably more interesting/optimal ways to do it.
that's basically what I was trying to do but i couldn't get it working, my brain was being dumb
then i just said screw it and started working on the rope thing
custom graphics library in my own programming language lmao
Plot/puzzle predictions for day 11?
saturday night, prolly gonna be a doozy
We're still in the ravine right?
I'm guessing some sort of graph traversal
something like day 15 of last year I'd think
i just used ⬜ and ⬛
idk what U+2B1C mean
unicode
def check_draw(cycle, x):
#Replaced '#' and '.' because they are difficult to read
if (cycle-1) % 40 in [x-1,x,x+1]: return '⬜'
return '⬛'
no idea
it's the unicode codepoint for that character
i think my console didnt like it ig?
it work in other one
oh no
i forgot smth in other=)
nvm
is that js?
how do you read in a file in js if its in the browser :S
yes
I did this on the challenge input which opens as a web page when you click the link (because it doesn't have a Content-Disposition that tells your browser to force you to download it)
ooh
i see because its somewhere in the HTML document
you can just use it
from browser?
its in this pre style="word-wrap" thing
why document.body.textContent
can fetch it
textContent only gets the text, and strips any HTML tags
it basically takes all the text nodes from every element and puts them together
:D
@sterile pagoda https://paste.pythondiscord.com/micawisaye
can i pm you rq?
threw it together with some of salt-die's code to put a utility together
sure
Ah nice
Did you make the letters of the font yourself?
i finally made the VM work
most fun challenge so far ngl
My solutions for the Advent of Code 2022 problems with python - GitHub - R1c4rdCo5t4/AdventOfCode2022: My solutions for the Advent of Code 2022 problems with python
now i wanna generate letters
First, you must define a font
salt-die's seems to work pretty well ```
.\get_art.py "There! An entire sentence" > test_art_vm.txt & py vm.py < test_art_vm.txt
where is .
i only made one punctuation
why
I see, your contributions are much appreciated thank you
i'll probably do all printables later
because my time isn't unlimited
You could make a text file containing pre-rendered images of all the ascii characters
also support a column argument to the program pls
it's not a program, it's a text file
ok
Why not just pipe instead of saving to a file and then redirecting
does that work in cmd?
I would hope so?
The redirects work, but not the &
it doesn't
& is for running something in the background in bash
Ah I guess I tried it on PowerShell at some point
I don't use windows often
Or at all, really
in powershell, & is to run a program by file path
pwsh (run program): & ./path/to/file.exe
bash (run program in background): ./path/to/file.sh &
<> is also a pipe
🤷♂️
i made the programs work with lengths greater than 40 now
epic
turns out that's possible with windows cmd
yeah haha i stuck with 40 so nobody would have to change their aoc code 😅
>.\get_art.py "Have you ever thought of something as great as this" 200 | .\vm.py 200
works pretty well
now all i want is word wrap instead of character wrap
Now do famous song lyrics
never g-
:, ., and / aren't supported
-onna get it never gonna get it
Sounds like a bug
add them!
idk how
yeah well idk how salt-die did it
print out the uncompressed data from load_font(), add whatever you want, re-compress it
salt-die just read it from a text file the compression shenanigans are mine
for easy sharing
lemme refactor it
how do you recompress
ok
print(repr(zlib.compress(font.encode('utf-8'))))
then replace the FONT = line starting with b'
inverse is actually pretty cool
did someone make a program to generate instructions to create anything for a monitor
.-.
yeah look at the link a few messages above
nice
it is almost the hour of choking yet again
indeed, wactch me choke so bad
Lmao
see yall in like 3 hours
you think this is a better s:
.##..
#....
..#..
##...
why only 4 lines
implied empty lines above it
the 5 is exactly the same as a S too, trying to change it
maybe just add a # at the top-left corner so it isn't rounded
Hey @gray olive!
It looks like you tried to attach a Python file - please use a code-pasting service such as https://paste.pythondiscord.com
updated file btw https://paste.pythondiscord.com/bahoceraqi.py
Had to change my code, after part 1, because it is not any good for part 2.
now with the rework part 1 doesn't work anymore 😦
I seem to be off one cycle, but I don't see where.
In case anyone wants to take a look: https://paste.pythondiscord.com/muvimeruso
thanks mustafa 🙂

