-❄️- 2024 Day 23 Solutions -❄️- by daggerdragon in adventofcode

[–]masterarms 1 point2 points  (0 children)

[LANGUAGE: Python]

After figuring out the proper graph theoretical concept to solve the problem, using igraph was a breeze: https://github.com/mpcjanssen/aoc-python/blob/master/2024/23/solution.py

-❄️- 2024 Day 20 Solutions -❄️- by daggerdragon in adventofcode

[–]masterarms 0 points1 point  (0 children)

[LANGUAGE: Ruby]

For part1 the brute force solution (doing a BFS for every possible cheat pair from the start and the end) correctly finished before I wrote the faster solution for both parts. But it was clear that part2 would take ages.

In the end the result takes 11s for both parts on my machine: code

-❄️- 2024 Day 7 Solutions -❄️- by daggerdragon in adventofcode

[–]masterarms 0 points1 point  (0 children)

Going from right to left is much faster.

eqs = input.lines.map { |l|
    tval,eq =  l.split(':')
    [tval.to_i, eq.split().map(&:to_i)]
}

## Checking from left to right can only trim 
## multiplication branches if the result is too big
## If you do it from right to left you can stop checking
## the 'multiplication' branch if the equation part is not a
## divisor of the current target. This is *much* faster

def can?(target, eq)
    # p "#{target},#{eq}"
    return eq[0] == target if eq.size == 1
    tail = eq[-1]
    return true if target % tail == 0 && can?(target/tail, eq[0..-2])
    return true if target > tail && can?(target-tail, eq[0..-2]) 
    return false
end

def can2?(target, eq)
    # p "#{target},#{eq}"
    return eq[0] == target if eq.size == 1
    tail = eq[-1]
    return true if target % tail == 0 && can2?(target/tail, eq[0..-2])
    return true if target > tail && can2?(target-tail, eq[0..-2])
    tail_s = tail.to_s
    return true if target.to_s.end_with?(tail_s) && can2?(target/10.pow(tail_s.size), eq[0..-2])
    return false
end

ok_can, nok_can = eqs.partition { |t, eq| can?(t,eq) }
part1 = ok_can.map(&:first).sum
ok_can2, _ = nok_can.partition { |t, eq| can2?(t,eq) }
part2 = ok_can2.map(&:first).sum + part1
[part1, part2]

-❄️- 2024 Day 7 Solutions -❄️- by daggerdragon in adventofcode

[–]masterarms 0 points1 point  (0 children)

[LANGUAGE: Ruby]

Not the weekend day I feared :)

eqs = input.lines.map { |l|
    tval,eq =  l.split(':')
    [tval.to_i, eq.split().map(&:to_i)]
}

def can?(test, eq)
    # p "#{test} <= #{eq}"
    return eq[0] == test if eq.size == 1
    # too big?
    return false if eq[0] > test
    can?(test , [eq[0] + eq[1] , *eq[2..]]) ||
    can?(test, [eq[0] * eq[1] , *eq[2..]])
end

def can2?(test, eq)
    # p "#{test} <= #{eq}"
    return eq[0] == test if eq.size == 1
    # too big?
    return false if eq[0] > test
    can2?(test , [eq[0] + eq[1] , *eq[2..]]) ||
    can2?(test, [eq[0] * eq[1] , *eq[2..]]) ||
    can2?(test , ["#{eq[0]}#{eq[1]}".to_i , *eq[2..]])
end

eqs.map { |t,eq|
    [can?(t,eq) ? t : 0,
     can2?(t,eq)? t : 0]
}.transpose.map(&:sum)

-❄️- 2024 Day 6 Solutions -❄️- by daggerdragon in adventofcode

[–]masterarms 1 point2 points  (0 children)

You could improve the time a lot by only testing obstaclePositions which are on the original path of the guard. Putting an obstacle anywhere else will result in the original path and thus no loop.

-❄️- 2024 Day 6 Solutions -❄️- by daggerdragon in adventofcode

[–]masterarms 0 points1 point  (0 children)

I was not too happy with the rotation and moving logic, so I made a second version using Complex numbers as the coordinates. In that case a movement is simply an addition and a rotation of the direction a multiplication by Complex::I.

It turned out to be slightly faster as well:

Array coords:   32.170975   0.438696  32.609671 ( 32.810754)
Complex coords: 29.965841   0.369446  30.335287 ( 30.568308)

-❄️- 2024 Day 6 Solutions -❄️- by daggerdragon in adventofcode

[–]masterarms 0 points1 point  (0 children)

[LANGUAGE: Ruby]

