Skip to content

Instantly share code, notes, and snippets.

@amirci
Last active February 10, 2016 18:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save amirci/9b5b447ce30312315f0b to your computer and use it in GitHub Desktop.
Save amirci/9b5b447ce30312315f0b to your computer and use it in GitHub Desktop.
Lunky's day 11 modified
namespace adventofcode
open System.Text.RegularExpressions
module Day11 =
let abc = ['a'..'z']
let succ (c: char) = int c |> (+) 1 |> char
let incChar = function
| 'z' -> 'a'
| c -> succ c
// 3 seconds faster than incSeries
let incSeries2 (input:string) =
let sb = input |> Seq.toArray
let rec inc' = function
| -1 -> sb.ToString()
| n when input.[n] = 'z' -> sb.[n] <- 'a' ; inc' (n - 1)
| n -> sb.[n] <- succ input.[n] ; System.String(sb)
inc' (input.Length - 1)
let incSeries (input:string) =
let rec inc' = function
| ('z'::xs) -> 'a'::inc' xs
| (n::xs) -> (succ n)::xs
| [] -> []
input
|> Seq.toList
|> List.rev
|> inc'
|> List.rev
|> List.toArray
|> (fun a -> System.String(a))
let mkRegex regex input = Regex.Match(input, regex)
let isMatch (regex: Match) = regex.Success
let matches pattern input = seq { for m in Regex.Matches(input, pattern) do yield m.Value }
let hasTriplet (input:string) =
let triplet [|a;b;c|] = b = succ a && c = succ b
input |> Seq.windowed 3 |> Seq.exists triplet
let notIol (pwd:string) = pwd |> mkRegex "^[^iol]*$" |> isMatch
let atLeastTwoPairs (pwd : string) =
pwd
|> Seq.windowed 2
|> Seq.filter (fun [| a; b |] -> a = b)
|> Seq.distinct
|> Seq.length
|> fun n -> n >= 2
let (<&&>) f g (x:string) = f x && g x
// around 10 second faster than isValid1
let isValid = hasTriplet <&&> atLeastTwoPairs <&&> notIol
let isValid1 (input: string) =
let allChars = "abc|bcd|cde|def|efg|fgh|ghi|hij|ijk|jkl|klm|lmn|mno|nop|opq|pqr|qrs|rst|stu|tuv|uvw|vwx|wxy|xyz"
let triplet = mkRegex allChars >> isMatch
let valid = mkRegex "^[^iol]*$" >> isMatch
let pairs = matches "(?:(\w)\1)" >> Seq.distinct >> Seq.length >> (<) 1
[triplet;valid;pairs] |> Seq.forall (fun fn -> fn input)
let rec genPwd (input: string) =
seq {
let value = incSeries input
yield value
yield! genPwd value
}
let nextPwd = genPwd >> Seq.find isValid
@amirci
Copy link
Author

amirci commented Feb 10, 2016

On line 67 changed the operator >= to < because of the infix order of the call....

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment