You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Circuit.hs 3.3 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. module Circuit (
  2. Fuel, Tank, cartanks, createTank, createFuel, evalChamber, checkChamber, evalFuel, checkFuel, build1, build, key_circuit, test_key_circ, key_input, key, big_input,
  3. Circuit(..), Chamber(..), Car(..), server_input, circ_from_perm,
  4. execCircuit, execCircuit2, checkCircuit, checkCircuits,
  5. permutations
  6. ) where
  7. import Encoding
  8. import CircuitBase
  9. import CircuitParser
  10. import CircuitSimulator
  11. -- import CircuitC
  12. import Data.List
  13. import Data.Maybe
  14. import Data.Packed
  15. type Fuel = [Tank]
  16. type Tank = Matrix Double
  17. -- IMPORANT functions:
  18. -- * build
  19. -- create a circuit for a desired fuel output
  20. -- example:
  21. -- build ""
  22. cartanks :: Car -> Int
  23. cartanks = (1+) . maximum . concat . map (\(Chamber upper _ lower) -> upper ++ lower) . chambers
  24. createTank :: [[Integer]] -> Tank
  25. createTank = fromLists . map (map fromIntegral)
  26. createFuel = map createTank
  27. evalChamber :: Fuel -> Chamber -> Matrix Double
  28. evalChamber tanks (Chamber upper _ lower) = product (map (tanks !! ) upper) - product (map (tanks !! ) lower)
  29. checkChamber :: Fuel -> Chamber -> Bool
  30. checkChamber tanks c@(Chamber upper main lower) = (all (>= 0) $ concat $ toLists diff) && (not main || (diff @@> (0,0)) > 0) where
  31. diff = evalChamber tanks c
  32. evalFuel :: Fuel -> Car -> [Matrix Double]
  33. evalFuel f = map (evalChamber f) . chambers
  34. checkFuel :: Fuel -> Car -> Bool
  35. checkFuel fuel car = checkfuel && all (checkChamber fuel) (chambers car) where
  36. checkfuel = if (all (>= 0) $ concat $ concat $ map toLists fuel) && all (\t -> (t @@> (0,0)) > 0) fuel then True else error "Fuel broken"
  37. -- zero everything:
  38. -- Circuit {outPin = 8, inPins = [2,9,4,5,-1,3,1,0,6,7]}
  39. -- basic blocks
  40. -- 0: 1R:2L1L0#X2L,2RX0#0R2R,0R1R0#0L1L:0L
  41. -- 1: 2L:2R1R0#2R1R,2L0R0#X0R,X0L0#1L0L:1L
  42. -- 2: 2R:2R1R0#2L1L,0R2L0#X0R,0LX0#1R0L:1L
  43. -- build circuit for needed output
  44. build1 s = let (p, pins) = step 4 [0,-1,1,6,2,3,5,7] (dropWhile (0 == ) $ reverse (key ++ (streamread s))) in Circuit p pins where
  45. step p gates [] = (p, gates)
  46. step p gates (x:xs) = let k = length gates in case x of
  47. 0 -> step k (gates ++ [k+4,k+2,k+5,p,k+1,k+3]) xs
  48. 1 -> step (k+2) (gates ++ [k+5,k+3,k+4,k+1,p,k]) xs
  49. 2 -> step (k+2) (gates ++ [k+5,k+3,k+1,k+4,k,p]) xs
  50. build s = let (p, pins) = step (-1) [] (reverse (key ++ (streamread s))) in Circuit p pins where
  51. step p gates [] = (p, gates)
  52. step p gates (x:xs) = let k = length gates in case x of
  53. 0 -> step k (gates ++ [k+4,k+2,k+5,p,k+1,k+3]) xs
  54. 1 -> step (k+2) (gates ++ [k+5,k+3,k+4,k+1,p,k]) xs
  55. 2 -> step (k+2) (gates ++ [k+5,k+3,k+1,k+4,k,p]) xs
  56. key_circuit = parseCircuit key_circuit_str
  57. key_circuit_str = "19L:12R13R0#1R12R,14R0L0#4R9L,9R10R0#3L8L,2L17R0#5L9R,15R1L0#10R13R,3L18R0#6L15L,5L11R0#13L12L,19R16R0#11R8R,2R7R0#11L10L,1R3R0#18L2L,8R4L0#16L2R,8L7L0#15R6R,6R0R0#14L0L,6L4R0#14R0R,12L13L0#17L1L,5R11L0#16R4L,10L15L0#17R7R,14L16L0#18R3R,9L17L0#19R5R,X18L0#X7L:19L"
  58. -- goal: Find a circuit with test_key_circ circ == True
  59. test_key_circ :: Circuit -> Bool
  60. test_key_circ circ = checkCircuit circ server_input key
  61. key_input :: [Trit]
  62. key_input = streamread "02222220210110011"
  63. key :: [Trit]
  64. key = execCircuit2 key_circuit key_input
  65. -- key: "11021210112101221"
  66. big_input = streamread "0120101201201020210210020210101010101110202022202020202001010210200102010201010201201020201201020120101202102021010120120210201201020120102102"