Skip to content

Refactor to use generic Set type and update stdlib imports#2

Open
willie wants to merge 12 commits intomainfrom
claude/advent-of-code-3b1RP
Open

Refactor to use generic Set type and update stdlib imports#2
willie wants to merge 12 commits intomainfrom
claude/advent-of-code-3b1RP

Conversation

@willie
Copy link
Owner

@willie willie commented Jan 31, 2026

Summary

This PR modernizes the codebase by replacing concrete StringSet and IntSet types with a generic Set[T] implementation, updates deprecated golang.org/x/exp imports to use Go 1.22+ stdlib packages, and adds new utility modules for common AoC patterns.

Key Changes

Generic Set Refactoring

  • Replace all aoc.StringSet with aoc.Set[string]
  • Replace all aoc.IntSet with aoc.Set[int]
  • Update constructor calls: NewStringSet()NewSet[string](), NewIntSet()NewSet[int]()
  • Rename method AddMany()AddSlice() for consistency

Standard Library Import Updates

  • Replace golang.org/x/exp/maps with stdlib maps package (Go 1.22+)
  • Replace golang.org/x/exp/slices with stdlib slices package
  • Wrap maps.Keys() and maps.Values() with slices.Collect() where needed for type compatibility

New Utility Modules

  • aoc/directions.go: Cardinal and diagonal direction constants, direction parsing, and neighbor finding utilities
  • aoc/dijkstra.go: Generic Dijkstra's algorithm implementation with variants for single goal, all distances, and predicate-based goals
  • aoc/binary.go: Hex-to-binary and binary-to-decimal conversion utilities (moved from functional.go)

Test Coverage

  • Add comprehensive test suites for new modules:
    • aoc/binary_test.go: 161 lines covering hex/binary conversions and round-trip tests
    • aoc/dijkstra_test.go: 143 lines covering pathfinding scenarios
    • aoc/directions_test.go: 210 lines covering direction operations and neighbor finding
    • aoc/functional_test.go: 287 lines covering Map/Filter/FilterMap operations

Bug Fixes

  • Fix SaveGIF() using hardcoded filename instead of parameter
  • Fix Grid.Width() to handle empty grids gracefully
  • Add Grid.IsEmpty() convenience method
  • Fix typos in Grid documentation ("Conveinence" → "Convenience")
  • Fix Grid2.SlopeIterate() variable naming issue

Code Quality

  • Remove unused aoc/functional.go (functionality preserved in tests)
  • Improve documentation and add convenience methods
  • Consistent method naming across the codebase

https://claude.ai/code/session_0177AokNsFRhuZtpAAVw2tmn

claude added 12 commits January 30, 2026 12:12
- download-puzzles: fetches all AoC puzzle descriptions (2015-2024) and converts to markdown
- analyze-puzzles: scans puzzles and identifies common algorithmic patterns

https://claude.ai/code/session_0177AokNsFRhuZtpAAVw2tmn
Tests:
- binary_test.go: hex/binary conversion tests
- functional_test.go: Map, Filter, FilterMap tests
- grid_test.go: Grid creation, access, iteration tests
- grid2_test.go: Grid2 sparse grid tests
- ints_test.go: Ints type method tests
- math_test.go: math utilities tests
- range_test.go: Range and Rangeset tests
- search_test.go: BFS/DFS tests
- set_test.go: Set, StringSet, IntSet tests
- stack_test.go: Stack and Queue tests
- tree_test.go: Node tree traversal tests
- utils_test.go: AtoI, BtoI, ReplaceAll tests

Bug fixes:
- range.go: Fixed Range.Equal (was comparing Start to End instead of End to End)
- grid2.go: Fixed SlopeIterate infinite loop (origin was never updated)
- graphics.go: Fixed SaveGIF ignoring filename parameter

https://claude.ai/code/session_0177AokNsFRhuZtpAAVw2tmn
New utilities:
- memo.go: Memoize, Memoize2, MemoizeRecursive for dynamic programming
- parse.go: ParseInts, ParseInt64s, SplitInts, Words for input parsing
- pqueue.go: Generic priority queue using container/heap
- dijkstra.go: Dijkstra, DijkstraAll, DijkstraFunc for weighted shortest path
- slices.go: Reverse, Chunk, Window, Pairs, Count, All, Any, Find, Unique, Flatten, Reduce
- directions.go: Direction constants (Up/Down/Left/Right), DirFromChar, TurnLeft/Right, Neighbors4/8

