#AoC 2022 | Day 5 | Solutions & Spoilers

1929 messages ยท Page 2 of 2 (latest)

scarlet wharf
#

saved myself the pain of re

little quiver
#

i used split by space

#

then int

#

easy.

surreal lichen
#

regex

#

eaiser

scarlet wharf
#

Some people, when confronted with a problem, think "I know, I'll use regular expressions." Now they have two problems.

subtle pewterBOT
#

events/advent_of_code/2022/5/python/script_day5.py line 68

*map(int, re.match(r"move (\d+) from (\d+) to (\d+)", instruction).groups())```
scarlet wharf
#

^ parse works like this and you get the int conversion for free

surreal lichen
#

I saw that
It is nice

#

But we talked about this Tom
Even they use regex

scarlet wharf
#

yeah I'm sure they use it internally

#

but that's the thing - they fiddle around with regex so you don't have to

#

kind of like how Python saves you from having to code from C (unless you decide you want to for AoC puzzles :P )

surreal lichen
#

At least use Rust BTW!!

edgy cypress
#

alright finished day 5 finally :p

tranquil nimbus
#

Just got day 5 done too.

scarlet wharf
#

nice to see non-golf once in a while :)

drowsy patrol
#

zip takes multiple inputs, but that is what that * does for me. zip(*[a,b,c]) the * expands the items into an argument list, so that is the equivalent of zip(a,b,c), when used like that it effectively transposes a 2D array (columns become rows, rows become columns).

rose mica
#

why did so many people use regex for parsing?
just doing the following seems so much simpler

amount, _from, _to = [int(word) for word in line.split()[1::2]]
torn turret
steel veldt
tranquil nimbus
#

What's wrong with map(int, ptrn.match(line).groups())?

rose mica
#

nothing?

tranquil nimbus
#

I was half tempted to use regex to parse the crates

surreal lichen
#

oh no

tranquil nimbus
#

(?:(?:\[\(d+)\]|( {3})) )+

torn turret
#

oh no indeed

vast wolf
#

If you didnt reformat the input, how did you figure out what letter corresponded to what column? Count the blanks between them?

edgy cypress
#

I ended up hardcoding it XD

#

The character in position 1 belongs to the first column, the one in pos 4 to the second and so on

rose mica
#

yea but that isn't really hardcoding

edgy cypress
#

why not? I had a list that looked like [1, 4, 5...]

#

I mean, I was using list comprehension to make it but still

tranquil nimbus
stark pagoda
#

line[1::4]?

tranquil nimbus
#

Darn, I should've thought of that.

tranquil nimbus
#

checks code
yes.

hexed flax
#

as a person who likes to implement things from scratch ~~apart from using collections module and parse ~~ i despise aoc helper

steep moon
#

but yes, the list slicer was much clever than my slot = index*4+1

warped robin
#

is this the channel to ask for help with something regarding Day 5? or would that be better suited for just #advent-of-code

hexed flax
#

this is the channel

steep moon
#

if you want spoilers I guess come in here?

hexed flax
#

just dont scroll up

#

ez

warped robin
#

๐Ÿ‘

tranquil nimbus
#

help usually involves spoilers

warped robin
#

so I'm trying to parse the "stacks" part of the input into a list of sublists, where each sublist is one "stack" and I am having trouble because for some reason, my code is adding every single crate into the stacks

#

for example, this is just printing out what should be the first stack, but I am getting this

scarlet wharf
#

@opal vine solution discussion so posting here:
don't feel too bad. If you really want, you can always hardcode the stack input in and come back to figuring a way to parse it afterwards

warped robin
#

i know discord code blocks are preferred over screenshots, but idk how to also include what I getting as my output. sorry

stark pagoda
#

that makes 9 copies references to the same list

warped robin
#

oh my god

#

๐Ÿคฆ

stark pagoda
#

try [[] for _ in range(9)]

tranquil nimbus
#

I did something like this. {int(slot): [] for slot in lines[-1].split()}

warped robin
tranquil nimbus
#

Yes, I parsed it backwards

warped robin
#

this was giving me such a headache last night that I had to call it quits and go to sleep

#

i could not for the life of me figure out what was going wrong

jolly sparrow
#

i coordinatededed out

surreal lichen
#

I think you missed an -ed

novel surge
jolly sparrow
#

coordinatededededed

surreal lichen
#

much better

novel surge
#

(ed)*

manic cobalt
warped robin
novel surge
#

ye

steep moon
#

I was doing some cockamamey thing counting spaces before I realized the important value was always in the same column

stark pagoda
#

basically yeah

jolly sparrow
#

where my i * 4 + 1 bros at

steep moon
#

and I thought it was a bit more elegant

jolly sparrow
#

i like going by columns, so i can create each stack at a time

#

so i didn't slice the line

steep moon
jolly sparrow
#

yep

#

in one single comprehension

steep moon
#

so you load in all BLAH lines of the input?

jolly sparrow
#

yep

steep moon
#

I mean, I do too, but I could conceivably rewrite it to only be looking at one line at a time

stark pagoda
#

!e I didn't write this task in python, but this would work

s = \
"""        [C] [B] [H]                
[W]     [D] [J] [Q] [B]            
[P] [F] [Z] [F] [B] [L]            
[G] [Z] [N] [P] [J] [S] [V]        
[Z] [C] [H] [Z] [G] [T] [Z]     [C]
[V] [B] [M] [M] [C] [Q] [C] [G] [H]
[S] [V] [L] [D] [F] [F] [G] [L] [F]
[B] [J] [V] [L] [V] [G] [L] [N] [J]
 1   2   3   4   5   6   7   8   9 """

print([''.join(x).strip() for x in zip(*(l[1::4] for l in s.splitlines()[-2::-1]))])
subtle pewterBOT
#

@stark pagoda :white_check_mark: Your 3.11 eval job has completed with return code 0.

['BSVZGPW', 'JVBCZF', 'VLMHNZDC', 'LDMZPFJB', 'VFCGJBQH', 'GFQTSLB', 'LGCZV', 'NLG', 'JFHC']
jolly sparrow
#
    stacks, commands = aoc_lube.fetch(year=2022, day=5).split("\n\n")

    stacks = stacks.splitlines()
    stacks = [
        [stacks[y][x] for y in range(7, -1, -1) if stacks[y][x] != " "]
        for x in range(1, 35, 4)
    ]

shadowed a few times, but this works

steep moon
steep moon
#

i feel like there's something cleverer I could do with my crane_operation function

jolly sparrow
#

unpacking into zip is infamous way to transpose

steep moon
#

so I avoid 2 loops

stark pagoda
manic cobalt
# jolly sparrow where my `i * 4 + 1` bros at

does a + (n-1)d count? ๐Ÿ˜ญ

def part_one(data):
    dictionary = defaultdict(list)

    for index, line in enumerate(get_stack_indices(data)):
        for items in line:
            stack_number = int((items - 1) / 4) + 1
            dictionary[stack_number].append(data[index][items])

    for key in dictionary.keys():
        dictionary[key].reverse()

    for line in data:
        if "move" in line:
            pop_n, source, dest = list(map(int, re.findall("\d+", line)))
            for i in range(pop_n):
                dictionary[dest].append(dictionary[source].pop())

    for key, value in sorted(dictionary.items()):
        print(value[-1], end="")
vocal lichen
#

I started reading and got 2021d23 flashbacks

steep moon
opal vine
stark pagoda
vocal lichen
#
from aocd import lines, submit
from collections import defaultdict, deque
from tools import chunks
import re
import pprint


def solve(lines, all_at_once=False):
    # Initial setup:
    stacks = defaultdict(deque)
    it = iter(lines)
    for line in it:
        if not line:
            break
        chunked = (
            (i + 1, x)
            for (i, x) in enumerate(x.strip("[] ") for x in chunks(line, 4))
            if x.isalpha()
        )

        for (i, crate) in chunked:
            stacks[i].appendleft(crate)

    # Commands:
    for line in it:
        m = re.search(r"^move (\d+) from (\d+) to (\d+)$", line)
        assert m, f"{line} doesn't match"
        amount, src, dst = map(int, m.groups())
        tmp_stack = []
        for _ in range(amount):
            tmp_stack.append(stacks[src].pop())

        if all_at_once:
            tmp_stack = tmp_stack[::-1]

        stacks[dst].extend(tmp_stack)

    result = "".join(stack[-1] for (i, stack) in sorted(stacks.items()))
    return result


submit(solve(lines, False), part="a")
submit(solve(lines, True), part="b")
jolly sparrow
steep moon
manic cobalt
jolly sparrow
#

no, zip is builtin

tranquil nimbus
#

There's always zipfile for actual zip archives

manic cobalt
#

had to go with defaultdict

sleek grail
#

parsing hell oh gosh

#

thank god for zip

#

just finished it

jolly sparrow
#

zip iterates over multiple iterables

manic cobalt
vocal lichen
stark pagoda
#

!e

print(list(zip('abc', '123', 'ABC')))
subtle pewterBOT
#

@stark pagoda :white_check_mark: Your 3.11 eval job has completed with return code 0.

[('a', '1', 'A'), ('b', '2', 'B'), ('c', '3', 'C')]
steep moon
#

huh, ooooh, zipping together two list? not the zip compression format?

sleek grail
#
import re

input_lines = open("input.txt").read().split("\n")
unparsed_boxes, unparsed_instructions = input_lines[:9], input_lines[10:]

boxes = [""] + ["".join(i).strip()[:-1] for i in zip(*unparsed_boxes)][1::4]
instructions = [[*map(int,re.findall(r"\d+", i))] for i in unparsed_instructions]

for num, origin, destination in instructions:
    boxes[destination] = boxes[origin][:num][::-1] + boxes[destination] # remove [::-1] for part 2
    boxes[origin] = boxes[origin][num:]

print("".join(s[0] for s in boxes[1:]))
manic cobalt
sleek grail
#

zip(*iter) life-saver

jolly sparrow
#

!e

for a, b, c in zip("cat", "dog", "hat"):
    print(a, b, c)
iron turtle
#

!e
print(list(zip('abc', '123', 'AB')))

subtle pewterBOT
#

@jolly sparrow :white_check_mark: Your 3.11 eval job has completed with return code 0.

001 | c d h
002 | a o a
003 | t g t
#

@iron turtle :white_check_mark: Your 3.11 eval job has completed with return code 0.

[('a', '1', 'A'), ('b', '2', 'B')]
manic cobalt
#

i see a goat in there somewhere

steep moon
#

ok, I wanna see a state initializer using zip

jolly sparrow
#

a goat is just a dog in a hat

sleek grail
#

!e ```py
l = ["aA1", "bB2", "cC3"]