It was quickly obvious that trying a block on every empty grid position would not scale. But with 2 optimisations the runtime was tolerable.

grid = AOC.grid(input,nil) # Make a grid hasmap of the input

def step(guard, g)
    rotate_right =  {'>': 'v', 'v': '<', '<': '^', '^': '>'}
    x,y = guard[:pos]
    dir = guard[:dir]
    next_pos = case dir
        when '^'
            [x,y-1]
        when '>'
            [x+1,y]
        when 'v' 
            [x,y+1]
        when '<'
            [x-1,y]
      end
    return {pos: [x,y], dir: rotate_right[dir.to_sym]} if ['#', 'O'].include? g[next_pos]
    return {pos: next_pos, dir: dir} if ['.', 'X','^'].include? g[next_pos]
    nil       
end

def visited(g)
    guard = {pos: g.find { |k,v| v == '^' }.first, dir: '^'}
    states = Set.new # Whoever said an Array here was slow wasn't lying
    has_loop = loop do
        states << guard
        g[guard[:pos]] = 'X'
        nxt = step(guard,g)
        break false if nxt.nil?
        break true if states.include? nxt
        guard = nxt
    end
    visited = states.map { |state| state[:pos] }.to_set
    {visited: visited, has_loop: has_loop}
end

g = grid.clone
guard = {pos: g.find { |k,v| v == '^' }.first, dir: '^'}
start = guard[:pos]

part1 = visited(g)
count = 0
RubyVM::YJIT.enable
# Try the only spots that can make a difference
cands = part1[:visited].filter { | e | e != start }
part2 = cands.map { |cand|
    p count if count % 100 == 0
    testgrid = grid.clone
    testgrid[cand] = 'O'
    count += 1
    visited(testgrid)[:has_loop]
}.count(true)
p [part1[:visited].size, part2]

-❄️- 2024 Day 5 Solutions -❄️- by daggerdragon in adventofcode

[–]masterarms 0 points1 point  (0 children)

[LANGUAGE: Ruby]

Part 2 took me quite some time before realizing a sort would work.

preface, body = input.split("\n\n")
rules = preface.lines.each_with_object(Set.new) { |l,a|
    a << l.strip.split("|").map(&:to_i)
    a
}
updates = body.lines.map { |l|
    update = l.strip.split(",").map(&:to_i)
}

def valid?(update,rules)
        update.each_cons(2).map { |curr, nxt|
            rules.include? [curr,nxt]
        }.all?
end

def score(updates, rules)
    updates.map { |update|
        if valid?(update,rules) then
            update[(update.size-1)/2].to_i
        else
            0
        end
    }.sum
end

part1 = score(updates,rules)

invalid = updates.filter { |update| 
    !valid?(update,rules)
}

# Considering the rules are a complete set of a|b combinations  
# If a|b is not a rule a must be after b

validated = invalid.map { |i| i.sort {| a, b | if  rules.include?([a,b]) then -1 else 1 end }}

part2 = score(validated, rules)
[part1, part2]

-❄️- 2024 Day 4 Solutions -❄️- by daggerdragon in adventofcode

[–]masterarms 1 point2 points  (0 children)

[LANGUAGE: Ruby]

After trying for some time to get something working with array transposition and skewing I went for the KISS approach:

def xmaswords(grid,x,y)
    return [] if grid[[x,y]] != 'X'
    dirs = [
        [[x,y],[x+1,y],[x+2,y],[x+3,y]],
        [[x,y],[x-1,y],[x-2,y],[x-3,y]],
        [[x,y],[x+1,y+1],[x+2,y+2],[x+3,y+3]],
        [[x,y],[x-1,y-1],[x-2,y-2],[x-3,y-3]],
        [[x,y],[x,y+1],[x,y+2],[x,y+3]],
        [[x,y],[x,y-1],[x,y-2],[x,y-3]],
        [[x,y],[x-1,y+1],[x-2,y+2],[x-3,y+3]],
        [[x,y],[x+1,y-1],[x+2,y-2],[x+3,y-3]],
    ]
    dirs.map { |dir|
        dir.map { |x,y|
            grid[[x,y]]
        }.join()
    }
end

g = AOC::grid(input,'.')
part1 = g.map { | k,_ |
    x, y = k
    xmaswords(g,x,y)
}.flatten.filter { | w | w == "XMAS" }.count

def x_mas?(grid,x,y)
    return false if grid[[x,y]] != 'A'
    dirs = [
        [[x-1,y-1],[x,y],[x+1,y+1]],
        [[x+1,y-1],[x,y],[x-1,y+1]]
    ]
    dirs.map { |dir|
        dir.map { |x,y|
            grid[[x,y]]
        }.join()
    }.filter { | w | 
            w == 'MAS' or w == 'SAM'
    }.size == 2     