Improvements:
- grid.go: Fixed Width() panic on empty grid, added IsEmpty(), fixed typo
- set.go: Added deprecation notices for StringSet/IntSet (use Set[T] instead)
- math.go: Added deprecation notice for PermutationsString
- ints.go: Added note about generic alternatives
- search.go: Improved BFS/DFS documentation, removed old commented code
- functional.go: Removed redundant commented Reduce (now in slices.go)

https://claude.ai/code/session_0177AokNsFRhuZtpAAVw2tmn
Changes:
- slices.go: Use slices.Clone + slices.Reverse for Reverse()
- ints.go: Use slices.Min, slices.Max, slices.Index from stdlib
- math.go: Use slices.Min/Max internally, define local Integer/Signed constraints
- set.go: Add MapKeys helper (maps.Keys not in stdlib until Go 1.23)
- grid2.go: Use MapKeys instead of maps.Keys

The aoc/ library no longer imports golang.org/x/exp.
(Some solution files in 2023/ still use x/exp/maps)

https://claude.ai/code/session_0177AokNsFRhuZtpAAVw2tmn
Update all 2023 solution files to use stdlib maps package with
slices.Collect() wrapper for maps.Keys/Values (Go 1.23+ returns
iterators). Removes golang.org/x/exp dependency entirely from project.

https://claude.ai/code/session_0177AokNsFRhuZtpAAVw2tmn
Major changes:
- Remove deprecated StringSet/IntSet types (use Set[string]/Set[int])
- Remove deprecated ReverseInPlace (use slices.Reverse)
- Remove deprecated PermutationsString (use Permutations[string])
- Remove MapKeys helper (use slices.Collect(maps.Keys()))
- Merge functional.go into slices.go (Map, Filter, FilterMap)
- Fix Queue to use two-stack implementation for O(1) amortized ops
- Fix Words() to filter empty strings
- Add deprecation notices to Ints type and StringInts

Updates to solution files:
- 2020/5, 2020/6, 2020/7, 2020/16: Use Set[T] instead of StringSet/IntSet
- 2021/4, 2021/8, 2021/12: Use Set[T] instead of StringSet/IntSet
- wordle: Use Set[T] instead of StringSet

https://claude.ai/code/session_0177AokNsFRhuZtpAAVw2tmn
Also simplified the Series implementation and fixed usage in 2020/5
that depended on the method syntax.

https://claude.ai/code/session_0177AokNsFRhuZtpAAVw2tmn
Major cleanup:
- Remove deprecated Ints type and all methods (Sum, Product, Min, Max, etc.)
- Remove deprecated StringInts function (use Map(AtoI, ...) instead)
- Remove Zip function (had weak typing with [][2]any return type)
- Keep only Series function in ints.go

Updated solution files:
- 2020/5, 2020/9, 2020/10, 2020/15, 2020/16: Use []int instead of Ints
- 2023/4, 2023/5, 2023/6, 2023/9, 2023/12: Use Map(AtoI, ...) instead of StringInts

The aoc library now uses modern Go idioms:
- []int with standalone Sum/Min/Max functions
- Map(AtoI, ...) for string-to-int conversion
- Set[T] generic type (no more StringSet/IntSet)
- O(1) amortized Queue

https://claude.ai/code/session_0177AokNsFRhuZtpAAVw2tmn
- Remove Test64 (redundant with generic Test[T])
- Remove MustInt (alias for AtoI)
- Remove Min/Max wrappers (use builtin min/max or slices.Min/Max)
- Merge ints.go (Series) into slices.go
- Merge functional_test.go into slices_test.go
- Update all solution files to use stdlib slices.Min/Max or builtins

https://claude.ai/code/session_0177AokNsFRhuZtpAAVw2tmn
Previously returned [goal] even when goal was unreachable, which could
cause incorrect results. Now matches Dijkstra behavior of returning nil.

https://claude.ai/code/session_0177AokNsFRhuZtpAAVw2tmn
The name SparseGrid better describes what it is:
- Sparse storage (map, not full 2D array)
- Supports negative coordinates
- Good for large/infinite grids

https://claude.ai/code/session_0177AokNsFRhuZtpAAVw2tmn
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants