Crespyl's recent activity

  1. Comment on You make friends *HERE*?! in ~tildes

    Crespyl
    Link Parent
    Some googling suggests that it's appeared a few times in the "tildeverse" networks, but as far as I know this is the first time it's been applied here. I wasn't aware of any previous uses when it...

    Some googling suggests that it's appeared a few times in the "tildeverse" networks, but as far as I know this is the first time it's been applied here. I wasn't aware of any previous uses when it popped into my head, and it was just too perfect not to share.

    4 votes
  2. Comment on You make friends *HERE*?! in ~tildes

    Crespyl
    Link Parent
    "Tildebeasts"

    The name for a group of people who use Tildes is deliberately unclear, to the point that it's an injoke to use a different name every time.

    "Tildebeasts"

    29 votes
  3. Comment on Astro Bot wins Game of the Year 2024 in ~games

    Crespyl
    Link Parent
    I was confused for a moment, but it turns out Astro's Playroom is a different game from The Playroom, though both are, as you say, focused on showcasing PlayStation features.

    I was confused for a moment, but it turns out Astro's Playroom is a different game from The Playroom, though both are, as you say, focused on showcasing PlayStation features.

    2 votes
  4. Comment on Podcast app recs in ~tech

    Crespyl
    Link
    I'm a big fan of AntennaPod. It's basic, but it does what I want with no hassle, and is open source (available on FDroid, even). It does support syncing across devices, but I think you have to...

    I'm a big fan of AntennaPod.

    It's basic, but it does what I want with no hassle, and is open source (available on FDroid, even). It does support syncing across devices, but I think you have to self-host that if it's something you need.

    Supports chapters, playback speed control, OPML import/export, etc.

    Edit: unfortunately it looks like there's not a version for iOS, so it's probably not a great fit for your use case, but maybe it'll be useful for others.

    12 votes
  5. Comment on Day 6: Guard Gallivant in ~comp.advent_of_code

    Crespyl
    Link
    Oof, I was slow on this one. Part 1 wasn't too bad with my usual "simulation" approach, but Part 2 took three minutes to run. Definitely room for optimization. Part 1 def compute_p1(input) map =...

    Oof, I was slow on this one. Part 1 wasn't too bad with my usual "simulation" approach, but Part 2 took three minutes to run. Definitely room for optimization.

    Part 1
    def compute_p1(input)
      map = Grid.new(input)
      guard_pos = map.coords_where { |ch| ch == "^" }.first
      map.set(guard_pos[0], guard_pos[1], ".")
      direction = :up
      visited = Set.new([guard_pos])
      while map.in_bounds?(guard_pos[0],guard_pos[1])
        guard_pos, direction = step(map, guard_pos, direction)
        visited.add(guard_pos) if map.in_bounds?(guard_pos[0], guard_pos[1])
      end
      return visited.count
    end
    
    def step(grid, guard_pos, direction)
      facing_coords = case direction
               when :up
                 [guard_pos[0],guard_pos[1]-1]
               when :down
                 [guard_pos[0],guard_pos[1]+1]
               when :left
                 [guard_pos[0]-1,guard_pos[1]]
               when :right
                 [guard_pos[0]+1,guard_pos[1]]
               end
      facing = grid.get(facing_coords[0], facing_coords[1])
      case facing
      when ".", nil
        guard_pos = facing_coords
      when "#", "O"
        direction = case direction
                    when :up
                      :right
                    when :right
                      :down
                    when :down
                      :left
                    when :left
                      :up
                    end
      end
      return [guard_pos, direction]
    end
    
    Part 2
    def loops?(map, start_pos)
      guard_pos = start_pos
      direction = :up
      visited = Set.new([guard_pos])
      while map.in_bounds?(guard_pos[0],guard_pos[1])
        guard_pos, direction = step(map, guard_pos, direction)
        if visited.include?([guard_pos, direction])
          return true
        end
        visited.add([guard_pos, direction])
      end
      return false
    end
    
    def compute_p2(input)
      map = Grid.new(input)
      start_pos = map.coords_where { |ch| ch == "^" }.first
      map.set(start_pos[0], start_pos[1], ".")
      count = 0
      map.each_index do |x, y|
        next if map.get(x,y) == "#"
        map.set(x,y, "O")
        count += 1 if loops?(map, start_pos)
        map.set(x,y, ".")
      end
      return count
    end
    
    2 votes
  6. Comment on Day 5: Print Queue in ~comp.advent_of_code

    Crespyl
    Link
    My code is pretty slow, it's probably possible to speed things up with a hash table of rules instead of just using a big list, but I was in a lazy mood. Part 1 def compute_p1(input) rules, updates...

    My code is pretty slow, it's probably possible to speed things up with a hash table of rules instead of just using a big list, but I was in a lazy mood.

    Part 1
    def compute_p1(input)
      rules, updates = input.split("\n\n")
      rules = rules.lines.map { |line|
        line.split("|").map(&:to_i)
      }.sort
      updates = updates.lines.map { |line|
        line.split(",").map(&:to_i)
      }
      correct_updates = updates.filter { |update| check_update(rules, update) }
      return correct_updates.map { |update| update[update.length/2] }.sum
    end
    
    def check_update(rules, update)
      update.each_with_index do |page, idx|
        # for each page, verify that all rules put the following pages after, and
        # the preceeding pages before
        before = update[0...idx]
        before.each do |before_page|
          if is_rule?(rules, before_page, page)
            next
          elsif is_rule?(rules, page, before_page)
            return false
          end
        end
    
        after = update[(idx+1)...]
        after.each do |after_page|
          if is_rule?(rules, page, after_page)
            next
          elsif is_rule?(rules, after_page, page)
            return false
          end
        end
      end
      return true
    end
    
    def is_rule?(rules, before, after)
      rules.index([before, after])
    end
    
    Part 2
    def compute_p2(input)
      rules, updates = input.split("\n\n")
      rules = rules.lines.map { |line|
        line.split("|").map(&:to_i)
      }.sort
      updates = updates.lines.map { |line|
        line.split(",").map(&:to_i)
      }
      incorrect_updates = updates.filter { |update| ! check_update(rules, update) }
      return incorrect_updates.map { |update| fix_update(rules, update) }.map { |update| update[update.length/2] }.sum
    end
    
    def fix_update(rules, update)
      return update.sort { |a, b|
        if is_rule?(rules, a, b)
          -1
        elsif is_rule?(rules, b, a)
          1
        else
          0
        end
      }
    end
    
    1 vote
  7. Comment on 2024 Spotify Wrapped thread in ~music

    Crespyl
    Link Parent
    It's got all sorts of stuff in there, I think I found Big Big Train, maybe Phideaux, Barrock Project, and a handful of other groups from that site. I love digging through and reading the reviews...

    It's got all sorts of stuff in there, I think I found Big Big Train, maybe Phideaux, Barrock Project, and a handful of other groups from that site.

    I love digging through and reading the reviews and seeing what interesting new releases have popped up since the last time I looked.

    1 vote
  8. Comment on 2024 Spotify Wrapped thread in ~music

    Crespyl
    Link
    Artists: Phideaux Vixy & Tony AlicebanD Fish in a Birdcage aeseaes Songs: Dawson's Christian (Vixy & Tony) Catharsis (AlicebanD) Megalomaniac (aeseaes) Fire with Fire (AlicebanD) Sabotage (Remi...

    Artists:

    1. Phideaux
    2. Vixy & Tony
    3. AlicebanD
    4. Fish in a Birdcage
    5. aeseaes

    Songs:

    1. Dawson's Christian (Vixy & Tony)
    2. Catharsis (AlicebanD)
    3. Megalomaniac (aeseaes)
    4. Fire with Fire (AlicebanD)
    5. Sabotage (Remi Gallego)

    Minutes Listened: 11,568

    Not a lot of new stuff this year other than Vixy & Tony, kind of feel like Spotify has me in a rut lately with its recommendations. I need to hit up ProgArchives again and see what's new.

    4 votes
  9. Comment on Day 4: Ceres Search in ~comp.advent_of_code

    Crespyl
    Link
    Grid problems! I pulled out the helper class I've used for a few years now, makes it a little easier to deal with various approaches to dealing with 2D grids; things like a method for doing...

    Grid problems! I pulled out the helper class I've used for a few years now, makes it a little easier to deal with various approaches to dealing with 2D grids; things like a method for doing something at each index of the grid, or handling out of bounds with a default value, that kind of thing.

    Part 1 Ruby
    def compute_p1(input)
      grid = Grid.new(input, default: nil)
      count = 0
      grid.each_index do |x, y|
        # skip any cell that isn't the start of an XMAS
        next unless grid.get(x,y) == "X"
    
        # check forwards
        forwards = [grid.get(x+1,y), grid.get(x+2,y), grid.get(x+3,y)].join()
        count += 1 if forwards == "MAS"
    
        # check backwards
        backwards = [grid.get(x-1,y), grid.get(x-2,y), grid.get(x-3,y)].join()
        count += 1 if backwards == "MAS"
    
        # check down
        down = [grid.get(x,y+1), grid.get(x,y+2), grid.get(x,y+3)].join()
        count += 1 if down == "MAS"
    
        # check up
        up = [grid.get(x,y-1), grid.get(x,y-2), grid.get(x,y-3)].join()
        count += 1 if up == "MAS"
    
        # check down_left
        down_left = [grid.get(x-1,y+1), grid.get(x-2,y+2), grid.get(x-3,y+3)].join()
        count += 1 if down_left == "MAS"
    
        # check down_right
        down_right = [grid.get(x+1,y+1), grid.get(x+2,y+2), grid.get(x+3,y+3)].join()
        count += 1 if down_right == "MAS"
    
        # check up_left
        up_left = [grid.get(x-1,y-1), grid.get(x-2,y-2), grid.get(x-3,y-3)].join()
        count += 1 if up_left == "MAS"
    
        # check up_right
        up_right = [grid.get(x+1,y-1), grid.get(x+2,y-2), grid.get(x+3,y-3)].join()
        count += 1 if up_right == "MAS"
      end
    
      return count
    end
    
    Part 2 Ruby
    def compute_p2(input)
      grid = Grid.new(input, default: nil)
      count = 0
      grid.each_index do |x, y|
        # skip any cell that isn't the center of an X-MAS
        next unless grid.get(x,y) == "A"
    
        # check \ direction
        down_right = [grid.get(x-1,y-1), grid.get(x,y), grid.get(x+1,y+1)].join
        next unless down_right == "MAS" || down_right == "SAM"
    
        # check / direction
        down_left = [grid.get(x+1,y-1), grid.get(x,y), grid.get(x-1,y+1)].join
        next unless down_left == "MAS" || down_left == "SAM"
    
        count += 1
    
      end
      return count
    end
    
    Helper "Grid" class
    #!/usr/bin/env ruby
    
    class Grid
      attr_accessor :grid
      attr_accessor :width
      attr_accessor :height
      attr_accessor :default
    
      def initialize(input, default: nil)
        @grid = input.lines
                  .map(&:strip)
                  .map(&:chars)
        @width = @grid[0].size
        @height = @grid.size
        @default = default
      end
    
      def in_bounds?(x, y)
        x >= 0 && x < @width && y >= 0 && y < @height
      end
    
      def get(x,y)
        if x < 0 || x >= @width || y < 0 || y >= @height
          @default
        else
          @grid[y][x]
        end
      end
    
      def set(x,y,val)
        if x < 0 || x >= @width || y < 0 || y >= @height
          raise "Tried to write out of bounds"
        else
          @grid[y][x] = val
        end
      end
    
      def all_coords
        (0...width).to_a.product((0...height).to_a)
      end
    
      def coords_where
        all_coords.filter { |x, y| yield(@grid[y][x]) }
      end
    
      def each_index
        all_coords.each do |x,y|
          yield(x,y)
        end
      end
    
      def update
        each_index do |x, y|
          @grid[y][x] = yield(x, y, @grid[y][x])
        end
      end
    
      def ==(other)
        return false if other.class != Grid
        return other.grid == @grid
      end
    
      def all?(value)
        return @grid.flatten.all?(value)
      end
    
      def neighbors(x,y)
        [
          [-1, -1], [0, -1], [+1, -1],
          [-1,  0],          [+1, 0],
          [-1, +1], [0, +1], [+1, +1]
        ].map { |dx, dy| get(x+dx, y+dy) }
      end
    
      def to_s
        s = ""
        height.times do |y|
          width.times do |x|
            s << get(x,y) || default.to_s
          end
          s << "\n"
        end
        return s
      end
    
      def count(value)
        if block_given?
          @grid.flatten.count(&block)
        else
          @grid.flatten.count(value)
        end
      end
    end
    
    2 votes
  10. Comment on Day 3: Mull It Over in ~comp.advent_of_code

    Crespyl
    (edited )
    Link
    Oooh smells like an interpreter... I really hope we get more of this, my all time favorite AoC was building the Intcode VM a few years back. Ruby def compute_p1(input) re = /mul\((\d+),(\d+)\)/...

    Oooh smells like an interpreter...

    I really hope we get more of this, my all time favorite AoC was building the Intcode VM a few years back.

    Ruby
    def compute_p1(input)
      re = /mul\((\d+),(\d+)\)/
      input.scan(re).map { |match|
        match.map(&:to_i).inject(:*)
      }.sum
    end
    
    def compute_p2(input)
      re = /(do)\(\)|(don't)\(\)|(mul)\((\d+),(\d+)\)/
      commands = input.scan(re).map(&:compact)
    
      state = :do
      value = 0
      until commands.empty?
        cmd = commands.shift
        case cmd[0]
        when "mul" then
          value += (cmd[1].to_i * cmd[2].to_i) unless state == :dont
        when "do"
          state = :do
        when "don't"
          state = :dont
        end
      end
      return value
    end
    
    4 votes
  11. Comment on Day 2: Red-Nosed Reports in ~comp.advent_of_code

    Crespyl
    Link
    Ruby solution def compute_p1(input) reports = input.lines.map { |line| line.split(/\s+/).map(&:to_i) } reports.map{ |r| report_safe?(r) }.count(true) end def report_safe?(report) return...
    Ruby solution
    def compute_p1(input)
      reports = input.lines.map { |line|
        line.split(/\s+/).map(&:to_i)
      }
      reports.map{ |r| report_safe?(r) }.count(true)
    end
    
    def report_safe?(report)
      return rule_1_all_inc_or_dec(report) && rule_2_step_size(report)
    end
    
    def rule_1_all_inc_or_dec(report)
      increasing = report[1] > report[0]
      idx = 0
      while (idx < report.length-1) do
        if increasing && (report[idx] > report[idx+1])
          return false
        elsif (not increasing) && (report[idx] < report[idx+1])
          return false
        elsif (report[idx] == report[idx+1])
          return false
        end
        idx += 1
      end
      return true
    end
    
    def rule_2_step_size(report)
      report.each_cons(2).map(&:sort).each do |a, b|
        diff = b - a
        if diff < 1 || diff > 3
          return false
        end
      end
      return true
    end
    
    def compute_p2(input)
      reports = input.lines.map { |line|
        line.split(/\s+/).map(&:to_i)
      }
      reports.map{ |r| report_safe_p2?(r) }.count(true)
    end
    
    def report_safe_p2?(report)
      if rule_1_all_inc_or_dec(report) && rule_2_step_size(report)
        return true
      else
        # try removing levels one at a time until the report passes
        for idx in (0...report.length)
          r = report.clone;
          r.delete_at(idx)
          if rule_1_all_inc_or_dec(r) && rule_2_step_size(r)
            return true
          end
        end
      end
      return false
    end
    
    2 votes
  12. Comment on Favorite "A Christmas Carol" adaptation? in ~movies

    Crespyl
    Link Parent
    Specifically, they cut "The Love is Gone" from every version after the original theatrical release IIRC. Apparently it was "too sad" for audiences. However, doing this cuts not only a beautiful...

    Specifically, they cut "The Love is Gone" from every version after the original theatrical release IIRC. Apparently it was "too sad" for audiences. However, doing this cuts not only a beautiful song, but also breaks the introduction of the musical theme that gets reprised with "The Love We Found" at the end of the movie!

    It's been an important part of my family's tradition to go pause the movie and watch the deleted scene at the appropriate moment for years, until literally just in the last year or two Disney added the fixed verison back up to Disney+ (you still have to go out of your way to find the correct "extended" version though, just hitting play will still get you the cut version.)

    11 votes
  13. Comment on Day 1: Historian Hysteria in ~comp.advent_of_code

    Crespyl
    Link
    Nice and straightforward, it's good to be back! I'm still a little busy with life at the moment, so I'm just doing it in Ruby again this year. Parts 1 and 2, Ruby def compute_p1(input) pairs =...

    Nice and straightforward, it's good to be back! I'm still a little busy with life at the moment, so I'm just doing it in Ruby again this year.

    Parts 1 and 2, Ruby
    def compute_p1(input)
      pairs = input.lines.map { |line|
        line.split(/\s+/).map(&:to_i)
      }
      list_a = pairs.map(&:first).sort
      list_b = pairs.map(&:last).sort
      list_a.zip(list_b).map { |x| x.sort.reverse.inject(:-) }.sum
    end
    
    def compute_p2(input)
      pairs = input.lines.map { |line|
        line.split(/\s+/).map(&:to_i)
      }
      list_a = pairs.map(&:first).sort
      list_b = pairs.map(&:last).sort
    
      list_a.reduce(0) { |sum, x|
        sum + (x * list_b.count(x))
      }
    end
    
    1 vote
  14. Comment on Tildes Book Club Discussion - The City We Became by N K Jemisin in ~books

    Crespyl
    Link Parent
    I had a pretty good time reading this one, finished it a couple days ago. It definitely kept my attention throughout, though I think I need some more time to processes the mixed reactions I had to...

    I had a pretty good time reading this one, finished it a couple days ago. It definitely kept my attention throughout, though I think I need some more time to processes the mixed reactions I had to some of it. Overall I enjoyed it.

    I think that the author comes off as being rather "online" in a way that becomes sort of predictable, some of the anti-racist themes were kind of on-the-nose, and I was a little disappointed that the only white people were... let's just say un-redeemable (SI included). For a book about a city coming together and embracing its fullness and diversity, that was kind of jarring with the theme.

    I loved the "inverse-lovecraftian" horror being derived from gentrification and racist white people, and the idea of the cities themselves being a kind of universal horror to everyone else in the multiverse that's being destroyed by all the cities. Any time the cities/boroughs engaged in combat by wielding iconic concepts against each other was a lot of fun. I would've loved to see more experimentation and back and forth to explore that, outside of a couple of scenes the avatars mostly seem to come by their powers when they need them in a way that felt kind of like a comic-book movie. I mean that in a good way, but it would've been more my thing if there had been more scenes like the one in the park by the big rock, where Manny is feeling out his powers before getting rescued by Brooklyn.

    I don't think I'm quite in the target audience for this one, but I had a good time with it despite the handful of things that didn't work for me.

    3 votes
  15. Comment on Where does your username come from? (Following up on last year's thread) in ~tildes

    Crespyl
    Link Parent
    Although AOL was a bit before my time, this is pretty much how I came by this tag. I've had it long enough now that I've allowed it to become pretty closely linked with my real name, and I'm not...

    Although AOL was a bit before my time, this is pretty much how I came by this tag. I've had it long enough now that I've allowed it to become pretty closely linked with my real name, and I'm not too bothered by it.

    I once read a bit about the head of Arcen Games (makers of the large scale RTS AI War) talking about how he kept a list of syllables and phonemes that he liked, and used that list to name the company. So when I needed a name for a character, I spent some time thinking about what I find fun to read and write, and ended up here. Liked it enough to keep using it some 10ish years later.

    6 votes
  16. Comment on 2024 United States election megathread in ~society

    Crespyl
    (edited )
    Link Parent
    My family started to suggest at first jokingly, now more seriously, that instead of watching the "horror movie" rollercoaster on the news we should just watch The Thing instead (one of our number...

    My family started to suggest at first jokingly, now more seriously, that instead of watching the "horror movie" rollercoaster on the news we should just watch The Thing instead (one of our number has never seen it before).

    I'll probably still inflict news on myself off and on anyway, but it'll be nice to not have this quite so much at the center of our evening.

    12 votes
  17. Comment on Best solution to extract PDF data? in ~comp

    Crespyl
    Link
    I don't use it much myself, but I have a couple family members who've used Microsoft's Power Query to extract data into Excel from a variety of sources, including PDFs.

    I don't use it much myself, but I have a couple family members who've used Microsoft's Power Query to extract data into Excel from a variety of sources, including PDFs.

    6 votes
  18. Comment on Seeking an Android podcast app without subscription. Impossible? in ~tech

  19. Comment on Vivaldi 7.0 has been released in ~tech

    Crespyl
    Link Parent
    Blink is the name Google gave to their Webkit fork, I believe Firefox is still using Gecko.

    Blink is the name Google gave to their Webkit fork, I believe Firefox is still using Gecko.

    7 votes
  20. Comment on Best way to voice call and screenshare with audio on Linux? in ~comp

    Crespyl
    Link Parent
    There's audio and then there's audio. Historically, voicechat audio from the microphone has worked fine, but desktop audio from the applications being screen-shared does not go through Discord...

    There's audio and then there's audio. Historically, voicechat audio from the microphone has worked fine, but desktop audio from the applications being screen-shared does not go through Discord without jumping through hoops.

    2 votes