bugsmith
- 57 Posts
- 144 Comments
bugsmith@programming.devOPMto
Programming@programming.dev•Adding Live Reload to a Static Site Generator Written in GoEnglish
1·28 days agoI’d say fsnotify is the least interesting part
Spectacle OCR is fantastic news. That is really going to simplify one of my current workflows.
bugsmith@programming.devMto
Programming@programming.dev•Programming.dev instance: Sponsors needed
2·2 months agoIt’s Lemmy.
bugsmith@programming.devMto
Programming@programming.dev•Programming.dev instance: Sponsors needed
1·2 months agodeleted by creator
bugsmith@programming.devto
Technology@lemmy.world•Android’s most beloved launcher may be done for goodEnglish
5·7 months agoI have used and enjoyed lawnchair for the past year. It’s quite minimal and I’ve found it very stable.
bugsmith@programming.devto
Asklemmy@lemmy.ml•How is Lobste.rs? Why did it break from HN? How does one even get in?
12·1 year agoPersonally, I think it’s great. It’s a smaller community than HN and the registration requirements, whilst not a perfect solution, do create a litmus test and ultimately creates an envrionment of mostly high quality posting.
To get in, you need to be invited in by an existing user. If you don’t know anybody, you can hang around on their IRC channel and once you’re familiar, somebody may be willing to invite you.
This should have been posted in programming.dev/c/meta. I’m leaving it up here as the question has been answered.
bugsmith@programming.devOPto
Advent Of Code@programming.dev•[2024 Day 06] Any Gleamings in the house?
1·1 year agoThanks - appreciate the feedback!
I’m a bit less extreme about it than many here. But, in short, back when Reddit made sweeping API changes it immediately gave me ‘the ick’ and so I sought less centralised platforms. Lemmy is the closest thing I’ve found to people just hosting their own message boards like back in the early internet.
I’m a big fan of decentralized platforms and I love the concept of ActivityPub.
That said, I still use Reddit and have recently started to really enjoy BlueSky, so I’m not militantly against the corporate platforms or anything.
Finally, I just like the natural selection things like Lemmy and Mastodon have for those who are naturally more techy and nerdy.
Gleam
Late as usual. This one challenged me. Functional programming is a lot of fun, but it’s kicking my ass.
import gleam/dict import gleam/io import gleam/list import gleam/option.{None, Some} import gleam/result import gleam/set.{type Set} import gleam/string import simplifile pub type Point = #(Int, Int) pub type Grid(a) = dict.Dict(Point, a) pub type Direction { North East South West } pub type Loops { DoesLoop DoesNotLoop } pub type Guard { Guard(position: Point, direction: Direction) } fn get_guard(grid: Grid(String)) -> Guard { let pos = dict.filter(grid, fn(_pos, char) { char == "^" }) let assert Ok(pos) = case dict.size(pos) { 1 -> list.first(dict.keys(pos)) 0 -> panic as "No guard found in input!" _ -> panic as "More than one guard found in input!" } Guard(pos, North) } fn move_guard(guard: Guard) -> Guard { let new_pos = case guard.direction { North -> #(-1, 0) East -> #(0, 1) South -> #(1, 0) West -> #(0, -1) } Guard( #(guard.position.0 + new_pos.0, guard.position.1 + new_pos.1), guard.direction, ) } fn turn_guard(guard: Guard) -> Guard { let new_dir = case guard.direction { North -> East East -> South South -> West West -> North } Guard(guard.position, new_dir) } fn get_obstacles(grid: Grid(String)) -> List(Point) { dict.filter(grid, fn(_pos, char) { char == "#" }) |> dict.keys() } fn recurse_grid( grid: Grid(String), guard: Guard, obstacles: List(#(Int, Int)), visited: Set(#(#(Int, Int), Direction)), ) -> #(Set(#(#(Int, Int), Direction)), Loops) { let new_guard = move_guard(guard) let position = new_guard.position let dir = new_guard.direction case dict.has_key(grid, position) { False -> #(visited, DoesNotLoop) True -> { case set.contains(visited, #(position, dir)) { True -> { #(visited, DoesLoop) } False -> { case list.contains(obstacles, position) { True -> recurse_grid(grid, turn_guard(guard), obstacles, visited) False -> recurse_grid( grid, new_guard, obstacles, set.insert(visited, #(position, dir)), ) } } } } } } fn get_grid_input(filename: String) -> Grid(String) { let lines = filename |> simplifile.read() |> result.unwrap("") |> string.trim() |> string.split("\n") use grid, row, row_idx <- list.index_fold(lines, dict.new()) use grid, col, col_idx <- list.index_fold(string.to_graphemes(row), grid) dict.insert(grid, #(row_idx, col_idx), col) } fn part_one( grid: Grid(String), ) -> #(#(Set(#(#(Int, Int), Direction)), Loops), Int) { let guard = get_guard(grid) let obstacles = get_obstacles(grid) let visited = set.new() |> set.insert(#(guard.position, guard.direction)) let visited = recurse_grid(grid, guard, obstacles, visited) let visited_without_dir = set.fold(visited.0, set.new(), fn(acc, x) { set.insert(acc, x.0) }) #(visited, visited_without_dir |> set.size()) } fn check_loop(grid: Grid(String), blocker: Point) -> Loops { let blocked_grid = dict.upsert(grid, blocker, fn(x) { case x { Some("^") -> "^" Some(_) -> "#" None -> "#" } }) let visited = part_one(blocked_grid).0 visited.1 } fn part_two(grid: Grid(String), visited: Set(#(#(Int, Int), Direction))) { let visited = set.fold(visited, set.new(), fn(acc, x) { set.insert(acc, x.0) }) use counter, position <- set.fold(visited, 0) case check_loop(grid, position) { DoesLoop -> counter + 1 DoesNotLoop -> counter } } pub fn main() { let input = "input.in" let p1 = input |> get_grid_input() |> part_one let visited = p1.0.0 io.debug(p1.1) input |> get_grid_input |> part_two(visited) |> io.debug() }
Gleam
Struggled with the second part as I am still very new to this very cool language, but got there after scrolling for some inspiration.
import gleam/int import gleam/io import gleam/list import gleam/regex import gleam/result import gleam/string import simplifile pub fn main() { let assert Ok(data) = simplifile.read("input.in") part_one(data) |> io.debug part_two(data) |> io.debug } fn part_one(data) { let assert Ok(multiplication_pattern) = regex.from_string("mul\\(\\d{1,3},\\d{1,3}\\)") let assert Ok(digit_pattern) = regex.from_string("\\d{1,3},\\d{1,3}") let multiplications = regex.scan(multiplication_pattern, data) |> list.flat_map(fn(reg) { regex.scan(digit_pattern, reg.content) |> list.map(fn(digits) { digits.content |> string.split(",") |> list.map(fn(x) { x |> int.parse |> result.unwrap(0) }) |> list.reduce(fn(a, b) { a * b }) |> result.unwrap(0) }) }) |> list.reduce(fn(a, b) { a + b }) |> result.unwrap(0) } fn part_two(data) { let data = "do()" <> string.replace(data, "\n", "") <> "don't()" let assert Ok(pattern) = regex.from_string("do\\(\\).*?don't\\(\\)") regex.scan(pattern, data) |> list.map(fn(input) { input.content |> part_one }) |> list.reduce(fn(a, b) { a + b }) }
Elixir
defmodule Day02 do defp part1(reports) do reports |> Enum.map(fn report -> levels = report |> String.split() |> Enum.map(&String.to_integer/1) cond do sequence_is_safe?(levels) -> :safe true -> :unsafe end end) |> Enum.count(fn x -> x == :safe end) end defp part2(reports) do reports |> Enum.map(fn report -> levels = report |> String.split() |> Enum.map(&String.to_integer/1) sequences = 0..(length(levels) - 1) |> Enum.map(fn i -> List.delete_at(levels, i) end) cond do sequence_is_safe?(levels) -> :safe Enum.any?(sequences, &sequence_is_safe?/1) -> :safe true -> :unsafe end end) |> Enum.count(fn x -> x == :safe end) end defp all_gaps_within_max_diff?(numbers) do numbers |> Enum.chunk_every(2, 1, :discard) |> Enum.all?(fn [a, b] -> abs(b - a) <= 3 end) end defp is_strictly_increasing?(numbers) do numbers |> Enum.chunk_every(2, 1, :discard) |> Enum.all?(fn [a, b] -> a < b end) end defp is_strictly_decreasing?(numbers) do numbers |> Enum.chunk_every(2, 1, :discard) |> Enum.all?(fn [a, b] -> a > b end) end defp sequence_is_safe?(numbers) do (is_strictly_increasing?(numbers) or is_strictly_decreasing?(numbers)) and all_gaps_within_max_diff?(numbers) end def run(data) do reports = data |> String.split("\n", trim: true) p1 = part1(reports) p2 = part2(reports) IO.puts(p1) IO.puts(p2) end end data = File.read!("input.in") Day02.run(data)
I’m late to the party, as usual. Damned timezones. This year I’m going to tackle with a small handful of languages, but primarily Elixir and Gleam. This is my first time trying this languages in earnest, so expect some terrible, inefficient and totally unidiomatic code!
Here’s day one:Elixir
part_one = File.read!("input.in") |> String.split("\n", trim: true) |> Enum.map(fn line -> line |> String.split() |> Enum.map(&String.to_integer/1) end) |> Enum.reduce({[], []}, fn [first, second], {list1, list2} -> {[first | list1], [second | list2]} end) |> then(fn {list1, list2} -> {Enum.sort(list1), Enum.sort(list2)} end) |> then(fn {list1, list2} -> Enum.zip(list1, list2) |> Enum.map(fn {x, y} -> abs(x - y) end) end) |> Enum.sum() part_two = File.read!("input.in") |> String.split("\n", trim: true) |> Enum.map(fn line -> line |> String.split() |> Enum.map(&String.to_integer/1) end) |> Enum.reduce({[], []}, fn [first, second], {list1, list2} -> {[first | list1], [second | list2]} end) |> then(fn {list1, list2} -> Enum.map(list1, fn line -> line * Enum.count(list2, fn x -> x === line end) end) |> Enum.sum() end) IO.inspect(part_one) IO.inspect(part_two)
bugsmith@programming.devto
United Kingdom@feddit.uk•Actress Dame Maggie Smith dies at 89English
17·2 years agoShe was 89 and no doubt lead a truly fulfilling life, and so I think objectively it’s not a sad passing - she had a truly remarkable life and long life.
That said, she was a significant part of my childhood, and always on the television in the various households I’ve lived in for one show or another. It feels like losing a beloved grandmother, and I’m devastated. RIP Maggie.
bugsmith@programming.devOPMto
Programming@programming.dev•Good software development habits
1·2 years agoTotally agree. Like most “rules”, it just needs treating with nuance and context.
bugsmith@programming.devto
Ask Lemmy@lemmy.world•What's an activity that you could foresee yourself doing every weekend for the rest of your life?
2·2 years agoI can totally see how it could be read like that!
bugsmith@programming.devto
Ask Lemmy@lemmy.world•What's an activity that you could foresee yourself doing every weekend for the rest of your life?
3·2 years agoFive-a-side is a specific format of football (soccer), aimed at more casual play with a much lower bar to skill level. Outside of five-a-side leagues (which do exist), it’s rarely played with fixed teams and often ran in a more “pick up group” fashion.
bugsmith@programming.devto
Ask Lemmy@lemmy.world•What's an activity that you could foresee yourself doing every weekend for the rest of your life?
19·2 years agoFive-a-side football (soccer). I’m not a sporty person, but started going with a local group a few years ago and have reaped the benefits of doing some intensive team exercise once per week. I go with a bunch of guys way older than I am, and it’s amazing how fit and healthy they are compared to the average person I meet of their age. I certainly plan to keep this up so long an injury doesn’t prevent me.
bugsmith@programming.devto
Godot@programming.dev•Godot 4: Sand pouring shader (quick tutorial)
3·2 years agoNice. I’ve not seen any of your other videos yet, but I can say that for this one, I really loved that you just jumped straight in to the action and kept the video tight, without missing important details.















I’m glad you enjoyed it. I appreciate the kind words.
Feel free to do so!