# prints the truth table of a boolean expression composed of the 26 lowercase variables a..z, #
# the boolean operators AND, OR, XOR and NOT and the literal values TRUE and FALSE            #
# The evaluation is done with the Algol 68G evaluate function which is an extension           #
PROC print truth table = ( STRING expr )VOID:
     BEGIN

        # recursively prints the truth table #
        PROC print line = ( INT v )VOID:
             IF v > UPB bv
             THEN
                 # at the end of the variables - print the line #
                 FOR e TO UPB bv DO
                     IF used[ e ] THEN print( ( " ", bv[ e ], " " ) ) FI
                 OD;
                 print( ( "     ", evaluate( expr ), newline ) )
             ELIF used[ v ]
             THEN
                 # have another variable #
                 bv[ v ] := TRUE;
                 print line( v + 1 );
                 bv[ v ] := FALSE;
                 print line( v + 1 )
             ELSE
                 # this variable is not used #
                 print line( v + 1 )
             FI # print line # ;

        # returns the name of the variable number #
        PROC variable name = ( INT number )CHAR: REPR ( number + ( ABS "a" - 1 ) );

        # the 26 boolean variables #
        BOOL a := FALSE, b := FALSE, c := FALSE, d := FALSE, e := FALSE, f := FALSE;
        BOOL g := FALSE, h := FALSE, i := FALSE, j := FALSE, k := FALSE, l := FALSE;
        BOOL m := FALSE, n := FALSE, o := FALSE, p := FALSE, q := FALSE, r := FALSE;
        BOOL s := FALSE, t := FALSE, u := FALSE, v := FALSE, w := FALSE, x := FALSE;
        BOOL y := FALSE, z := FALSE;
        # table of the variables allowng access by number #
        []REF BOOL bv = ( a, b, c, d, e, f, g, h, i, j, k, l, m
                        , n, o, p, q, r, s, t, u, v, w, x, y, z
                        );
        [ 26 ]BOOL used;
        BOOL at least one variable := FALSE;
        # determine which variables are used in the expression #
        FOR v TO UPB bv DO
            used[ v ] := char in string( variable name( v ), NIL, expr );
            IF used[ v ]THEN at least one variable := TRUE FI
        OD;
        # print truth table headings #
        print( ( expr, ":", newline ) );
        FOR v TO UPB bv DO
            IF used[ v ] THEN print( ( " ", variable name( v ), " " ) ) FI
        OD;
        print( ( " value", newline ) );
        FOR v TO UPB bv DO
            IF used[ v ] THEN print( ( " - " ) ) FI
        OD;
        print( ( " -----", newline ) );
        # evaluate the expression for each cobination of variables #
        IF at least one variable
        THEN
             # the expression does not consist of literals only #
             FOR v TO UPB bv DO bv[ v ] := FALSE OD;
             print line( LWB bv )
        ELSE
             # the expression is constant #
             print( ( "     ", evaluate( expr ), newline ) )
        FI
     END # print truth table # ;

# print truth tables from the user's expressions #
print( ( "Please enter Boolean expressions using variables a, b, c, ..., z,",                  newline ) );
print( ( "operators AND, OR, NOT and XOR and literals TRUE and FALSE",                         newline ) );
print( ( "(Note operators and TRUE/FALSE must be uppercase and variables must be lower case)", newline ) );
print( ( "Enter a blank line to quit",                                                         newline ) );
WHILE
    STRING expr;
    print( ( "expression> " ) );
    read( ( expr, newline ) );
    expr /= ""
DO
    print truth table( expr )
OD


(defun rad_to_deg (rad)(* 180.0 (/ rad PI)))
(defun deg_to_rad (deg)(* PI (/ deg 180.0)))

(defun asin (x)
  (cond
    ((and(> x -1.0)(< x 1.0)) (atan (/ x (sqrt (- 1.0 (* x x))))))
    ((= x -1.0) (* -1.0 (/ pi 2)))
    ((= x 1) (/ pi 2))
  )
)

(defun acos (x)
  (cond
    ((and(>= x -1.0)(<= x 1.0)) (-(* pi 0.5) (asin x)))
  )
)

(list
(list "cos PI/6" (cos (/ pi 6)) "cos 30 deg" (cos (deg_to_rad 30)))
(list "sin PI/4" (sin (/ pi 4)) "sin 45 deg" (sin (deg_to_rad 45)))
(list "tan PI/3" (tan (/ pi 3))"tan 60 deg" (tan (deg_to_rad 60)))
(list "asin 1 rad" (asin 1.0) "asin 1 rad (deg)" (rad_to_deg (asin 1.0)))
(list "acos 1/2 rad" (acos (/ 1 2.0)) "acos 1/2 rad (deg)" (rad_to_deg (acos (/ 1 2.0))))
(list "atan pi/12" (atan (/ pi 12)) "atan 15 deg" (rad_to_deg(atan(deg_to_rad 15))))
)


# tan(x) = tangent of x
function tan(x) {
	return sin(x) / cos(x)
}

# asin(y) = arcsine of y, domain [-1, 1], range [-pi/2, pi/2]
function asin(y) {
	return atan2(y, sqrt(1 - y * y))
}

# acos(x) = arccosine of x, domain [-1, 1], range [0, pi]
function acos(x) {
	return atan2(sqrt(1 - x * x), x)
}

# atan(y) = arctangent of y, range (-pi/2, pi/2)
function atan(y) {
	return atan2(y, 1)
}

BEGIN {
	pi = atan2(0, -1)
	degrees = pi / 180

	print "Using radians:"
	print "  sin(-pi / 6) =", sin(-pi / 6)
	print "  cos(3 * pi / 4) =", cos(3 * pi / 4)
	print "  tan(pi / 3) =", tan(pi / 3)
	print "  asin(-1 / 2) =", asin(-1 / 2)
	print "  acos(-sqrt(2) / 2) =", acos(-sqrt(2) / 2)
	print "  atan(sqrt(3)) =", atan(sqrt(3))

	print "Using degrees:"
	print "  sin(-30) =", sin(-30 * degrees)
	print "  cos(135) =", cos(135 * degrees)
	print "  tan(60) =", tan(60 * degrees)
	print "  asin(-1 / 2) =", asin(-1 / 2) / degrees
	print "  acos(-sqrt(2) / 2) =", acos(-sqrt(2) / 2) / degrees
	print "  atan(sqrt(3)) =", atan(sqrt(3)) / degrees
}


// Adapted from http://www-cs-faculty.stanford.edu/~uno/programs/topswops.w
// at Donald Knuth's web site.  Algorithm credited there to Pepperdine
// and referenced to Mathematical Gazette 73 (1989), 131-133.
package main

import "fmt"

const ( // array sizes
    maxn = 10 // max number of cards
    maxl = 50 // upper bound for number of steps
)

func main() {
    for i := 1; i <= maxn; i++ {
        fmt.Printf("%d: %d\n", i, steps(i))
    }
}

func steps(n int) int {
    var a, b [maxl][maxn + 1]int
    var x [maxl]int
    a[0][0] = 1
    var m int
    for l := 0; ; {
        x[l]++
        k := int(x[l])
        if k >= n {
            if l <= 0 {
                break
            }
            l--
            continue
        }
        if a[l][k] == 0 {
            if b[l][k+1] != 0 {
                continue
            }
        } else if a[l][k] != k+1 {
            continue
        }
        a[l+1] = a[l]
        for j := 1; j <= k; j++ {
            a[l+1][j] = a[l][k-j]
        }
        b[l+1] = b[l]
        a[l+1][0] = k + 1
        b[l+1][k+1] = 1
        if l > m-1 {
            m = l + 1
        }
        l++
        x[l] = 0
    }
    return m
}


truth←{
    op←⍉↑'~∧∨≠→('(4 3 2 2 1 0)
    order←⍬⍬{
        out stk←⍺
        0=≢⍵:out,⌽stk
        c rst←(⊃⍵) (1↓⍵)
        c∊⎕A:((out,c)stk)∇rst
        c∊'01':((out,⍎c)stk)∇rst
        (c≠'(')∧(≢op)≥n←op[;1]⍳c:rst∇⍨out{
            cnd←⌽∧\⌽(⍵≠'(')∧op[op[;1]⍳⍵;2]≥op[n;2]
            (⍺,⌽cnd/⍵)(((~cnd)/⍵),c)
        }stk
        c='(':(out(stk,c))∇rst
        c=')':rst∇⍨out{
            ⍬≡par←⍸'('=⍵:'Missing ('⎕SIGNAL 11
            n←⌈/par
            (⍺,n↓⍵)((n-1)↑⍵)
        }stk
        ('Invalid character ',c)⎕SIGNAL 11
    }1(819⌶)⍵~4↑⎕TC
    '('∊order:'Missing )'⎕SIGNAL 11
    nvar←≢vars←∪(order∊⎕A)/order
    eval←{
        ⍺←⍬
        0=≢⍵:{
            1≠≢⍵:'Missing operator'⎕SIGNAL 11 ⋄ ⊃⍵
        }⍺
        c rst←(⊃⍵) (1↓⍵)
        c∊⎕A:(⍺⍺[vars⍳c],⍺)∇rst
        c∊0 1:(c,⍺)∇rst
        c='~':(⍺≠1 0↑⍨≢⍺)∇rst ⊣ 'Missing operand'⎕SIGNAL(0=≢⍺)/11
        c∊op[;1]:({
            2>≢⍵:'Missing operand'⎕SIGNAL 11
            c='→':(≥/2↑⍵),2↓⍵
            ((⍎c)/2↑⍵),2↓⍵
        }⍺)∇rst
    }
    _←(nvar/0) eval order
    confs←⍉(nvar/2)⊤¯1+⍳2*nvar
    tab←'FT│'[1+(confs,2),{⍵ eval order}¨↓confs]
    tab←↑,/ ' ',¨tab
    hdr←((∊,/(' ',¨vars),' '),[0.5]'─'),⍪'│┼'
    hdr←hdr,(' ',⍵,' '),[0.5]'─'
    hdr⍪(,∘' '⍣(⊃⊃-/1↓¨⍴¨hdr tab))tab
}


Disp sin(43)▶Dec,i
Disp cos(43)▶Dec,i
Disp tan⁻¹(10,10)▶Dec,i


' Trigonometric functions in BaCon use Radians for input values
' The RAD() function converts from degrees to radians

FOR v$ IN "0, 10, 45, 90, 190.5"
    d = VAL(v$) * 1.0
    r = RAD(d) * 1.0

    PRINT "Sine: ", d, " degrees (or ", r, " radians) is ", SIN(r)
    PRINT "Cosine: ", d, " degrees (or ", r, " radians) is ", COS(r)
    PRINT "Tangent: ", d, " degrees (or ", r, " radians) is ", TAN(r)
    PRINT
    PRINT "Arc Sine: ", SIN(r), " is ", DEG(ASIN(SIN(r))), " degrees (or ", ASIN(SIN(r)), " radians)"
    PRINT "Arc CoSine: ", COS(r), " is ", DEG(ACOS(COS(r))), " degrees (or ", ACOS(COS(r)), " radians)"
    PRINT "Arc Tangent: ", TAN(r), " is ", DEG(ATN(TAN(r))), " degrees (or ", ATN(TAN(r)), " radians)"
    PRINT
NEXT


import Data.List (permutations)

topswops :: Int -> Int
topswops n = maximum $ map tops $ permutations [1 .. n]
  where
    tops (1:_) = 0
    tops xa@(x:_) = 1 + tops reordered
      where
        reordered = reverse (take x xa) ++ drop x xa

main =
  mapM_ (putStrLn . ((++) <$> show <*> (":\t" ++) . show . topswops)) [1 .. 10]


procedure main()
    every n := 1 to 10 do {
        ts := 0
        every (ts := 0) <:= swop(permute([: 1 to n :]))
        write(right(n, 3),": ",right(ts,4))
        }
end

procedure swop(A)
    count := 0
    while A[1] ~= 1 do {
        A := reverse(A[1+:A[1]]) ||| A[(A[1]+1):0]
        count +:= 1
        }
    return count
end

procedure permute(A)
    if *A <= 1 then return A
    suspend [(A[1]<->A[i := 1 to *A])] ||| permute(A[2:0])
end


#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define TRUE 1
#define FALSE 0
#define STACK_SIZE 80
#define BUFFER_SIZE 100

typedef int bool;

typedef struct {
    char name;
    bool val;
} var;

typedef struct {
    int top;
    bool els[STACK_SIZE];
} stack_of_bool;

char expr[BUFFER_SIZE];
int expr_len;
var vars[24];
int vars_len;

/* stack manipulation functions */

bool is_full(stack_of_bool *sp) {
    return sp->top == STACK_SIZE - 1;
}

bool is_empty(stack_of_bool *sp) {
    return sp->top == -1;
}

bool peek(stack_of_bool *sp) {
    if (!is_empty(sp))
        return sp->els[sp->top];
    else {
        printf("Stack is empty.\n");
        exit(1);
    }
}

void push(stack_of_bool *sp, bool val) {
    if (!is_full(sp)) {
        sp->els[++(sp->top)] = val;
    }
    else {
        printf("Stack is full.\n");
        exit(1);
    }
}

bool pop(stack_of_bool *sp) {
    if (!is_empty(sp))
        return sp->els[(sp->top)--];
    else {
        printf("\nStack is empty.\n");
        exit(1);
    }
}

void make_empty(stack_of_bool *sp) {
    sp->top = -1;
}

int elems_count(stack_of_bool *sp) {
    return (sp->top) + 1;
}