print(["".join(i) for i in zip(*l)])

subtle pewterBOT
#

@sleek grail :white_check_mark: Your 3.11 eval job has completed with return code 0.

['abc', 'ABC', '123']
manic cobalt
iron turtle
stark pagoda
#

my rust code for parsing wasn't terrible

  let mut piles: [Vec<_>; 9] = Default::default();
  for s in crane.lines().rev().skip(1) {
    for (i, &c) in s.into_iter().skip(1).step_by(4).enumerate() {
      if c != b' ' {
        piles[i].push(c);
      }
    }
  }
```though I'm annoyed that there isn't a nicer way to initialize an array of vectors
sleek grail
#

๐Ÿ

calm helm
#

oh we can post other lang solutions here?

stark pagoda
#

I think that's fine, AoC is full of people playing with new languages

iron turtle
#

as you can see

iron turtle
#

you can

opal vine
#

can i type check if an array only has specific type of elements

vocal lichen
#

๐Ÿฆ€

calm helm
hoary egret
manic cobalt
#

!e

dictionary = dict.fromkeys(range(3), [])
print(dictionary)
dictionary[0].append("1")
print(dictionary)

@vocal lichen

subtle pewterBOT
#

@manic cobalt :white_check_mark: Your 3.11 eval job has completed with return code 0.

001 | {0: [], 1: [], 2: []}
002 | {0: ['1'], 1: ['1'], 2: ['1']}
manic cobalt
#

why does this happen

stark pagoda
sleek grail
vocal lichen
hoary egret
stark pagoda
#

I hope the latter

#

you can do a lot with macros

sleek grail
#
l = []
temp = l
l.append(1)

# temp is now [1]
manic cobalt
jolly sparrow
#

my nim parsing just copied python:

let
  raw = fetch(2022, 5).split("\n\n").mapIt(it.splitLines)

  stacks = collect(for x in 0..8:
    collect(for y in 0..7:
      let chr = raw[0][7 - y][1 + 4 * x]
      if  chr != ' ': chr))

  commands = collect(for line in raw[1]:
    line.scanTuple("move $i from $i to $i"))
stark pagoda
#

I coded a bfs in vim using some regex ๐Ÿ˜›

sleek grail
hoary egret
sleek grail
#

generally mutable objects get passed around as references

manic cobalt
#

this was a first for me

sleek grail
stark pagoda
manic cobalt
#

yeah i'm aware of that but dunno how it sneaked by me in dicts

sleek grail
#

ah

iron girder
#
g=str.split;I='\n';x,y=g(open(0).read(),2*I);j=''.join;exec("d=[' ']+[j(m).strip()for m in zip(*g(x,I))][1::4]\nfor l in g(y,I):a,b,c=map(int,g(l)[1::2]);d[c]=d[b][:a][::%d]+d[c];d[b]=d[b][a:]\nprint(j(*zip(*d)));"*2%(-1,1))```
224 exec

```py
g,j,I=str.split,''.join,'\n'
x,y=g(open(0).read(),2*I)
def f(o):
 d=[' ']+[j(m).strip()for m in zip(*g(x,I))][1::4]
 for l in g(y,I):a,b,c=map(int,g(l)[1::2]);d[c]=d[b][:a][::o]+d[c];d[b]=d[b][a:]
 print(j(*zip(*d)))
f(-1)
f(1)```
227 no exec
sleek grail
#

damn you actually golf it today ๐Ÿ˜ญ

#

i gave up after looking at what i had to parse

iron girder
#

lol

sleek grail
#

wait i see [::%d]

#

that's valid syntax?

stark pagoda
sleek grail
#

AH

#

i see

stark pagoda
#

it's being formatted with %

vocal lichen
#

wait I don't even think you need vim

stark pagoda
#

-1 for part 1, 1 for part 2

vocal lichen
#

I think vscode is enough ๐Ÿ˜…

iron turtle
#

...

opal vine
#
with open("input.in", "r", encoding="utf-8") as file:
    file = file.readlines()

    # get amount of stacks without looking at the file b4 and only knowing the file scheme
    for index in range(len(file)):
        if file[index].split()[0].isnumeric():
            temp = index
            for i in file[index].split():
                containers[i] = []
            break
```getting the amount of stacks
#

when reading the containers from a non full line(line where not every stack has a container) how should i approach assigning the containers to the correct stack

iron girder
#

zip only has 1 elt so you can just star it

stark pagoda
#

historically I have had fun hacking together solutions in bash

#

e.g. day 1 part 1

tr '\n' + | sed 's/+$/\n/;s/++/\n/g' | bc | sort | tail -n1
#

part 2

tr '\n' + | sed 's/+$/\n/;s/++/\n/g' | bc | sort | tail -n3 | xargs | tr ' ' + | bc
#

I love me some hacked together bash

warped robin
surreal lichen
#

The latter

stark pagoda
#

neither

#

it would be the same as [[]]

#

because the content of an empty list repeated 9 times is an empty list

calm helm
stark pagoda
calm helm
#

hmm

vocal lichen
#

yeah, you're thinkinging of [[]] * 9

#

(which also wouldn't work)

opal vine
stark pagoda
#

dammit, I get the urge to write some hacky bash for today

warped robin
stark pagoda
#

I think you can write the updates as regex

opal vine
vocal lichen
warped robin
opal vine
#
containers = {}

with open("input.in", "r", encoding="utf-8") as file:
    file = file.readlines()

    # get amount of stacks without looking at the file b4 and only knowing the file scheme
    for index in range(len(file)):
        if file[index].split()[0].isnumeric():
            temp = index
            for i in file[index].split():
                containers[i] = []
            break

    # assign containers to correct stack in start position
    for layer in range(temp - 1, -1, -1):
        for index, char in enumerate(file[layer]):
            if index % 2 == 1 and char != " " and char != "\n":
                containers[str(index // 4 + 1)].append(char)
    file = file[temp+2:]

    for operation in file:
        _, amount, _, prev, _, after = operation.split()
        for i in range(int(amount)):
            temp = containers[prev].pop()
            containers[after].append(temp)

    # outputting solution for task 1
    for stack in containers:
        print(containers[stack][-1], end="")
```part 1 solved
#

i think i did way too many for loops but its working

astral ivy
#

on my phone rn. can't compare ๐Ÿ˜…

thorn magnet
#

exams started ๐Ÿฅฒ ,

from  ..aoc import get_input


day_input = get_input(5).strip()
def print_stack(stack):
    for i in stack:
        print(*i)
    print()

stack_raw, movements = day_input.split('\n\n')
stack = []
stack_temp = []
stacks = 8
stack_raw = stack_raw.split('\n')[0:-1]

for i in range(1, len(stack_raw[0]), 4):
    stack.append([])
    for j in range(stacks):
        crate = stack_raw[j][i]
        if crate != ' ':
            stack[-1].append(crate)
    stack[-1] = stack[-1][::-1]

movements = [list(map(int, [j for j in  i.split(' ') if j.isnumeric()])) for i in movements.split('\n')]
for movement in movements:
    times,from_, to = movement[0], movement[1]-1, movement[2]-1
    
    temp_stack = []
    while times > 0 and stack[from_]:
        temp_stack.append(stack[from_].pop())
        times -= 1
    stack[to].extend(temp_stack[::-1])

print(''.join([i[-1] for i in stack if len(i)]))
opal vine
#
containers = {}
containers2 = {}

