57 lines
1.5 KiB
FSharp
57 lines
1.5 KiB
FSharp
module _59
|
|
|
|
open System
|
|
open System.IO
|
|
|
|
let cypher =
|
|
let encrypted =
|
|
File.ReadAllLines(@"59_cipher1.txt")
|
|
|> Array.collect (fun line -> line.Split(',') |> Array.map uint16)
|
|
|
|
let decrypt f message key =
|
|
let repeatedKey = seq { while true do yield! key }
|
|
Seq.map2 f message repeatedKey
|
|
|
|
let decryptXor = decrypt (^^^)
|
|
|
|
let decriptMessage = decryptXor encrypted
|
|
|
|
let de = encrypted |> Seq.distinct |> Seq.toArray
|
|
|
|
let filteri f s =
|
|
seq {
|
|
for i in 0..((s |> Seq.length) - 1) do
|
|
let si = Seq.nth i s
|
|
if f i si then yield si
|
|
}
|
|
|
|
let validKeys encryptedSymbols =
|
|
let lowercase = [97us..122us] |> List.toArray
|
|
let validSymbols = [32us..122us] |> List.toArray
|
|
|
|
let isValidChar i =
|
|
Array.exists ((=) i) validSymbols
|
|
|
|
[0..2]
|
|
|> List.map (fun offset ->
|
|
lowercase
|
|
|> Seq.filter (fun lc ->
|
|
encryptedSymbols
|
|
|> filteri (fun i e -> i % 3 = offset)
|
|
|> Seq.forall (fun e -> (e ^^^ lc) |> isValidChar))
|
|
)
|
|
|
|
let messageToText message =
|
|
message
|
|
|> Seq.map (char >> string)
|
|
|> Seq.fold (fun acc e -> acc + e) ""
|
|
|
|
validKeys encrypted
|
|
|> common.slottedPermutations
|
|
|> Seq.map (fun p -> (p, (decriptMessage >> messageToText) p))
|
|
|> Seq.find (fun p -> (snd p).Contains(" the "))
|
|
|> (fst >> decriptMessage)
|
|
|> Seq.map (int)
|
|
|> Seq.sum
|
|
|