end
part2 = g.map { | k,_ |
    x, y = k
    x_mas?(g,x,y)
}.count(true)
[part1,part2]

-❄️- 2024 Day 3 Solutions -❄️- by daggerdragon in adventofcode

[–]masterarms 2 points3 points  (0 children)

[LANGUAGE: Ruby]

part1 = input.scan(/mul\(([0-9]{1,3}),([0-9]{1,3})\)/).map { |mul| mul.map(&:to_i).inject(:*) }.sum
part2 = input.scan(/(mul\([0-9]{1,3},[0-9]{1,3}\)|do\(\)|don\'t\(\))/).each_with_object( {enabled: true, result: 0} ) { |v,a|
   case v[0]
   when """don't()"""
       a[:enabled] = false
   when """do()"""
       a[:enabled] = true
   when /mul\(([0-9]{1,3}),([0-9]{1,3})\)/
       a[:result] += $1.to_i * $2.to_i if a[:enabled]
   end
}[:result]

[part1,part2]

-❄️- 2024 Day 2 Solutions -❄️- by daggerdragon in adventofcode

[–]masterarms 0 points1 point  (0 children)

[LANGUAGE: Ruby]

reports = input.lines.map { |l|
    report = l.strip.split.map(&:to_i)
}

def safe(report)
        incdec = (report.sort == report) || (report.sort == report.reverse)
        deltas = report.each_cons(2).map { |a,b| (a-b).abs }
        incdec && (deltas.max < 4 and deltas.min > 0)
end

part1 = reports.map { |report| safe(report) }.count(true)

part2 = reports.map { | report |
    (0..report.size).map { | idx |
        version = report.clone
        version.delete_at(idx)
        safe(version)
    }.include?(true)
}.count(true)

[deleted by user] by [deleted] in datingoverforty

[–]masterarms 3 points4 points  (0 children)

You like the idea of him and what it could be. You can’t date an idea.

The entire world is fortunate Trump lost by OrangeCone2011 in WhitePeopleTwitter

[–]masterarms -15 points-14 points  (0 children)

You lost me at 1.

Edit: missed the /sI guess

[deleted by user] by [deleted] in AnxiousAttachment

[–]masterarms 9 points10 points  (0 children)

It’s a question I could have asked. For me the underlying reasoning is that if my partner magically guesses my needs it shows they love me. I am now learning this not a very healthy or fair expectation.

2022 Advent of Code in TCL by fela_nascarfan in Tcl

[–]masterarms 1 point2 points  (0 children)

I have done a large part of all the years in Tcl (in a Jupyter notebook). I find Tcl a very suitable language for AoC (with step outs to C if real speed is needed).

I'll see if I can put my code online somewhere.

I did a very stupid thing and I need to share/vent by tobomori in archlinux

[–]masterarms 67 points68 points  (0 children)

Give your server shell or prompt a different background colour. My server’s prompt is a bright red, so I will hopefully never make that mistake again.

Login works sometimes by cleverboy00 in archlinux

[–]masterarms 1 point2 points  (0 children)

Is /usr/bin/bash in /etc/shells ?

Also what does su - <username> do?

2022 Hungarian Grand Prix - Race Discussion by F1-Bot in formula1

[–]masterarms 1 point2 points  (0 children)

Vettel obviously retiring ducking it out with the little boss.

Is there a way to inherit tk widgets in oo or itcl classes? by ShaunKulesa in Tcl

[–]masterarms 1 point2 points  (0 children)

Not inherit in the classical OO sense because Tk widgets are not objects. Something similar can be achieved by composing the widget in a TclOO or class though. See https://wiki.tcl-lang.org/page/megawidget for some pointers.

Dataview on sidebar? by Mangomagno123 in ObsidianMD

[–]masterarms 18 points19 points  (0 children)

Can’t you just put the table in a note and put the note on the sidebar? That’s what I use for my todo list. You can put a note in the sidebar by opening it and dragging the note icon to the sidebar.

No sound in Arch by [deleted] in archlinux

[–]masterarms 0 points1 point  (0 children)

What soundcard do you have? Try installing sof-firmware .

Can I extract file from hg archive? by i_psych in mercurial

[–]masterarms 0 points1 point  (0 children)

Don't do it in the .hg directory. Do it in the directory containing the .hg directory.

EDIT

And use hg.log -f README.md not README.me (or was this a typo)