Created
February 19, 2011 12:48
-
-
Save ostronom/835048 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
import Data.List | |
langs = [Haskell, Perl, Python, Ruby, C, Java] | |
data Languages = Haskell | Ruby | Perl | C | Python | Java | |
sequenceFromString Haskell s = "map toEnum[" ++ (intercalate "," $ | |
map (\c -> show (fromEnum c)) s) ++ "]" | |
sequenceFromString Perl s = (intercalate "," $ | |
map (\c -> "chr(" ++ show (fromEnum c) ++ ")") s) | |
sequenceFromString Python s = (intercalate "+" $ | |
map (\c -> "chr(" ++ show (fromEnum c) ++ ")") s) | |
sequenceFromString Ruby s = (intercalate "+" $ | |
map (\c -> show (fromEnum c) ++ ".chr") s) | |
sequenceFromString C s = concatMap | |
(\c -> "putchar(" ++ show (fromEnum c) ++ ");") s | |
sequenceFromString Java s = concatMap | |
(\c -> "o.write(" ++ show (fromEnum c) ++ ");") s | |
paramList' Haskell = intercalate " " . map (\n -> "a" ++ show n) | |
paramList' C = intercalate "," . map (\n -> "char *a" ++ show n) | |
paramList' Python = intercalate "," . map (\n -> "a" ++ show n) | |
paramList' Ruby = intercalate "," . map (\n -> "a" ++ show n) | |
paramList' Java = intercalate "," . map (\n -> "String a" ++ show n) | |
paramList Perl _ = "" | |
paramList lang n = paramList' lang [0..n-1] | |
driver l args = defn l ++ intercalate (divider l) args ++ endDefn l | |
divider C = "\",\"" | |
divider Perl = "','" | |
divider Ruby = "\",\"" | |
divider Python = "\",\"" | |
divider Haskell = "\" \"" | |
divider Java = "\",\"" | |
defn C = "main(){q(\"" | |
defn Perl = "&q('" | |
defn Python = "q(\"" | |
defn Ruby = "q(\"" | |
defn Haskell = "main=q \"" | |
defn Java = "public static void main(String[]args){q(\"" | |
endDefn C = "\");}" | |
endDefn Perl = "')" | |
endDefn Python = "\")" | |
endDefn Ruby = "\")" | |
endDefn Haskell = "\"" | |
endDefn Java = "\");}}" | |
arg Haskell n = "a" ++ show n | |
arg Perl n = "$_[" ++ show n ++ "]" | |
arg C n = "printf(a" ++ show n ++ ");" | |
arg Python n = "a" ++ show n | |
arg Ruby n = "a" ++ show n | |
arg Java n = "o.print(a" ++ show n ++ ");" | |
argDivide Haskell l = "++" ++ sequenceFromString Haskell (divider l) ++ "++" | |
argDivide Perl l = "," ++ sequenceFromString Perl (divider l) ++ "," | |
argDivide C l = sequenceFromString C (divider l) | |
argDivide Python l = "+" ++ sequenceFromString Python (divider l) ++ "+" | |
argDivide Ruby l = "+" ++ sequenceFromString Ruby (divider l) ++ "+" | |
argDivide Java l = sequenceFromString Java (divider l) | |
argList lang1 lang2 n = intercalate (argDivide lang1 lang2) $ | |
map (arg lang1) ([1..n-1] ++ [0]) | |
fromTo Haskell l n = "q " ++ paramList Haskell n ++ "=putStrLn$a0++" ++ | |
sequenceFromString Haskell ("\n" ++ defn l) ++ "++" ++ | |
argList Haskell l n ++ "++" ++ sequenceFromString Haskell (endDefn l) | |
fromTo Perl l n = "sub q {" ++ "print $_[0]," ++ | |
sequenceFromString Perl ("\n" ++ defn l) ++ "," ++ argList Perl l n ++ "," ++ | |
sequenceFromString Perl (endDefn l ++ "\n") ++ "}" | |
fromTo Python l n = "def q(" ++ paramList Python n ++ | |
"): print a0+" ++ sequenceFromString Python ("\n" ++ defn l) ++ | |
"+" ++ argList Python l n ++ "+" ++ sequenceFromString Python (endDefn l) | |
fromTo Ruby l n = "def q(" ++ paramList Ruby n ++ | |
") print a0+" ++ sequenceFromString Ruby ("\n" ++ defn l) ++ | |
"+" ++ argList Ruby l n ++ "+" ++ sequenceFromString Ruby (endDefn l ++ "\n") ++ " end" | |
fromTo C l n = "q(" ++ paramList C n ++ "){" ++ "printf(a0);" ++ | |
sequenceFromString C ("\n" ++ defn l) ++ argList C l n ++ | |
sequenceFromString C (endDefn l ++ "\n") ++ "}" | |
fromTo Java l n = "public class quine{public static void q(" ++ | |
paramList Java n ++ "){java.io.PrintStream o=System.out;o.print(a0);" ++ | |
sequenceFromString Java ("\n" ++ defn l) ++ argList Java l n ++ | |
sequenceFromString Java (endDefn l ++ "\n") ++ "}" | |
main = do | |
let n = length langs | |
let langs' = cycle langs | |
putStrLn $ fromTo (head langs') (head (tail langs')) n | |
putStrLn $ driver (head langs') $ zipWith (\lang1 lang2 -> fromTo lang1 lang2 n) | |
(take n (tail langs')) (tail (tail langs')) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment