advent of code 2025 in ts and nix
1{ 2 description = "Advent of Code 2025 Solutions"; 3 4 inputs = { 5 nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; 6 flake-utils.url = "github:numtide/flake-utils"; 7 }; 8 9 outputs = { self, nixpkgs, flake-utils }: 10 flake-utils.lib.eachDefaultSystem (system: 11 let 12 pkgs = nixpkgs.legacyPackages.${system}; 13 gum = pkgs.gum; 14 15 # Get list of available days 16 getDays = '' 17 days=() 18 for dir in ts/* nix/*; do 19 if [ -d "$dir" ]; then 20 day=$(basename "$dir") 21 if [[ ! " ''${days[@]} " =~ " ''${day} " ]]; then 22 days+=("$day") 23 fi 24 fi 25 done 26 echo "''${days[@]}" | tr ' ' '\n' | sort 27 ''; 28 29 # Run a specific day's solution 30 runDay = day: lang: '' 31 if [ "$lang" = "ts" ] && [ -f "ts/${day}/index.ts" ]; then 32 ${gum}/bin/gum style --border rounded --border-foreground 212 --padding "0 1" --margin "1 0" "Day ${day} (TypeScript)" 33 (cd ts/${day} && ${pkgs.bun}/bin/bun run index.ts) 34 elif [ "$lang" = "nix" ] && [ -f "nix/${day}/solution.nix" ]; then 35 ${gum}/bin/gum style --border rounded --border-foreground 212 --padding "0 1" --margin "1 0" "Day ${day} (Nix)" 36 result=$(${pkgs.nix}/bin/nix-instantiate --eval --strict --json nix/${day}/solution.nix) 37 part1=$(echo "$result" | ${pkgs.jq}/bin/jq -r '.part1') 38 part2=$(echo "$result" | ${pkgs.jq}/bin/jq -r '.part2') 39 echo "part 1: $part1" 40 echo "part 2: $part2" 41 fi 42 ''; 43 44 # Interactive runner with gum 45 runner = pkgs.writeShellScriptBin "aoc" '' 46 set -e 47 48 ${gum}/bin/gum style \ 49 --border double \ 50 --border-foreground 212 \ 51 --padding "1 2" \ 52 --margin "1 0" \ 53 "$(${gum}/bin/gum style --foreground 212 '🎄 Advent of Code 2025 🎄')" 54 55 # Choose action 56 action=$(${gum}/bin/gum choose "Run specific day" "Run all solutions" "Exit") 57 58 case "$action" in 59 "Run specific day") 60 # Get available days 61 days=$(${getDays}) 62 63 if [ -z "$days" ]; then 64 ${gum}/bin/gum style --foreground 196 "No solutions found!" 65 exit 1 66 fi 67 68 day=$(echo "$days" | ${gum}/bin/gum choose) 69 70 # Check what languages are available for this day 71 langs=() 72 [ -f "ts/$day/index.ts" ] && langs+=("TypeScript") 73 [ -f "nix/$day/solution.nix" ] && langs+=("Nix") 74 langs+=("Both") 75 76 lang=$(printf '%s\n' "''${langs[@]}" | ${gum}/bin/gum choose) 77 78 echo "" 79 case "$lang" in 80 "TypeScript") 81 if [ -f "ts/$day/index.ts" ]; then 82 ${gum}/bin/gum style --border rounded --border-foreground 212 --padding "0 1" "Day $day" 83 echo "" 84 ${gum}/bin/gum style --foreground 212 "TypeScript:" 85 (cd ts/$day && ${pkgs.bun}/bin/bun run index.ts) 86 fi 87 ;; 88 "Nix") 89 if [ -f "nix/$day/solution.nix" ]; then 90 ${gum}/bin/gum style --border rounded --border-foreground 212 --padding "0 1" "Day $day" 91 echo "" 92 ${gum}/bin/gum style --foreground 212 "Nix:" 93 result=$(${pkgs.nix}/bin/nix-instantiate --eval --strict --json nix/$day/solution.nix) 94 echo "$result" | ${pkgs.jq}/bin/jq -r 'to_entries | .[] | "\(.key): \(.value)"' 95 fi 96 ;; 97 "Both") 98 ${gum}/bin/gum style --border rounded --border-foreground 212 --padding "0 1" "Day $day" 99 echo "" 100 if [ -f "ts/$day/index.ts" ]; then 101 ${gum}/bin/gum style --foreground 212 "TypeScript:" 102 (cd ts/$day && ${pkgs.bun}/bin/bun run index.ts) 103 echo "" 104 fi 105 if [ -f "nix/$day/solution.nix" ]; then 106 ${gum}/bin/gum style --foreground 212 "Nix:" 107 result=$(${pkgs.nix}/bin/nix-instantiate --eval --strict --json nix/$day/solution.nix) 108 echo "$result" | ${pkgs.jq}/bin/jq -r 'to_entries | .[] | "\(.key): \(.value)"' 109 fi 110 ;; 111 esac 112 ;; 113 114 "Run all solutions") 115 # Collect all unique days 116 all_days=() 117 for dir in ts/* nix/*; do 118 if [ -d "$dir" ]; then 119 day=$(basename "$dir") 120 if [[ ! " ''${all_days[@]} " =~ " ''${day} " ]]; then 121 all_days+=("$day") 122 fi 123 fi 124 done 125 126 # Sort and run each day 127 for daynum in $(printf '%s\n' "''${all_days[@]}" | sort); do 128 ${gum}/bin/gum style --border rounded --border-foreground 212 --padding "0 1" "Day $daynum" 129 echo "" 130 131 if [ -f "ts/$daynum/index.ts" ]; then 132 ${gum}/bin/gum style --foreground 212 "TypeScript:" 133 (cd ts/$daynum && ${pkgs.bun}/bin/bun run index.ts) 134 echo "" 135 fi 136 137 if [ -f "nix/$daynum/solution.nix" ]; then 138 ${gum}/bin/gum style --foreground 212 "Nix:" 139 result=$(${pkgs.nix}/bin/nix-instantiate --eval --strict --json nix/$daynum/solution.nix) 140 echo "$result" | ${pkgs.jq}/bin/jq -r 'to_entries | .[] | "\(.key): \(.value)"' 141 echo "" 142 fi 143 done 144 ;; 145 146 "Exit") 147 ${gum}/bin/gum style --foreground 212 "Happy coding! 🎅" 148 exit 0 149 ;; 150 esac 151 ''; 152 153 in { 154 # Development shell with all tools 155 devShells.default = pkgs.mkShell { 156 packages = with pkgs; [ 157 bun 158 jq 159 gum 160 runner 161 ]; 162 163 shellHook = '' 164 ${gum}/bin/gum style --foreground 212 "🎄 Advent of Code 2025 🎄" 165 echo "" 166 ${gum}/bin/gum style "Run 'aoc' to start the interactive runner" 167 ''; 168 }; 169 170 # Packages 171 packages = { 172 default = runner; 173 }; 174 175 # Apps 176 apps = { 177 default = { 178 type = "app"; 179 program = "${runner}/bin/aoc"; 180 }; 181 }; 182 } 183 ); 184}