with open("input.in", "r", encoding="utf-8") as file:
    file = file.readlines()

    # get amount of stacks without looking at the file b4 and only knowing the file scheme
    for index in range(len(file)):
        if file[index].split()[0].isnumeric():
            temp = index
            for i in file[index].split():
                containers[i] = []
                containers2[i] = []
            break

    # assign containers to correct stack in start position
    for layer in range(temp - 1, -1, -1):
        for index, char in enumerate(file[layer]):
            if index % 2 == 1 and char != " " and char != "\n":
                containers[str(index // 4 + 1)].append(char)
                containers2[str(index // 4 + 1)].append(char)
    file = file[temp+2:]

    for operation in file:
        _, amount, _, prev, _, after = operation.split()
        amount = int(amount)
        for i in range(amount):
            temp = containers[prev].pop()
            containers[after].append(temp)
        containers2[after] += containers2[prev][-amount:]
        containers2[prev] = containers2[prev][:-amount]

    # outputting solution for task 1
    for stack in containers:
        print(containers[stack][-1], end="")

    print()

    # output for task 2
    for stack in containers2:
        print(containers2[stack][-1], end="")
iron girder
#
g=str.split;I='\n';x,y=g(open(0).read(),2*I);j=''.join;exec("d=[' ']+[j(g(j(m)))for m in zip(*g(x,I))][1::4]\nfor l in g(y,I):a,b,c=map(int,g(l)[1::2]);d[c]=d[b][:a][::%d]+d[c];d[b]=d[b][a:]\nprint(j(*zip(*d)));"*2%(-1,1))```
222 exec

```py
g,j,I=str.split,''.join,'\n'
x,y=g(open(0).read(),2*I)
def f(o):
 d=[' ']+[j(g(j(m)))for m in zip(*g(x,I))][1::4]
 for l in g(y,I):a,b,c=map(int,g(l)[1::2]);d[c]=d[b][:a][::o]+d[c];d[b]=d[b][a:]
 print(j(*zip(*d)))
f(-1)
f(1)

225 no exec

#

j(m).strip() -> j(g(j(m)))

vast wolf
#

so I figured out how to parse my letters, but I need to know first how many lists/deques I need first right? I feel like reading the last number of the 1 2 3 ... 9 would work but it feels wrong?

iron girder
#
g=str.split;I='\n';x,y=g(open(0).read(),2*I);j=''.join;exec("d=[I]+[j(g(j(m)))for m in zip(*g(x,I))][1::4]\nfor l in g(y,I):a,b,c=map(int,g(l)[1::2]);d[c]=d[b][:a][::%d]+d[c];d[b]=d[b][a:]\nprint(j(*zip(*d)));"*2%(-1,1))

220 exec

g,j,I=str.split,''.join,'\n'
x,y=g(open(0).read(),2*I)
def f(o):
 d=[I]+[j(g(j(m)))for m in zip(*g(x,I))][1::4]
 for l in g(y,I):a,b,c=map(int,g(l)[1::2]);d[c]=d[b][:a][::o]+d[c];d[b]=d[b][a:]
 print(j(*zip(*d)))
f(-1)
f(1)```
223 no exec
#

[' '] -> [I]

vast wolf
#

this is how im parsing atm

for d in data:
    if d == '':
        break
    for i in range(len(d) % 4):
        if d[i*4+1].isalpha():
            print(d[i*4+1], i)
vocal lichen
#

!e

from collections import defaultdict

a = defaultdict(list)
a[1].append(2)
a[2].append(3)
a[1].append(4)

print(a)
subtle pewterBOT
#

@vocal lichen :white_check_mark: Your 3.11 eval job has completed with return code 0.

defaultdict(<class 'list'>, {1: [2, 4], 2: [3]})
grave iron
scarlet wharf
vast wolf
#

no i meant hardcode the idea:
"find the line that that contains the indexes of the crates and find the last/largest number" which would be the number of lists you need

#

feels icky

scarlet wharf
#

so the latter of my two comments then. You can solve it however you want.

vocal lichen
#

Well you don't really need that line because you can just dynamically add stacks when needed

scarlet wharf
#

For example, there's nothing wrong with hardcoding, solving and coming back to it if you wish

jolly sparrow
#

i mean parsing the input sort of implies you've looked at it before --- it's not purely programmatic

vocal lichen
stark pagoda
# stark pagoda dammit, I get the urge to write some hacky bash for today

indeed it's possible, here is part 2

s="$(for i in {1..9}; do head -n8 $1 | tac | cut -c$((-2 + 4*i)); echo "$i"; done | tr -d '\n ')"

while read line; do
  set $line
  s="$(echo "$s" | sed -E "s/(.{$2})$4(.*)$6/$4\2\1$6/;s/$6(.*)(.{$2})$4/\2$6\1$4/;")"
done < <(tail -n+11 $1)
echo "$s" | grep -o '.[0-9]' | tr -d '\n0-9'
#

transposing was probably the most annoying part

little dirge
#

No way, you actually did it in bash

stark pagoda
#

otherwise regex for updating is cute

jolly sparrow
stark pagoda
#

I store the letters followed by the number for the pile

ZN1MCD2P3
```that way I can target specific piles when replacing
vast wolf
#

got this working

crates = defaultdict(list)
for d in data:
    if d == '':
        break
    for i in range(len(d) % 4):
        if d[i*4+1].isalpha():
            crates[i+1].append(d[i*4+1])

crate[0] will never be used but im just doing that it matches with the later instructions

#

could also just do i-1 later on

stark pagoda
jolly sparrow
#

if it's a default dict, why even have a [0]

stark pagoda
#

isn't it nice when you think "I think this would technically work" and then it works?

boreal beacon
#

Isn't it depressing when you think it works but it doesn't.

grave iron
#

I had that feeling multiple times this morning

boreal beacon
#

Then figuring out you putted the calculation backwards.

grave iron
#

But that just makes it feel even better when you do figure it out

boreal beacon
#

My solution today was decent

stark pagoda
tulip kindle
dusky swift
#
text = open(r"boxes.txt", "r").read().splitlines()
instructions = open(r"instructions.txt").read().splitlines()

array = [[],[],[],[],[],[],[],[],[]]
charcounter = 0

for line in text:
    mainind = 0
    spacecounter = 0
    for char in line:
        if char == " ":
            spacecounter += 1
            if spacecounter == 4:
                mainind += 1
                spacecounter = 0
        elif char == "[":
            spacecounter = 0
        elif char == "]":
            pass
        elif char != "\n":
            array[mainind].append(char)
            mainind += 1
            
moveinstructs = []
frominstructs = []
toinstructs = []
for line in instructions:
    offset = 0
    if line[6] == " ":
        moveinstructs.append(line[5])
    else:
        moveinstructs.append((str(line[5]) + str(line[6])))
        offset += 1                     
    frominstructs.append(line[12 + offset])
    toinstructs.append(line[17 + offset])    
for i in range(len(moveinstructs)):
    moveinstructs[i] = int(moveinstructs[i])
for i in range(len(frominstructs)):
    frominstructs[i] = int(frominstructs[i])
for i in range(len(toinstructs)):
    toinstructs[i] = int(toinstructs[i])


for insnum in range(len(moveinstructs)):
    fromcolumn = frominstructs[insnum] - 1
    tocolumn = toinstructs[insnum] - 1
    numofmoves = moveinstructs[insnum]
    for i in range(numofmoves):
        boxletter = array[fromcolumn][len(array[fromcolumn])-1]
        array[fromcolumn].pop(len(array[fromcolumn])-1)
        array[tocolumn].append(boxletter)

total = ""
for i in range(len(array)):
    total += array[i][len(array[i]) - 1]
print(total)

why no worky

#

i just get the wrong answers

#

the block of code to read the boxes works

#

and the block of code to read the instructions works

#

and after blood, sweat and tears i finally managed to get the block of code executing the instructions to not error

#

but it's saying that it's the wrong answer

#

anyone know why???

flat mountain
dusky swift
#

good idea

#

i'll try

flat mountain
#

also, consider printing out array to see all the values inside it. it's short.

stark pagoda
dusky swift
#

you do?

stark pagoda
#

if you reverse them things seem to work

array = [x[::-1] for x in array]
dusky swift
stark pagoda
#

because you add the crates from top to bottom

dusky swift
#

ahhhh yea

#

tru

#

e

#

but if you reverse the array won't it just reverse the order of the columns?

#

or is that not how reversing 2d arrays works

flat mountain
dusky swift
#

yep

stark pagoda
#

my thing is reversing the columns themselves

#

not the whole list

dusky swift
#

ah

#

thx

#

LET'S GO

#

CMZ

#

ok now imma try with input data

#

thx so much

flat mountain
#

yeah I get the right answer when I reversed each row in your array:

array = [row[::-1] for row in array]
dusky swift
#

me too

#

thx so much @flat mountain @stark pagoda

flat mountain
#

good luck!

dusky swift
#

thx

#

LET'S GO

#

thx so much

civic yacht
tropic crescent
#

What is the best way to get the numbers from the commands?
I'm currently iterating over every line and check if the character is an int but that gets pretty messy when the number is bigger than 9.

civic yacht
#

I went with a regular expression: ```py
instruction_pattern = re.compile(r'move (\d+) from (\d) to (\d)')

#

@tropic crescent

#

A useful helper function to have is one that extracts all the integers from a string.

tropic crescent
#

Yes, just saw that in your solution. That seems a lot easier, I will try that out thanks a lot.

high juniper
#

parse("move {moves:d} from {source:d} to {destination:d}", line) , with the parse lib.. {:d} matches all

civic yacht
#

!eval ```py
import re

def ints(s: str) -> list[int]:
pattern = re.compile(r'\d+')
return [
int(group)
for group in pattern.findall(s)
]

print(ints('move 1 from 1 to 2'))

subtle pewterBOT
#

@civic yacht :white_check_mark: Your 3.11 eval job has completed with return code 0.

[1, 1, 2]
civic yacht
#

You can use this for processing the input of many of the problems this

#

You might also want to have one for floats too.

iron girder
#

screw that, split and take every odd index

civic yacht
tropic crescent
#

Yeah I had to mess around with the numbers a lot the last day, thanks

high juniper
calm helm
surreal lichen
lilac sand
#

Finally I catched up again

tropic crescent
#
from typing import List, Iterator, Dict, Tuple
import re

def get_data() -> Tuple[Dict[int, List[str]], List[List[int]]]:
    with open("input.txt", "r") as file:
        lines_: Iterator[str] = iter(file.read().split("\n"))

    stacks_: Dict[int, List[str]] = dict()
    line: str = None
    while line != "":
        line = next(lines_)
        for count, char in enumerate(line):
            if char.isalpha():
                count = int(count / 4) + 1
                if stacks_.get(count):
                    stacks_.get(count).append(char)
                else:
                    stacks_[count] = [char]

    pattern: re.Pattern = re.compile(r'\d+')
    commands_ = []
    while True:
        char: str
        try:
            line = next(lines_)
            commands_.append([int(number) for number in pattern.findall(line)])
        except StopIteration:
            break

    return dict(sorted(stacks_.items())), commands_

def move_crates(reversed_: bool = True) -> str:
    stacks: Dict[int, List[str]]
    commands: List[List[int]]
    stacks, commands = get_data()

    for command in commands:
        crates = reversed(stacks.get(command[1])[:command[0]]) if reversed_ else stacks.get(command[1])[:command[0]]
        stacks.get(command[2])[:0] = crates
        stacks[command[1]] = stacks[command[1]][command[0]:]

    message: str = ""
    for stack in stacks.values():
        message += stack[0]
    return message

def part_one() -> str:
    return move_crates()

def part_two() -> str:
    return move_crates(False)

if __name__ == "__main__":
    print(part_one())
    print(part_two())

My solution for today.
I would appreciate any suggestionsyayy

tulip kindle
fresh plinth
#

magic ๐Ÿ‘€

umbral dawn
vocal lichen
subtle pewterBOT
#

@vocal lichen :white_check_mark: Your 3.11 eval job has completed with return code 0.

001 | first loop 1
002 | first loop 2
003 | first loop 3
004 | Doing other stuff
005 | second loop 5
006 | second loop 6
007 | second loop 7
008 | second loop 8
009 | second loop 9
vast wolf
#

shield your eyes folks

#
from collections import defaultdict, deque
import re

with open("crates.txt", "r") as f:
    drawings, moves = f.read().split("\n\n")

crates = defaultdict(deque)
for d in drawings.split("\n"):
    for i in range(len(d) % 4):
        if d[i*4+1].isalpha():
            crates[i+1].appendleft(d[i*4+1])

for m in moves.split("\n"):
    amount, old, new = list(map(int, re.findall("\d+",m)))
    for i in range(amount):
        crates[new].append(crates[old].pop())

for crate in crates.values(): print(crate[-1])
vocal lichen
#

That's not terrible

iron girder
#

511 chars, that's not great compared to the record of 220

vast wolf
#

timeout

#

this works on the demo

#

but

#
Traceback (most recent call last):
  File "main.py", line 16, in <module>
    crates[new].append(crates[old].pop())
IndexError: pop from an empty deque
#

i would assume all the instructions are valid no?

flat mountain
flat mountain
#

so no worries that there is a line to move from 3, to 4, pizza times.

#

are you sure you'rea accounting for the crates being 1-indexed and not 0-indexed ?

vast wolf
#

when i add it to the deque I use crates[i+1].appendleft(d[i*4+1]) so it should line up with the move instruction 1:1

flat mountain
#

ah I see, and crates is a dict. got it

vast wolf
#

for example on the demo

#

crates:

defaultdict(<class 'collections.deque'>, {2: deque(['M']), 1: deque(['C']), 3: deque(['P', 'D', 'N', 'Z'])})
flat mountain
#

try printing you crates to be sure they rotated correctly ?

#

your crates look to be in reverse order

stark pagoda
flat mountain
#

ah,. but it's a dict, nm

vast wolf
#

hmm, I put a print here

for m in moves.split("\n"):
    amount, old, new = list(map(int, re.findall("\d+",m)))
    for i in range(amount):
        crates[new].append(crates[old].pop())
    print(crates[new])

and insta error out, so it must be happening in the very beginning

flat mountain
#

wait, I only see 3 crates

vast wolf
#

yes

flat mountain
vast wolf
#

if you are talking about my output

flat mountain
#

that's why the demo works, the demo only has 3. the input has 9

frank rampart
vast wolf
#

i think im missing the point here lol, nothing is hard coded there so the amount of crates shouldnt affect my code?

flat mountain
civic yacht
vast wolf
#

my modulo?

vocal lichen
#

yeah

vast wolf
#

length of line % 4 would be the max amount of letters per crate

#

no?

#

since its NUM bracket space bracket NUM

vast wolf
#

or space space space

vocal lichen
#

What if the line is 100 chars long?

#

!e print(100 % 4)

subtle pewterBOT
#

@vocal lichen :white_check_mark: Your 3.11 eval job has completed with return code 0.

0
flat mountain
# vast wolf my modulo?

for i in range(len(d) // 4 + 1):
this will get you the correct number of crates, which will expose your next issue.
for debugging try this:

for n in range(1,10):
    print(n, crates.get(n))
vocal lichen
#

I'm guessing there's more than 0 crates

vast wolf
#

next issue? flushWide

flat mountain
smoky hemlock
#

the hardest part was putting the input boxes into arrays - the actual instructions was just ```py
crates[to].extend(crates[from_][-move:])
crates[from_] = crates[from_][:-move]

vast wolf
# flat mountain ` for i in range(len(d) // 4 + 1):` this will get you the correct number of c...
1 deque(['T'])
2 deque(['C', 'G', 'N', 'J', 'H', 'P', 'D'])
3 deque(['M', 'G', 'V', 'H', 'G', 'N', 'H', 'F', 'G', 'M', 'W', 'V', 'J', 'L', 'N', 'Z', 'H', 'M', 'M', 'R', 'R', 'S', 'D', 'L', 'G', 'V', 'P', 'B', 'N', 'C'])
4 deque(['N', 'F', 'H'])
5 deque(['M', 'D', 'Z', 'J', 'W', 'F', 'B', 'V'])
6 deque(['B', 'H'])
7 deque(['J'])
8 deque(['V', 'F', 'T'])
9 deque(['G'])

Nothing looks glaringly wrong here

#

๐Ÿค”

flat mountain
#

Yup. looks like you're getting all 9 crates now.

#

with the change to the for loop, it parsed correctly on my input too (which is different than your input)

vast wolf
#

so I get

for crate in crates.values(): print(crate[-1])
THHCVTJGD
#

which is ... not the answer?

flat mountain
#

for crate in crates.values(): print(crate[-1])
does not print IN NUMERICAL ORDER.

vast wolf
#

ohhhh

#

yep yep

flat mountain
#

๐Ÿ™‚

#

also, throw a join in there, save yourself some trouble.

#
print(''.join(crates[n][-1] for n in range(1,10)))
flat mountain
flat mountain
vocal lichen
vast wolf
#

Thanks for your help @flat mountain I feel like I got 95% there and then just broke down lol

little quiver
#

just do a manual parsing. Big deal?

#

That is exactly why AI failed yesterday, BTW.

smoky hemlock
carmine merlin
#

Parsing the initial crates took me longer than any of the other entire challenges wo far this year ๐Ÿคฃ. If only the initial stacks were represented horizontally!

smoky hemlock
round cradle
#

Oh, this one will be tricky to do as a one-liner. Finally some challenge!

little quiver
iron girder
#

you need to beat 220 chars

little quiver
#

a twit?

surreal lichen
#

Tweet*
But we use the real OG Twitter around here
You have to get <140 for that

vocal lichen
round cradle
#

Parsing is annoying here, I already parsed first part in one-liner. Functional programming ftw XD

round cradle
little quiver
tulip kindle
#

Also you can do lambda calculus so also yes

astral ivy
#

@tulip kindle any improvements in the golfing?

tulip kindle
#

A couple in the channel I think but I've been busy

astral ivy
iron girder
#

220

astral ivy
#

howww

iron girder
#

nah we're not at ๐Ÿ’ฏ yet

#

still 220

#

๐Ÿ˜”

tulip kindle
#

There we go, 220

astral ivy
iron girder
#

yeah

#

i was behind only maybe 20 of those chars

#

someone else did a ton

astral ivy
iron girder
#

oh damn

astral ivy
#

hehe

iron girder
#

now with exec is more chars so i don't need to post that anymore

#

i think

foggy jacinth
#

Now these return strings... wtf

def day5(inp: str) -> tuple[str, str]:
    did = -1
    data = inp.strip().split("\n")
    for i, j in enumerate(data):
        if j.startswith(" "):
            did = i
            break
    numbe_of_stacks = (len(data[did]) + 1) // 4
    stacks = []
    for i in range(numbe_of_stacks):
        stacks.append([])
    for i in range(did - 1, -1, -1):
        for i, j in enumerate(data[i][1::4]):
            if j != " ":
                stacks[i].append(j)
    cstacks = list(i[:] for i in stacks)
    for i in data[did + 2:]:
        print(i)
        match i.split(" "):
            case "move", a, "from", b, "to", c:
                for _ in range(int(a)):
                    stacks[int(c) - 1].append(stacks[int(b) - 1].pop(-1))
                cstacks[int(c) - 1] += cstacks[int(b) - 1][-int(a):]
                cstacks[int(b) - 1] = cstacks[int(b) - 1][:-int(a)]
                print("moved", a, "from", b, "to", c)
            case o:
                raise ValueError(o)
    ret1 = "".join(i[-1] for i in stacks)
    ret2 = "".join(i[-1] for i in cstacks)
    return (ret1, ret2)```
#

did you know? I am a big fan of slicing

astral ivy
#

check it once

vast wolf
#

le part 2

from collections import defaultdict, deque
import re

with open("crates.txt", "r") as f:
    drawings, moves = f.read().split("\n\n")

crates = defaultdict(deque)
for d in drawings.split("\n"):
    for i in range(len(d) // 4 + 1):
        if d[i*4+1].isalpha():
            crates[i+1].appendleft(d[i*4+1])

for m in moves.split("\n"):
    amount, old, new = list(map(int, re.findall("\d+",m)))
    step = len(crates[old]) - amount

    crates[old].rotate(-step)
    for i in range(amount):
        crates[new].append(crates[old].popleft())

print(''.join(crate[-1] for (_, crate) in sorted(crates.items())))
iron girder
#

exec has the same # of chars since your change just removed the function calls

#

not really applicable for the exec solution

astral ivy
foggy jacinth
iron girder
#

requests is 3rd party

foggy jacinth
#

urllib?

iron girder
#

sure ig

foggy jacinth
#

SOCKETS?

iron girder
#

just cut off internet access

#

ez

foggy jacinth
#

buw why doe

iron girder
#

security risk

#

obviously

tranquil nimbus
#
print(__import__("json").load(__import__("urllib.request").urlopen("..."))
lilac sand
#

After some research I figured out the deque is the best data structure for this but Idk exactly how to put each stack in a deque

iron girder
#
g,j,I=str.split,''.join,'\n'
x,y=g(open(0).read(),2*I)
for o in-1,1:
 d=[I]+[j(g(j(m)))for m in zip(*g(x,I))][1::4]
 for l in g(y,I):a,b,c=map(int,g(l)[1::2]);d[c]=d[b][:a][::o]+d[c];d[b]=d[b][a:]
 print(j(*zip(*d)))```216
lilac sand
#

Can someone please help me I am stuck?

tranquil nimbus
iron girder
astral ivy
tranquil nimbus
#

python does not have pre-processors

iron girder
#

๐Ÿ˜”

#

if only

tranquil nimbus
#

Use environment variables instead

astral ivy
iron girder
#

maybe i should make python with macros

astral ivy
tranquil nimbus
#

Why use macros when you monkeypatch?

astral ivy
iron girder
#

macros are best practice, monkeypatch is not

scarlet wharf
tranquil nimbus
#

It was the best of practices, it was the blurst of practices.

iron girder
#

python macros will be blursed

lilac sand
tranquil nimbus
#

Make it yourself by wrapping your script in exec()

iron girder
#

well yes, that's how i intend to make it

scarlet wharf
lilac sand
#

Trying to make every line in a list

#

Then connect each item with it's equivalent in the list under it

scarlet wharf
#

when you say every line, do you mean every line in the input file (in the section with the stacks)?

lilac sand
#

Yeah

scarlet wharf
#

So, I'm not sure that you necessarily need every line in a list

astral ivy
scarlet wharf
iron girder
#

maybe

lilac sand
scarlet wharf
#

That is one approach to it, yes

astral ivy
scarlet wharf
scarlet wharf
#

sure. Just note it's the opposite of code golf :)

astral ivy
#
s=[n:=open("input"),*map(lambda x:[*filter(str.isalpha,x[::-1])],[*zip(*[l[1::4] for l in next(zip(*[n]*10))[:8]])])]
for c,f,t in map(lambda x:[*map(int,x.split()[1::2])],n):
 s[t]+=s[f][-c:]
 s[f]=s[f][:-c]
[print(i[-1],end="")for i in s[1:]]

found this on reddit (247)
maybe it can give some ideas@iron girder

lilac sand
#

Wdym by code golf?๐Ÿ˜…

scarlet wharf
#

Others are experts in code golf, not me - maybe they can explain :P

astral ivy
scarlet wharf
#

^

#

In contrast, my solutions can be measured in number of classes

#

three classes today :)

scarlet wharf
#
class CrateStacks(list[Optional[list[str]]]):
    @classmethod
    def from_text(cls, stack_txt: str) -> "CrateStacks":
        stack_list = reversed(stack_txt.splitlines())
        header, stack_contents = next(stack_list), list(stack_list)
        assert (
            max(int(crate_no) for crate_no in header.strip().split()) <= 9
        )  # Only a single-digit number of stacks are supported
        stack_text_indices = [
            (int(ele), idx) for idx, ele in enumerate(header) if ele != " "
        ]
        stacks: list[Optional[list[str]]] = [None] + [[] for _ in stack_text_indices]

        for row in stack_contents:
            for stack_index, stack_text_index in stack_text_indices:
                stack_value = row[stack_text_index]
                if stack_value != " ":  # found a stack value
                    stack = stacks[stack_index]
                    assert stack is not None
                    stack.append(stack_value)
        return cls(stacks)

this is where I do my stack parsing

steel veldt
scarlet wharf
astral ivy
scarlet wharf
lilac sand
#

Oh

scarlet wharf
#

then adding to a list of lists

lilac sand
#

What is cls?

scarlet wharf
#

oh, this is a class method. I did this this way by extending onto the list class

#

basically, instantiating a list a different way

#

not important for understanding how to parse the text

#
        stack_list = reversed(stack_txt.splitlines())
        header, stack_contents = next(stack_list), list(stack_list)
        assert (
            max(int(crate_no) for crate_no in header.strip().split()) <= 9
        )  # Only a single-digit number of stacks are supported
        stack_text_indices = [
            (int(ele), idx) for idx, ele in enumerate(header) if ele != " "
        ]
        stacks: list[Optional[list[str]]] = [None] + [[] for _ in stack_text_indices]

        for row in stack_contents:
            for stack_index, stack_text_index in stack_text_indices:
                stack_value = row[stack_text_index]
                if stack_value != " ":  # found a stack value
                    stack = stacks[stack_index]
                    assert stack is not None
                    stack.append(stack_value)

this is all that matters really

lilac sand
#

Oh k

iron girder
#
g,j,I=str.split,''.join,'\n'
f=open(0).readlines()
for o in-1,1:
 d=[I]+[j(g(j(m)))for m in zip(*f[:8])][1::4]
 for l in f[10:]:a,b,c=map(int,g(l)[1::2]);d[c]=d[b][:a][::o]+d[c];d[b]=d[b][a:]
 print(j(*zip(*d)))```
211
lilac sand
#

What is assert?

scarlet wharf
#

also not important

scarlet wharf
#

it just checks an assumption made about the program

lilac sand
#

Oh

scarlet wharf
#

I've tried to code this in a general way

scarlet wharf
scarlet wharf
iron girder
#
g,j,I,f=str.split,''.join,'\n',[*open(0)]
for o in-1,1:
 d=[I]+[j(g(j(m)))for m in zip(*f[:8])][1::4]
 for l in f[10:]:a,b,c=map(int,g(l)[1::2]);d[c]=d[b][:a][::o]+d[c];d[b]=d[b][a:]
 print(j(*zip(*d)))```
202
scarlet wharf
lilac sand
#

It seems like I need to improve my OOP knowledge but Idk where to read

#

All what I was redirected for were 2 articles from real python

scarlet wharf
#

maybe check out resources on here?

#

!resources

subtle pewterBOT
#
Resources

The Resources page on our website contains a list of hand-selected learning resources that we regularly recommend to both beginners and experts.

scarlet wharf
#

I'd say get familiar with the constructs, then have a look at OOP code to see the style it's written in

#

that said, don't go crazy with OOP

#

I mostly do composition, and stay away from inheritance, for example

lilac sand
#

Oh k

scarlet wharf
#

(even though the code snippet I posted above was inheritance but ignore that :) )

astral ivy
#

*open(0)

#

never seen that in my life

iron girder
#

๐Ÿ˜Ž

lilac sand
round cradle
#

Okay, 3 lines instead of 1. I chose to split input separately (can be incorporated into the main part, but that wouldn't be optimal)
And then python complained about walrus in the iterable part, so I had to split that as well

in_s, in_m = map(str.splitlines,in5a.split("\n\n"))

d5a = (s:=[*map(lambda x: [*reversed("".join(x).replace(" ",""))],(zip(*([line[i] for i in range(1, len(in_s[-1]), 4)] for line in in_s[:-1]))))]) + ([[s[int(c)-1].append(s[int(b)-1].pop()) for _ in range(int("".join(a)))] for *a,b,c in ((e for e in line if e.isdigit()) for line in in_m)] and [])

print("".join(e[-1] for e in d5a))
scarlet wharf
#

Firstly re isn't "really" going to help you for the stack parsing. It'd be more for the rearrangements

#

Secondly, there's a quote by a programmer called Jamie Zawinski

round cradle
#

I hate myself for the [something_that_returns_none(e) for...] and []

astral ivy
iron girder
#

best way to get a better solution from me is to beat my solution

scarlet wharf
#

There are other ways to parse text

lilac sand
#

Oh

scarlet wharf
#

String operations is one of them, and generally easier

iron girder
#

the golfed solution uses no regex

scarlet wharf
#

Another nice way is the parse library

#

!pypi parse

subtle pewterBOT
round cradle
# astral ivy *open(0)

open(0) == open stdin as file-like

  • is for unpacking
    So this is quick making a list from stdin
lilac sand
#

Okay I will check that out

steel veldt
iron girder
#

parse still uses regex

scarlet wharf
#

I would say generally see if you can use operations like .split() before busting out the regex

tranquil nimbus
#

re.split(" ")

astral ivy
scarlet wharf
iron girder
astral ivy
iron girder
#

i checked with multiple accounts, they all had stack heights of 8

#

so my solution should work for any aoc input

astral ivy
#

that's all

scarlet wharf
# lilac sand Oh

Parse works like this:

rearrangement_txt = 'move 1 from 2 to 1'
parsed_text = parse.parse(
    "move {move:d} from {start:d} to {end:d}", rearrangement_txt
)
print(parsed_text["move"], parsed_text["start"], parsed_text["end"])

a simpler way than re IMO (but still good to know re for when things get complex)

iron girder
#

who cares about being generic

#

pfft

#

this works for aoc, that's what matters

grave iron
#

regex was what messed up my code the first few times, since I did move (\d) from (\d) to (\d) and didn't realize that the first number could be two digits

scarlet wharf
#

That was one issue

edgy cypress
scarlet wharf
#

someone else did [1-9]+

edgy cypress
#

i'm someone else lemon_angrysad

iron girder
#

but my golfed code assumes starting height of 8, that's all

scarlet wharf
grave iron
#

I also did regex for the stacks, and I somehow got that first try with \[(\S)\][ \n]?| [ \n]?

scarlet wharf
#

all I remember were that there were 2 regex boo-boos here

edgy cypress
astral ivy
scarlet wharf
#

@lilac sand anyhow, is that all good or do you have any further questions about completing today?

static agate
#

what does open(0) do, what is an integer file descriptor

iron girder
#

0 := stdin
1 := stdout
2 := stderr

steel veldt
#

i think that's an OS specific thing though, right?

static agate
#

ahh makes sense, i should've figured. ty

iron girder
#

i don't have access to a windows machine

#

so i can't check

steel veldt
#

let's see..

static agate
#

is *open(x) bad form or something? like not using with

iron girder
#

it's considered best practice in code golf

#

because anything is best practice if it's short ๐Ÿ˜Ž

steel veldt
#

open(0) seems to be stdin at least

iron girder
#

๐Ÿ‘Œ

steel veldt
#

good enough lul

static agate
#

yea seems super cool but not widely spread so i'm curious why

iron girder
#

because input() is more useful

steel veldt
#

because in general, reading from stdin is rare

iron girder
#

tessa posting a shorter solution? ๐Ÿ‘€

static agate
#

yea but i mean the unpack with open in general not just for reading from stdin

astral ivy
#

@iron girderWhat about mapping this part?

[j(g(j(m)))for m in zip(*f[:8])][1::4]

Also j(g(j... feels cringe ngl

astral ivy
steel veldt
iron girder
#

usually people don't send eofs through stdin if it's a command line thing

static agate
#

ok so bad form in the sense of readability

iron girder
#

more of a usability issue

#

people probably don't want to do ctrl + d when running your code

#

for golfing though, it's fine

static agate
#

ok cool, tyty

iron girder
#

lambda would also be longer

#

if there was a way to compose functions without lambda, then maybe

astral ivy
iron girder
#

what would you walrus

atomic coyote
#

bro

#

the code works on the exmaple

#

and doesnt on the actual thing

#

ima cry myself to sleep

iron girder
#

rip

astral ivy
#

the post add is still irking me. there's gotta be a shorter += solution ๐Ÿ˜ฉ

atomic coyote
#

like bro what even went wrong there

edgy cypress
atomic coyote
#

it can yes

#

this is a move 10 from 5 to 3

iron girder
#

like the zip

astral ivy
#

yep

iron girder
#

and flipping the order also means we need to use -a instead of a

astral ivy
#

that would fuck the zip up

iron girder
#

i don't remember how many chars zip saved

edgy cypress
static agate
#
    for n, x, y in inst:
        stack[y-1].extend([stack[x-1].pop() for _ in range(n)][::-1 if stackmove else 1])```
is there a smarter way to do this
atomic coyote
#

the line youre thinking about is the previous command

iron girder
#

are you sure that the end of the array is the top of each stack?

atomic coyote
#

wait something went wrong

#

why is 1 empty

#

at the end

#

LMAO WHY IS THERE A Q

edgy cypress
#

but what instruction makes [V, Q, R, L, H] become [V, Q, R, L]?

atomic coyote
#

this one

#

move 1 from 3

#

which is indexed 2

iron girder
atomic coyote
iron girder
#

the penultimate movement

#

the printed result ignores the last movement

atomic coyote
#

actually no mb all is fine

#

well this works

#

does any1 have like a short example I could test the code on

iron girder
#
g,j,I,*f=str.split,''.join,'\n',*open(0)
for o in-1,1:
 d=[I]+[j(g(j(m)))for m in zip(*f[:8])][1::4]
 for l in f[10:]:a,b,c=map(int,g(l)[1::2]);d[c]=d[b][:a][::o]+d[c];d[b]=d[b][a:]
 print(j(*zip(*d)))```
201
atomic coyote
#

wtf

#

this worksssss

iron girder
#
g,j,*f=str.split,''.join,*open(0)
for o in-1,1:
 d=[I:='\n']+[j(g(j(m)))for m in zip(*f[:8])][1::4]
 for l in f[10:]:a,b,c=map(int,g(l)[1::2]);d[c]=d[b][:a][::o]+d[c];d[b]=d[b][a:]
 print(j(*zip(*d)))```
200
atomic coyote
#

CMZ

atomic coyote
#

for o in -1,1

#

is that legal

iron girder
#

depends on your notion of legality

atomic coyote
#

compilesโ„ข๏ธ

iron girder
#

it compiles

atomic coyote
#

bro

#

this is so dumb

#

i dont know what to do

iron girder
#

skill issue

scarlet wharf
#

@atomic coyote are you having a problem trying to get your code to work correctly?

atomic coyote
#

yes

astral ivy
#

yay walrus!

iron girder
#
g,j,*f=str.split,''.join,*open(0)
for o in-1,1:
 d=['']+[j(g(j(m)))for m in zip(*f[:8])][1::4]
 for l in f[10:]:a,b,c=map(int,g(l)[1::2]);d[c]=d[b][:a][::o]+d[c];d[b]=d[b][a:]
 print(j(*zip(*d)))

196

astral ivy
#

we need a walrus emoji

iron girder
#

I was completely useless and i didn't realize

scarlet wharf
smoky hemlock
#

if you found a way to reduce the number of indexes/make the index code more condense you could get lower

iron girder
#

we're sub-200 now

atomic coyote
scarlet wharf
#

ah lol

astral ivy
scarlet wharf
#

well post it anyway

#

maybe I'll be bored enough to try

atomic coyote
scarlet wharf
#

though true story, I once read the opening chapter of a Java book and fell asleep on my bed

astral ivy
scarlet wharf
#

got into a really deep sleep

iron girder
scarlet wharf
iron girder
#

not that hard smh

atomic coyote
#

fair

astral ivy
atomic coyote
#

also theres no uh.....

#

๐Ÿ‘€

scarlet wharf
#

lol

#

!paste

subtle pewterBOT
#

Pasting large amounts of code

If your code is too long to fit in a codeblock in Discord, you can paste your code here:
https://paste.pythondiscord.com/

After pasting your code, save it by clicking the floppy disk icon in the top right, or by typing ctrl + S. After doing that, the URL should change. Copy the URL and post it here so others can see it.

scarlet wharf
#

just paste here

atomic coyote
#

parsing too hard

iron girder
#

is Z the top crate in the first stack?

subtle pewterBOT
#

Hey @atomic coyote!

You either uploaded a .txt file or entered a message that was too long. Please use our paste bin instead.

atomic coyote
#

oh

#

i cant

#

๐Ÿ’€

scarlet wharf
#

!paste

astral ivy
#

why?

atomic coyote
#

tried to cheat the system kekw

iron girder
#

asking sunder

astral ivy
#

ah ok

atomic coyote
#

no its the bottom one

#

im going bottom to top

#

cuz in that case I can use the stack

#

to peek (get top element), push (slap on top), and pop (remove from top)

scarlet wharf
#

I know no Java but I love classes

#

I should feel right at home

atomic coyote
#

oh shi

#

i

#

I didnt

scarlet wharf
#

you didn't what?

iron girder
#

lol

atomic coyote
#

RDG

#

and i did RGD

iron girder
#

yeah i saw that, was gonna tell you

atomic coyote
#

bro i love parsing code am I right

lilac sand
#

No golfing indeed

atomic coyote
#

god

#

that was terrible

#

oh hell naw multiple at once

#

cmon

lilac sand
lilac sand
#

Tysm

warped robin
#

is there a cleaner way for me to combine move_crates() and move_crates_2()? ```python
def parse_raw():
with open('input.txt') as f:
data = f.read().split('\n')
instructions = data[10:-1]

    horizontal_stacks = [stack[1::4] for stack in data[:8]]
    stacks = [[] for _ in range(9)]

    for row in reversed(horizontal_stacks):
        for position, crate in enumerate(row):
            if crate != ' ':
                stacks[position].append(crate)

return stacks, instructions

stacks, instructions = parse_raw()

def move_crates(amount, source, dest):
for _ in range(amount):
dest.append(source.pop())

def move_crates_2(amount, source, dest):
dest.extend(source[-amount:])
del source[-amount:]

def part_one():
stacks = parse_raw()[0]

for instruction in instructions:
    amount, source, dest = instruction.split()[1::2]
    move_crates(int(amount), stacks[int(source) - 1], stacks[int(dest) - 1])

result = ''.join([stack.pop() for stack in stacks])
print(result)

def part_two():
stacks = parse_raw()[0]

for instruction in instructions:
    amount, source, dest = instruction.split()[1::2]
    move_crates_2(int(amount), stacks[int(source) - 1], stacks[int(dest) - 1])

result = ''.join([stack.pop() for stack in stacks])
print(result)

part_one()
part_two()

atomic coyote
#

wtf

#

it worked first try

#

all I had to do

scarlet wharf
atomic coyote
#

my code is so ugly tho

#

ima make a cool parser for the stuff tmr

astral ivy
atomic coyote
#

isnt that a lot of chars to import np

astral ivy
#

but the import may be a problem

astral ivy
warped robin
scarlet wharf
#

you could still do that if you wanted to :)

atomic coyote
#

my code gets worse every day

#

we started with this and we end with 50 lines of adding stuff to a stack

#

the part I hate the most is parsing ngl

scarlet wharf
warped robin
#

going with that same thought process though, i guess I could do something like ```python
def move_crates(amount, source, dest, part):
if part == 1:
for _ in range(amount):
dest.append(source.pop())
elif part == 2:
dest.extend(source[-amount:])
del source[-amount:]

iron girder
#

edited the 196 to use the bs character, this way the space doesn't show up when printing

astral ivy
astral ivy
#

loop break check would be problematic

atomic coyote
astral ivy
atomic coyote
#

damn

#

how does it do that

#

doesnt it have to edit badically python stuff

stark pagoda
#

err -2 even?

#

or wait, are these tuples?

#

str rather

#

I guess it doesn't work then

atomic coyote
#

you guys are psychos

#

better than an obfuscator

iron girder
#

ok

atomic coyote
#

just make the code 20 chars

vocal lichen
astral ivy
atomic coyote
iron girder
# atomic coyote just make the code 20 chars
exec(bytes('โฑงโฑชๆ˜ช็Œฝ็‰ด็Œฎๆฑฐ็‘ฉโœฌโธงๆฝชๆนฉโจฌ็ฏๆนฅใ€จเจฉๆฝฆโฒโฏๆนฉใ„ญใ„ฌเจบๆ ๅฌฝเ งๅดงๅฌซโกชโกงโกชโฅญโคฉๆฝฆโฒโญๆนฉ็จ ็ฉโจจๅญฆใ บโฅๅญใจฑใบเฉๆ˜ ็‰ฏๆฐ ๆค โฎๅญฆใ€ฑๅดบๆ„บๆˆฌๆŒฌๆดฝ็กๆคจ็‘ฎๆœฌๆฐจๅฌฉใจฑใˆบโฅๆปๆ›ใตๅญคๅตขใฉ›ๅตกใฉ›ๆผบโญๅญคๅตฃๆปๆ‰›ใตๅญคๅตขๆ…›ๅดบโ€Š็‰ฐๆนฉโกดโกช็จช็ฉโจจโฅคโคฉ','u16')[2:])```
123 chars, close enough
atomic coyote
#

what

vocal lichen
atomic coyote
#

idk how np works

vocal lichen
#

no

iron girder
atomic coyote
#

all I know is that I could do [1,2,3] * 2

stark pagoda
atomic coyote
vocal lichen
#

!e ```py
import numpy as np
print(np.array([1,2,3]) * np.array([4, 5, 6]))
[1,2,3] * [4,5,6]

subtle pewterBOT
#

@vocal lichen :x: Your 3.11 eval job has completed with return code 1.

001 | [ 4 10 18]
002 | Traceback (most recent call last):
003 |   File "<string>", line 3, in <module>
004 | TypeError: can't multiply sequence by non-int of type 'list'
atomic coyote
#

without with actually

#

faater that way

vocal lichen
flat mountain
iron girder
#

no you shouldn't

flat mountain
hallow verge
#

Watching top positions from today taught me that if effort to hardcore input is relatively low it should be chosen over parsing programmatically:)

iron girder
elfin falcon
#

where's the golfing at rn

iron girder
#

196

#
g,j,*f=str.split,''.join,*open(0)
for o in-1,1:
 d=['']+[j(g(j(m)))for m in zip(*f[:8])][1::4]
 for l in f[10:]:a,b,c=map(int,g(l)[1::2]);d[c]=d[b][:a][::o]+d[c];d[b]=d[b][a:]
 print(j(*zip(*d)))```
flat mountain
hallow verge
#

I parsed it in python. Took me a while lol

astral ivy
iron girder
#

it's the same thing tbh, just combining assignments

flat mountain
# hallow verge I parsed it in python. Took me a while lol

My original working parsing :

data = open(filename).read().splitlines()
part1 = [list(x for x in row if x !=' ')
         for row in zip(*data[:8][::-1])
         if row[0] not in '[] ']

and the shorter rewrite:

data = open(filename).read().splitlines()
part1 = [list(''.join(r).strip())
         for r in zip(*data[:8][::-1])][1:36:4]
astral ivy
hallow verge
# flat mountain My original working parsing : ```py data = open(filename).read().splitlines() pa...

This is what I did

def parse_stacks(stacks_input: str) -> list[list[str]]:
    """Parse stacks string input into a list"""
    stacks = stacks_input.split("\n")[:-1]
    number_of_stacks = len(list(stacks[0])) // 4 + 1
    stack_content: list[list[Any]] = [[] for _ in range(number_of_stacks)]
    for line in stacks:
        stack_line = line[1::4]
        for idx, sl in enumerate(stack_line):
            if sl != " ":
                stack_content[idx].append(sl)
    return [list(reversed(s)) for s in stack_content]
atomic coyote
#

I do know python yeah, yall have the job way easier

edgy cypress
edgy cypress
#

probably the length of a row

shadow cradle
#

pandas rocks yet again

d1 = pd.DataFrame(pd.read_csv("day_5.input", nrows=pd.read_csv("day_5.input", sep=" ", engine="python", header=None)[0].str.startswith("[", na=False).argmin(), header=None, squeeze=True).str.replace(r" {4}", " NaN", regex=1).str.replace(r"\[|\]", "", regex=2).str.split().tolist()).T.iloc[:, ::-1].pipe(lambda fr: fr.set_axis(fr.columns[::-1], axis=1)).dropna().agg(list, 1).pipe(lambda fr: fr.set_axis(fr.index + 1)).explode().replace("NaN", pd.NA).dropna().groupby(level=0).agg(list)

print(pd.read_csv("day_5.input", skiprows=pd.read_csv("day_5.input", sep=" ", engine="python", header=None)[0].str.startswith("[", na=False).argmin() + 1, header=None, squeeze=True).str.findall(r"\d+").explode().astype(int).groupby(level=0).agg(list).apply(lambda a: d1[a[-1]].extend(d1[a[1]][-a[0]:][::-1]) or d1[a[1]].__setitem__(slice(-a[0], None), [])).any() or d1.str[-1].pipe(lambda s: s.groupby([0] * len(s))).agg("".join).item())

# Part 2
d2 = pd.DataFrame(pd.read_csv("day_5.input", nrows=pd.read_csv("day_5.input", sep=" ", engine="python", header=None)[0].str.startswith("[", na=False).argmin(), header=None, squeeze=True).str.replace(r" {4}", " NaN", regex=1).str.replace(r"\[|\]", "", regex=2).str.split().tolist()).T.iloc[:, ::-1].pipe(lambda fr: fr.set_axis(fr.columns[::-1], axis=1)).dropna().agg(list, 1).pipe(lambda fr: fr.set_axis(fr.index + 1)).explode().replace("NaN", pd.NA).dropna().groupby(level=0).agg(list)

print(pd.read_csv("day_5.input", skiprows=pd.read_csv("day_5.input", sep=" ", engine="python", header=None)[0].str.startswith("[", na=False).argmin() + 1, header=None, squeeze=True).str.findall(r"\d+").explode().astype(int).groupby(level=0).agg(list).apply(lambda a: d2[a[-1]].extend(d2[a[1]][-a[0]:][::+1]) or d2[a[1]].__setitem__(slice(-a[0], None), [])).any() or d2.str[-1].pipe(lambda s: s.groupby([0] * len(s))).agg("".join).item())
edgy cypress
subtle pewterBOT
#

@edgy cypress :white_check_mark: Your 3.11 eval job has completed with return code 0.

DWWFTHZWR
iron girder
#

!e

print("[D] [W] [W] [F] [T] [H] [Z] [W] [R]"[1::4])
subtle pewterBOT
#

@iron girder :white_check_mark: Your 3.11 eval job has completed with return code 0.

DWWFTHZWR
iron girder
#

don't need the 36 smh

edgy cypress
#

smh

astral ivy
shadow cradle
#

that's not golfing

astral ivy
#

the way you wrote it looks like golfing

shadow cradle
#

golfing aims smallest bytes, i did not

#

my aim is to write the thing using only pandas methods

#

because pure Python is too restrictive in functionality, no fun

#

and it's pandas with an "s" at the end, other thing is something different :)

flat mountain
#

I tried converting it to processing strings, but the lack of "string pop" seemed to make it worse.

#
    part1[c-1].extend([part1[b-1].pop() for _ in range(a)])

vs

    part1[c] += part1[b][:-a-1:-1]
    part1[b]  = part1[b][:-a]
iron girder
shadow cradle
#

yeah i should've used .to_csv :)

steel veldt
#

i don't think you need print. i think pandas has things that can write to files

shadow cradle
#

it can even write to clipboard indeed

#

i'm doing these in IPython, so i don't even print, but in case someone tries to do in a script, which is super unlikely, i put prints when bringing here.

steel veldt
#

i mean, that's kinda impressive lol

edgy cypress
#

are you doing part 1 or 2?

rain flame
# shadow cradle pandas rocks yet again ```py d1 = pd.DataFrame(pd.read_csv("day_5.input", nrows=...

not sure if any better when you combine them, but here's part 1 + 2 together:

print((T:=(R:=(I:=__import__)("functools").reduce)(lambda P,L:(R(lambda p,i:((P[0][i+1].append(L[i*4+1]),P[1][i+1].append(L[i*4+1]))if L[i*4]=="["else P,P)[-1],range(len(L)//4),P)if"["in L else((t:=[*map(int,I("re").findall("\d+",L))]),R(lambda *_:P[0][t[2]].insert(0,P[0][t[1]].pop(0)),range(t[0]),0),P:=(P[0],D(list,{**P[1],t[2]:P[1][t[1]][:t[0]]+P[1][t[2]],t[1]:P[1][t[1]][t[0]:]})))[-1]if"move"in L else P),open("input/05.txt"),((D:=I("collections").defaultdict)(list),D(list))),*["".join(x[1][0]for x in sorted(t.items()))for t in T])[-2:])
sleek charm
#

are you going for shortest chars?

#

if so the lambda * can be lambda* iirc

rain flame
#

not strictly, was mostly going for a one-liner, but improvements are welcome

#

thanks!

#

can probably also refactor some of the x if a else y to [y,x][a], will get to that at some point

#

it's just very hard editing this monstrosity without breaking stuff ๐Ÿ˜‚

sleek charm
#

ooh yeah that trick is cool

#

i never would have thought of that

iron girder
sleek charm
#

for both? wow

#

oh yeah i meant bytes

iron girder
#
g,j,*f=str.split,''.join,*open(0)
for o in-1,1:
 d=['']+[j(g(j(m)))for m in zip(*f[:8])][1::4]
 for l in f[10:]:a,b,c=map(int,g(l)[1::2]);d[c]=d[b][:a][::o]+d[c];d[b]=d[b][a:]
 print(j(*zip(*d)))```
196 bytes
```py
exec(bytes('โฑงโฑชๆ˜ช็Œฝ็‰ด็Œฎๆฑฐ็‘ฉโœฌโธงๆฝชๆนฉโจฌ็ฏๆนฅใ€จเจฉๆฝฆโฒโฏๆนฉใ„ญใ„ฌเจบๆ ๅฌฝเ งๅดงๅฌซโกชโกงโกชโฅญโคฉๆฝฆโฒโญๆนฉ็จ ็ฉโจจๅญฆใ บโฅๅญใจฑใบเฉๆ˜ ็‰ฏๆฐ ๆค โฎๅญฆใ€ฑๅดบๆ„บๆˆฌๆŒฌๆดฝ็กๆคจ็‘ฎๆœฌๆฐจๅฌฉใจฑใˆบโฅๆปๆ›ใตๅญคๅตขใฉ›ๅตกใฉ›ๆผบโญๅญคๅตฃๆปๆ‰›ใตๅญคๅตขๆ…›ๅดบโ€Š็‰ฐๆนฉโกดโกช็จช็ฉโจจโฅคโคฉ','u16')[2:])```
123 chars
strong trench
#

wow

viscid marsh
#

I am coding in JS using Functional Programming

#

This was so time-consuming

#

5-1: ```js
.split("\n\n").reduce((a,c)=>[[a,c]]).map(e=>[e[0],...e[1].trim().split("\n").map(f=>[1,3,5].map(g=>+f.split(' ')[g]))])[0].reduce((a,c,i,)=>i==0?Array(+c.trim().split("\n").map(e=>e.split(' ')).pop().pop()).fill().map((,j)=>c.split('\n').slice(0,-1).map(e=>[...e].filter((e,k)=>(k-1)%4==0)[j]).filter(e=>e!=' ')):a.map((e,j,a)=>j==c[1]-1?e.slice(c[0]):j==c[2]-1?[...a[c[1]-1].slice(0,c[0]).reverse(),...e]:e),0).map(e=>e[0]).join("")

5-2: ```js
.split("\n\n").reduce((a,c)=>[[a,c]]).map(e=>[e[0],...e[1].trim().split("\n").map(f=>[1,3,5].map(g=>+f.split(' ')[g]))])[0].reduce((a,c,i,_)=>i==0?Array(+c.trim().split("\n").map(e=>e.split(' ')).pop().pop()).fill().map((_,j)=>c.split('\n').slice(0,-1).map(e=>[...e].filter((e,k)=>(k-1)%4==0)[j]).filter(e=>e!=' ')):a.map((e,j,a)=>j==c[1]-1?e.slice(c[0]):j==c[2]-1?[...a[c[1]-1].slice(0,c[0]),...e]:e),0).map(e=>e[0]).join("")
#

I'm glad the second was the same as the first just without the .reverse(), but still... wow... so easy to make mistakes

manic cobalt
#

what are you guys zipping again?

#

most readable i could cook was

import re
from collections import defaultdict, deque


def helper(data):
    stacks = defaultdict(deque)
    instructions = []
    for index, line in enumerate(data):
        crate_positions = [(m.span()[0] + 1) for m in re.finditer("\[[a-zA-Z]\]", line)]
        if crate_positions:
            for crate_position in crate_positions:
                stacks[crate_position // 4].append(line[crate_position])
        else:
            if line:
                instructions.append(list(map(int, re.findall("\d+", line))))
    instructions = instructions[1:]

    return (dict(sorted(stacks.items())), instructions)


def part_one(data):
    stacks, instructions = helper(data)
    for pop_n, source, dest in instructions:
        for _ in range(pop_n):
            stacks[dest - 1].appendleft(stacks[source - 1].popleft())
    return "".join([stack[0] for stack in stacks.values()])


def part_two(data):
    stacks, instructions = helper(data)
    for pop_n, source, dest in instructions:
        poppers = deque()
        for _ in range(pop_n):
            poppers.appendleft(stacks[source - 1].popleft())
        stacks[dest - 1].extendleft(poppers)

    return "".join([stack[0] for stack in stacks.values()])
manic cobalt
#

@molten hamlet

def get_stack_indices(data):
    indicies = []
    for line in data:
        indexes = [index for index, char in enumerate(line) if char.isalpha()]
        if not indexes:
            break
        indicies.append(indexes)
    return indicies


def part_one(data):
    dictionary = defaultdict(list)

    for index, line in enumerate(get_stack_indices(data)):
        for items in line:
            stack_number = int((items - 1) / 4) + 1
            dictionary[stack_number].append(data[index][items])

    for key in dictionary.keys():
        dictionary[key].reverse()

    for line in data:
        if "move" in line:
            pop_n, source, dest = list(map(int, re.findall("\d+", line)))
            for i in range(pop_n):
                dictionary[dest].append(dictionary[source].pop())

    for key, value in sorted(dictionary.items()):
        print(value[-1], end="")
    print()


def part_two(data):
    dictionary = defaultdict(list)

    for index, line in enumerate(get_stack_indices(data)):
        for items in line:
            stack_number = int((items - 1) / 4) + 1
            dictionary[stack_number].append(data[index][items])

    for key in dictionary.keys():
        dictionary[key].reverse()

    for line in data:
        if "move" in line:
            pop_n, source, dest = list(map(int, re.findall("\d+", line)))
            lst = []
            for i in range(pop_n):
                lst.append(dictionary[source].pop())
            lst.reverse()
            dictionary[dest].extend(lst)

    for key, value in sorted(dictionary.items()):
        print(value[-1], end="")
molten hamlet
#

oh no

little quiver
hardy mortar
#

day 5 looks hard

scarlet wharf
#

And even then you can just hardcode to begin with if you struggle, and then come back to parse the input afterwards

hardy mortar
#

time to brush up my regex skills

scarlet wharf
hardy mortar
#
# aoc problem 5

import re


def getinput():
    stacks = []
    moves = []
    with open('5.txt') as f:
        acc = []
        part = 0
        for line in f:
            match part:
                case 0:
                    slots = [line[i+1] for i in range(0, len(line), 4)]
                    try:
                        int(slots[0])
                    except ValueError:
                        acc.append(slots)
                    else:
                        for stack in zip(*acc):
                            stacks.append([s for s in stack[::-1] if s != ' '])
                        part += 1

                case 1:
                    part += 1

                case 2:
                    m = re.fullmatch(r'move (\d+) from (\d) to (\d)\n?', line)
                    depth, orig_num, dest_num = map(int, m.groups())
                    moves.append((depth, orig_num - 1, dest_num - 1))

    return stacks, moves


def rearrange(depth, orig, dest):
    for i in range(depth):
        dest.append(orig.pop())


def rearrange2(depth, orig, dest):
    dest.extend(orig[-depth:])
    for i in range(depth):
        orig.pop()


def rearrangement_process(function, stack, moves):
    for m in moves:
        depth, orig_i, dest_i = m
        function(depth, stack[orig_i], stack[dest_i])


def main():
    stacks, moves = getinput()

    stacks1 = [s.copy() for s in stacks]
    rearrangement_process(rearrange, stacks1, moves)
    print(*(s[-1] for s in stacks1), sep='') # part 1 solution

    stacks2 = [s.copy() for s in stacks]
    rearrangement_process(rearrange2, stacks2, moves)
    print(*(s[-1] for s in stacks2), sep='') # part 2 solution


if __name__ == '__main__':
    main()
safe schooner
#

My solution: ```py
from string import digits

import numpy as np

def chunked_between(iterable, chunk_size: int, between_size: int):
in_between = False
curr_chunk_size = chunk_size
chunk_step = 0
chunk = []
for item in iterable:
chunk.append(item)
chunk_step += 1
if curr_chunk_size == chunk_step:
if not in_between:
yield chunk
chunk = []
in_between = not in_between
curr_chunk_size = between_size if in_between else chunk_size
chunk_step = 0

with open('5.txt') as f:
text = f.read().strip('\n')

lineiter = iter(text.split('\n'))

lines = []

for line in lineiter:
if line[:3] == ' 1 ':
next(lineiter)
break
curr_line = []
for chunk in chunked_between(line, 3, 1):
char = chunk[1]
if char == ' ':
char = None
curr_line.append(char)
lines.append(curr_line)

stacks = [
list(
filter(
lambda x: x is not None,
reversed(stack)
))
for stack
in np.array(lines).transpose()
]

moves = []
for line in lineiter:
move = []
num = ''
for char in line:
if char == ' ' and num:
move.append(int(num))
num = ''
elif char in digits:
num += char
if num:
move.append(int(num))
moves.append(move)

moves = ((num, orig - 1, dest - 1) for num, orig, dest in moves)

for num, orig, dest in moves:
orig = stacks[orig]
dest = stacks[dest]
print(orig, dest)
items = orig[-num:]
del orig[-num:]
dest.extend(reversed(items)) # remove reversed for part 2
print(orig, dest)

print(''.join(stack[-1] for stack in stacks))

#

It uses some pretty dumb and unnecessary things, but it works

surreal goblet
#

Took me a second, but here's my solution

#
import re
from collections import defaultdict


def partOne():
    for line in open('input.txt'):
        if '[' in line:
            for i in range(1, len(line) - 1, 4):
                if line[i] != ' ':
                    stacks[(i - 1) // 4].append(line[i])
        elif line.startswith('move'):
            a, b, c = map(int, re.findall(r'\d+', line))
            stacks[c - 1] = stacks[b - 1][:a][::-1] + stacks[c - 1]
            stacks[b - 1] = stacks[b - 1][a:]

    print(''.join(stacks[i][0] for i in range(len(stacks))))


def partTwo():
    for line in open('input.txt'):
        if '[' in line:
            for i in range(1, len(line) - 1, 4):
                if line[i] != ' ':
                    stacks[(i - 1) // 4].append(line[i])
        elif line.startswith('move'):
            a, b, c = map(int, re.findall(r'\d+', line))
            stacks[c - 1] = stacks[b - 1][:a] + stacks[c - 1]
            stacks[b - 1] = stacks[b - 1][a:]

    print(''.join(stacks[i][0] for i in range(len(stacks))))


stacks = defaultdict(list)
little quiver
jolly wadi
#

anyone got any slight hint on parsing the inputs into stacks?

worldly finch
worldly finch
#

how much of a hint do you want?

worldly finch
novel surge
#

i love how that hint makes sense if you already know what it means but is completely unhelpful if you dont

astral ivy
#

@smoky hinge

g,j,*f=str.split,''.join,*open(0)
for o in-1,1:
 d=['']+[j(g(j(m)))for m in zip(*f[:8])][1::4]
 for l in f[10:]:a,b,c=map(int,g(l)[1::2]);d[c],d[b]=d[b][:a][::o]+d[c],d[b][a:]
 print(j(*zip(*d)))

d5 if you wanna improve it lol

smoky hinge
#

Damn

#

That's already compact af

astral ivy
dusky thistle
#

whoo, time finally freed up

#

time for 6 and 7 >.>

#

the parsing was more tedious than the solution, I found

subtle pewterBOT
lunar fox
#

im losing my mind, i just cant figure out what could possibly be wrong - code works for the test case, when i use print statements to debug the sequence of steps my script takes, it looks totally fine, but plugging the end result into AOC doesnt work.
i doubt i will get a response but anything is appreciated thanks

smoky hinge
#

.pop() by itself will already remove the last item for you and return the result so ||boxSelected = stackSelected.pop()|| will be fine

lunar fox
#

i am now feeling very, very silly

#

very appreciated seriously i spent way too long on that

smoky hinge
#
    for l in f[10:]:a,b,c=map(int,g(l)[1::2]);d[c],d[b]=d[b][:a][::o]+d[c],d[b][a:]
                                                        ~^^^
IndexError: list index out of range
elfin falcon
smoky hinge
#

I have to do that?

elfin falcon
#

or is there a newline at the end

elfin falcon
smoky hinge
#

no trailing newlines

smoky hinge
#

seems like it's only reading the first 6 stacks

#

nvm its my ide stripping trailing whitespace

#

when I save the input file

#

yep it works fine

smoky hinge
#
j,*f=''.join,*open(0)
for o in-1,1:
 d=['']+[j(j(m).split())for m in zip(*f[:8])][1::4]
 for l in f[10:]:a,b,c=map(int,l.split()[1::2]);d[c],d[b]=d[b][:a][::o]+d[c],d[b][a:]
 print(j(*zip(*d)))
```195
#

I don't think I'll get that below 188 though

lunar fox
#

is this just a challenge for getting an accurate solution in the smallest number of characters?

smoky hinge
#

Yeah

#

it's called 'code golfing'

trim nexus
#

the readability plummets lmfao

wild mango
#

guys, how should I get each vertical line for the crates?

earnest ginkgo
#

Hi, a bit late with this one- I have wrote the following code but it outputs the wrong answer. I tried to use a debugger tool but didn't get really far, can someone help me?

with open("input.txt", "r") as file:
    stacks, instructions = file.read().split("\n\n")
    instructions = instructions.split("\n")
    stacks = stacks.replace("[", " ").replace("]", " ").split("\n")

    for i in range(len(stacks)):
        stacks[i] = [stacks[i][n : n + 4] for n in range(0, len(stacks[i]), 4)]

    stacks = stacks[:-1][::-1]
    _stacks = []
    for i in range(len(stacks)):
        _stacks.append(
            list(filter(None, [stacks[n][i].strip() for n in range(0, len(stacks))]))
        )

    for _ in _stacks:
        print(_)

    for instruction in instructions:
        amount, stack, new_stack = (
            instruction.replace("move", "")
            .replace("from", "")
            .replace("to", "")
            .split()
        )

        amount, stack, new_stack = int(amount), int(stack), int(new_stack)

        crates = _stacks[stack - 1][len(_stacks[stack - 1]) - amount :]

        for crate in crates[::-1]:
            _stacks[stack - 1].remove(crate)
            if new_stack - 1 not in _stacks:
                _stacks.append([])
            _stacks[new_stack - 1].append(crate)

top_crates = []
for stack in _stacks:
    if stack == []:
        continue
    top_crates.append(stack[::-1][0])

print("Part 1:", "".join(top_crates))
smoky hinge
#

Ah I see the problem

#

You can't use .remove to get the crates from the stack because you can have multiple of the same numbered crates in the same stack