Возвращение расшифрованной строки как части кортежа в Haskell - PullRequest
0 голосов
/ 19 декабря 2009

Для проекта euler 59 я придумал это, чтобы получить список кортежей, содержащих дешифрованную строку и используемый ключ (и да, я знаю о Data.Bits):

module XOR where
import Data.List
import Data.Char
decToBin :: Integer -> [Integer]
decToBin x = reverse $ decToBin' x
    where
        decToBin' 0 = []
        decToBin' y = let (a,b) = quotRem y 2 in [b] ++ decToBin' a
binToDec ::  [Integer] -> Integer
binToDec xs = foldl (+) 0 $ map (\(x,y) -> x*(2^y) ) $reverse $ zip (reverse xs) [0..]

bitwise f x y = zipWith f x y

lenBin :: Integer -> Integer
lenBin x= length$ decToBin x

xor :: Integer -> Integer -> Bool
xor x y  | x == y = 0
         | x /= y = 1
         | otherwise = error "Impossible"

bitwiseXOR :: Integer -> Integer -> Integer    
bitwiseXOR a b | (lenBin a) > (lenBin b) = binToDec $ bitwise xor ((replicate ((lenBin a) - (lenBin b)) 0)++(decToBin b)) (decToBin a)
               | (lenBin a) < (lenBin b) = binToDec $ bitwise xor ((replicate ((lenBin b) - (lenBin a)) 0)++(decToBin a)) (decToBin b)
               | otherwise =binToDec $ bitwise xor (decToBin b) (decToBin a)

decyph :: [char] -> [char]
decyph key = map chr $ map (\(x,y)-> bitwiseXOR x (ord y) ) $ zip numbers $ cycle key

brute :: [([Char],[Char])]
brute = [(n,k)|k<- (sequence $ replicate 3 ['a'..'z']) ,n <- decyph k, "the" `isInfixOf` n]

numbers :: [Integer]
numbers = [79,59,12,2,79,35,8...]

Проблема в том, что когда я не могу запустить decyph, потому что создаваемые им кортежи содержат только один символ в первой части и ключ во второй, а не весь расшифрованный текст с использованным ключом. Как я могу это исправить?

PS: Разумно ли предположить, что текст будет содержать строку "the"?

1 Ответ

2 голосов
/ 19 декабря 2009

decyph key возвращает расшифрованный текст как [Char]. С синтаксисом

n <- decyph k

в вашем понимании списка, n будет иметь тип Char и будет назначен отдельным символам расшифрованного текста, но здесь вам нужно, чтобы ему был присвоен полный результат decyph, поэтому сделайте его

let n = decyph k

Наконец, проверьте тип elem:

> :t elem
elem :: (Eq a) => a -> [a] -> Bool

с типом n, равным [Char], первый аргумент должен быть Char, но у вас есть другая строка. Если вы хотите работать с elems, вы можете разбить расшифрованный текст на слова:

"the" `elem` words n

Это будет скомпилировано здесь.

PS: Разумно ли предположить, что текст будет содержать строку "the"?

Это, безусловно, обычное английское слово, но текст может быть в верхнем регистре или the может отображаться только как The в начале предложения.

...