Quest 16: Harmonics of Stone

  • Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
  • You can send code in code blocks by using three backticks, the code, and then three backticks or use something such as https://topaz.github.io/paste/ if you prefer sending it through a URL

Link to participate: https://everybody.codes/

you are viewing a single comment's thread
view the rest of the comments
[โ€“] 2 points 11 months ago

Python

def part1(data: str):
    elements = map(int, data.split(','))
    total = 0
    for ele in elements:
        # a spell element will add (90 // number) bricks for 90 columns
        total += 90 // ele
    return total

assert part1("1,2,3,5,9") == 193

# Gets all spell elements needed to build a wall
# Useful for part 2 and part 3
def get_elements(data: str):
    wall = map(int, data.split(','))
    elements = []   # spell elements

    for col_idx, fragments in enumerate(wall):
        # fix for 1-based indexing
        col = col_idx + 1

        # account bricks for recorded elements
        for ele in elements:
            if col % ele == 0:
                fragments -= 1
        
        # if we still have fragments, we need to add a new element with that column number
        if fragments > 0:
            elements.append(col)
    
    return elements

def part2(data: str):
    # Get all spell elements needed to build the wall
    elements = get_elements(data)
    # return product of all elements
    ans = 1
    for ele in elements:
        ans *= ele
    return ans

assert part2("1,2,2,2,2,3,1,2,3,3,1,3,1,2,3,2,1,4,1,3,2,2,1,3,2,2") == 270

# Part 3: Binary Search for maximum full columns
def part3(data: str):
    BRICKS = 202520252025000
    elements = get_elements(data)

    # Check if we can build 'cols' full columns within BRICKS bricks
    def can_build(cols: int) -> bool:
        bricks_used = 0
        for ele in elements:
            bricks_used += cols // ele
            if bricks_used > BRICKS:
                return False
        return True

    # binary search: break on first column size we cannot build
    lo = 1
    hi = BRICKS
    while lo < hi:
        mid = lo + (hi - lo) // 2
        if can_build(mid):
            lo = mid + 1
        else:
            hi = mid
    
    # if lo is the first we cannot build, lo - 1 is the maximum we can build
    return lo - 1

assert part3("1,2,2,2,2,3,1,2,3,3,1,3,1,2,3,2,1,4,1,3,2,2,1,3,2,2") == 94439495762954
  • source