bool is_operator(const char c) {
   return c == '&' || c == '|' || c == '!' || c == '^';
}

int vars_index(const char c) {
   int i;
   for (i = 0; i < vars_len; ++i) {
       if (vars[i].name == c) return i;
   }
   return -1;
}

bool eval_expr() {
    int i, vi;
    char e;
    stack_of_bool s;
    stack_of_bool *sp = &s;
    make_empty(sp);
    for (i = 0; i < expr_len; ++i) {
        e = expr[i];
        if (e == 'T')
            push(sp, TRUE);
        else if (e == 'F')
            push(sp, FALSE);
        else if((vi = vars_index(e)) >= 0) {
            push(sp, vars[vi].val);
        }
        else switch(e) {
            case '&':
                push(sp, pop(sp) & pop(sp));
                break;
            case '|':
                push(sp, pop(sp) | pop(sp));
                break;
            case '!':
                push(sp, !pop(sp));
                break;
            case '^':
                push(sp, pop(sp) ^ pop(sp));
                break;
            default:
                printf("\nNon-conformant character '%c' in expression.\n", e);
                exit(1);
        }
    }
    if (elems_count(sp) != 1) {
        printf("\nStack should contain exactly one element.\n");
        exit(1);
    }
    return peek(sp);
}

void set_vars(int pos) {
    int i;
    if (pos > vars_len) {
        printf("\nArgument to set_vars can't be greater than the number of variables.\n");
        exit(1);
    }
    else if (pos == vars_len) {
        for (i = 0; i < vars_len; ++i) {
            printf((vars[i].val) ? "T  " : "F  ");
        }
        printf("%c\n", (eval_expr()) ? 'T' : 'F');
    }
    else {
        vars[pos].val = FALSE;
        set_vars(pos + 1);
        vars[pos].val = TRUE;
        set_vars(pos + 1);
    }
}

/* removes whitespace and converts to upper case */
void process_expr() {
    int i, count = 0;
    for (i = 0; expr[i]; ++i) {
        if (!isspace(expr[i])) expr[count++] = toupper(expr[i]);
    }
    expr[count] = '\0';
}

int main() {
    int i, h;
    char e;
    printf("Accepts single-character variables (except for 'T' and 'F',\n");
    printf("which specify explicit true or false values), postfix, with\n");
    printf("&|!^ for and, or, not, xor, respectively; optionally\n");
    printf("seperated by whitespace. Just enter nothing to quit.\n");

    while (TRUE) {
        printf("\nBoolean expression: ");
        fgets(expr, BUFFER_SIZE, stdin);
        fflush(stdin);
        process_expr();
        expr_len = strlen(expr);
        if (expr_len == 0) break;
        vars_len = 0;
        for (i = 0; i < expr_len; ++i) {
            e = expr[i];
            if (!is_operator(e) && e != 'T' && e != 'F' && vars_index(e) == -1) {
                vars[vars_len].name = e;
                vars[vars_len].val = FALSE;
                vars_len++;
            }
        }
        printf("\n");
        if (vars_len == 0) {
            printf("No variables were entered.\n");
        }
        else {
            for (i = 0; i < vars_len; ++i)
                printf("%c  ", vars[i].name);
            printf("%s\n", expr);
            h = vars_len * 3 + expr_len;
            for (i = 0; i < h; ++i) printf("=");
            printf("\n");
            set_vars(0);
        }
    }
    return 0;
}


pi = 3.141592653589793#
radians = pi / 4 'a.k.a. 45 degrees
degrees = 45 * pi / 180 'convert 45 degrees to radians once
PRINT SIN(radians) + " " + SIN(degrees) 'sine
PRINT COS(radians) + " " + COS(degrees) 'cosine
PRINT TAN(radians) + " " + TAN (degrees) 'tangent
'arcsin
thesin = SIN(radians)
arcsin = ATN(thesin / SQR(1 - thesin ^ 2))
PRINT arcsin + " " + arcsin * 180 / pi
'arccos
thecos = COS(radians)
arccos = 2 * ATN(SQR(1 - thecos ^ 2) / (1 + thecos))
PRINT arccos + " " + arccos * 180 / pi
PRINT ATN(TAN(radians)) + " " + ATN(TAN(radians)) * 180 / pi 'arctan


