Created
December 15, 2015 00:22
-
-
Save plecong/1db0f1ddbe86df953235 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
open System | |
open System.Text | |
let getCharEx (input : int) = | |
Encoding.ASCII.GetString([| byte (97 + (int (input % 26))) |]).ToCharArray().[0] | |
let codeToChar = | |
seq { for i = 0 to 25 do yield (uint64 i), getCharEx i } | |
|> dict | |
let charToCode = | |
seq { for i = 0 to 25 do yield getCharEx i, (uint64 i) } | |
|> dict | |
let getCode (input : char) = charToCode.[input] | |
let getChar (input : uint64) = codeToChar.[input] | |
let convertToInt (input : string) = | |
let rec convertToIntLoop (acc : uint64) (part : char list) = | |
match part with | |
| [] -> acc | |
| head :: tail -> convertToIntLoop ((acc * 26UL) + (getCode head)) tail | |
convertToIntLoop 0UL (input.ToCharArray() |> Array.toList) | |
let convertToString (input : uint64) = | |
let rec convertToStringLoop (acc : char list) (i : uint64) = | |
if i = 0UL then acc | |
else convertToStringLoop ((getChar (i % 26UL)) :: acc) (uint64 (Math.Floor (float (i / 26UL)))) | |
convertToStringLoop List.empty input | |
|> List.toArray | |
|> (fun x -> (new String(x)).PadLeft(8, 'a')) | |
let hasTwoPer (input : string) = | |
input.ToCharArray() | |
|> Seq.pairwise | |
|> Seq.filter (fun (a, b) -> a = b) | |
|> Seq.map (fun (a, b) -> a) | |
|> Seq.distinct | |
|> Seq.length | |
|> (fun x -> x >= 2) | |
let hasRestricted (input : string) = | |
input.ToCharArray() | |
|> Seq.exists (fun x -> x = 'i' || x = 'o' || x = 'l') | |
let hasConsecutive (input : string) = | |
let s = input.ToCharArray() | |
seq { | |
for i = 0 to s.Length - 3 do | |
yield (s.[i], s.[i+1], s.[i+2]) | |
} | |
|> Seq.exists (fun (a, b, c) -> (getCode b) = ((getCode a) + 1UL) && (getCode c) = ((getCode b) + 1UL)) | |
let isValidPassword (input : string) = | |
(hasTwoPer input) && (not (hasRestricted input)) && (hasConsecutive input) | |
let findNextPassword (input : string) = | |
let asInt = convertToInt input | |
seq { for x = (asInt + 1UL) to UInt64.MaxValue do yield convertToString x } | |
|> Seq.find isValidPassword | |
let part1 = findNextPassword "hepxcrrq" | |
let part2 = findNextPassword part1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment