#include #include // Because of technical limitations, characters within a "string" must be separated by white spaces. // For the sake of simplicity, only upper-case characters are supported here. // A few lines of boiler-plate oriented programming are needed to enable character parsing and comparison. #define ORDER_PP_TOKEN_A (A) #define ORDER_PP_TOKEN_B (B) #define ORDER_PP_TOKEN_C (C) #define ORDER_PP_TOKEN_D (D) #define ORDER_PP_TOKEN_E (E) #define ORDER_PP_TOKEN_F (F) #define ORDER_PP_TOKEN_G (G) #define ORDER_PP_TOKEN_H (H) #define ORDER_PP_TOKEN_I (I) #define ORDER_PP_TOKEN_J (J) #define ORDER_PP_TOKEN_K (K) #define ORDER_PP_TOKEN_L (L) #define ORDER_PP_TOKEN_M (M) #define ORDER_PP_TOKEN_N (N) #define ORDER_PP_TOKEN_O (O) #define ORDER_PP_TOKEN_P (P) #define ORDER_PP_TOKEN_Q (Q) #define ORDER_PP_TOKEN_R (R) #define ORDER_PP_TOKEN_S (S) #define ORDER_PP_TOKEN_T (T) #define ORDER_PP_TOKEN_U (U) #define ORDER_PP_TOKEN_V (V) #define ORDER_PP_TOKEN_W (W) #define ORDER_PP_TOKEN_X (X) #define ORDER_PP_TOKEN_Y (Y) #define ORDER_PP_TOKEN_Z (Z) #define ORDER_PP_SYM_A(...) __VA_ARGS__ #define ORDER_PP_SYM_B(...) __VA_ARGS__ #define ORDER_PP_SYM_C(...) __VA_ARGS__ #define ORDER_PP_SYM_D(...) __VA_ARGS__ #define ORDER_PP_SYM_E(...) __VA_ARGS__ #define ORDER_PP_SYM_F(...) __VA_ARGS__ #define ORDER_PP_SYM_G(...) __VA_ARGS__ #define ORDER_PP_SYM_H(...) __VA_ARGS__ #define ORDER_PP_SYM_I(...) __VA_ARGS__ #define ORDER_PP_SYM_J(...) __VA_ARGS__ #define ORDER_PP_SYM_K(...) __VA_ARGS__ #define ORDER_PP_SYM_L(...) __VA_ARGS__ #define ORDER_PP_SYM_M(...) __VA_ARGS__ #define ORDER_PP_SYM_N(...) __VA_ARGS__ #define ORDER_PP_SYM_O(...) __VA_ARGS__ #define ORDER_PP_SYM_P(...) __VA_ARGS__ #define ORDER_PP_SYM_Q(...) __VA_ARGS__ #define ORDER_PP_SYM_R(...) __VA_ARGS__ #define ORDER_PP_SYM_S(...) __VA_ARGS__ #define ORDER_PP_SYM_T(...) __VA_ARGS__ #define ORDER_PP_SYM_U(...) __VA_ARGS__ #define ORDER_PP_SYM_V(...) __VA_ARGS__ #define ORDER_PP_SYM_W(...) __VA_ARGS__ #define ORDER_PP_SYM_X(...) __VA_ARGS__ #define ORDER_PP_SYM_Y(...) __VA_ARGS__ #define ORDER_PP_SYM_Z(...) __VA_ARGS__ /// 8blocks_lexer (string) : Seq String -> Seq (Seq Sym) #define ORDER_PP_DEF_8blocks_lexer ORDER_PP_FN \ (8fn (8S \ ,8seq_map (8tokens_to_seq \ ,8S \ ) \ ) \ ) // Keying the blocks makes filtering them way more efficient than by comparing their letters. /// 8seq_keyed (sequence) : Seq a -> Seq (Pair Num a) #define ORDER_PP_DEF_8seq_keyed ORDER_PP_FN \ (8fn (8S \ ,8stream_to_seq (8stream_pair_with (8pair \ ,8stream_of_naturals \ ,8seq_to_stream (8S) \ ) \ ) \ ) \ ) /// 8abc_internal (blocks, word) : Seq (Pair Num (Seq Token)) -> Seq Token -> Bool #define ORDER_PP_DEF_8abc_internal ORDER_PP_FN \ (8fn (8B, 8W \ ,8if (8seq_is_nil (8W) \ ,8true \ ,8lets ((8C, 8seq_head (8W)) \ (8S, 8seq_filter (8chain (8seq_exists (8same (8C)) \ ,8tuple_at_1 \ ) \ ,8B \ ) \ ) \ (8T, 8seq_map (8chain (8flip (8seq_filter \ ,8B \ ) \ ,8bin_pr (8not_eq \ ,8tuple_at_0 \ ) \ ) \ ,8S \ ) \ ) \ ,8seq_exists (8flip (8abc_internal \ ,8seq_tail (8W) \ ) \ ,8T \ ) \ ) \ ) \ ) \ ) /// 8abc (blocks, word) : Seq (String) -> String -> Bool #define ORDER_PP_DEF_8abc ORDER_PP_FN \ (8fn (8B, 8W \ ,8abc_internal (8seq_keyed (8blocks_lexer (8B)) \ ,8tokens_to_seq (8W) \ ) \ ) \ ) #define ORDER_PP_DEF_8blocks ORDER_PP_CONST ( \ (B O) \ (X K) \ (D Q) \ (C P) \ (N A) \ (G T) \ (R E) \ (T G) \ (Q D) \ (F S) \ (J W) \ (H U) \ (V I) \ (A N) \ (O B) \ (E R) \ (F S) \ (L Y) \ (P C) \ (Z M) \ ) ORDER_PP (8seq_map (8step (8pair (8identity ,8abc (8blocks) ) ) ,8quote ((A) (B A R K) (B O O K) (T R E A T) (C O M M O N) (S Q U A D) (C O N F U S E) ) ) )