diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..763f9d1 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,13 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Rider ignored files +/.idea.coding-challenges.iml +/projectSettingsUpdater.xml +/modules.xml +/contentModel.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/everybody-codes/2025/EveryBodyCodes2025/.idea/.idea.EveryBodyCodes2025/.idea/.gitignore b/everybody-codes/2025/EveryBodyCodes2025/.idea/.idea.EveryBodyCodes2025/.idea/.gitignore new file mode 100644 index 0000000..433514d --- /dev/null +++ b/everybody-codes/2025/EveryBodyCodes2025/.idea/.idea.EveryBodyCodes2025/.idea/.gitignore @@ -0,0 +1,13 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Rider ignored files +/projectSettingsUpdater.xml +/.idea.EveryBodyCodes2025.iml +/modules.xml +/contentModel.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/everybody-codes/2025/EveryBodyCodes2025/EveryBodyCodes2025/Inputs/Q01_P01.txt b/everybody-codes/2025/EveryBodyCodes2025/EveryBodyCodes2025/Inputs/Q01_P01.txt new file mode 100644 index 0000000..f10b63d --- /dev/null +++ b/everybody-codes/2025/EveryBodyCodes2025/EveryBodyCodes2025/Inputs/Q01_P01.txt @@ -0,0 +1,10 @@ +A=9 B=5 C=8 X=6 Y=6 Z=5 M=21 +A=2 B=5 C=9 X=3 Y=7 Z=5 M=15 +A=2 B=9 C=5 X=6 Y=5 Z=6 M=23 +A=5 B=9 C=8 X=4 Y=3 Z=6 M=23 +A=4 B=4 C=7 X=5 Y=4 Z=7 M=20 +A=8 B=8 C=9 X=6 Y=8 Z=7 M=15 +A=5 B=9 C=8 X=8 Y=7 Z=9 M=12 +A=9 B=8 C=8 X=6 Y=6 Z=7 M=11 +A=4 B=9 C=9 X=4 Y=3 Z=6 M=16 +A=3 B=3 C=6 X=3 Y=3 Z=9 M=10 \ No newline at end of file diff --git a/everybody-codes/2025/EveryBodyCodes2025/EveryBodyCodes2025/Inputs/Q01_P02.txt b/everybody-codes/2025/EveryBodyCodes2025/EveryBodyCodes2025/Inputs/Q01_P02.txt new file mode 100644 index 0000000..29462ad --- /dev/null +++ b/everybody-codes/2025/EveryBodyCodes2025/EveryBodyCodes2025/Inputs/Q01_P02.txt @@ -0,0 +1,100 @@ +A=3963 B=8842 C=8687 X=409495541 Y=7293148889 Z=69968178871 M=172 +A=7942 B=7029 C=6244 X=839539903 Y=4169342114 Z=95037937077 M=160 +A=7979 B=8971 C=6912 X=442664734 Y=6237597808 Z=86442494244 M=68 +A=7688 B=9813 C=8682 X=332021203 Y=9856217610 Z=80328955369 M=62 +A=5835 B=5848 C=9080 X=142585645 Y=1900208603 Z=95352568867 M=102 +A=5334 B=9954 C=9648 X=905887097 Y=9241714569 Z=54782995871 M=64 +A=7455 B=3708 C=8255 X=504254875 Y=4435182630 Z=47061156208 M=196 +A=7792 B=9864 C=5393 X=480894345 Y=7574321009 Z=28916297468 M=162 +A=8393 B=3232 C=8104 X=330175845 Y=5289733360 Z=31518107012 M=79 +A=3882 B=3375 C=6068 X=518104895 Y=1025354059 Z=23851183794 M=109 +A=7157 B=6688 C=8802 X=343914437 Y=8548573578 Z=39640082726 M=108 +A=9267 B=9026 C=5652 X=552894284 Y=5449382534 Z=15095836120 M=131 +A=7709 B=7053 C=6015 X=692558506 Y=3648795546 Z=80249693831 M=94 +A=4090 B=7395 C=9247 X=462765550 Y=4135859740 Z=20266326837 M=98 +A=5319 B=9603 C=8458 X=837675237 Y=7562163981 Z=81526783792 M=98 +A=5056 B=3354 C=8506 X=215467750 Y=8934346014 Z=80156785083 M=64 +A=8946 B=9714 C=8466 X=186796372 Y=6752172401 Z=97885508408 M=85 +A=6634 B=3765 C=5216 X=684211300 Y=7194085573 Z=84235702575 M=93 +A=7700 B=9075 C=8639 X=769343115 Y=4951946895 Z=12460628812 M=192 +A=2270 B=6794 C=9887 X=753574022 Y=1010353710 Z=22079276874 M=199 +A=4608 B=6704 C=6374 X=489461820 Y=2617126841 Z=99189476796 M=56 +A=7991 B=6698 C=5009 X=865348038 Y=6628450920 Z=82542609090 M=138 +A=9146 B=3602 C=5757 X=948362149 Y=6536500415 Z=42356087927 M=63 +A=6135 B=6979 C=7331 X=296914642 Y=5562957551 Z=15296896818 M=154 +A=6740 B=4037 C=9925 X=664678186 Y=2062390238 Z=26147984893 M=127 +A=4286 B=3122 C=7026 X=326371845 Y=1116546423 Z=13319294289 M=72 +A=2440 B=4715 C=8385 X=255209406 Y=9382774924 Z=54150329024 M=196 +A=3576 B=9613 C=9732 X=944415768 Y=5592859961 Z=38006825858 M=75 +A=3943 B=4271 C=8115 X=435401018 Y=3803008103 Z=87256283762 M=71 +A=5046 B=5121 C=7477 X=882139913 Y=1929832251 Z=25182537189 M=51 +A=3106 B=5337 C=7157 X=456093739 Y=5663851313 Z=64060187791 M=66 +A=6809 B=5664 C=8361 X=881954026 Y=6714747784 Z=67415739912 M=193 +A=2947 B=4118 C=7935 X=459311447 Y=1504393004 Z=93240766891 M=120 +A=6368 B=5612 C=8266 X=231311396 Y=2500175052 Z=54868769612 M=155 +A=7059 B=8353 C=9272 X=386198328 Y=6033513339 Z=34890243693 M=95 +A=6639 B=7182 C=9599 X=203138028 Y=8848877703 Z=41738077352 M=50 +A=4327 B=9940 C=7620 X=144124863 Y=2255030420 Z=72197832296 M=187 +A=8129 B=3767 C=7930 X=874606203 Y=2598169766 Z=43845885455 M=76 +A=7857 B=6832 C=6907 X=739251256 Y=6913635659 Z=68561001761 M=105 +A=3786 B=5820 C=9138 X=497623985 Y=1048832748 Z=22080414607 M=58 +A=2235 B=4081 C=7532 X=481034867 Y=6763036282 Z=90858998586 M=146 +A=6570 B=4019 C=9385 X=687612339 Y=5923858682 Z=37417952027 M=173 +A=8715 B=6433 C=6347 X=302773772 Y=5836323573 Z=85318938543 M=149 +A=5272 B=5147 C=6267 X=952029958 Y=5064309718 Z=46637498104 M=158 +A=8251 B=3017 C=9953 X=520837819 Y=4171582367 Z=32996622261 M=186 +A=5058 B=5497 C=8865 X=209462541 Y=3152901709 Z=28469776806 M=127 +A=7458 B=4164 C=5570 X=504629974 Y=2847240248 Z=58865406911 M=69 +A=3860 B=3876 C=7655 X=406121777 Y=8124355470 Z=87786303696 M=63 +A=3203 B=8316 C=6886 X=455814102 Y=4577442858 Z=78541358333 M=159 +A=3125 B=6022 C=7456 X=381823686 Y=5752089240 Z=93786233800 M=65 +A=3159 B=5387 C=8685 X=867405378 Y=4700629430 Z=13338543360 M=110 +A=9443 B=8949 C=9618 X=708422252 Y=5713427199 Z=93352128799 M=138 +A=8269 B=8771 C=9138 X=115479767 Y=6857455766 Z=88859949122 M=148 +A=5030 B=7425 C=8196 X=382353180 Y=5987748430 Z=25607872228 M=57 +A=3129 B=9466 C=6663 X=436840184 Y=4007277476 Z=67936955089 M=121 +A=8863 B=4951 C=6103 X=474069087 Y=2653137145 Z=50414775315 M=142 +A=7710 B=5762 C=7992 X=599214654 Y=7004049394 Z=34839364869 M=60 +A=3632 B=7511 C=9400 X=363797903 Y=6114932282 Z=92960791069 M=102 +A=5952 B=4083 C=5910 X=774389174 Y=5176494427 Z=12141381856 M=56 +A=3348 B=7169 C=7752 X=235855845 Y=7501135473 Z=66780467588 M=53 +A=5619 B=7340 C=9967 X=294184624 Y=2180513244 Z=79033007662 M=168 +A=7091 B=6809 C=8576 X=451316478 Y=5083584456 Z=75461336471 M=132 +A=6986 B=7754 C=7425 X=757283512 Y=6808223862 Z=34941686102 M=85 +A=9456 B=7652 C=8565 X=979905517 Y=5198120313 Z=89655367929 M=145 +A=6408 B=3375 C=9204 X=167783992 Y=7153984590 Z=92427049931 M=163 +A=5763 B=6148 C=9274 X=279889725 Y=9964940531 Z=70350391483 M=107 +A=8547 B=3879 C=6951 X=378902964 Y=2470752240 Z=41679149795 M=164 +A=9030 B=7546 C=9608 X=362501898 Y=4119049939 Z=34688334048 M=63 +A=6606 B=3185 C=7598 X=989305093 Y=8605576905 Z=51083739654 M=75 +A=6638 B=6554 C=9533 X=454809416 Y=9071666311 Z=84656936473 M=153 +A=5935 B=6809 C=7923 X=466741209 Y=3713819811 Z=67566769458 M=82 +A=4142 B=3634 C=8916 X=533140627 Y=2195880417 Z=63200440973 M=155 +A=6744 B=6198 C=6326 X=537074856 Y=6435636287 Z=37528504509 M=187 +A=4239 B=4620 C=7151 X=462984355 Y=5222077949 Z=15395506154 M=128 +A=6828 B=3182 C=6966 X=496586089 Y=7568408954 Z=19431263615 M=154 +A=9989 B=3481 C=5907 X=513706785 Y=7730898126 Z=95604573977 M=187 +A=3705 B=7381 C=9078 X=944788648 Y=3774196339 Z=94727056559 M=109 +A=6519 B=8081 C=6652 X=515939261 Y=7364208903 Z=76245157293 M=119 +A=6783 B=3628 C=6785 X=612616358 Y=2730449251 Z=43338128854 M=119 +A=5754 B=4424 C=9976 X=455602255 Y=3399840701 Z=39884578932 M=58 +A=7329 B=5584 C=9481 X=765182920 Y=1848910508 Z=45635859967 M=136 +A=6519 B=3508 C=5784 X=715678818 Y=9372223394 Z=26437577265 M=148 +A=4079 B=8159 C=7501 X=806798900 Y=3775959987 Z=13667259165 M=171 +A=5610 B=8246 C=9431 X=876328126 Y=3062507221 Z=76968043190 M=192 +A=8793 B=7191 C=8651 X=507531146 Y=1481324914 Z=10641325001 M=140 +A=3474 B=4504 C=6865 X=153892044 Y=1499530230 Z=23327074226 M=148 +A=2283 B=7236 C=6691 X=349591700 Y=5648605259 Z=52789615621 M=193 +A=5353 B=7290 C=8351 X=904035360 Y=1079381894 Z=32939365470 M=151 +A=3335 B=3714 C=9424 X=490506342 Y=3864608302 Z=22684283111 M=193 +A=6639 B=4126 C=6774 X=303155063 Y=8058444773 Z=51242239037 M=140 +A=5939 B=8415 C=7647 X=864474320 Y=7501144894 Z=16280658244 M=158 +A=7462 B=5382 C=6626 X=507130448 Y=5725528199 Z=64532140016 M=189 +A=7292 B=9734 C=9202 X=249977263 Y=9609502439 Z=18773414989 M=151 +A=4252 B=6928 C=7069 X=520151955 Y=5022079447 Z=17156955195 M=168 +A=6024 B=9247 C=8017 X=691392384 Y=2452486474 Z=98856856289 M=188 +A=3965 B=6464 C=7846 X=890087137 Y=1960036667 Z=58084547133 M=117 +A=3493 B=4567 C=5429 X=385555783 Y=9048831860 Z=95579371679 M=132 +A=6806 B=3897 C=6437 X=760150394 Y=7972134501 Z=88248014690 M=178 +A=5943 B=7880 C=9482 X=796170662 Y=8924797876 Z=68139919278 M=77 +A=4792 B=6913 C=7409 X=184894441 Y=4869520047 Z=27653781346 M=166 \ No newline at end of file diff --git a/everybody-codes/2025/EveryBodyCodes2025/EveryBodyCodes2025/Inputs/Q01_P02a.txt b/everybody-codes/2025/EveryBodyCodes2025/EveryBodyCodes2025/Inputs/Q01_P02a.txt new file mode 100644 index 0000000..f443543 --- /dev/null +++ b/everybody-codes/2025/EveryBodyCodes2025/EveryBodyCodes2025/Inputs/Q01_P02a.txt @@ -0,0 +1,2 @@ +A=5 B=9 C=7 X=6 Y=16 Z=18 M=15 +A=8 B=8 C=8 X=6 Y=19 Z=16 M=16 \ No newline at end of file diff --git a/everybody-codes/2025/EveryBodyCodes2025/EveryBodyCodes2025/Program.fs b/everybody-codes/2025/EveryBodyCodes2025/EveryBodyCodes2025/Program.fs new file mode 100644 index 0000000..c33ec32 --- /dev/null +++ b/everybody-codes/2025/EveryBodyCodes2025/EveryBodyCodes2025/Program.fs @@ -0,0 +1,14 @@ +// For more information see https://aka.ms/fsharp-console-apps +open System +open EveryBodyCodes2025.QuestOne + +[] +let main argv = + //printfn $"{part1Answer}" + //printfn $"{test2}" + printfn $"part 2 answer {part2Answer}" + //let testAnswer = part2Answer' "Inputs/Q01_P02a.txt" + //printfn $"part 2 answer test 1 {testAnswer}" + //printfn $"part 2 answer test 1 11051340 expected" + 0 + diff --git a/everybody-codes/2025/EveryBodyCodes2025/EveryBodyCodes2025/QuestOne.fs b/everybody-codes/2025/EveryBodyCodes2025/EveryBodyCodes2025/QuestOne.fs new file mode 100644 index 0000000..c2126f0 --- /dev/null +++ b/everybody-codes/2025/EveryBodyCodes2025/EveryBodyCodes2025/QuestOne.fs @@ -0,0 +1,143 @@ +module EveryBodyCodes2025.QuestOne + +open System +open System.Collections.Generic +open System.IO +open System.Linq +open System.Numerics +open System.Threading.Tasks + +let eni (n:BigInteger) (exp:BigInteger) (m:BigInteger) = + let mutable remainders = [] + let mutable score = BigInteger 1 + for _ in (BigInteger 1)..exp do + score <- (score * n) % m + remainders <- score::remainders + List.rev remainders // Reverse to get correct order (oldest first) + +// let test1 = eni 2 4 5 |> fun l -> String.Join("", l) |> int64 +// let test2 = eni 3 5 16 |> fun l -> String.Join("", l) |> int64 + +let part1Lines (input:String array) = + input |> Array.map (fun line -> + line.Split(" ") |> Array.map(fun segment -> + let parts = segment.Split("=") + let alias = parts[0] + let num = parts[1] |> BigInteger.Parse + (alias, num) + ) + |> dict + ) + +let toBigInt (list:'a list) = String.Join("", list) |> BigInteger.Parse + +let part1 (input: IDictionary array)= + input + |> Seq.map (fun line -> + let a = eni line["A"] line["X"] line["M"] |> toBigInt + let b = eni line["B"] line["Y"] line["M"] |> toBigInt + let c = eni line["C"] line["Z"] line["M"] |> toBigInt + a + b + c + ) |> Seq.max + |> fun x -> + printfn $"{x}" + x + +let part1Answer = + File.ReadAllLines "Inputs/Q01_P01.txt" + |> part1Lines + |> part1 + +/// Map from (prev, curr) pair to position +type PositionMap = Map +let rec findCycle (pairToNextPair: PositionMap) startPair currentPair acc = + if currentPair = startPair && List.length acc > 0 then + Some (List.rev acc) + else + match Map.tryFind currentPair pairToNextPair with + | None -> None + | Some nextPair -> + findCycle pairToNextPair startPair nextPair (snd currentPair :: acc) + +let rec eni2' score (n:BigInteger) (exp:BigInteger) (m:BigInteger) (pairMap: PositionMap) (scores:BigInteger list) iter = + if iter > exp then scores |> List.rev |> List.skip (max 0 (List.length scores - 5)) |> toBigInt + else + let newScore = (score * n) % m + let key = (score, newScore) + + match Map.tryFind key pairMap with + | Some _ -> + match findCycle pairMap key key [] with + | Some cycle -> + let remaining = int64 (exp - iter) + let cycleValues = cycle + let cycleLength = List.length cycleValues |> int64 + let scoresLength = List.length scores |> int64 + let totalLength = scoresLength + 1L + remaining // scores + newScore + remaining + + let needCount = min 5L totalLength + let startPos = max 0L (totalLength - needCount) + + let scoresReversed = List.rev scores + + let final5 = + [startPos..totalLength - 1L] + |> List.map (fun pos -> + if pos < scoresLength then + // Position is in scores (scores is reversed, so oldest is at end) + scoresReversed.[int pos] + elif pos = scoresLength then + // Position is newScore + newScore + else + let cycleOffset = pos - scoresLength + let cyclePos = cycleOffset % cycleLength + cycleValues.[int cyclePos] + ) + + // final 5 comes out in reverse order + final5 |> List.rev |> toBigInt + | None -> + eni2' newScore n exp m (Map.add key ((newScore, (newScore * n) % m)) pairMap) (newScore::scores) (iter + BigInteger 1) + | None -> + let nextPair = (newScore, (newScore * n) % m) + eni2' newScore n exp m (Map.add key nextPair pairMap) (newScore::scores) (iter + BigInteger 1) + +let eni2 (n) (exp) (m) = eni2' (BigInteger 1) n exp m Map.empty [] (BigInteger 1) + +let part2 (input: IDictionary array)= + input + |> Array.mapi (fun i line -> + //printfn $"""running line {line.AsEnumerable() |> Seq.map(fun kv -> kv.Key + "=" + kv.Value.ToString()) |> fun x -> String.Join(", ", x)}""" + let a = eni2 line["A"] line["X"] line["M"] + let b = eni2 line["B"] line["Y"] line["M"] + let c = eni2 line["C"] line["Z"] line["M"] + let ret = a + b + c + //printfn $"found {ret}" + ret + ) |> Seq.max + +let test2 = + let a = eni2 5 6 15 + let b = eni2 9 16 15 + let c = eni2 7 18 15 + let r = a + b + c + printfn $"{r}" + r + + +let part2Answer = + File.ReadAllLines "Inputs/Q01_P02.txt" + |> part1Lines + |> part2 + |> fun x -> + printfn $"part2 {x}" + x + +let part2Answer' file = + File.ReadAllLines file + |> part1Lines + |> part2 + |> fun x -> + printfn $"part2 {x}" + x \ No newline at end of file diff --git a/everybody-codes/2025/EveryBodyCodes2025/EveryBodyCodes2025/QuestOne_ai.fs b/everybody-codes/2025/EveryBodyCodes2025/EveryBodyCodes2025/QuestOne_ai.fs new file mode 100644 index 0000000..1022e75 --- /dev/null +++ b/everybody-codes/2025/EveryBodyCodes2025/EveryBodyCodes2025/QuestOne_ai.fs @@ -0,0 +1,123 @@ +module EveryBodyCodes2025.QuestOne_ai + +open System +open System.Collections.Generic +open System.IO +open System.Numerics +open System.Threading.Tasks + +let eni (n:int64) (exp:int64) (m:int64) = + // Compute n^k mod m for k = 1..exp + // The sequence will cycle, so we detect the cycle and use it + // Track pairs of consecutive remainders to detect cycles + let mutable remainders = [] + let mutable score : int64 = 1 + let mutable seenPairs = Map.empty // Map from (prev, curr) pair to position + let mutable prevScore = 0L + let mutable cycleLength = -1 + let mutable doneWithCycle = false + + // Build sequence until we detect a cycle + let mutable k = 1 + while k <= int exp && not doneWithCycle do + prevScore <- score + score <- (score * n) % m + remainders <- score::remainders + + // Check if we've seen this (prev, curr) pair before + if k > 1 && seenPairs.ContainsKey (prevScore, score) && cycleLength = -1 then + let prevPos = seenPairs[(prevScore, score)] + let candidateLength = (remainders.Length - 1) - prevPos + + // Verify it's a cycle by checking one more value + if candidateLength > 0 then + let nextScore = (score * n) % m + let nextPos = if prevPos + 1 < remainders.Length then + (remainders.Length - 1) - (prevPos + 1) + else -1 + if nextPos >= 0 && nextPos < remainders.Length && remainders[nextPos] = nextScore then + // Found a cycle! + cycleLength <- candidateLength + + // Use cycle to compute remaining values + let remaining = int exp - k + if remaining > 0 then + // Extract the cycle (in correct order) + let cycleList = remainders.[0..cycleLength - 1] |> List.rev + let fullCycles = remaining / cycleLength + let extra = remaining % cycleLength + + for _ in 1..fullCycles do + remainders <- cycleList @ remainders + + for i in 0..extra - 1 do + remainders <- cycleList.[i]::remainders + + doneWithCycle <- true + else + if cycleLength = -1 && k > 1 then + seenPairs <- seenPairs.Add((prevScore, score), remainders.Length - 1) + + k <- k + 1 + + List.rev remainders + +// let test1 = eni 2 4 5 |> fun l -> String.Join("", l) |> int64 +// let test2 = eni 3 5 16 |> fun l -> String.Join("", l) |> int64 + +let part1Lines (input:String array) = + input |> Array.map (fun line -> + line.Split(" ") |> Array.map(fun segment -> + let parts = segment.Split("=") + let alias = parts[0] + let num = parts[1] |> int64 + (alias, num) + ) + |> dict + ) + +let toBigInt (list:int64 list) = String.Join("", list) |> BigInteger.Parse + +let part1 (input: IDictionary array)= + input + |> Seq.map (fun line -> + let a = eni line["A"] line["X"] line["M"] |> toBigInt + let b = eni line["B"] line["Y"] line["M"] |> toBigInt + let c = eni line["C"] line["Z"] line["M"] |> toBigInt + a + b + c + ) |> Seq.max + +let part1Answer = + File.ReadAllLines "Inputs/Q01_P01.txt" + |> part1Lines + |> part1 + + +let eni2 (n:int64) (exp:int64) (m:int64) = + // For part 2, we only need the last 5 remainders + // Use the same cycle detection as eni, then take last 5 + let allRemainders = eni n exp m + let len = List.length allRemainders + if len <= 5 then + allRemainders + else + allRemainders |> List.skip (len - 5) + +let part2 (input: IDictionary array)= + input + |> Array.Parallel.map (fun line -> + let a = eni2 line["A"] line["X"] line["M"] |> toBigInt + let b = eni2 line["B"] line["Y"] line["M"] |> toBigInt + let c = eni2 line["C"] line["Z"] line["M"] |> toBigInt + a + b + c + ) |> Seq.max + +let test2 = + toBigInt(eni2 5 6 15) + toBigInt(eni2 9 16 15) + toBigInt(eni2 7 18 15) + + +let part2Answer = + File.ReadAllLines "Inputs/Q01_P02.txt" + |> part1Lines + |> part2 + \ No newline at end of file