ace

joined 1 year ago
[–] ace@lemmy.ananace.dev 2 points 11 months ago

Well, this one ended up being a really nice and terse solution when done naΓ―vely, here with a trimmed snippet from my simple solution;

Ruby

puts "Part 1:", @races.map do |race|
  (0..race[:time]).count { |press_dur| press_dur * (race[:time] - press_dur) > race[:distance] }
end.inject(:*)

full_race_time = @races.map { |r| r[:time].to_s }.join.to_i
full_race_dist = @races.map { |r| r[:distance].to_s }.join.to_i

puts "Part 2:", (0..full_race_time).count { |press_dur| press_dur * (full_race_time - press_dur) > full_race_dist }

[–] ace@lemmy.ananace.dev 3 points 11 months ago

Writing and debugging 4D code is... interesting.

When your code can't just run forwards and backwards, but also left and right, up and down, and even inwards and outwards.

[–] ace@lemmy.ananace.dev 3 points 11 months ago

"It's a ndiswrapper miracle!" - a statement only uttered by the completely deranged.

[–] ace@lemmy.ananace.dev 6 points 11 months ago* (last edited 11 months ago) (2 children)

Yep, funge has been used to describe any kind of multi-dimensional programming language - often with self-modifying code, I've personally found both 3D and 4D funge languages.

There's just something with the whole concept that amuses me, I've been trying to build some kind of funge-style programming puzzle game for a while now, but haven't figured out a good hook to take it past being just a PoC yet.

[–] ace@lemmy.ananace.dev 13 points 11 months ago (4 children)

2D grids and parsing data from them in all manner of interesting ways is a real AoC staple.

I'm still hoping to be met with a problem at some point which can be solved by handling it as a type of funge program.

[–] ace@lemmy.ananace.dev 2 points 11 months ago (2 children)

Amusingly enough, one of the HP laptops I used in that era actually worked better with ndiswrapper somehow.

It was the only one to do so though.

[–] ace@lemmy.ananace.dev 2 points 11 months ago

I get the feeling that I should include some default types for handling 2D maps in my boilerplate, it's a very recurring problem in AoC after all.

My solution is reasonably simplistic - and therefore also a bit slow, but the design meant I could do part 2 with just a few extra lines of code on the already processed data, here's the functional part of it; (I push the previous days solution as part of my workflow for starting with the current day so the full code won't be up until tomorrow)

RubyThe code has been compressed for brevity.

Point = Struct.new('Point', :x, :y)
PartNumber = Struct.new('PartNumber', :number, :adjacent) do
  def adjacent?(to); adjacent.include?(to); end
  def irrelevant?; adjacent.empty?; end
  def to_i; number; end
end

class Implementation
  def initialize
    @map = []; @dim = { width: 0, height: 0 }; @symbols = []; @numbers = []
  end

  def input(line)
    @dim[:width] = line.size; @dim[:height] += 1
    @map += line.chars
  end

  def calc
    for y in (0..@dim[:height]-1) do
      for x in (0..@dim[:width]-1) do
        chr = get(x, y); next if chr =~ /\d/ || chr == '.'
        @symbols << Point.new(x, y)
      end
    end

    for y in (0..@dim[:height]-1) do
      buf = ""; adj = []
      for x in (0..@dim[:width]) do # Going one over, to fake a non-number as an end char on all lines
        chr = get(x, y)
        if chr =~ /\d/
          buf += chr
          (-1..1).each do |adj_x|
            (-1..1).each do |adj_y|
              next if adj_x == 0 && adj_y == 0 ||
                (x + adj_x < 0) || (x + adj_x >= @dim[:width]) ||
                (y + adj_y < 0) || (y + adj_y >= @dim[:height])
              sym = Point.new(x + adj_x, y + adj_y)
              adj << sym if @symbols.any? sym
            end
          end
        elsif !buf.empty?
          @numbers << PartNumber.new(buf.to_i, adj)
          buf = ""; adj = []
        end
      end
    end
  end

  def output
    part1 = @numbers.reject(&:irrelevant?).map(&:to_i).sum
    puts "Part 1:", part1

    gears = @symbols.select do |sym|
      next unless get(sym) == '*'
      next unless @numbers.select { |num| num.adjacent? sym }.size == 2
      true
    end
    part2 = gears.sum { |gear| @numbers.select { |num| num.adjacent? gear }.map(&:to_i).inject(:*) }

    puts "Part 2:", part2
  end

  private

  def get(x, y = -1)
    y = x.y if x.is_a?(Point)
    x = x.x if x.is_a?(Point)
    return unless (0..@dim[:width]-1).include?(x) && (0..@dim[:height]-1).include?(y)

    @map[y * @dim[:width] + x % @dim[:width]]
  end
end

[–] ace@lemmy.ananace.dev 3 points 11 months ago

Definitely the third / middle left, but the bottom right definitely gets second place to me.
Not a major fan of too abstract art, and those are just both so serene.

[–] ace@lemmy.ananace.dev 52 points 11 months ago (2 children)

People love to complain about CMake, often with valid complaints as well. But it - to this day - remains the only build system where I'll actually trust a project when they say they are cross-platform.

Being the Windows maintainer for OpenMW, it used to be absolute hell back a decade and half ago when an indirect dependency changed - and used something like SCons or Premake while claiming to be "cross-platform", used to be that I had to write my own build solutions for Windows since it was all hardcoded against Linux paths and libraries.

CMake might not be the coolest, most hip, build system, but it delivers on actually letting you build your software regardless of platform. So it remains my go-to for whenever I need to actually build something that's supposed to be used.
For personal things I still often hack together a couple of Makefiles though, it's just a lot faster to do.

[–] ace@lemmy.ananace.dev 2 points 11 months ago

Have a snippet of Ruby, something I hacked together as part of a solution during the WFH morning meeting;

class String
  def to_numberstring(digits_only: false)
    tokens = { 
      one: 1, two: 2, three: 3,
      four: 4, five: 5, six: 6,
      seven: 7, eight: 8, nine: 9
    }.freeze
    ret = ""

    i = 0
    loop do
      if self[i] =~ /\d/
        ret += self[i]
      elsif !digits_only
        tok = tokens.find { |k, _| self[i, k.size] == k.to_s }
        ret += tok.last.to_s if tok
      end
      
      i += 1
      break if i >= size
    end

    ret
  end
end
[–] ace@lemmy.ananace.dev 3 points 11 months ago

It's basically just a copy of the main leaderboard, but the scores are given based on the size of the group.

[–] ace@lemmy.ananace.dev 2 points 11 months ago

It could be interesting with something like the old Pharaoh game and its receding riverbed farming, but you'd have to balance that compared to costs of resourcing in Factorio - or offer some reasonably simple way for the player to protect their resourcing operations against the rising lava.

view more: β€Ή prev next β€Ί