swops =:  ((|[email protected]:{. , }.)~ {.)^:a:


public class Topswops {
    static final int maxBest = 32;
    static int[] best;

    static private void trySwaps(int[] deck, int f, int d, int n) {
        if (d > best[n])
            best[n] = d;

        for (int i = n - 1; i >= 0; i--) {
            if (deck[i] == -1 || deck[i] == i)
                break;
            if (d + best[i] <= best[n])
                return;
        }

        int[] deck2 = deck.clone();
        for (int i = 1; i < n; i++) {
            final int k = 1 << i;
            if (deck2[i] == -1) {
                if ((f & k) != 0)
                    continue;
            } else if (deck2[i] != i)
                continue;

            deck2[0] = i;
            for (int j = i - 1; j >= 0; j--)
                deck2[i - j] = deck[j]; // Reverse copy.
            trySwaps(deck2, f | k, d + 1, n);
        }
    }

    static int topswops(int n) {
        assert(n > 0 && n < maxBest);
        best[n] = 0;
        int[] deck0 = new int[n + 1];
        for (int i = 1; i < n; i++)
            deck0[i] = -1;
        trySwaps(deck0, 1, 0, n);
        return best[n];
    }

    public static void main(String[] args) {
        best = new int[maxBest];
        for (int i = 1; i < 11; i++)
            System.out.println(i + ": " + topswops(i));
    }
}


#include <iostream>
#include <stack>
#include <string>
#include <sstream>
#include <vector>

struct var {
    char name;
    bool value;
};
std::vector<var> vars;

template<typename T>
T pop(std::stack<T> &s) {
    auto v = s.top();
    s.pop();
    return v;
}

bool is_operator(char c) {
    return c == '&' || c == '|' || c == '!' || c == '^';
}

bool eval_expr(const std::string &expr) {
    std::stack<bool> sob;
    for (auto e : expr) {
        if (e == 'T') {
            sob.push(true);
        } else if (e == 'F') {
            sob.push(false);
        } else {
           auto it = std::find_if(vars.cbegin(), vars.cend(), [e](const var &v) { return v.name == e; });
           if (it != vars.cend()) {
               sob.push(it->value);
           } else {
               int before = sob.size();
               switch (e) {
               case '&':
                   sob.push(pop(sob) & pop(sob));
                   break;
               case '|':
                   sob.push(pop(sob) | pop(sob));
                   break;
               case '!':
                   sob.push(!pop(sob));
                   break;
               case '^':
                   sob.push(pop(sob) ^ pop(sob));
                   break;
               default:
                   throw std::exception("Non-conformant character in expression.");
               }
           }
        }
    }
    if (sob.size() != 1) {
        throw std::exception("Stack should contain exactly one element.");
    }
    return sob.top();
}

void set_vars(int pos, const std::string &expr) {
    if (pos > vars.size()) {
        throw std::exception("Argument to set_vars can't be greater than the number of variables.");
    }
    if (pos == vars.size()) {
        for (auto &v : vars) {
            std::cout << (v.value ? "T  " : "F  ");
        }
        std::cout << (eval_expr(expr) ? 'T' : 'F') << '\n'; //todo implement evaluation
    } else {
        vars[pos].value = false;
        set_vars(pos + 1, expr);
        vars[pos].value = true;
        set_vars(pos + 1, expr);
    }
}

/* removes whitespace and converts to upper case */
std::string process_expr(const std::string &src) {
    std::stringstream expr;

    for (auto c : src) {
        if (!isspace(c)) {
            expr << (char)toupper(c);
        }
    }

    return expr.str();
}

int main() {
    std::cout << "Accepts single-character variables (except for 'T' and 'F',\n";
    std::cout << "which specify explicit true or false values), postfix, with\n";
    std::cout << "&|!^ for and, or, not, xor, respectively; optionally\n";
    std::cout << "seperated by whitespace. Just enter nothing to quit.\n";

    while (true) {
        std::cout << "\nBoolean expression: ";

        std::string input;
        std::getline(std::cin, input);

        auto expr = process_expr(input);
        if (expr.length() == 0) {
            break;
        }

        vars.clear();
        for (auto e : expr) {
            if (!is_operator(e) && e != 'T' && e != 'F') {
                vars.push_back({ e, false });
            }
        }
        std::cout << '\n';
        if (vars.size() == 0) {
            std::cout << "No variables were entered.\n";
        } else {
            for (auto &v : vars) {
                std::cout << v.name << "  ";
            }
            std::cout << expr << '\n';

            auto h = vars.size() * 3 + expr.length();
            for (size_t i = 0; i < h; i++) {
                std::cout << '=';
            }
            std::cout << '\n';

            set_vars(0, expr);
        }
    }

    return 0;
}


/* t(x) = tangent of x */
define t(x) {
	return s(x) / c(x)
}

/* y(y) = arcsine of y, domain [-1, 1], range [-pi/2, pi/2] */
define y(y) {
	/* Handle angles with no tangent. */
	if (y == -1) return -2 * a(1)  /* -pi/2 */
	if (y == 1) return 2 * a(1)    /* pi/2 */

	/* Tangent of angle is y / x, where x^2 + y^2 = 1. */
	return a(y / sqrt(1 - y * y))
}

/* x(x) = arccosine of x, domain [-1, 1], range [0, pi] */
define x(x) {
	auto a

	/* Handle angle with no tangent. */
	if (x == 0) return 2 * a(1)  /* pi/2 */

	/* Tangent of angle is y / x, where x^2 + y^2 = 1. */
	a = a(sqrt(1 - x * x) / x)
	if (a < 0) {
		return a + 4 * a(1)  /* add pi */
	} else {
		return a
	}
}

scale = 50
p = 4 * a(1)  /* pi */
d = p / 180   /* one degree in radians */

"Using radians:
"
"  sin(-pi / 6) = "; s(-p / 6)
"  cos(3 * pi / 4) = "; c(3 * p / 4)
"  tan(pi / 3) = "; t(p / 3)
"  asin(-1 / 2) = "; y(-1 / 2)
"  acos(-sqrt(2) / 2) = "; x(-sqrt(2) / 2)
"  atan(sqrt(3)) = "; a(sqrt(3))

"Using degrees:
"
"  sin(-30) = "; s(-30 * d)
"  cos(135) = "; c(135 * d)
"  tan(60) = "; t(60 * d)
"  asin(-1 / 2) = "; y(-1 / 2) / d
"  acos(-sqrt(2) / 2) = "; x(-sqrt(2) / 2) / d
"  atan(sqrt(3)) = "; a(sqrt(3)) / d

quit


# "while" as defined here is included in recent versions (>1.4) of jq:
def until(cond; next):
  def _until:
    if cond then . else (next|_until) end;
  _until;

# Generate a stream of permutations of [1, ... n].
# This implementation uses arity-0 filters for speed.
def permutations:
  # Given a single array, insert generates a stream by inserting (length+1) at different positions
  def insert: # state: [m, array]
     .[0] as $m | (1+(.[1]|length)) as $n
     | .[1]
     | if $m >= 0 then (.[0:$m] + [$n] + .[$m:]), ([$m-1, .] | insert) else empty end;

  if .==0 then []
  elif . == 1 then [1]
  else
    . as $n | ($n-1) | permutations | [$n-1, .] | insert
  end;


function fannkuch(n)
	n == 1 && return 0
	n == 2 && return 1
	p = [1:n]
	q = copy(p)
	s = copy(p)
	sign = 1; maxflips = sum = 0
	while true
		q0 = p[1]
		if q0 != 1
			for i = 2:n
				q[i] = p[i]
			end
			flips = 1
			while true
				qq = q[q0] #??
				if qq == 1
					sum += sign*flips
					flips > maxflips && (maxflips = flips)
					break
				end
				q[q0] = q0
				if q0 >= 4
					i = 2; j = q0-1
					while true
						t = q[i]
						q[i] = q[j]
						q[j] = t
						i += 1
						j -= 1
						i >= j && break
					end
				end
				q0 = qq
				flips += 1
			end
		end
		#permute
		if sign == 1
			t = p[2]
			p[2] = p[1]
			p[1] = t
			sign = -1
		else
			t = p[2]
			p[2] = p[3]
			p[3] = t
			sign = 1
			for i = 3:n
				sx = s[i]
				if sx != 1
					s[i] = sx-1
					break
				end
				i == n && return maxflips
				s[i] = i
				t = p[1]
				for j = 1:i
					p[j] = p[j+1]
				end
				p[i+1] = t
			end
		end
	end
end


// version 1.1.2

val best = IntArray(32)

fun trySwaps(deck: IntArray, f: Int, d: Int, n: Int) {
    if (d > best[n]) best[n] = d
    for (i in n - 1 downTo 0) {
        if (deck[i] == -1 || deck[i] == i) break
        if (d + best[i] <= best[n]) return
    }
    val deck2 = deck.copyOf()
    for (i in 1 until n) {
        val k = 1 shl i
        if (deck2[i] == -1) {
            if ((f and k) != 0) continue
        }
        else if (deck2[i] != i) continue
        deck2[0] = i
        for (j in i - 1 downTo 0) deck2[i - j] = deck[j]
        trySwaps(deck2, f or k, d + 1, n)
    }
}

fun topswops(n: Int): Int {
    require(n > 0 && n < best.size)
    best[n] = 0
    val deck0 = IntArray(n + 1)
    for (i in 1 until n) deck0[i] = -1
    trySwaps(deck0, 1, 0, n)
    return best[n]
}

fun main(args: Array<String>) {
    for (i in 1..10) println("${"%2d".format(i)} : ${topswops(i)}")
}


using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

public class TruthTable
{
    enum TokenType { Unknown, WhiteSpace, Constant, Operand, Operator, LeftParenthesis, RightParenthesis }

    readonly char trueConstant, falseConstant;
    readonly IDictionary<char, Operator> operators = new Dictionary<char, Operator>();

    public TruthTable(char falseConstant, char trueConstant)
    {
        this.trueConstant = trueConstant;
        this.falseConstant = falseConstant;
        Operators = new OperatorCollection(operators);
    }

    public OperatorCollection Operators { get; }

    public void PrintTruthTable(string expression, bool isPostfix = false)
    {
        try {
            foreach (string line in GetTruthTable(expression, isPostfix)) {
                Console.WriteLine(line);
            }
        } catch (ArgumentException ex) {
            Console.WriteLine(expression + "   " + ex.Message);
        }
    }

    public IEnumerable<string> GetTruthTable(string expression, bool isPostfix = false)
    {
        if (string.IsNullOrWhiteSpace(expression)) throw new ArgumentException("Invalid expression.");
        //Maps parameters to an index in BitSet
        //Makes sure they appear in the truth table in the order they first appear in the expression
        var parameters = expression
            .Where(c => TypeOf(c) == TokenType.Operand)
            .Distinct()
            .Reverse()
            .Select((c, i) => (symbol: c, index: i))
            .ToDictionary(p => p.symbol, p => p.index);

        int count = parameters.Count;
        if (count > 32) throw new ArgumentException("Cannot have more than 32 parameters.");
        string header = count == 0 ? expression : string.Join(" ",
            parameters.OrderByDescending(p => p.Value).Select(p => p.Key)) + " " + expression;

        if (!isPostfix) expression = ConvertToPostfix(expression);

        var values = default(BitSet);
        var stack = new Stack<char>(expression.Length);
        for (int loop = 1 << count; loop > 0; loop--) {
            foreach (char token in expression) stack.Push(token);
            bool result = Evaluate(stack, values, parameters);
            if (header != null) {
                if (stack.Count > 0) throw new ArgumentException("Invalid expression.");
                yield return header;
                header = null;
            }
            string line = (count == 0 ? "" : " ") + (result ? trueConstant : falseConstant);
            line = string.Join(" ", Enumerable.Range(0, count)
                .Select(i => values[count - i - 1] ? trueConstant : falseConstant)) + line;
            yield return line;
            values++;
        }
    }

    public string ConvertToPostfix(string infix)
    {
        var stack = new Stack<char>();
        var postfix = new StringBuilder();
        foreach (char c in infix) {
            switch (TypeOf(c)) {
            case TokenType.WhiteSpace:
                continue;
            case TokenType.Constant:
            case TokenType.Operand:
                postfix.Append(c);
                break;
            case TokenType.Operator:
                int precedence = Precedence(c);
                while (stack.Count > 0 && Precedence(stack.Peek()) > precedence) {
                    postfix.Append(stack.Pop());
                }
                stack.Push(c);
                break;
            case TokenType.LeftParenthesis:
                stack.Push(c);
                break;
            case TokenType.RightParenthesis:
                char top = default(char);
                while (stack.Count > 0) {
                    top = stack.Pop();
                    if (top == '(') break;
                    else postfix.Append(top);
                }
                if (top != '(') throw new ArgumentException("No matching left parenthesis.");
                break;
            default:
                throw new ArgumentException("Invalid character: " + c);
            }
        }
        while (stack.Count > 0) {
            char top = stack.Pop();
            if (top == '(') throw new ArgumentException("No matching right parenthesis.");
            postfix.Append(top);
        }
        return postfix.ToString();
    }

    private bool Evaluate(Stack<char> expression, BitSet values, IDictionary<char, int> parameters)
    {
        if (expression.Count == 0) throw new ArgumentException("Invalid expression.");
        char c = expression.Pop();
        TokenType type = TypeOf(c);
        while (type == TokenType.WhiteSpace) type = TypeOf(c = expression.Pop());
        switch (type) {
        case TokenType.Constant:
            return c == trueConstant;
        case TokenType.Operand:
            return values[parameters[c]];
        case TokenType.Operator:
            bool right = Evaluate(expression, values, parameters);
            Operator op = operators[c];
            if (op.Arity == 1) return op.Function(right, right);
            bool left = Evaluate(expression, values, parameters);
            return op.Function(left, right);
        default:
            throw new ArgumentException("Invalid character: " + c);
        }
    }

    private TokenType TypeOf(char c)
    {
        if (char.IsWhiteSpace(c)) return TokenType.WhiteSpace;
        if (c == '(') return TokenType.LeftParenthesis;
        if (c == ')') return TokenType.RightParenthesis;
        if (c == trueConstant || c == falseConstant) return TokenType.Constant;
        if (operators.ContainsKey(c)) return TokenType.Operator;
        if (char.IsLetter(c)) return TokenType.Operand;
        return TokenType.Unknown;
    }

    private int Precedence(char op) => operators.TryGetValue(op, out var o) ? o.Precedence : int.MinValue;
}

struct Operator
{
    public Operator(char symbol, int precedence, Func<bool, bool> function) : this(symbol, precedence, 1, (l, r) => function(r)) { }

    public Operator(char symbol, int precedence, Func<bool, bool, bool> function) : this(symbol, precedence, 2, function) { }

    private Operator(char symbol, int precedence, int arity, Func<bool, bool, bool> function) : this()
    {
        Symbol = symbol;
        Precedence = precedence;
        Arity = arity;
        Function = function;
    }

    public char Symbol { get; }
    public int Precedence { get; }
    public int Arity { get; }
    public Func<bool, bool, bool> Function { get; }
}

public class OperatorCollection : IEnumerable
{
    readonly IDictionary<char, Operator> operators;

    internal OperatorCollection(IDictionary<char, Operator> operators) {
        this.operators = operators;
    }

    public void Add(char symbol, int precedence, Func<bool, bool> function)
        => operators[symbol] = new Operator(symbol, precedence, function);
    public void Add(char symbol, int precedence, Func<bool, bool, bool> function)
        => operators[symbol] = new Operator(symbol, precedence, function);

    public void Remove(char symbol) => operators.Remove(symbol);

    IEnumerator IEnumerable.GetEnumerator() => operators.Values.GetEnumerator();
}

struct BitSet
{
    private int bits;

    private BitSet(int bits) { this.bits = bits; }

    public static BitSet operator ++(BitSet bitSet) => new BitSet(bitSet.bits + 1);

    public bool this[int index] => (bits & (1 << index)) != 0;
}

class Program
{
    public static void Main() {
        TruthTable tt = new TruthTable('F', 'T') {
            Operators = {
                { '!', 6, r => !r },
                { '&', 5, (l, r) => l && r },
                { '^', 4, (l, r) => l ^ r },
                { '|', 3, (l, r) => l || r }
            }
        };
        //Add a crazy operator:
        var rng = new Random();
        tt.Operators.Add('?', 6, r => rng.NextDouble() < 0.5);
        string[] expressions = {
            "!!!T",
            "?T",
            "F & x | T",
            "F & (x | T",
            "F & x | T)",
            "a ! (a & a)",
            "a | (a * a)",
            "a ^ T & (b & !c)",
        };
        foreach (string expression in expressions) {
            tt.PrintTruthTable(expression);
            Console.WriteLine();
        }

        //Define a different language
        tt = new TruthTable('0', '1') {
            Operators = {
                { '-', 6, r => !r },
                { '^', 5, (l, r) => l && r },
                { 'v', 3, (l, r) => l || r },
                { '>', 2, (l, r) => !l || r },
                { '=', 1, (l, r) => l == r },
            }
        };
        expressions = new[] {
            "-X v 0 = X ^ 1",
            "(H > M) ^ (S > H) > (S > M)"
        };
        foreach (string expression in expressions) {
            tt.PrintTruthTable(expression);
            Console.WriteLine();
        }
    }
}


#include <math.h>
#include <stdio.h>

int main() {
  double pi = 4 * atan(1);
  /*Pi / 4 is 45 degrees. All answers should be the same.*/
  double radians = pi / 4;
  double degrees = 45.0;
  double temp;
  /*sine*/
  printf("%f %f\n", sin(radians), sin(degrees * pi / 180));
  /*cosine*/
  printf("%f %f\n", cos(radians), cos(degrees * pi / 180));
  /*tangent*/
  printf("%f %f\n", tan(radians), tan(degrees * pi / 180));
  /*arcsine*/
  temp = asin(sin(radians));
  printf("%f %f\n", temp, temp * 180 / pi);
  /*arccosine*/
  temp = acos(cos(radians));
  printf("%f %f\n", temp, temp * 180 / pi);
  /*arctangent*/
  temp = atan(tan(radians));
  printf("%f %f\n", temp, temp * 180 / pi);

  return 0;
}


-- Return an iterator to produce every permutation of list
function permute (list)
    local function perm (list, n)
        if n == 0 then coroutine.yield(list) end
        for i = 1, n do
            list[i], list[n] = list[n], list[i]
            perm(list, n - 1)
            list[i], list[n] = list[n], list[i]
        end
    end
    return coroutine.wrap(function() perm(list, #list) end)
end

-- Perform one topswop round on table t
function swap (t)
    local new, limit = {}, t[1]
    for i = 1, #t do
        if i <= limit then
            new[i] = t[limit - i + 1]
        else
            new[i] = t[i]
        end
    end
    return new
end

-- Find the most swaps needed for any starting permutation of n cards
function topswops (n)
    local numTab, highest, count = {}, 0
    for i = 1, n do numTab[i] = i end
    for numList in permute(numTab) do
        count = 0
        while numList[1] ~= 1 do
            numList = swap(numList)
            count = count + 1
        end
        if count > highest then highest = count end
    end
    return highest
end

-- Main procedure
for i = 1, 10 do print(i, topswops(i)) end


flip[a_] := Block[{a1 = [email protected]}, If[a1 == [email protected], Reverse[a], Join[Reverse[a[[;; a1]]], a[[a1 + 1 ;;]]]]]
swaps[a_] := [email protected][flip, a] - 2
Print[#, ": ", Max[swaps /@ Permutations[[email protected]#]]] & /@ Range[10];


 (ns clojure-sandbox.truthtables
  (:require [clojure.string :as s]
            [clojure.pprint :as pprint]))

;; Definitions of the logical operators
(defn !op [expr]
  (not expr))

(defn |op [e1 e2]
  (not (and (not e1)
            (not e2))))

(defn &op [e1 e2]
  (and e1 e2))

(defn ->op [e1 e2]
  (if e1
    e2
    true))

(def operators {"!" !op
                "|" |op
                "&" &op
                "->" ->op})

;; The evaluations of expressions always call the value method on sub-expressions
(defn evaluate-unary [operator operand valuemap]
  (let [operand-value (value operand valuemap)
        operator (get operators operator)]
    (operator operand-value)))

(defn evaluate-binary [o1 op o2 valuemap]
  (let [op1-value (value o1 valuemap)
        op2-value (value o2 valuemap)
        operator (get operators op)]
    (operator op1-value op2-value)))

;; Protocol to handle all kinds of expressions : unary (!x), binary (x & y), symbolic (x)
(defprotocol Expression
  (value [_ valuemap] "Returns boolean value of expression")) ;; this value map specifies the variables' truth values

(defrecord UnaryExpression [operator operand]
  Expression
  (value [self valuemap] (evaluate-unary operator operand valuemap)))

(defrecord BinaryExpression [op1 operator op2]
  Expression
  (value [self valuemap] (evaluate-binary op1 operator op2 valuemap)))

(defrecord SymbolExpression [operand]
  Expression
  (value [self valuemap] (get valuemap operand)))

;; Recursively create the right kind of boolean expression, evaluating from the right
(defn expression [inputs]
  (if (contains? operators (first inputs))
    (->UnaryExpression (first inputs) (expression (rest inputs)))
    (if (= 1 (count inputs))
      (->SymbolExpression (first inputs))
      (->BinaryExpression (->SymbolExpression (first inputs)) (nth inputs 1) (expression (nthrest inputs (- (count inputs) 1)))))))

;; This won't handle brackets, so it is all evaluated right to left
(defn parse [input-str]
  (-> input-str
      s/trim ;; remove leading/trailing space
      (s/split #"\s+"))) ;;remove intermediate spaces

(defn extract-var-names [inputs]
  "Get a list of variables that can have truth value"
  (->> inputs
       (filter (fn[i] (not (contains? operators i))))
       set))

(defn all-var-values [inputs]
  "Returns a list of all potential variable assignments"
  (let [vars (extract-var-names inputs)]
    (loop [vars-left vars
           outputs []]
      (if (empty? vars-left)
        outputs
        (let [this-var (first vars-left)]
          (if (empty? outputs)
            (recur (rest vars-left) [{this-var true} {this-var false}])
            (recur (rest vars-left)
                   (concat (map (fn[x] (assoc x this-var true)) outputs)
                           (map (fn[x] (assoc x this-var false)) outputs)))))))))

(defn truth-table [input]
  "Print out the truth table for an input string"
  (let [input-values (parse input)
        value-maps (all-var-values input-values)
        expression (expression input-values)]
    (value expression (first value-maps))
    (->> value-maps
         (map (fn [x] (assoc x input (value expression x))))
         pprint/print-table)))

(truth-table "! a | b") ;; interpreted as ! (a | b)


using System;

namespace RosettaCode {
    class Program {
        static void Main(string[] args) {
            Console.WriteLine("=== radians ===");
            Console.WriteLine("sin (pi/3) = {0}", Math.Sin(Math.PI / 3));
            Console.WriteLine("cos (pi/3) = {0}", Math.Cos(Math.PI / 3));
            Console.WriteLine("tan (pi/3) = {0}", Math.Tan(Math.PI / 3));
            Console.WriteLine("arcsin (1/2) = {0}", Math.Asin(0.5));
            Console.WriteLine("arccos (1/2) = {0}", Math.Acos(0.5));
            Console.WriteLine("arctan (1/2) = {0}", Math.Atan(0.5));
            Console.WriteLine("");
            Console.WriteLine("=== degrees ===");
            Console.WriteLine("sin (60) = {0}", Math.Sin(60 * Math.PI / 180));
            Console.WriteLine("cos (60) = {0}", Math.Cos(60 * Math.PI / 180));
            Console.WriteLine("tan (60) = {0}", Math.Tan(60 * Math.PI / 180));
            Console.WriteLine("arcsin (1/2) = {0}", Math.Asin(0.5) * 180/ Math.PI);
            Console.WriteLine("arccos (1/2) = {0}", Math.Acos(0.5) * 180 / Math.PI);
            Console.WriteLine("arctan (1/2) = {0}", Math.Atan(0.5) * 180 / Math.PI);

            Console.ReadLine();
        }
    }
}


import strformat

const maxBest = 32
var best: array[maxBest, int]

proc trySwaps(deck: seq[int], f, d, n: int) =
  if d > best[n]:
    best[n] = d

  for i in countdown(n - 1, 0):
    if deck[i] == -1 or deck[i] == i:
      break
    if d + best[i] <= best[n]:
      return

  var deck2 = deck
  for i in 1..<n:
    var k = 1 shl i
    if deck2[i] == -1:
      if (f and k) != 0:
        continue
    elif deck2[i] != i:
      continue

    deck2[0] = i
    for j in countdown(i - 1, 0):
      deck2[i - j] = deck[j]
    trySwaps(deck2, f or k, d + 1, n)

proc topswops(n: int): int =
  assert(n > 0 and n < maxBest)
  best[n] = 0
  var deck0 = newSeq[int](n + 1)
  for i in 1..<n:
    deck0[i] = -1
  trySwaps(deck0, 1, 0, n)
  best[n]

for i in 1..10:
  echo &"{i:2}: {topswops(i):2}"


flip(v:vec)={
  my(t=v[1]+1);
  if (t==2, return(0));
  for(i=1,t\2, [v[t-i],v[i]]=[v[i],v[t-i]]);
  1+flip(v)
}
topswops(n)={
  my(mx);
  for(i=0,n!-1,
    mx=max(flip(Vecsmall(numtoperm(n,i))),mx)
  );
  mx;
}
vector(10,n,topswops(n))


sub next_swop {
  my( $max, $level, $p, $d ) = @_;
  my $swopped = 0;
  for( 2..@$p ){ # find possibilities
    my @now = @$p;
    if( $_ == $now[$_-1] ) {
      splice @now, 0, 0, reverse splice @now, 0, $_;
      $swopped = 1;
      next_swop( $max, $level+1, \@now, [ @$d ] );
    }
  }
  for( 1..@$d ) { # create possibilities
    my @now = @$p;
    my $next = shift @$d;
    if( not $now[$next-1] ) {
      $now[$next-1] = $next;
      splice @now, 0, 0, reverse splice @now, 0, $next;
      $swopped = 1;
      next_swop( $max, $level+1, \@now, [ @$d ] );
    }
    push @$d, $next;
  }
  $$max = $level if !$swopped and $level > $$max;
}

sub topswops {
  my $n = shift;
  my @d = 2..$n;
  my @p = ( 1, (0) x ($n-1) );
  my $max = 0;
  next_swop( \$max, 0, \@p, \@d );
  return $max;
}

printf "Maximum swops for %2d cards: %2d\n", $_, topswops $_ for 1..10;


# Truth table generator in Cowgol
# -
# This program will generate a truth table for the Boolean expression
# given on the command line.
#
# The expression is in infix notation, and operator precedence is impemented,
# i.e., the following expression:
#       A & B | C & D => E
# is parsed as:
#       ((A & B) | (C & D)) => E.
#
# Syntax:
#   * Variables are single letters (A-Z). They are case-insensitive.
#   * 0 and 1 can be used as constant true or false.
#   * Operators are ~ (not), & (and), | (or), ^ (xor), and => (implies).
#   * Parentheses may be used to override the normal precedence.

include "cowgol.coh";
include "strings.coh";
include "argv.coh";
ArgvInit();

# Concatenate all command line arguments together, skipping whitespace
var code: uint8[512];
var codeptr := &code[0];
loop
    var argmt := ArgvNext();
    if argmt == 0 as [uint8] then break; end if;
    loop
        var char := [argmt];
        argmt := @next argmt;
        if char == 0 then break;
        elseif char == ' ' then continue;
        end if;
        [codeptr] := char;
        codeptr := @next codeptr;
    end loop;
end loop;
[codeptr] := 0;

# If no code given, print an error and stop
if StrLen(&code[0]) == 0 then
    print("Error: no boolean expression given\n");
    ExitWithError();
end if;

interface TokenReader(str: [uint8]): (next: [uint8], tok: uint8);

# Operators
interface OpFn(l: uint8, r: uint8): (v: uint8);
sub And  implements OpFn is v := l & r; end sub;
sub Or   implements OpFn is v := l | r; end sub;
sub Xor  implements OpFn is v := l ^ r; end sub;
sub Not  implements OpFn is v := ~l; end sub;
sub Impl implements OpFn is
    if l == 0 then v := 1;
    else v := r;
    end if;
end sub;
record Operator is
    fn: OpFn;
    name: [uint8];
    val: uint8;
    prec: uint8;
end record;
var ops: Operator[] := {
    {Not,  "~",  1, 5},
    {And,  "&",  2, 4},
    {Or,   "|",  2, 3},
    {Xor,  "^",  2, 3},
    {Impl, "=>", 2, 2}
};

const TOKEN_MASK := (1<<5)-1;
const TOKEN_OP := 1<<5;
sub ReadOp implements TokenReader is
    tok := 0;
    next := str;
    while tok < @sizeof ops loop
        var find := ops[tok].name;
        while [find] == [next] loop
            next := @next next;
            find := @next find;
        end loop;
        if [find] == 0 then
            tok := tok | TOKEN_OP;
            return;
        end if;
        next := str;
        tok := tok + 1;
    end loop;
    tok := 0;
end sub;

# Values (constants, variables)
const TOKEN_VAR := 2<<5;
const TOKEN_CONST := 3<<5;
const CONST_TRUE := 0;
const CONST_FALSE := 1;
sub ReadValue implements TokenReader is
    var cur := [str];
    next := str;
    tok := 0;
    if cur == '0' or cur == '1' then
        next := @next str;
        tok := TOKEN_CONST | cur - '0';
    elseif (cur >= 'A' and cur <= 'Z') or (cur >= 'a' and cur <= 'z') then
        next := @next str;
        tok := TOKEN_VAR | (cur | 32) - 'a';
    end if;
end sub;

# Parentheses
const TOKEN_PAR := 4<<5;
const PAR_OPEN := 0;
const PAR_CLOSE := 1;
sub ReadParen implements TokenReader is
    case [str] is
        when '(': next := @next str; tok := TOKEN_PAR | PAR_OPEN;
        when ')': next := @next str; tok := TOKEN_PAR | PAR_CLOSE;
        when else: next := str; tok := 0;
    end case;
end sub;

# Read next token
sub NextToken(str: [uint8]): (next: [uint8], tok: uint8) is
    var toks: TokenReader[] := {ReadOp, ReadValue, ReadParen};
    var i: uint8 := 0;
    while i < @sizeof toks loop
        (next, tok) := (toks[i]) (str);
        if tok != 0 then return; end if;
        i := i + 1;
    end loop;
    # Invalid token
    print("cannot tokenize: ");
    print(str);
    print_nl();
    ExitWithError();
end sub;

# Use shunting yard algorithm to parse the input
var expression: uint8[512];
var oprstack: uint8[512];
var expr_ptr := &expression[0];
var ostop := &oprstack[0];
var varmask: uint32 := 0; # mark which variables are in use
var one: uint32 := 1; # cannot shift constant by variable

sub GetOp(o: uint8): (r: [Operator]) is
    r := &ops[o];
end sub;

codeptr := &code[0];
while [codeptr] != 0 loop
    var tok: uint8;
    (codeptr, tok) := NextToken(codeptr);
    var toktype := tok & ~TOKEN_MASK;
    var tokval := tok & TOKEN_MASK;
    case toktype is
        # constants and variables get pushed to output queue
        when TOKEN_CONST:
            [expr_ptr] := tok; expr_ptr := @next expr_ptr;
        when TOKEN_VAR:
            [expr_ptr] := tok; expr_ptr := @next expr_ptr;
            varmask := varmask | one << tokval;
        # operators
        when TOKEN_OP:
            if ops[tokval].val == 1 then
                # unary operator binds immediately
                [ostop] := tok; ostop := @next ostop;
            else
                while ostop > &oprstack[0]
                and   [@prev ostop] != TOKEN_PAR|PAR_OPEN
                and   [GetOp([@prev ostop] & TOKEN_MASK)].prec
                   >= ops[tokval].prec
                loop
                    ostop := @prev ostop;
                    [expr_ptr] := [ostop];
                    expr_ptr := @next expr_ptr;
                end loop;
                [ostop] := tok;
                ostop := @next ostop;
            end if;
        # parenthesis
        when TOKEN_PAR:
            if tokval == PAR_OPEN then
                # push left parenthesis onto operator stack
                [ostop] := tok; ostop := @next ostop;
            else
                # pop whole operator stack until left parenthesis
                while ostop > &oprstack[0]
                and   [@prev ostop] != TOKEN_PAR|PAR_OPEN
                loop
                    ostop := @prev ostop;
                    [expr_ptr] := [ostop];
                    expr_ptr := @next expr_ptr;
                end loop;
                # if we run out of stack, mismatched parenthesis
                if ostop == &oprstack[0] then
                   print("Error: missing (");
                   print_nl();
                   ExitWithError();
                else
                   ostop := @prev ostop;
                end if;
            end if;
    end case;
end loop;

# push remaining operators onto expression
while ostop != &oprstack[0] loop
    ostop := @prev ostop;
    [expr_ptr] := [ostop];
    if [expr_ptr] & ~TOKEN_MASK == TOKEN_PAR then
        print("Error: missing )");
        print_nl();
        ExitWithError();
    end if;
    expr_ptr := @next expr_ptr;
end loop;

# terminate expression
[expr_ptr] := 0;

# Evaluate expression given set of variables
sub Eval(varset: uint32): (r: uint8) is
    # We can reuse the operator stack as the evaluation stack
    var ptr := &oprstack[0];
    var exp := &expression[0];
    var one: uint32 := 1;

    while [exp] != 0 loop
        var toktype := [exp] & ~TOKEN_MASK;
        var tokval := [exp] & TOKEN_MASK;
        case toktype is
            when TOKEN_CONST:
                [ptr] := tokval;
                ptr := @next ptr;
            when TOKEN_VAR:
                [ptr] := ((varset & (one << tokval)) >> tokval) as uint8;
                ptr := @next ptr;
            when TOKEN_OP:
                var op := GetOp(tokval);
                ptr := ptr - ([op].val as intptr);
                if ptr < &oprstack[0] then
                    # not enough values on the stack
                    print("Missing operand\n");
                    ExitWithError();
                end if;
                [ptr] := ([op].fn)([ptr], [@next ptr]) & 1;
                ptr := @next ptr;
            when else:
                # wrong token left in the expression
                print("invalid expression token ");
                print_hex_i8([exp]);
                print_nl();
                ExitWithError();
        end case;
        exp := @next exp;
    end loop;

    # There should be exactly one item on the stack
    ptr := @prev ptr;
    if ptr != &oprstack[0] then
        print("Too many operands\n");
        ExitWithError();
    else
        r := [ptr];
    end if;
end sub;

var v := Eval(0); # evaluate once to catch errors

# Print header and count variables
var ch: uint8 := 'A';
var vcount: uint8 := 0;
var vars := varmask;

while vars != 0 loop
    if vars & 1 != 0 then
        print_char(ch);
        print_char(' ');
        vcount := vcount + 1;
    end if;
    ch := ch + 1;
    vars := vars >> 1;
end loop;
print("| ");
print(&code[0]);
print_nl();

ch := 2 + vcount * 2 + StrLen(&code[0]) as uint8;
while ch != 0 loop
    print_char('-');
    ch := ch - 1;
end loop;
print_nl();

# Given configuration number, generate variable configuration
sub distr(val: uint32): (r: uint32) is
    var vars := varmask;
    r := 0;
    var n: uint8 := 0;
    while vars != 0 loop
        r := r >> 1;
        if vars & 1 != 0 then
            r := r | ((val & 1) << 31);
            val := val >> 1;
        end if;
        vars := vars >> 1;
        n := n + 1;
    end loop;
    r := r >> (32-n);
end sub;

vars := 0; # start with F F F F F
var bools: uint8[] := {'F', 'T'};
while vars != one << vcount loop
    var dist := distr(vars);
    var rslt := Eval(dist);

    # print configuration
    var vmask := varmask;
    while vmask != 0 loop
        if vmask & 1 != 0 then
            print_char(bools[(dist & 1) as uint8]);
            print_char(' ');
        end if;
        vmask := vmask >> 1;
        dist := dist >> 1;
    end loop;

    # print result
    print("| ");
    print_char(bools[rslt]);
    print_nl();

    # next configuration
    vars := vars + 1;
end loop;


import std.stdio, std.string, std.array, std.algorithm, std.typecons;

struct Var {
    const char name;
    bool val;
}
const string expr;
Var[] vars;

bool pop(ref bool[] arr) pure nothrow {
    const last = arr.back;
    arr.popBack;
    return last;
}

enum isOperator = (in char c) pure => "&|!^".canFind(c);

enum varsCountUntil = (in char c) nothrow =>
    .vars.map!(v => v.name).countUntil(c).Nullable!(int, -1);

bool evalExp() {
    bool[] stack;

    foreach (immutable e; .expr) {
        if (e == 'T')
            stack ~= true;
        else if (e == 'F')
            stack ~= false;
        else if (!e.varsCountUntil.isNull)
            stack ~= .vars[e.varsCountUntil.get].val;
        else switch (e) {
            case '&':
                stack ~= stack.pop & stack.pop;
                break;
            case '|':
                stack ~= stack.pop | stack.pop;
                break;
            case '!':
                stack ~= !stack.pop;
                break;
            case '^':
                stack ~= stack.pop ^ stack.pop;
                break;
            default:
                throw new Exception("Non-conformant character '" ~
                                    e ~ "' in expression.");
        }
    }

    assert(stack.length == 1);
    return stack.back;
}

void setVariables(in size_t pos)
in {
    assert(pos <= .vars.length);
} body {
    if (pos == .vars.length)
        return writefln("%-(%s %) %s",
                        .vars.map!(v => v.val ? "T" : "F"),
                        evalExp ? "T" : "F");

    .vars[pos].val = false;
    setVariables(pos + 1);
    .vars[pos].val = true;
    setVariables(pos + 1);
}

static this() {
"Accepts single-character variables (except for 'T' and 'F',
which specify explicit true or false values), postfix, with
&|!^ for and, or, not, xor, respectively; optionally
seperated by whitespace.".writeln;

    "Boolean expression: ".write;
    .expr = readln.split.join;
}

void main() {
    foreach (immutable e; expr)
        if (!e.isOperator && !"TF".canFind(e) &&
            e.varsCountUntil.isNull)
            .vars ~= Var(e);
    if (.vars.empty)
        return;

    writefln("%-(%s %) %s", .vars.map!(v => v.name), .expr);
    setVariables(0);
}


#include <iostream>
#include <cmath>

#ifdef M_PI // defined by all POSIX systems and some non-POSIX ones
double const pi = M_PI;
#else
double const pi = 4*std::atan(1);
#endif

double const degree = pi/180;

int main()
{
  std::cout << "=== radians ===\n";
  std::cout << "sin(pi/3) = " << std::sin(pi/3) << "\n";
  std::cout << "cos(pi/3) = " << std::cos(pi/3) << "\n";
  std::cout << "tan(pi/3) = " << std::tan(pi/3) << "\n";
  std::cout << "arcsin(1/2) = " << std::asin(0.5) << "\n";
  std::cout << "arccos(1/2) = " << std::acos(0.5) << "\n";
  std::cout << "arctan(1/2) = " << std::atan(0.5) << "\n";

  std::cout << "\n=== degrees ===\n";
  std::cout << "sin(60°) = " << std::sin(60*degree) << "\n";
  std::cout << "cos(60°) = " << std::cos(60*degree) << "\n";
  std::cout << "tan(60°) = " << std::tan(60*degree) << "\n";
  std::cout << "arcsin(1/2) = " << std::asin(0.5)/degree << "°\n";
  std::cout << "arccos(1/2) = " << std::acos(0.5)/degree << "°\n";
  std::cout << "arctan(1/2) = " << std::atan(0.5)/degree << "°\n";

  return 0;
}


with javascript_semantics
function fannkuch(integer n)
    sequence count = tagset(n),
             perm1 = tagset(n)
    integer maxFlipsCount = 0, r = n+1
    while true do
        while r!=1 do
            count[r-1] = r
            r -= 1
        end while
        if not (perm1[1]=1 or perm1[n]=n) then
            sequence perm = perm1
            integer flipsCount = 0,
                    k = perm[1]
            while k!=1 do
                perm = reverse(perm[1..k]) & perm[k+1..n]
                flipsCount += 1
                k = perm[1]
            end while
            if flipsCount>maxFlipsCount then
                maxFlipsCount = flipsCount
            end if
        end if
        -- Use incremental change to generate another permutation
        while true do
            if r>n then return maxFlipsCount end if
            integer perm0 = perm1[1]
            perm1[1..r-1] = perm1[2..r]
            perm1[r] = perm0
            count[r] -= 1
            if count[r]>1 then exit end if
            r += 1
        end while
    end while
end function -- fannkuch

atom t0 = time()
for i=1 to iff(platform()=JS?9:10) do
    ?fannkuch(i)
end for
?elapsed(time()-t0)


print-line lst end:
    for v in reversed copy lst:
        print\( v chr 9 )
    print end

(print-truth-table) t n func:
    if n:
        (print-truth-table) push-through copy t 0 -- n @func
        (print-truth-table) push-through copy t 1 -- n @func
    else:
        print-line t func for in copy t

print-truth-table vars name func:
    print-line vars name
    (print-truth-table) [] len vars @func
    print "" # extra new line

stu s t u:
    or s /= t u

abcd a b c d:
    /= a /= b /= c d

print-truth-table [ "A" "B" ] "A ^ B" @/=
print-truth-table [ "S" "T" "U" ] "S | (T ^ U)" @stu
print-truth-table [ "A" "B" "C" "D" ] "A ^ (B ^ (C ^ D))" @abcd


USING: arrays combinators eval formatting io kernel listener
math.combinatorics prettyprint qw sequences splitting
vocabs.parser ;
IN: rosetta-code.truth-table

: prompt ( -- str )
    "Please enter a boolean expression using 1-long" print
    "variable names and postfix notation. Available" print
    "operators are and, or, not, and xor. Example:"  print
    "> a b and"                                      print nl
    "> " write readln nl ;

: replace-var ( str -- str' )
    dup length 1 = [ drop "%s" ] when ;

: replace-vars ( str -- str' )
    " " split [ replace-var ] map " " join ;

: extract-vars ( str -- seq )
    " " split [ length 1 = ] filter ;

: count-vars ( str -- n )
    " " split [ "%s" = ] count ;

: truth-table ( n -- seq )
    qw{ t f } swap selections ;

: print-row ( seq -- )
    [ write bl ] each ;

: print-table ( seq -- )
    [ print-row nl ] each ;

! Adds a column to the end of a two-dimensional array.
: add-col ( seq col -- seq' )
    [ flip ] dip 1array append flip ;

: header ( str -- )
    [ extract-vars ] [ ] bi
    [ print-row "| " write ] [ print ] bi*
    "=================" print ;

: solve-expr ( seq str -- ? )
    vsprintf [ "kernel" use-vocab ( -- x ) (eval) ]
    with-interactive-vocabs ;

: results ( str -- seq )
    replace-vars dup count-vars truth-table
    [ swap solve-expr unparse ] with map ;

: main ( -- )
    prompt
    [ header t ]
    [ replace-vars count-vars truth-table ]
    [ results [ "| " prepend ] map ] tri
    add-col print-table drop ;

MAIN: main


(ns user
  (:require [clojure.contrib.generic.math-functions :as generic]))

;(def pi Math/PI)
(def pi (* 4 (atan 1)))
(def dtor (/ pi 180))
(def rtod (/ 180 pi))
(def radians (/ pi 4))
(def degrees 45)

(println (str (sin radians) " " (sin (* degrees dtor))))
(println (str (cos radians) " " (cos (* degrees dtor))))
(println (str (tan radians) " " (tan (* degrees dtor))))
(println (str (asin (sin radians) ) " " (* (asin (sin (* degrees dtor))) rtod)))
(println (str (acos (cos radians) ) " " (* (acos (cos (* degrees dtor))) rtod)))
(println (str (atan (tan radians) ) " " (* (atan (tan (* degrees dtor))) rtod)))


go ?=>
  member(N,1..10),
  Perm = 1..N,
  Rev = Perm.reverse(),
  Max = 0,
  while(Perm != Rev)
    next_permutation(Perm),
    C = topswops(Perm),
    if C > Max then
       Max := C
    end
  end,
  printf("%2d: %2d\n",N,Max),
  fail,
  nl.
go => true.

topswops([]) = 0 => true.
topswops([1]) = 0 => true.
topswops([1|_]) = 0 => true.
topswops(P) = Count =>
   Len = P.length,
   Count = 0,
   while (P[1] > 1)
      Pos = P[1],
      P := [P[I] : I in 1..Pos].reverse() ++ [P[I] : I in Pos+1..Len],
      Count := Count + 1
   end.

% Inline
next_permutation(Perm) =>
   N = Perm.length,
   K = N - 1,
   while (Perm[K] > Perm[K+1], K >= 0)
      K := K - 1
   end,
   if K > 0 then
      J = N,
      while (Perm[K] > Perm[J])  J := J - 1 end,
      Tmp := Perm[K],
      Perm[K] := Perm[J],
      Perm[J] := Tmp,
      R = N,
      S = K + 1,
      while (R > S)
         Tmp := Perm[R],
         Perm[R] := Perm[S],
         Perm[S] := Tmp,
         R := R - 1,
         S := S + 1
      end
   end.


(de fannkuch (N)
   (let (Lst (range 1 N)  L Lst  Max)
      (recur (L)  # Permute
         (if (cdr L)
            (do (length L)
               (recurse (cdr L))
               (rot L) )
            (zero N)  # For each permutation
            (for (P (copy Lst)  (> (car P) 1)  (flip P (car P)))
               (inc 'N) )
            (setq Max (max N Max)) ) )
      Max ) )

(for I 10
   (println I (fannkuch I)) )


(subscriptrange):
topswap: procedure options (main); /* 12 November 2013 */
   declare cards(*) fixed (2) controlled, t fixed (2);
   declare dealt(*) bit(1) controlled;
   declare (count, i, m, n, c1, c2) fixed binary;
   declare random builtin;

   do n = 1 to 10;
      allocate cards(n), dealt(n);
      /* Take the n cards, in order ... */
      do i = 1 to n; cards(i) = i; end;
      /* ... and shuffle them. */
      do i = 1 to n;
         c1 = random*n+1; c2 = random*n+1;
         t = cards(c1); cards(c1) = cards(c2); cards(c2) = t;
      end;
      /* If '1' is the first card, game is trivial; swap it with another. */
      if cards(1) = 1 & n > 1 then
         do; t = cards(1); cards(1) = cards(2); cards(2) = t; end;

      count = 0;
      do until (cards(1) = 1);
         /* take the value of the first card, M, and reverse the first M cards. */
         m = cards(1);
         do i = 1 to m/2;
            t = cards(i); cards(i) = cards(m-i+1); cards(m-i+1) = t;
         end;
         count = count + 1;
      end;
      put skip edit (n, ':', count) (f(2), a, f(4));
   end;
end topswap;


range = (a, b):
  i = 0, l = list(b-a+1)
  while (a + i <= b):
    l (i) = a + i++.
  l.

fannkuch = (n):
  flips = 0, maxf = 0, k = 0, m = n - 1, r = n
  perml = range(0, n), count = list(n), perm = list(n)

  loop:
    while (r != 1):
      count (r-1) = r
      r--.

    if (perml (0) != 0 and perml (m) != m):
      flips = 0, i = 1
      while (i < n):
        perm (i) = perml (i)
        i++.
      k = perml (0)
      loop:
        i = 1, j = k - 1
        while (i < j):
          t = perm (i), perm (i) = perm (j), perm (j) = t
          i++, j--.
        flips++
        j = perm (k), perm (k) = k, k = j
        if (k == 0): break.
      .
      if (flips > maxf): maxf = flips.
    .

    loop:
      if (r == n):
        (n, maxf) say
        return (maxf).

      i = 0, j = perml (0)
      while (i < r):
        k = i + 1
        perml (i) = perml (k)
        i = k.
      perml (r) = j

      j = count (r) - 1
      count (r) = j
      if (j > 0): break.
      r++
_ n

n = argv(1) number
if (n<1): n=10.
fannkuch(n)


>>> from itertools import permutations
>>> def f1(p):
	i = 0
	while True:
		p0  = p[0]
		if p0 == 1: break
		p[:p0] = p[:p0][::-1]
		i  += 1
	return i

>>> def fannkuch(n):
	return max(f1(list(p)) for p in permutations(range(1, n+1)))

>>> for n in range(1, 11): print(n,fannkuch(n))

1 0
2 1
3 2
4 4
5 7
6 10
7 16
8 22
9 30
10 38
>>>


package main

import (
    "bufio"
    "errors"
    "fmt"
    "go/ast"
    "go/parser"
    "go/token"
    "os"
    "reflect"
)

func main() {
    in := bufio.NewScanner(os.Stdin)
    for {
        fmt.Print("Expr:  ")
        in.Scan()
        if err := in.Err(); err != nil {
            fmt.Println(err)
            return
        }
        if !tt(in.Text()) {
            return
        }
    }
}

func tt(expr string) bool {
    // call library parser
    tree, err := parser.ParseExpr(expr)
    if err != nil {
        fmt.Println(err)
        return false
    }
    // create handy object to pass around
    e := &evaluator{nil, map[string]bool{}, tree}
    // library tree traversal function calls e.Visit for each node.
    // use this to collect variables of the expression.
    ast.Walk(e, tree)
    // print headings for truth table
    for _, n := range e.names {
        fmt.Printf("%-6s", n)
    }
    fmt.Println(" ", expr)
    // start recursive table generation function on first variable
    e.evalVar(0)
    return true
}

type evaluator struct {
    names []string        // variables, in order of appearance
    val   map[string]bool // map variables to boolean values
    tree  ast.Expr        // parsed expression as ast
}

// visitor function called by library Walk function.
// builds a list of unique variable names.
func (e *evaluator) Visit(n ast.Node) ast.Visitor {
    if id, ok := n.(*ast.Ident); ok {
        if !e.val[id.Name] {
            e.names = append(e.names, id.Name)
            e.val[id.Name] = true
        }
    }
    return e
}

// method recurses for each variable of the truth table, assigning it to
// false, then true.  At bottom of recursion, when all variables are
// assigned, it evaluates the expression and outputs one line of the
// truth table
func (e *evaluator) evalVar(nx int) bool {
    if nx == len(e.names) {
        // base case
        v, err := evalNode(e.tree, e.val)
        if err != nil {
            fmt.Println(" ", err)
            return false
        }
        // print variable values
        for _, n := range e.names {
            fmt.Printf("%-6t", e.val[n])
        }
        // print expression value
        fmt.Println(" ", v)
        return true
    }
    // recursive case
    for _, v := range []bool{false, true} {
        e.val[e.names[nx]] = v
        if !e.evalVar(nx + 1) {
            return false
        }
    }
    return true
}

// recursively evaluate ast
func evalNode(nd ast.Node, val map[string]bool) (bool, error) {
    switch n := nd.(type) {
    case *ast.Ident:
        return val[n.Name], nil
    case *ast.BinaryExpr:
        x, err := evalNode(n.X, val)
        if err != nil {
            return false, err
        }
        y, err := evalNode(n.Y, val)
        if err != nil {
            return false, err
        }
        switch n.Op {
        case token.AND:
            return x && y, nil
        case token.OR:
            return x || y, nil
        case token.XOR:
            return x != y, nil
        default:
            return unsup(n.Op)
        }
    case *ast.UnaryExpr:
        x, err := evalNode(n.X, val)
        if err != nil {
            return false, err
        }
        switch n.Op {
        case token.XOR:
            return !x, nil
        default:
            return unsup(n.Op)
        }
    case *ast.ParenExpr:
        return evalNode(n.X, val)
    }
    return unsup(reflect.TypeOf(nd))
}

func unsup(i interface{}) (bool, error) {
    return false, errors.New(fmt.Sprintf("%v unsupported", i))
}


       IDENTIFICATION DIVISION.
       PROGRAM-ID. Trig.

       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  Pi-Third   USAGE COMP-2.
       01  Degree     USAGE COMP-2.

       01  60-Degrees USAGE COMP-2.

       01  Result     USAGE COMP-2.

       PROCEDURE DIVISION.
           COMPUTE Pi-Third = FUNCTION PI / 3

           DISPLAY "Radians:"
           DISPLAY "  Sin(π / 3)  = " FUNCTION SIN(Pi-Third)
           DISPLAY "  Cos(π / 3)  = " FUNCTION COS(Pi-Third)
           DISPLAY "  Tan(π / 3)  = " FUNCTION TAN(Pi-Third)
           DISPLAY "  Asin(0.5)   = " FUNCTION ASIN(0.5)
           DISPLAY "  Acos(0.5)   = " FUNCTION ACOS(0.5)
           DISPLAY "  Atan(0.5)   = " FUNCTION ATAN(0.5)

           COMPUTE Degree = FUNCTION PI / 180
           COMPUTE 60-Degrees = Degree * 60

           DISPLAY "Degrees:"
           DISPLAY "  Sin(60°)  = " FUNCTION SIN(60-Degrees)
           DISPLAY "  Cos(60°)  = " FUNCTION COS(60-Degrees)
           DISPLAY "  Tan(60°)  = " FUNCTION TAN(60-Degrees)
           COMPUTE Result = FUNCTION ASIN(0.5) / 60
           DISPLAY "  Asin(0.5) = " Result
           COMPUTE Result = FUNCTION ACOS(0.5) / 60
           DISPLAY "  Acos(0.5) = " Result
           COMPUTE Result = FUNCTION ATAN(0.5) / 60
           DISPLAY "  Atan(0.5) = " Result

           GOBACK
           .


topswops <- function(x){
  i <- 0
  while(x[1] != 1){
    first <- x[1]
    if(first == length(x)){
      x <- rev(x)
    } else{
      x <- c(x[first:1], x[(first+1):length(x)])
    }
    i <- i + 1
  }
  return(i)
}

library(iterpc)

result <- NULL

for(i in 1:10){
  I <- iterpc(i, labels = 1:i, ordered = T)
  A <- getall(I)
  A <- data.frame(A)
  A$flips <- apply(A, 1, topswops)
  result <- rbind(result, c(i, max(A$flips)))
}


#lang racket

(define (all-misplaced? l)
  (for/and ([x (in-list l)] [n (in-naturals 1)]) (not (= x n))))

(define (topswops n)
  (for/fold ([m 0]) ([p (in-permutations (range 1 (add1 n)))]
                     #:when (all-misplaced? p))
    (let loop ([p p] [n 0])
      (if (= 1 (car p))
        (max n m)
        (loop (let loop ([l '()] [r p] [n (car p)])
                (if (zero? n) (append l r)
                    (loop (cons (car r) l) (cdr r) (sub1 n))))
              (add1 n))))))

(for ([i (in-range 1 11)]) (printf "~a\t~a\n" i (topswops i)))


sub swops(@a is copy) {
    my int $count = 0;
    until @a[0] == 1 {
        @a[ ^@a[0] ] .= reverse;
        ++$count;
    }
    $count
}

sub topswops($n) { max (1..$n).permutations.race.map: &swops }

say "$_ {topswops $_}" for 1 .. 10;


/*REXX program generates  N  decks of  numbered cards  and  finds the maximum  "swops". */
parse arg things .;          if things=='' then things= 10

      do n=1  for things;         #= decks(n, n) /*create a (things) number of "decks". */
      mx= n\==1                                  /*handle the case of a  one-card  deck.*/
                  do i=1  for #;  p= swops(!.i)  /*compute the SWOPS for this iteration.*/
                  if p>mx  then mx= p            /*This a new maximum?   Use a new max. */
                  end   /*i*/
      say '──────── maximum swops for a deck of'   right(n,2)   ' cards is'    right(mx,4)
      end   /*n*/
exit 0                                           /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
decks:  procedure expose !.; parse arg x,y,,$ @. /*   X  things  taken   Y   at a time. */
        #= 0;                call .decks 1       /* [↑]  initialize  $  &   @.  to null.*/
        return #                                 /*return number of permutations (decks)*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
.decks: procedure expose !. @. x y $ #;          parse arg ?
        if ?>y  then do;  [email protected].1;  do j=2  for y-1;  _= _ @.j;  end /*j*/;   #= #+1;  !.#=_
                     end
                else do;           qm= ? - 1
                     if ?==1  then qs= 2         /*don't use 1-swops that start with  1 */
                              else if @.1==?  then qs=2  /*skip the 1-swops: 3 x 1 x ···*/
                                              else qs=1
                         do q=qs  to x           /*build the permutations recursively.  */
                               do k=1  for qm;  if @.k==q  then iterate q
                               end  /*k*/
                         @.?=q ;                call .decks ? + 1
                         end        /*q*/
                     end
        return
/*──────────────────────────────────────────────────────────────────────────────────────*/
swops:  parse arg z;   do u=1;    parse var z t .;    if \datatype(t, 'W')  then t= x2d(t)
                       if word(z, t)==1  then return u             /*found unity at  T. */
                               do h=10  to things;    if pos(h, z)==0  then iterate
                               z= changestr(h, z, d2x(h) )         /* [↑]  any H's in Z?*/
                               end   /*h*/
                       z= reverse( subword(z, 1, t) )     subword(z, t + 1)
                       end   /*u*/


(defun deg->rad (x) (* x (/ pi 180)))
(defun rad->deg (x) (* x (/ 180 pi)))

(mapc (lambda (x) (format t "~s => ~s~%" x (eval x)))
  '((sin (/ pi 4))
    (sin (deg->rad 45))
    (cos (/ pi 6))
    (cos (deg->rad 30))
    (tan (/ pi 3))
    (tan (deg->rad 60))
    (asin 1)
    (rad->deg (asin 1))
    (acos 1/2)
    (rad->deg (acos 1/2))
    (atan 15)
    (rad->deg (atan 15))))


def f1(a)
  i = 0
  while (a0 = a[0]) > 1
    a[0...a0] = a[0...a0].reverse
    i += 1
  end
  i
end

def fannkuch(n)
  [*1..n].permutation.map{|a| f1(a)}.max
end

for n in 1..10
  puts "%2d : %d" % [n, fannkuch(n)]
end


use itertools::Itertools;

fn solve(deck: &[usize]) -> usize {
    let mut counter = 0_usize;
    let mut shuffle = deck.to_vec();
    loop {
        let p0 = shuffle[0];
        if p0 == 1 {
            break;
        }
        shuffle[..p0].reverse();
        counter += 1;
    }

    counter
}

// this is a naive method which tries all permutations and works up to ~12 cards
fn topswops(number: usize) -> usize {
    (1..=number)
        .permutations(number)
        .fold(0_usize, |mut acc, p| {
            let steps = solve(&p);
            if steps > acc {
                acc = steps;
            }
            acc
        })
}
fn main() {
    (1_usize..=10).for_each(|x| println!("{}: {}", x, topswops(x)));
}


object Fannkuch extends App {

  def fannkuchen(l: List[Int], n: Int, i: Int, acc: Int): Int = {
    def flips(l: List[Int]): Int = (l: @unchecked) match {
      case 1 :: ls => 0
      case (n :: ls) =>
        val splitted = l.splitAt(n)
        flips(splitted._2.reverse_:::(splitted._1)) + 1
    }

    def rotateLeft(l: List[Int]) =
      l match {
        case Nil => List()
        case x :: xs => xs ::: List(x)
      }

    if (i >= n) acc
    else {
      if (n == 1) acc.max(flips(l))
      else {
        val split = l.splitAt(n)
        fannkuchen(rotateLeft(split._1) ::: split._2, n, i + 1, fannkuchen(l, n - 1, 0, acc))
      }
    }
  } // def fannkuchen(

  val result = (1 to 10).map(i => (i, fannkuchen(List.range(1, i + 1), i, 0, 0)))
  println("Computing results...")
  result.foreach(x => println(s"Pfannkuchen(${x._1})\t= ${x._2}"))
  assert(result == Vector((1, 0), (2, 1), (3, 2), (4, 4), (5, 7), (6, 10), (7, 16), (8, 22), (9, 30), (10, 38)), "Bad results")
  println(s"Successfully completed without errors. [total ${scala.compat.Platform.currentTime - executionStart} ms]")
}


import Control.Monad (mapM, foldM, forever)
import Data.List (unwords, unlines, nub)
import Data.Maybe (fromJust)

truthTable expr = let
    tokens = words expr
    operators = ["&", "|", "!", "^", "=>"]
    variables = nub $ filter (not . (`elem` operators)) tokens
    table = zip variables <$> mapM (const [True,False]) variables
    results = map (\r -> (map snd r) ++ (calculate tokens) r) table
    header = variables ++ ["result"]
    in
      showTable $ header : map (map show) results

-- Performs evaluation of token sequence in a given context.
-- The context is an assoc-list, which binds variable and it's value.
-- Here the monad is simple ((->) r).
calculate :: [String] -> [(String, Bool)] -> [Bool]
calculate = foldM interprete []
  where
    interprete (x:y:s) "&"  = (: s) <$> pure (x && y)
    interprete (x:y:s) "|"  = (: s) <$> pure (x || y)
    interprete (x:y:s) "^"  = (: s) <$> pure (x /= y)
    interprete (x:y:s) "=>" = (: s) <$> pure (not y || x)
    interprete (x:s)   "!"  = (: s) <$> pure (not x)
    interprete s var        = (: s) <$> fromJust . lookup var

-- pretty printing
showTable tbl = unlines $ map (unwords . map align) tbl
  where
    align txt = take colWidth $ txt ++ repeat ' '
    colWidth = max 6 $ maximum $ map length (head tbl)

main = forever $ getLine >>= putStrLn . truthTable


void main() {
    import std.stdio, std.math;

    enum degrees = 45.0L;
    enum t0 = degrees * PI / 180.0L;
    writeln("Reference:  0.7071067811865475244008");
    writefln("Sine:       %.20f  %.20f", PI_4.sin, t0.sin);
    writefln("Cosine:     %.20f  %.20f", PI_4.cos, t0.cos);
    writefln("Tangent:    %.20f  %.20f", PI_4.tan, t0.tan);

    writeln;
    writeln("Reference:  0.7853981633974483096156");
    immutable real t1 = PI_4.sin.asin;
    writefln("Arcsine:    %.20f %.20f", t1, t1 * 180.0L / PI);

    immutable real t2 = PI_4.cos.acos;
    writefln("Arccosine:  %.20f %.20f", t2, t2 * 180.0L / PI);

    immutable real t3 = PI_4.tan.atan;
    writefln("Arctangent: %.20f %.20f", t3, t3 * 180.0L / PI);
}


package require struct::list

proc swap {listVar} {
    upvar 1 $listVar list
    set n [lindex $list 0]
    for {set i 0; set j [expr {$n-1}]} {$i<$j} {incr i;incr j -1} {
	set tmp [lindex $list $i]
	lset list $i [lindex $list $j]
	lset list $j $tmp
    }
}

proc swaps {list} {
    for {set i 0} {[lindex $list 0] > 1} {incr i} {
	swap list
    }
    return $i
}

proc topswops list {
    set n 0
    ::struct::list foreachperm p $list {
	set n [expr {max($n,[swaps $p])}]
    }
    return $n
}

proc topswopsTo n {
    puts "n\ttopswops(n)"
    for {set i 1} {$i <= $n} {incr i} {
	puts $i\t[topswops [lappend list $i]]
    }
}
topswopsTo 10


import "/fmt" for Fmt

var maxn = 10
var maxl = 50

var steps = Fn.new { |n|
    var a = List.filled(maxl, null)
    var b = List.filled(maxl, null)
    var x = List.filled(maxl, 0)
    for (i in 0...maxl) {
        a[i] = List.filled(maxn + 1, 0)
        b[i] = List.filled(maxn + 1, 0)
    }
    a[0][0] = 1
    var m = 0
    var l = 0
    while (true) {
        x[l] = x[l] + 1
        var k = x[l]
        var cont = false
        if (k >= n) {
            if (l <= 0) break
            l = l - 1
            cont = true
        } else if (a[l][k] == 0) {
            if (b[l][k+1] != 0) cont = true
        } else if (a[l][k] != k + 1) {
            cont = true
        }
        if (!cont) {
            a[l+1] = a[l].toList
            var j = 1
            while (j <= k) {
                a[l+1][j] = a[l][k-j]
                j = j + 1
            }
            b[l+1] = b[l].toList
            a[l+1][0] = k + 1
            b[l+1][k+1] = 1
            if (l > m - 1) {
                m = l + 1
            }
            l = l + 1
            x[l] = 0
        }
    }
    return m
}

for (i in 1..maxn) Fmt.print("$2d: $d", i, steps.call(i))


truthTable=:3 :0
  assert. -. 1 e. 'data expr names table' e.&;: y
  names=. ~. (#~ _1 <: nc) ;:expr=. y
  data=. #:i.2^#names
  (names)=. |:data
  (' ',;:inv names,<expr),(1+#@>names,<expr)":data,.".expr
)


import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;

public class TruthTable {
    public static void main( final String... args ) {
        System.out.println( new TruthTable( args ) );
    }

    private interface Operator {
        boolean evaluate( Stack<Boolean> s );
    }

    /**
     * Supported operators and what they do. For more ops, add entries here.
     */
    private static final Map<String,Operator> operators = new HashMap<String,Operator>() {{
        // Can't use && or || because shortcut evaluation may mean the stack is not popped enough
        put( "&", stack -> Boolean.logicalAnd( stack.pop(), stack.pop() ) );
        put( "|", stack -> Boolean.logicalOr( stack.pop(), stack.pop() ) );
        put( "!", stack -> ! stack.pop() );
        put( "^", stack -> ! stack.pop().equals ( stack.pop() ) );
    }};

    private final List<String> variables;
    private final String[]     symbols;

    /**
     * Constructs a truth table for the symbols in an expression.
     */
    public TruthTable( final String... symbols ) {
        final Set<String> variables = new LinkedHashSet<>();

        for ( final String symbol : symbols ) {
            if ( ! operators.containsKey( symbol ) ) {
                variables.add( symbol );
            }
        }
        this.variables = new ArrayList<>( variables );
        this.symbols = symbols;
    }

    @Override
    public String toString () {
        final StringBuilder result = new StringBuilder();

        for ( final String variable : variables ) {
            result.append( variable ).append( ' ' );
        }
        result.append( ' ' );
        for ( final String symbol : symbols ) {
            result.append( symbol ).append ( ' ' );
        }
        result.append( '\n' );
        for ( final List<Boolean> values : enumerate( variables.size () ) ) {
            final Iterator<String> i = variables.iterator();

            for ( final Boolean value : values ) {
                result.append(
                    String.format(
                        "%-" + i.next().length() + "c ",
                        value ? 'T' : 'F'
                    )
                );
            }
            result.append( ' ' )
                .append( evaluate( values ) ? 'T' : 'F' )
                .append( '\n' );
        }

        return result.toString ();
    }

    /**
     * Recursively generates T/F values
     */
    private static List<List<Boolean>> enumerate( final int size ) {
        if ( 1 == size )
            return new ArrayList<List<Boolean>>() {{
                add( new ArrayList<Boolean>() {{ add(false); }} );
                add( new ArrayList<Boolean>() {{ add(true);  }} );
            }};

        return new ArrayList<List<Boolean>>() {{
            for ( final List<Boolean> head : enumerate( size - 1 ) ) {
                add( new ArrayList<Boolean>( head ) {{ add(false); }} );
                add( new ArrayList<Boolean>( head ) {{ add(true);  }} );
            }
        }};
    }

    /**
     * Evaluates the expression for a set of values.
     */
    private boolean evaluate( final List<Boolean> enumeration ) {
        final Iterator<Boolean>   i      = enumeration.iterator();
        final Map<String,Boolean> values = new HashMap<>();
        final Stack<Boolean>      stack  = new Stack<>();

        variables.forEach ( v -> values.put( v, i.next() ) );
        for ( final String symbol : symbols ) {
            final Operator op = operators.get ( symbol );

            // Reverse Polish notation makes this bit easy
            stack.push(
                null == op
                    ? values.get ( symbol )
                    : op.evaluate ( stack )
            );
        }
        return stack.pop();
    }
}


def pi := (-1.0).acos()

def radians := pi / 4.0
def degrees := 45.0

def d2r := (pi/180).multiply
def r2d := (180/pi).multiply

println(`$\
${radians.sin()} ${d2r(degrees).sin()}
${radians.cos()} ${d2r(degrees).cos()}
${radians.tan()} ${d2r(degrees).tan()}
${def asin := radians.sin().asin()} ${r2d(asin)}
${def acos := radians.cos().acos()} ${r2d(acos)}
${def atan := radians.tan().atan()} ${r2d(atan)}
`)


import system'math;
import extensions;

public program()
{
    console.printLine("Radians:");
    console.printLine("sin(π/3) = ",(Pi_value/3).sin());
    console.printLine("cos(π/3) = ",(Pi_value/3).cos());
    console.printLine("tan(π/3) = ",(Pi_value/3).tan());
    console.printLine("arcsin(1/2) = ",0.5r.arcsin());
    console.printLine("arccos(1/2) = ",0.5r.arccos());
    console.printLine("arctan(1/2) = ",0.5r.arctan());
    console.printLine();

    console.printLine("Degrees:");
    console.printLine("sin(60º) = ",60.0r.Radian.sin());
    console.printLine("cos(60º) = ",60.0r.Radian.cos());
    console.printLine("tan(60º) = ",60.0r.Radian.tan());
    console.printLine("arcsin(1/2) = ",0.5r.arcsin().Degree,"º");
    console.printLine("arccos(1/2) = ",0.5r.arccos().Degree,"º");
    console.printLine("arctan(1/2) = ",0.5r.arctan().Degree,"º");

    console.readChar()
}


code ChOut=8, CrLf=9, IntOut=11;
int  N, Max, Card1(16), Card2(16);

proc Topswop(D);        \Conway's card swopping game
int  D;                 \depth of recursion
int  I, J, C, T;
[if D # N then                  \generate N! permutations of 1..N in Card1
     [for I:= 0 to N-1 do
        [for J:= 0 to D-1 do    \check if object (letter) already used
            if Card1(J) = I+1 then J:=100;
        if J < 100 then
            [Card1(D):= I+1;    \card number not used so append it
            Topswop(D+1);       \recurse next level deeper
            ];
        ];
     ]
else [\determine number of topswops to get card 1 at beginning
     for I:= 0 to N-1 do Card2(I):= Card1(I);   \make working copy of deck
        C:= 0;                  \initialize swop counter
        while Card2(0) # 1 do
            [I:= 0;  J:= Card2(0)-1;
            while I < J do
                [T:= Card2(I);  Card2(I):= Card2(J);  Card2(J):= T;
                I:= I+1;  J:= J-1;
                ];
            C:= C+1;
            ];
     if C>Max then Max:= C;
     ];
];

[for N:= 1 to 10 do
    [Max:= 0;
    Topswop(0);
    IntOut(0, N);  ChOut(0, ^ );  IntOut(0, Max);  CrLf(0);
    ];
]


fcn topswops(n){
   flip:=fcn(xa){
      if (not xa[0]) return(0);
      xa.reverse(0,xa[0]+1);  // inplace, ~4x faster than making new lists
      return(1 + self.fcn(xa));
   };
   (0).pump(n,List):Utils.Helpers.permute(_).pump(List,"copy",flip).reduce("max");
}

foreach n in ([1 .. 10]){ println(n, ": ", topswops(n)) }


iex(61)> deg = 45
45
iex(62)> rad = :math.pi / 4
0.7853981633974483
iex(63)> :math.sin(deg * :math.pi / 180) == :math.sin(rad)
true
iex(64)> :math.cos(deg * :math.pi / 180) == :math.cos(rad)
true
iex(65)> :math.tan(deg * :math.pi / 180) == :math.tan(rad)
true
iex(66)> temp = :math.acos(:math.cos(rad))
0.7853981633974483
iex(67)> temp * 180 / :math.pi == deg
true
iex(68)> temp = :math.atan(:math.tan(rad))
0.7853981633974483
iex(69)> temp * 180 / :math.pi == deg
true


Deg=45.
Rad=math:pi()/4.

math:sin(Deg * math:pi() / 180)==math:sin(Rad).


module TruthTable

using Printf
using MacroTools

isvariablename(::Any) = false
isvariablename(s::Symbol) = all(x -> isletter(x) || x == '_', string(s))

function table(expr)
    if !isvariablename(expr) && !Meta.isexpr(expr, :call)
        throw(ArgumentError("expr must be a boolean expression"))
    end

    exprstr = string(expr)
    # Collect variable names
    symset = Set{Symbol}()
    MacroTools.prewalk(expr) do node
        isvariablename(node) && push!(symset, node)
        return node
    end
    symlist = collect(symset)

    # Create assignment assertions + evaluate
    blocks = Vector{Expr}(undef, 2 ^ length(symlist) + 1)
    blocks[1] = quote
        println(join(lpad.($(symlist), 6), " | "), " || ", $exprstr)
    end
    for (i, tup) in enumerate(Iterators.product(Iterators.repeated((false, true), length(symlist))...))
        blocks[i + 1] = quote
            let $(Expr(:(=), Expr(:tuple, symlist...), Expr(:tuple, tup...)))
                println(join(lpad.($(Expr(:tuple, symlist...)), 6), " | "), " || ", lpad($expr, $(length(exprstr))))
            end
        end
    end

    return esc(Expr(:block, blocks...))
end

macro table(expr)
    return table(expr)
end

end  # module TruthTable


// Version 1.2.31

import java.util.Stack

class Variable(val name: Char, var value: Boolean = false)

lateinit var expr: String
var variables = mutableListOf<Variable>()

fun Char.isOperator() = this in "&|!^"

fun Char.isVariable() = this in variables.map { it.name }

fun evalExpression(): Boolean {
    val stack = Stack<Boolean>()

    for (e in expr) {
        stack.push(
            if (e == 'T')
                true
            else if (e == 'F')
                false
            else if (e.isVariable())
                variables.single { it.name == e }.value
            else when (e) {
                '&'   -> stack.pop() and stack.pop()
                '|'   -> stack.pop() or  stack.pop()
                '!'   -> !stack.pop()
                '^'   -> stack.pop() xor stack.pop()
                else  -> throw RuntimeException("Non-conformant character '$e' in expression")
            }
        )
    }

    require(stack.size == 1)
    return stack.peek()
}

fun setVariables(pos: Int) {
    require(pos <= variables.size)
    if (pos == variables.size) {
        val vs = variables.map { if (it.value) "T" else "F" }.joinToString("  ")
        val es = if (evalExpression()) "T" else "F"
        return println("$vs  $es")
    }
    variables[pos].value = false
    setVariables(pos + 1)
    variables[pos].value = true
    setVariables(pos + 1)
}

fun main(args: Array<String>) {
    println("Accepts single-character variables (except for 'T' and 'F',")
    println("which specify explicit true or false values), postfix, with")
    println("&|!^ for and, or, not, xor, respectively; optionally")
    println("seperated by spaces or tabs. Just enter nothing to quit.")

    while (true) {
        print("\nBoolean expression: ")
        expr = readLine()!!.toUpperCase().replace(" ", "").replace("\t", "")
        if (expr == "") return
        variables.clear()
        for (e in expr) {
            if (!e.isOperator() && e !in "TF" && !e.isVariable()) variables.add(Variable(e))
        }
        if (variables.isEmpty()) return
        val vs = variables.map { it.name }.joinToString("  ")
        println("\n$vs  $expr")
        val h = vs.length + expr.length + 2
        repeat(h) { print("=") }
        println("\n")
        setVariables(0)
    }
}


open NUnit.Framework
open FsUnit

// radian

[<Test>]
let ``Verify that sin pi returns 0`` () =
  let x = System.Math.Sin System.Math.PI
  System.Math.Round(x,5) |> should equal 0

[<Test>]
let ``Verify that cos pi returns -1`` () =
  let x = System.Math.Cos System.Math.PI
  System.Math.Round(x,5) |> should equal -1

[<Test>]
let ``Verify that tan pi returns 0`` () =
  let x = System.Math.Tan System.Math.PI
  System.Math.Round(x,5) |> should equal 0

[<Test>]
let ``Verify that sin pi/2 returns 1`` () =
  let x = System.Math.Sin (System.Math.PI / 2.0)
  System.Math.Round(x,5) |> should equal 1

[<Test>]
let ``Verify that cos pi/2 returns -1`` () =
  let x = System.Math.Cos (System.Math.PI / 2.0)
  System.Math.Round(x,5) |> should equal 0

[<Test>]
let ``Verify that sin pi/3 returns sqrt 3/2`` () =
  let actual = System.Math.Sin (System.Math.PI / 3.0)
  let expected = System.Math.Round((System.Math.Sqrt 3.0) / 2.0, 5)
  System.Math.Round(actual,5) |> should equal expected

[<Test>]
let ``Verify that cos pi/3 returns -1`` () =
  let x = System.Math.Cos (System.Math.PI / 3.0)
  System.Math.Round(x,5) |> should equal 0.5

[<Test>]
let ``Verify that cos and sin of pi/4 return same value`` () =
  let c = System.Math.Cos (System.Math.PI / 4.0)
  let s = System.Math.Sin (System.Math.PI / 4.0)
  System.Math.Round(c,5) = System.Math.Round(s,5) |> should be True

[<Test>]
let ``Verify that acos pi/3 returns 1/2`` () =
  let actual = System.Math.Acos 0.5
  let expected = System.Math.Round((System.Math.PI / 3.0),5)
  System.Math.Round(actual,5) |> should equal expected

[<Test>]
let ``Verify that asin 1 returns pi/2`` () =
  let actual = System.Math.Asin 1.0
  let expected = System.Math.Round((System.Math.PI / 2.0),5)
  System.Math.Round(actual,5) |> should equal expected

[<Test>]
let ``Verify that atan 0 returns 0`` () =
  let actual = System.Math.Atan 0.0
  let expected = System.Math.Round(0.0,5)
  System.Math.Round(actual,5) |> should equal expected

// degree

let toRadians d = d * System.Math.PI / 180.0

[<Test>]
let ``Verify that pi is 180 degrees`` () =
  toRadians 180.0 |> should equal System.Math.PI

[<Test>]
let ``Verify that pi/2 is 90 degrees`` () =
  toRadians 90.0 |> should equal (System.Math.PI / 2.0)

[<Test>]
let ``Verify that pi/3 is 60 degrees`` () =
  toRadians 60.0 |> should equal (System.Math.PI / 3.0)

[<Test>]
let ``Verify that sin 180 returns 0`` () =
  let x = System.Math.Sin (toRadians 180.0)
  System.Math.Round(x,5) |> should equal 0

[<Test>]
let ``Verify that cos 180 returns -1`` () =
  let x = System.Math.Cos (toRadians 180.0)
  System.Math.Round(x,5) |> should equal -1

[<Test>]
let ``Verify that tan 180 returns 0`` () =
  let x = System.Math.Tan (toRadians 180.0)
  System.Math.Round(x,5) |> should equal 0

[<Test>]
let ``Verify that sin 90 returns 1`` () =
  let x = System.Math.Sin (toRadians 90.0)
  System.Math.Round(x,5) |> should equal 1

[<Test>]
let ``Verify that cos 90 returns -1`` () =
  let x = System.Math.Cos (toRadians 90.0)
  System.Math.Round(x,5) |> should equal 0

[<Test>]
let ``Verify that sin 60 returns sqrt 3/2`` () =
  let actual = System.Math.Sin (toRadians 60.0)
  let expected = System.Math.Round((System.Math.Sqrt 3.0) / 2.0, 5)
  System.Math.Round(actual,5) |> should equal expected

[<Test>]
let ``Verify that cos 60 returns -1`` () =
  let x = System.Math.Cos (toRadians 60.0)
  System.Math.Round(x,5) |> should equal 0.5

[<Test>]
let ``Verify that cos and sin of 45 return same value`` () =
  let c = System.Math.Cos (toRadians 45.0)
  let s = System.Math.Sin (toRadians 45.0)
  System.Math.Round(c,5) = System.Math.Round(s,5) |> should be True


print
    print " TRUTH TABLES"
    print
    print " Input a valid Boolean expression for creating the truth table "
    print " Use lowercase 'and', 'or', 'xor', '(', 'not(' and ')'."
    print
    print " Take special care to precede closing bracket with a space."
    print
    print " You can use any alphanumeric variable names, but no spaces."
    print " You can refer again to a variable used already."
    print " Program assumes <8 variables will be used.."
    print
    print " eg 'A xor B and not( C or A )'"
    print " or 'Too_High xor not( Fuel_Out )'"

    print

 [start]
    input "        "; expression$
    if expression$ ="" then [start]

    print

    'used$           =""
    numVariables    =0  '   count of detected variable names
    variableNames$  ="" '   filled with detected variable names
    i               =1  '   index to space-delimited word in the expression$

  [parse]
    m$ =word$( expression$, i, " ")
    if m$ ="" then [analyse]
    '   is it a reserved word, or a variable name already met?
    if m$ <>"and" and m$ <>"or" and m$ <>"not(" and m$ <>")" and m$ <>"xor"_
     and not( instr( variableNames$, m$)) then
        variableNames$ =variableNames$ +m$ +" ": numVariables =numVariables +1
    end if

    i =i +1
    goto [parse]

  [analyse]
    for i =1 to numVariables
        ex$          =FindReplace$( expression$, word$( variableNames$, i, " "), chr$( 64 +i), 1)
        expression$  =ex$
    next i

    'print " "; numVariables; " variables, simplifying to "; expression$

    print ,;
    for j =1 to numVariables
        print word$( variableNames$, j, " "),
    next j
    print "Result"
    print

    for i =0 to ( 2^numVariables) -1
        print ,;
        A                         =i mod 2:          print A,
        if numVariables >1 then B =int( i /2) mod 2: print B,
        if numVariables >2 then C =int( i /4) mod 2: print C,
        if numVariables >3 then D =int( i /4) mod 2: print D,
        if numVariables >4 then E =int( i /4) mod 2: print E,
        if numVariables >5 then F =int( i /4) mod 2: print F,
        if numVariables >6 then G =int( i /4) mod 2: print G,
        '   .......................... etc

        'e =eval( expression$)
        if eval( expression$) <>0 then e$ ="1" else e$ ="0"
        print "==>  "; e$
    next i

    print

    goto [start]

    end

function FindReplace$( FindReplace$, find$, replace$, replaceAll)
    if ( ( FindReplace$ <>"") and ( find$ <>"")) then
        fLen = len( find$)
        rLen = len( replace$)
        do
            fPos            = instr( FindReplace$, find$, fPos)
            if not( fPos) then exit function
            pre$            = left$( FindReplace$, fPos -1)
            post$           =  mid$( FindReplace$, fPos +fLen)
            FindReplace$    = pre$ +replace$ +post$
            fPos            = fPos +(rLen -fLen) +1
        loop while ( replaceAll)
    end if
end function


USING: kernel math math.constants math.functions math.trig
prettyprint ;

pi 4 / 45 deg>rad [ sin ] [ cos ] [ tan ]
[ [ . ] compose dup compose ] [email protected] 2tri

.5 [ asin ] [ acos ] [ atan ] tri [ dup rad>deg [ . ] [email protected] ] [email protected]


class Main
{
  public static Void main ()
  {
    Float r := Float.pi / 4
    echo (r.sin)
    echo (r.cos)
    echo (r.tan)
    echo (r.asin)
    echo (r.acos)
    echo (r.atan)
    // and from degrees
    echo (45.0f.toRadians.sin)
    echo (45.0f.toRadians.cos)
    echo (45.0f.toRadians.tan)
    echo (45.0f.toRadians.asin)
    echo (45.0f.toRadians.acos)
    echo (45.0f.toRadians.atan)
  }
}


VariableNames[data_] := Module[ {TokenRemoved},
 TokenRemoved = StringSplit[data,{"~And~","~Or~","~Xor~","!","(",")"}];
 Union[Select[Map[StringTrim,TokenRemoved] , Not[StringMatchQ[#,""]]&]]
]

TruthTable[BooleanEquation_] := Module[ {TestDataSet},
  TestDataSet = MapThread[Rule,{[email protected][BooleanEquation],#}]&/@
     Tuples[{False,True}, Length[VariableNames[BooleanEquation]]];

  Join[List[Flatten[{VariableNames[BooleanEquation],BooleanEquation}]],
    Flatten[{#/.Rule[x_,y_] -> y,ReplaceAll[ToExpression[BooleanEquation],#]}]&/@TestDataSet]//Grid
]


/* Maxima already has the following logical operators
          =, # (not equal), not, and, or
define some more and set 'binding power' (operator
precedence) for them
*/
infix("xor", 60)$
"xor"(A,B):= (A or B) and not(A and B)$

infix("=>", 59)$
"=>"(A,B):= not A or B$

/*
Substitute variables `r' in `e' with values taken from list `l' where
`e' is expression, `r' is a list of independent variables, `l' is a
list of the values
lsubst( '(A + B), ['A, 'B], [1, 2]);
1 + 2;
*/
lsubst(e, r, l):= ev(e, maplist( lambda([x, y], x=y), r, l), 'simp)$

/*
"Cartesian power" `n' of list `b'. Returns a list of lists of the form
[<x_1>, ..., <x_n>], were <x_1>, .. <x_n> are elements of list `b'
cartesian_power([true, false], 2);
[[true, true], [true, false], [false, true], [false, false]];
cartesian_power([true, false], 3);
[[true, true, true], [true, true, false], [true, false, true],
[true, false, false], [false, true, true], [false, true, false],
[false, false, true], [false, false, false]];
*/
cartesian_power(b, n) := block(
    [aux_lst: makelist(setify(b), n)],
    listify(apply(cartesian_product, aux_lst))
    )$

gen_table(expr):= block(
  [var_lst: listofvars(expr), st_lst, res_lst, m],
  st_lst: cartesian_power([true, false], length(var_lst)),
  res_lst: create_list(lsubst(expr, var_lst, val_lst), val_lst, st_lst),
  m      : apply('matrix, cons(var_lst, st_lst)),
  addcol(m, cons(expr, res_lst))
  );

/* examples */
gen_table('(not A));
gen_table('(A xor B));
gen_table('(Jim and (Spock xor Bones) or Scotty));
gen_table('(A => (B and A)));
gen_table('(V xor (B xor (K xor D ) )));


import sequtils, strutils, sugar

# List of possible variables names.
const VarChars = {'A'..'E', 'G'..'S', 'U'..'Z'}

type

  Expression = object
    names: seq[char]    # List of variables names.
    values: seq[bool]   # Associated values.
    formula: string     # Formula as a string.

proc initExpression(str: string): Expression =
  ## Build an expression from a string.
  for ch in str:
    if ch in VarChars and ch notin result.names:
      result.names.add ch
  result.values.setLen(result.names.len)
  result.formula = str

template apply(stack: seq[bool]; op: (bool, bool) -> bool): bool =
  ## Apply an operator on the last two operands of an evaluation stack.
  ## Needed to make sure that pops are done (avoiding short-circuit optimization).
  let op2 = stack.pop()
  let op1 = stack.pop()
  op(op1, op2)

proc evaluate(expr: Expression): bool =
  ## Evaluate the current expression.

  var stack: seq[bool]  # Evaluation stack.

  for e in expr.formula:
    stack.add case e
              of 'T': true
              of 'F': false
              of '!': not stack.pop()
              of '&': stack.apply(`and`)
              of '|': stack.apply(`or`)
              of '^': stack.apply(`xor`)
              else:
                if e in VarChars: expr.values[expr.names.find(e)]
                else:
                  raise newException(
                    ValueError, "Non-conformant character in expression: '$#'.".format(e))

  if stack.len != 1:
    raise newException(ValueError, "Ill-formed expression.")
  result = stack[0]

proc setVariables(expr: var Expression; pos: Natural) =
  ## Recursively set the variables.
  ## When all the variables are set, launch the evaluation of the expression
  ## and print the result.

  assert pos <= expr.values.len

  if pos == expr.values.len:
    # Evaluate and display.
    let vs = expr.values.mapIt(if it: 'T' else: 'F').join("  ")
    let es = if expr.evaluate(): 'T' else: 'F'
    echo vs, "  ", es

  else:
    # Set values.
    expr.values[pos] = false
    expr.setVariables(pos + 1)
    expr.values[pos] = true
    expr.setVariables(pos + 1)

echo "Accepts single-character variables (except for 'T' and 'F',"
echo "which specify explicit true or false values), postfix, with"
echo "&|!^ for and, or, not, xor, respectively; optionally"
echo "seperated by spaces or tabs. Just enter nothing to quit."

while true:
  # Read formula and create expression.
  stdout.write "\nBoolean expression: "
  let line = stdin.readLine.toUpperAscii.multiReplace((" ", ""), ("\t", ""))
  if line.len == 0: break
  var expr = initExpression(line)
  if expr.names.len == 0: break

  # Display the result.
  let vs = expr.names.join("  ")
  echo '\n', vs, "  ", expr.formula
  let h = vs.len + expr.formula.len + 2
  echo repeat('=', h)
  expr.setVariables(0)


45e  pi f* 180e f/     \ radians

cr fdup  fsin f.       \ also available: fsincos ( r -- sin cos )
cr fdup  fcos f.
cr fdup  ftan f.
cr fdup fasin f.
cr fdup facos f.
cr      fatan f.       \ also available: fatan2 ( r1 r2 -- atan[r1/r2] )