function T(t) return setmetatable(t, {__index=table}) end
table.range = function(t,n) local s=T{} for i=1,n do s[i]=i end return s end
table.map = function(t,f) local s=T{} for i=1,#t do s[i]=f(t[i]) end return s end

function cullen(n) return (n<<n)+1 end
print("First 20 Cullen numbers:")
print(T{}:range(20):map(cullen):concat(" "))

function woodall(n) return (n<<n)-1 end
print("First 20 Woodall numbers:")
print(T{}:range(20):map(woodall):concat(" "))


use strict;
use warnings;
use bigint;
use ntheory 'is_prime';
use constant Inf  => 1e10;

sub cullen {
    my($n,$c) = @_;
    ($n * 2**$n) + $c;
}

my($m,$n);

($m,$n) = (20,0);
print "First $m Cullen numbers:\n";
print do { $n < $m ? (++$n and cullen($_,1) . ' ') : last } for 1 .. Inf;

($m,$n) = (20,0);
print "\n\nFirst $m Woodall numbers:\n";
print do { $n < $m ? (++$n and cullen($_,-1) . ' ') : last } for 1 .. Inf;

($m,$n) = (5,0);
print "\n\nFirst $m Cullen primes: (in terms of n)\n";
print do { $n < $m ? (!!is_prime(cullen $_,1) and ++$n and "$_ ") : last } for 1 .. Inf;

($m,$n) = (12,0);
print "\n\nFirst $m Woodall primes: (in terms of n)\n";
print do { $n < $m ? (!!is_prime(cullen $_,-1) and ++$n and "$_ ") : last } for 1 .. Inf;


with javascript_semantics
atom t0 = time()
include mpfr.e

procedure cullen(mpz r, integer n)
    mpz_ui_pow_ui(r,2,n)
    mpz_mul_si(r,r,n)
    mpz_add_si(r,r,1)
end procedure

procedure woodall(mpz r, integer n)
    cullen(r,n)
    mpz_sub_si(r,r,2)
end procedure

sequence c = {}, w = {}
mpz z = mpz_init()
for i=1 to 20 do
    cullen(z,i)
    c = append(c,mpz_get_str(z))
    mpz_sub_si(z,z,2)
    w = append(w,mpz_get_str(z))
end for
printf(1," Cullen[1..20]:%s\nWoodall[1..20]:%s\n",{join(c),join(w)})

atom t1 = time()+1
c = {}
integer n = 1
while length(c)<iff(platform()=JS?2:5) do
    cullen(z,n)
    if mpz_prime(z) then c = append(c,sprint(n)) end if
    n += 1
    if time()>t1 and platform()!=JS then
        progress("c(%d) [needs to get to 6611], %d found\r",{n,length(c)})
        t1 = time()+2
    end if
end while
if platform()!=JS then progress("") end if
printf(1,"First 5 Cullen primes (in terms of n):%s\n",{join(c)})
w = {}
n = 1
while length(w)<12 do
    woodall(z,n)
    if mpz_prime(z) then w = append(w,sprint(n)) end if
    n += 1
end while
printf(1,"First 12 Woodall primes (in terms of n):%s\n",{join(w)})
?elapsed(time()-t0)


print("working...")
print("First 20 Cullen numbers:")

for n in range(1,20):
    num = n*pow(2,n)+1
    print(str(num),end= " ")

print()
print("First 20 Woodall numbers:")

for n in range(1,20):
    num = n*pow(2,n)-1
    print(str(num),end=" ")

print()
print("done...")


  [ dup << 1+ ]  is cullen  ( n --> n )

  [ dup << 1 - ] is woodall ( n --> n )

  say "First 20 Cullen numbers:" cr
  20 times [ i^ 1+ cullen echo sp ] cr
  cr
  say "First 20 Woodall numbers:" cr
  20 times [ i^ 1+ woodall echo sp ] cr


my @cullen  = ^∞ .map: { $_ × 1 +< $_ + 1 };
my @woodall = ^∞ .map: { $_ × 1 +< $_ - 1 };

put "First 20 Cullen numbers: ( n × 2**n + 1)\n",     @cullen[1..20]; # A002064
put "\nFirst 20 Woodall numbers: ( n × 2**n - 1)\n", @woodall[1..20]; # A003261
put "\nFirst 5 Cullen primes: (in terms of n)\n",     @cullen.grep( &is-prime, :k )[^5];  # A005849
put "\nFirst 12 Woodall primes:  (in terms of n)\n", @woodall.grep( &is-prime, :k )[^12]; # A002234


load "stdlib.ring"

see "working..." + nl
see "First 20 Cullen numbers:" + nl

for n = 1 to 20
    num = n*pow(2,n)+1
    see "" + num + " "
next

see nl + nl + "First 20 Woodall numbers:" + nl

for n = 1 to 20
    num = n*pow(2,n)-1
    see "" + num + " "
next

see nl + "done..." + nl


// [dependencies]
// rug = "1.15.0"

use rug::integer::IsPrime;
use rug::Integer;

fn cullen_number(n: u32) -> Integer {
    let num = Integer::from(n);
    (num << n) + 1
}

fn woodall_number(n: u32) -> Integer {
    let num = Integer::from(n);
    (num << n) - 1
}

fn main() {
    println!("First 20 Cullen numbers:");
    let cullen: Vec<String> = (1..21).map(|x| cullen_number(x).to_string()).collect();
    println!("{}", cullen.join(" "));

    println!("\nFirst 20 Woodall numbers:");
    let woodall: Vec<String> = (1..21).map(|x| woodall_number(x).to_string()).collect();
    println!("{}", woodall.join(" "));

    println!("\nFirst 5 Cullen primes in terms of n:");
    let cullen_primes: Vec<String> = (1..)
        .filter_map(|x| match cullen_number(x).is_probably_prime(25) {
            IsPrime::No => None,
            _ => Some(x.to_string()),
        })
        .take(5)
        .collect();
    println!("{}", cullen_primes.join(" "));

    println!("\nFirst 12 Woodall primes in terms of n:");
    let woodall_primes: Vec<String> = (1..)
        .filter_map(|x| match woodall_number(x).is_probably_prime(25) {
            IsPrime::No => None,
            _ => Some(x.to_string()),
        })
        .take(12)
        .collect();
    println!("{}", woodall_primes.join(" "));
}


func cullen(n)  { n * (1 << n) + 1 }
func woodall(n) { n * (1 << n) - 1 }

say "First 20 Cullen numbers:"
say cullen.map(1..20).join(' ')

say "\nFirst 20 Woodall numbers:"
say woodall.map(1..20).join(' ')

say "\nFirst 5 Cullen primes: (in terms of n)"
say 5.by { cullen(_).is_prime }.join(' ')

say "\nFirst 12 Woodall primes: (in terms of n)"
say 12.by { woodall(_).is_prime }.join(' ')


module main;
  integer n, num;

  initial begin
      $display("First 20 Cullen numbers:");
      for(n = 1; n <= 20; n=n+1)
      begin
        num = n * (2 ** n) + 1;
        $write(num, "  ");
      end
      $display("");
      $display("First 20 Woodall numbers:");
      for(n = 1; n <= 20; n=n+1)
      begin
        num = n * (2 ** n) - 1;
        $write(num, "  ");
      end
      $finish ;
    end
endmodule


import "./big" for BigInt

var cullen = Fn.new { |n| (BigInt.one << n) * n + 1 }

var woodall = Fn.new { |n| cullen.call(n) - 2 }

System.print("First 20 Cullen numbers (n * 2^n + 1):")
for (n in 1..20) System.write("%(cullen.call(n)) ")

System.print("\n\nFirst 20 Woodall numbers (n * 2^n - 1):")
for (n in 1..20) System.write("%(woodall.call(n)) ")

System.print("\n\nFirst 2 Cullen primes (in terms of n):")
var count = 0
var n = 1
while (count < 2) {
    var cn = cullen.call(n)
    if (cn.isProbablePrime(5)){
        System.write("%(n) ")
        count = count + 1
    }
    n = n + 1
}

System.print("\n\nFirst 12 Woodall primes (in terms of n):")
count = 0
n = 1
while (count < 12) {
    var wn = woodall.call(n)
    if (wn.isProbablePrime(5)){
        System.write("%(n) ")
        count = count + 1
    }
    n = n + 1
}
System.print()


F addN(n)
   F adder(x)
      R x + @=n
   R adder

V add2 = addN(2)
V add3 = addN(3)
print(add2(7))
print(add3(7))


generic
    type Argument_1 (<>) is limited private;
    type Argument_2 (<>) is limited private;
    type Argument_3 (<>) is limited private;
    type Return_Value (<>) is limited private;

    with function Func
           (A : in Argument_1;
            B : in Argument_2;
            C : in Argument_3)
        return Return_Value;
package Curry_3 is

    generic
        First : in Argument_1;
    package Apply_1 is

        generic
            Second : in Argument_2;
        package Apply_2 is

            function Apply_3
                   (Third : in Argument_3)
                return Return_Value;

        end Apply_2;

    end Apply_1;

end Curry_3;


ri(list l)
{
    l[0] = apply.apply(l[0]);
}
curry(object o)
{
    (o.__count - 1).times(ri, list(o));
}
main(void)
{
    o_wbfxinteger.curry()(16)(3)(12)(16)(1 << 30);
    0;
}


# Raising a function to a power #

MODE FUN = PROC (REAL) REAL;
PROC pow = (FUN f, INT n, REAL x) REAL: f(x) ** n;
OP ** = (FUN f, INT n) FUN: pow (f, n, );

# Example: sin (3 x) = 3 sin (x) - 4 sin^3 (x) (follows from DeMoivre's theorem) #

REAL x = read real;
print ((new line, sin (3 * x),  3 *  sin (x) - 4 * (sin ** 3) (x)))


-- curry :: (Script|Handler) -> Script
on curry(f)
    script
        on |λ|(a)
            script
                on |λ|(b)
                    |λ|(a, b) of mReturn(f)
                end |λ|
            end script
        end |λ|
    end script
end curry

-- TESTS ----------------------------------------------------------------------

-- add :: Num -> Num -> Num
on add(a, b)
    a + b
end add

-- product :: Num -> Num -> Num
on product(a, b)
    a * b
end product

-- Test 1.
curry(add)

-->  «script»

-- Test 2.
curry(add)'s |λ|(2)

--> «script»

-- Test 3.
curry(add)'s |λ|(2)'s |λ|(3)

--> 5

-- Test 4.
map(curry(product)'s |λ|(7), enumFromTo(1, 10))

--> {7, 14, 21, 28, 35, 42, 49, 56, 63, 70}

-- Combined:
{curry(add), ¬
    curry(add)'s |λ|(2), ¬
    curry(add)'s |λ|(2)'s |λ|(3), ¬
    map(curry(product)'s |λ|(7), enumFromTo(1, 10))}

--> {«script», «script», 5, {7, 14, 21, 28, 35, 42, 49, 56, 63, 70}}

-- GENERIC FUNCTIONS ----------------------------------------------------------

-- enumFromTo :: Int -> Int -> [Int]
on enumFromTo(m, n)
    if n < m then
        set d to -1
    else
        set d to 1
    end if
    set lst to {}
    repeat with i from m to n by d
        set end of lst to i
    end repeat
    return lst
end enumFromTo

-- map :: (a -> b) -> [a] -> [b]
on map(f, xs)
    tell mReturn(f)
        set lng to length of xs
        set lst to {}
        repeat with i from 1 to lng
            set end of lst to |λ|(item i of xs, i, xs)
        end repeat
        return lst
    end tell
end map

-- Lift 2nd class handler function into 1st class script wrapper
-- mReturn :: Handler -> Script
on mReturn(f)
    if class of f is script then
        f
    else
        script
            property |λ| : f
        end script
    end if
end mReturn


Plus3 ← 3⊸+
Plus3_1 ← +⟜3

•Show Plus3 1
•Show Plus3_1 1


#include<stdarg.h>
#include<stdio.h>

long int factorial(int n){
	if(n>1)
		return n*factorial(n-1);
	return 1;
}

long int sumOfFactorials(int num,...){
	va_list vaList;
	long int sum = 0;

	va_start(vaList,num);

	while(num--)
		sum += factorial(va_arg(vaList,int));

	va_end(vaList);

	return sum;
}

int main()
{
	printf("\nSum of factorials of [1,5] : %ld",sumOfFactorials(5,1,2,3,4,5));
	printf("\nSum of factorials of [3,5] : %ld",sumOfFactorials(3,3,4,5));
	printf("\nSum of factorials of [1,3] : %ld",sumOfFactorials(3,1,2,3));

	return 0;
}


public delegate int Plus(int y);
public delegate Plus CurriedPlus(int x);
public static CurriedPlus plus =
      delegate(int x) {return delegate(int y) {return x + y;};};
static void Main()
{
    int sum = plus(3)(4); // sum = 7
    int sum2= plus(2)(plus(3)(4)) // sum2 = 9
}


shared void run() {

    function divide(Integer x, Integer y) => x / y;

    value partsOf120 = curry(divide)(120);

    print("half of 120 is ``partsOf120(2)``
           a third is ``partsOf120(3)``
           and a quarter is ``partsOf120(4)``");
}


(def plus-a-hundred (partial + 100))
(assert (=
           (plus-a-hundred 1)
           101))


(defun curry (function &rest args-1)
  (lambda (&rest args-2)
    (apply function (append args-1 args-2))))


add_things = ->(x1 : Int32, x2 : Int32, x3 : Int32) { x1 + x2 + x3 }
add_curried = add_things.partial(2, 3)
add_curried.call(4)  #=> 9

def add_two_things(x1)
  return ->(x2 : Int32) {
    ->(x3 : Int32) { x1 + x2 + x3 }
  }
end
add13 = add_two_things(3).call(10)
add13.call(5)  #=> 18


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

    int add(int a, int b) {
        return a + b;
    }

    alias add2 = partial!(add, 2);
    writeln("Add 2 to 3: ", add(2, 3));
    writeln("Add 2 to 3 (curried): ", add2(3));
}


program Currying;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  System.SysUtils;

var
  Plus: TFunc<Integer, TFunc<Integer, Integer>>;

begin
  Plus :=
    function(x: Integer): TFunc<Integer, Integer>
    begin
      result :=
        function(y: Integer): Integer
        begin
          result := x + y;
        end;
    end;

  Writeln(Plus(3)(4));
  Writeln(Plus(2)(Plus(3)(4)));
  readln;
end.


;;
;; curry functional definition
;; (define (curry proc . left-args) (lambda right-args (apply proc (append left-args right-args))))
;;
;; right-curry
;; (define (rcurry proc . right-args) (lambda left-args (apply proc (append left-args right-args))))
;;

(define add42 (curry + 42))
(add42 666) → 708

(map (curry cons 'simon) '( gallubert garfunkel et-merveilles))
   →   ((simon . gallubert) (simon . garfunkel) (simon . et-merveilles))
(map (rcurry cons 'simon) '( gallubert garfunkel et-merveilles))
   →   ((gallubert . simon) (garfunkel . simon) (et-merveilles . simon))

;Implementation : result of currying :
(curry * 2 3 (+ 2 2))
    → (λ _#:g1004 (#apply-curry #* (2 3 4)  _#:g1004))


#import <stdio.h>

int main()

  addN := (int n)
    int adder(int x)
      return x + n
    return adder

  add2 := addN(2)

  printf( "Result = %d\n", add2(7) )

  return 0


   g (x: X): FUNCTION [ANY, TUPLE [Y], Z]
       do
           Result := agent (closed_x: X; y: Y): Z
              do
                 Result := f (closed_x, y)
              end (x, ?)
       end


-module(currying).

-compile(export_all).

% Function that curry the first or the second argument of a given function of arity 2

curry_first(F,X) ->
    fun(Y) -> F(X,Y) end.

curry_second(F,Y) ->
    fun(X) -> F(X,Y) end.

% Usual curry

curry(Fun,Arg) ->
	case erlang:fun_info(Fun,arity) of
		{arity,0} ->
			erlang:error(badarg);
		{arity,ArityFun} ->
			create_ano_fun(ArityFun,Fun,Arg);
		_ ->
			erlang:error(badarg)
	end.

create_ano_fun(Arity,Fun,Arg) ->
	Pars =
		[{var,1,list_to_atom(lists:flatten(io_lib:format("X~p", [N])))}
		 || N <- lists:seq(2,Arity)],
	Ano =
		{'fun',1,
			{clauses,[{clause,1,Pars,[],
				[{call,1,{var,1,'Fun'},[{var,1,'Arg'}] ++ Pars}]}]}},
	{_,Result,_} = erl_eval:expr(Ano, [{'Arg',Arg},{'Fun',Fun}]),
	Result.

% Generalization of the currying

curry_gen(Fun,GivenArgs,PosGivenArgs,PosParArgs) ->
    Pos = PosGivenArgs ++ PosParArgs,
    case erlang:fun_info(Fun,arity) of
        {arity,ArityFun} ->
            case ((length(GivenArgs) + length(PosParArgs)) == ArityFun) and
                 (length(GivenArgs) == length(PosGivenArgs)) and
                 (length(Pos) == sets:size(sets:from_list(Pos))) of
                true ->
                    fun(ParArgs) ->
                        case length(ParArgs) == length(PosParArgs) of
                            true ->
                                Given = lists:zip(PosGivenArgs,GivenArgs),
                                Pars = lists:zip(PosParArgs,ParArgs),
                                {_,Args} = lists:unzip(lists:sort(Given ++ Pars)),
                                erlang:apply(Fun,Args);
                            false ->
                                erlang:error(badarg)
                        end
                    end;
                false ->
                    erlang:error(badarg)
            end;
        _ ->
            erlang:error(badarg)
    end.


IN: scratchpad 2 [ 3 + ] curry

--- Data stack:
[ 2 3 + ]
IN: scratchpad call

--- Data stack:
5


: curry ( x xt1 -- xt2 )
  swap 2>r :noname r> postpone literal r> compile, postpone ; ;

5 ' + curry constant +5
5 +5 execute .
7 +5 execute .


' FB 1.05.0 Win64

Type CurriedAdd
  As Integer i
  Declare Function add(As Integer) As Integer
End Type

Function CurriedAdd.add(j As Integer) As Integer
  Return i + j
End Function

Function add (i As Integer) as CurriedAdd
   Return Type<CurriedAdd>(i)
End Function

Print "3 + 4 ="; add(3).add(4)
Print "2 + 6 ="; add(2).add(6)
Sleep


F cut_it(=h, =w)
   V dirs = [(1, 0), (-1, 0), (0, -1), (0, 1)]
   I h % 2 != 0
      swap(&h, &w)
   I h % 2 != 0
      R 0
   I w == 1
      R 1
   V count = 0

   V next = [w + 1, -w - 1, -1, 1]
   V blen = (h + 1) * (w + 1) - 1
   V grid = [0B] * (blen + 1)

   F walk(Int y, x, =count) -> Int
      I y == 0 | y == @h | x == 0 | x == @w
         R count + 1

      V t = y * (@w + 1) + x
      @grid[t] = @grid[@blen - t] = 1B

      L(i) 4
         I [email protected][t + @next[i]]
            count = @walk(y + @dirs[i][0], x + @dirs[i][1], count)

      @grid[t] = @grid[@blen - t] = 0B
      R count

   V t = h I/ 2 * (w + 1) + w I/ 2
   I w % 2 != 0
      grid[t] = grid[t + 1] = 1B
      count = walk(h I/ 2, w I/ 2 - 1, count)
      V res = count
      count = 0
      count = walk(h I/ 2 - 1, w I/ 2, count)
      R res + count * 2
   E
      grid[t] = 1B
      count = walk(h I/ 2, w I/ 2 - 1, count)
      I h == w
         R count * 2
      count = walk(h I/ 2 - 1, w I/ 2, count)
      R count

L(w) 1..9
   L(h) 1..w
      I (w * h) % 2 == 0
         print(‘#. x #.: #.’.format(w, h, cut_it(w, h)))


package main

import (
        "fmt"
        "math"
)

func PowN(b float64) func(float64) float64 {
        return func(e float64) float64 { return math.Pow(b, e) }
}

func PowE(e float64) func(float64) float64 {
        return func(b float64) float64 { return math.Pow(b, e) }
}

type Foo int

func (f Foo) Method(b int) int {
        return int(f) + b
}

func main() {
        pow2 := PowN(2)
        cube := PowE(3)

        fmt.Println("2^8 =", pow2(8))
        fmt.Println("4³ =", cube(4))

        var a Foo = 2
        fn1 := a.Method   // A "method value", like currying 'a'
        fn2 := Foo.Method // A "method expression", like uncurrying

        fmt.Println("2 + 2 =", a.Method(2)) // regular method call
        fmt.Println("2 + 3 =", fn1(3))
        fmt.Println("2 + 4 =", fn2(a, 4))
        fmt.Println("3 + 5 =", fn2(Foo(3), 5))
}


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

typedef unsigned char byte;
byte *grid = 0;

int w, h, len;
unsigned long long cnt;

static int next[4], dir[4][2] = {{0, -1}, {-1, 0}, {0, 1}, {1, 0}};
void walk(int y, int x)
{
	int i, t;

	if (!y || y == h || !x || x == w) {
		cnt += 2;
		return;
	}

	t = y * (w + 1) + x;
	grid[t]++, grid[len - t]++;

	for (i = 0; i < 4; i++)
		if (!grid[t + next[i]])
			walk(y + dir[i][0], x + dir[i][1]);

	grid[t]--, grid[len - t]--;
}

unsigned long long solve(int hh, int ww, int recur)
{
	int t, cx, cy, x;

	h = hh, w = ww;

	if (h & 1) t = w, w = h, h = t;
	if (h & 1) return 0;
	if (w == 1) return 1;
	if (w == 2) return h;
	if (h == 2) return w;

	cy = h / 2, cx = w / 2;

	len = (h + 1) * (w + 1);
	grid = realloc(grid, len);
	memset(grid, 0, len--);

	next[0] = -1;
	next[1] = -w - 1;
	next[2] = 1;
	next[3] = w + 1;

	if (recur) cnt = 0;
	for (x = cx + 1; x < w; x++) {
		t = cy * (w + 1) + x;
		grid[t] = 1;
		grid[len - t] = 1;
		walk(cy - 1, x);
	}
	cnt++;

	if (h == w)
		cnt *= 2;
	else if (!(w & 1) && recur)
		solve(w, h, 0);

	return cnt;
}

int main()
{
	int y, x;
	for (y = 1; y <= 10; y++)
		for (x = 1; x <= y; x++)
			if (!(x & 1) || !(y & 1))
				printf("%d x %d: %llu\n", y, x, solve(y, x, 1));

	return 0;
}


def divide = { Number x, Number y ->
  x / y
}

def partsOf120 = divide.curry(120)

println "120: half: ${partsOf120(2)}, third: ${partsOf120(3)}, quarter: ${partsOf120(4)}"


procedure main(A)
    add2 := addN(2)
    write("add2(7) = ",add2(7))
    write("add2(1) = ",add2(1))
end

procedure addN(n)
    return makeProc{ repeat { (x := (x@&source)[1], x +:= n) } }
end

procedure makeProc(A)
    return (@A[1], A[1])
end


#include <array>
#include <iostream>
#include <stack>
#include <vector>

const std::array<std::pair<int, int>, 4> DIRS = {
    std::make_pair(0, -1),
    std::make_pair(-1,  0),
    std::make_pair(0,  1),
    std::make_pair(1,  0),
};

void printResult(const std::vector<std::vector<int>> &v) {
    for (auto &row : v) {
        auto it = row.cbegin();
        auto end = row.cend();

        std::cout << '[';
        if (it != end) {
            std::cout << *it;
            it = std::next(it);
        }
        while (it != end) {
            std::cout << ", " << *it;
            it = std::next(it);
        }
        std::cout << "]\n";
    }
}

void cutRectangle(int w, int h) {
    if (w % 2 == 1 && h % 2 == 1) {
        return;
    }

    std::vector<std::vector<int>> grid(h, std::vector<int>(w));
    std::stack<int> stack;

    int half = (w * h) / 2;
    long bits = (long)pow(2, half) - 1;

    for (; bits > 0; bits -= 2) {
        for (int i = 0; i < half; i++) {
            int r = i / w;
            int c = i % w;
            grid[r][c] = (bits & (1 << i)) != 0 ? 1 : 0;
            grid[h - r - 1][w - c - 1] = 1 - grid[r][c];
        }

        stack.push(0);
        grid[0][0] = 2;
        int count = 1;
        while (!stack.empty()) {
            int pos = stack.top();
            stack.pop();

            int r = pos / w;
            int c = pos % w;
            for (auto dir : DIRS) {
                int nextR = r + dir.first;
                int nextC = c + dir.second;

                if (nextR >= 0 && nextR < h && nextC >= 0 && nextC < w) {
                    if (grid[nextR][nextC] == 1) {
                        stack.push(nextR * w + nextC);
                        grid[nextR][nextC] = 2;
                        count++;
                    }
                }
            }
        }
        if (count == half) {
            printResult(grid);
            std::cout << '\n';
        }
    }
}

int main() {
    cutRectangle(2, 2);
    cutRectangle(4, 3);

    return 0;
}


curry := method(fn,
	a := call evalArgs slice(1)
	block(
		b := a clone appendSeq(call evalArgs)
		performWithArgList("fn", b)
	)
)

// example:
increment := curry( method(a,b,a+b), 1 )
increment call(5)
// result => 6


   threePlus=: 3&+
   threePlus 7
10
   halve =: %&2  NB.  % means divide
   halve 20
10
   someParabola =: _2 3 1 &p. NB. x^2 + 3x - 2


    public class Currier<ARG1, ARG2, RET> {
        public interface CurriableFunctor<ARG1, ARG2, RET> {
            RET evaluate(ARG1 arg1, ARG2 arg2);
        }

        public interface CurriedFunctor<ARG2, RET> {
            RET evaluate(ARG2 arg);
        }

        final CurriableFunctor<ARG1, ARG2, RET> functor;

        public Currier(CurriableFunctor<ARG1, ARG2, RET> fn) { functor = fn; }

        public CurriedFunctor<ARG2, RET> curry(final ARG1 arg1) {
            return new CurriedFunctor<ARG2, RET>() {
                public RET evaluate(ARG2 arg2) {
                    return functor.evaluate(arg1, arg2);
                }
            };
        }

        public static void main(String[] args) {
            Currier.CurriableFunctor<Integer, Integer, Integer> add
                = new Currier.CurriableFunctor<Integer, Integer, Integer>() {
                    public Integer evaluate(Integer arg1, Integer arg2) {
                        return new Integer(arg1.intValue() + arg2.intValue());
                    }
            };

            Currier<Integer, Integer, Integer> currier
                = new Currier<Integer, Integer, Integer>(add);

            Currier.CurriedFunctor<Integer, Integer> add5
                = currier.curry(new Integer(5));

            System.out.println(add5.evaluate(new Integer(2)));
        }
    }


(defun cut-it (w h &optional (recur t))
  (if (oddp (* w h)) (return-from cut-it 0))
  (if (oddp h) (rotatef w h))
  (if (= w 1) (return-from cut-it 1))

  (let ((cnt 0)
	(m (make-array (list (1+ h) (1+ w))
		       :element-type 'bit
		       :initial-element 0))
	(cy (truncate h 2))
	(cx (truncate w 2)))

    (setf (aref m cy cx) 1)
    (if (oddp w) (setf (aref m cy (1+ cx)) 1))

    (labels
      ((walk (y x turned)
	     (when (or (= y 0) (= y h) (= x 0) (= x w))
	       (incf cnt (if turned 2 1))
	       (return-from walk))

	     (setf (aref m y x) 1)
	     (setf (aref m (- h y) (- w x)) 1)
	     (loop for i from 0
		   for (dy dx) in '((0 -1) (-1 0) (0 1) (1 0))
		   while (or turned (< i 2)) do
		   (let ((y2 (+ y dy))
			 (x2 (+ x dx)))
		     (when (zerop (aref m y2 x2))
		       (walk y2 x2 (or turned (> i 0))))))
	     (setf (aref m (- h y) (- w x)) 0)
	     (setf (aref m y x) 0)))

      (walk cy (1- cx) nil)
      (cond ((= h w) (incf cnt cnt))
	    ((oddp w) (walk (1- cy) cx t))
	    (recur (incf cnt (cut-it h w nil))))
    cnt)))

(loop for w from 1 to 9 do
      (loop for h from 1 to w do
	    (if (evenp (* w h))
	      (format t "~d x ~d: ~d~%" w h (cut-it w h)))))


 function addN(n) {
    var curry = function(x) {
        return x + n;
    };
    return curry;
 }

 add2 = addN(2);
 alert(add2);
 alert(add2(7));


def plus(x): . + x;

def plus5: plus(5);


function addN(n::Number)::Function
  adder(x::Number) = n + x
  return adder
end


// version 1.1.2

fun curriedAdd(x: Int) = { y: Int -> x + y }

fun main(args: Array<String>) {
    val a = 2
    val b = 3
    val sum = curriedAdd(a)(b)
    println("$a + $b = $sum")
}


import core.stdc.stdio, core.stdc.stdlib, core.stdc.string, std.typecons;

enum int[2][4] dir = [[0, -1], [-1, 0], [0, 1], [1, 0]];

__gshared ubyte[] grid;
__gshared uint w, h, len;
__gshared ulong cnt;
__gshared uint[4] next;

void walk(in uint y, in uint x) nothrow @nogc {
    if (!y || y == h || !x || x == w) {
        cnt += 2;
        return;
    }

    immutable t = y * (w + 1) + x;
    grid[t]++;
    grid[len - t]++;

    foreach (immutable i; staticIota!(0, 4))
        if (!grid[t + next[i]])
            walk(y + dir[i][0], x + dir[i][1]);

    grid[t]--;
    grid[len - t]--;
}

ulong solve(in uint hh, in uint ww, in bool recur) nothrow @nogc {
    h = (hh & 1) ? ww : hh;
    w = (hh & 1) ? hh : ww;

    if (h & 1) return 0;
    if (w == 1) return 1;
    if (w == 2) return h;
    if (h == 2) return w;

    immutable cy = h / 2;
    immutable cx = w / 2;

    len = (h + 1) * (w + 1);
    {
        // grid.length = len; // Slower.
        alias T = typeof(grid[0]);
        auto ptr = cast(T*)alloca(len * T.sizeof);
        if (ptr == null)
            exit(1);
        grid = ptr[0 .. len];
    }
    grid[] = 0;
    len--;

    next = [-1, -w - 1, 1, w + 1];

    if (recur)
        cnt = 0;
    foreach (immutable x; cx + 1 .. w) {
        immutable t = cy * (w + 1) + x;
        grid[t] = 1;
        grid[len - t] = 1;
        walk(cy - 1, x);
    }
    cnt++;

    if (h == w)
        cnt *= 2;
    else if (!(w & 1) && recur)
        solve(w, h, 0);

    return cnt;
}

void main() {
    foreach (immutable uint y; 1 .. 11)
        foreach (immutable uint x; 1 .. y + 1)
            if (!(x & 1) || !(y & 1))
                printf("%d x %d: %llu\n", y, x, solve(y, x, true));
}


1) just define function a binary function:
{def power {lambda {:a :b} {pow :a :b}}}
-> power

2) and use it:
{power 2 8}                            // power is a function waiting for two numbers
-> 256

{{power 2} 8}                          // {power 2} is a function waiting for the missing number
-> 256

{S.map {power 2} {S.serie 1 10}}       // S.map applies the {power 2} unary function
-> 2 4 8 16 32 64 128 256 512 1024     // to a sequence of numbers from 1 to 10


(defun curry (f arg)
  (lambda (x)
    (apply f
      (list arg x))))


| ?- logtalk << call([Z]>>(call([X,Y]>>(Y is X*X), 5, R), Z is R*R), T).
T = 625
yes


program Cut_a_rectangle;

{$APPTYPE CONSOLE}

uses
  System.SysUtils;

var
  grid: array of byte;
  w, h, len: Integer;
  cnt: UInt64;
  next: array of Integer;
  dir: array of array of Integer = [[0, -1], [-1, 0], [0, 1], [1, 0]];

procedure walk(y, x: Integer);
var
  i, t: Integer;
begin
  if (y = 0) or (y = h) or (x = 0) or (x = w) then
  begin
    inc(cnt);
    Exit;
  end;
  t := y * (w + 1) + x;
  inc(grid[t]);
  inc(grid[len - t]);

  for i := 0 to 3 do
    if grid[t + next[i]] = 0 then
      walk(y + dir[i][0], x + dir[i][1]);
  dec(grid[t]);
  dec(grid[len - t]);
end;

function solve(hh, ww: Integer; recur: Boolean): UInt64;
var
  t, cx, cy, x, i: Integer;
begin
  h := hh;
  w := ww;

  if Odd(h) then
  begin
    t := w;
    w := h;
    h := t;
  end;

  if Odd(h) then
    Exit(0);

  if w = 1 then
    Exit(1);

  if w = 2 then
    Exit(h);

  if h = 2 then
    Exit(w);

  cy := h div 2;
  cx := w div 2;
  len := (h + 1) * (w + 1);

  setlength(grid, len);

  for i := 0 to High(grid) do
    grid[i] := 0;

  dec(len);

  next := [-1, -w - 1, 1, w + 1];

  if recur then
    cnt := 0;

  for x := cx + 1 to w - 1 do
  begin
    t := cy * (w + 1) + x;
    grid[t] := 1;
    grid[len - t] := 1;
    walk(cy - 1, x);
  end;
  Inc(cnt);

  if h = w then
    inc(cnt, 2)
  else if not odd(w) and recur then
    solve(w, h, False);
  Result := cnt;
end;

var
  y, x: Integer;

begin
  for y := 1 to 10 do
    for x := 1 to y do
      if not Odd(x) or not Odd(y) then
        writeln(format('%d x %d:  %d', [y, x, solve(y, x, True)]));
  Readln;
end.


function curry2(f)
   return function(x)
      return function(y)
         return f(x,y)
      end
   end
end

function add(x,y)
   return x+y
end

local adder = curry2(add)
assert(adder(3)(4) == 3+4)
local add2 = adder(2)
assert(add2(3) == 2+3)
assert(add2(5) == 2+5)


Module LikeCpp {
      divide=lambda (x, y)->x/y
      partsof120=lambda divide ->divide(![], 120)
      Print "half of 120 is ";partsof120(2)
      Print "a third is ";partsof120(3)
      Print "and a quarter is ";partsof120(4)
}
LikeCpp

Module Joke {
      \\ we can call F1(),  with any number of arguments, and always read one and then
      \\ call itself passing the remain arguments
      \\ ![] take stack of values and place it in the next call.
      F1=lambda -> {
            if empty then exit
            Read x
            =x+lambda(![])
      }

      Print F1(F1(2),2,F1(-4))=0
      Print F1(-4,F1(2),2)=0
      Print F1(2, F1(F1(2),2))=F1(F1(F1(2),2),2)
      Print F1(F1(F1(2),2),2)=6
      Print F1(2, F1(2, F1(2),2))=F1(F1(F1(2),2, F1(2)),2)
      Print F1(F1(F1(2),2, F1(2)),2)=8
      Print F1(2, F1(10, F1(2, F1(2),2)))=F1(F1(F1(2),2, F1(2)),2, 10)
      Print F1(F1(F1(2),2, F1(2)),2, 10)=18
      Print F1(2,2,2,2,10)=18
      Print F1()=0

      Group F2 {
            Sum=0
            Function Add  (x){
                  .Sum+=x
                  =x
            }
      }
      Link F2.Add() to F2()
      Print F1(F1(F1(F2(2)),F2(2), F1(F2(2))),F2(2))=8
      Print F2.Sum=8
}
Joke


In[1]:=   plusFC = Function[{x},Function[{y},Plus[x,y]]];


using System;
using System.Console;

module Curry
{
    Curry[T, U, R](f : T * U -> R) : T -> U -> R
    {
        fun (x) { fun (y) { f(x, y) } }
    }

    Main() : void
    {
        def f(x, y) { x + y }
	def g = Curry(f);
	def h = Curry(f)(12);              // partial application
	WriteLine($"$(Curry(f)(20)(22))");
	WriteLine($"$(g(21)(21))");
	WriteLine($"$(h(30))")
    }
}


class
	APPLICATION

create
	make

feature {NONE} -- Initialization

	make
			-- Finds solution for cut a rectangle up to 10 x 10.
		local
			i, j, n: Integer
			r: GRID
		do
			n := 10
			from
				i := 1
			until
				i > n
			loop
				from
					j := 1
				until
					j > i
				loop
					if i.bit_and (1) /= 1 or j.bit_and (1) /= 1 then
						create r.make (i, j)
						r.print_solution
					end
					j := j + 1
				end
				i := i + 1
			end
		end

end


import  Integer

defmodule Rectangle do
  def cut_it(h, w) when is_odd(h) and is_odd(w), do: 0
  def cut_it(h, w) when is_odd(h), do: cut_it(w, h)
  def cut_it(_, 1), do: 1
  def cut_it(h, 2), do: h
  def cut_it(2, w), do: w
  def cut_it(h, w) do
    grid = List.duplicate(false, (h + 1) * (w + 1))
    t = div(h, 2) * (w + 1) + div(w, 2)
    if is_odd(w) do
      grid = grid |> List.replace_at(t, true) |> List.replace_at(t+1, true)
      walk(h, w, div(h, 2), div(w, 2) - 1, grid) + walk(h, w, div(h, 2) - 1, div(w, 2), grid) * 2
    else
      grid = grid |> List.replace_at(t, true)
      count = walk(h, w, div(h, 2), div(w, 2) - 1, grid)
      if h == w, do: count * 2,
               else: count + walk(h, w, div(h, 2) - 1, div(w, 2), grid)
    end
  end

  defp walk(h, w, y, x, grid, count\\0)
  defp walk(h, w, y, x,_grid, count) when y in [0,h] or x in [0,w], do: count+1
  defp walk(h, w, y, x, grid, count) do
    blen = (h + 1) * (w + 1) - 1
    t = y * (w + 1) + x
    grid = grid |> List.replace_at(t, true) |> List.replace_at(blen-t, true)
    Enum.reduce(next(w), count, fn {nt, dy, dx}, cnt ->
      if Enum.at(grid, t+nt), do: cnt, else: cnt + walk(h, w, y+dy, x+dx, grid)
    end)
  end

  defp next(w), do: [{w+1, 1, 0}, {-w-1, -1, 0}, {-1, 0, -1}, {1, 0, 1}]  # {next,dy,dx}
end

Enum.each(1..9, fn w ->
  Enum.each(1..w, fn h ->
    if is_even(w * h), do: IO.puts "#{w} x #{h}: #{Rectangle.cut_it(w, h)}"
  end)
end)


package main

import "fmt"

var grid []byte
var w, h, last int
var cnt int
var next [4]int
var dir = [4][2]int{{0, -1}, {-1, 0}, {0, 1}, {1, 0}}

func walk(y, x int) {
    if y == 0 || y == h || x == 0 || x == w {
        cnt += 2
        return
    }
    t := y*(w+1) + x
    grid[t]++
    grid[last-t]++
    for i, d := range dir {
        if grid[t+next[i]] == 0 {
            walk(y+d[0], x+d[1])
        }
    }
    grid[t]--
    grid[last-t]--
}

func solve(hh, ww, recur int) int {
    h = hh
    w = ww

    if h&1 != 0 {
        h, w = w, h
    }
    switch {
    case h&1 == 1:
        return 0
    case w == 1:
        return 1
    case w == 2:
        return h
    case h == 2:
        return w
    }
    cy := h / 2
    cx := w / 2

    grid = make([]byte, (h+1)*(w+1))
    last = len(grid) - 1
    next[0] = -1
    next[1] = -w - 1
    next[2] = 1
    next[3] = w + 1

    if recur != 0 {
        cnt = 0
    }
    for x := cx + 1; x < w; x++ {
        t := cy*(w+1) + x
        grid[t] = 1
        grid[last-t] = 1
        walk(cy-1, x)
    }
    cnt++

    if h == w {
        cnt *= 2
    } else if w&1 == 0 && recur != 0 {
        solve(w, h, 0)
    }
    return cnt
}

func main() {
    for y := 1; y <= 10; y++ {
        for x := 1; x <= y; x++ {
            if x&1 == 0 || y&1 == 0 {
                fmt.Printf("%d x %d: %d\n", y, x, solve(y, x, 1))
            }
        }
    }
}


proc addN[T](n: T): auto = (proc(x: T): T = x + n)

let add2 = addN(2)
echo add2(7)


let addnums x y = x+y        (* declare a curried function *)

let add1 = addnums 1         (* bind the first argument to get another function *)
add1 42                      (* apply to actually compute a result, 43 *)


class CutRectangle {
    private static int[][] dirs = [[0, -1], [-1, 0], [0, 1], [1, 0]]

    static void main(String[] args) {
        cutRectangle(2, 2)
        cutRectangle(4, 3)
    }

    static void cutRectangle(int w, int h) {
        if (w % 2 == 1 && h % 2 == 1) {
            return
        }

        int[][] grid = new int[h][w]
        Stack<Integer> stack = new Stack<>()

        int half = (int) ((w * h) / 2)
        long bits = (long) Math.pow(2, half) - 1

        for (; bits > 0; bits -= 2) {
            for (int i = 0; i < half; i++) {
                int r = (int) (i / w)
                int c = i % w
                grid[r][c] = (bits & (1 << i)) != 0 ? 1 : 0
                grid[h - r - 1][w - c - 1] = 1 - grid[r][c]
            }

            stack.push(0)
            grid[0][0] = 2
            int count = 1
            while (!stack.empty()) {
                int pos = stack.pop()
                int r = (int) (pos / w)
                int c = pos % w

                for (int[] dir : dirs) {
                    int nextR = r + dir[0]
                    int nextC = c + dir[1]

                    if (nextR >= 0 && nextR < h && nextC >= 0 && nextC < w) {
                        if (grid[nextR][nextC] == 1) {
                            stack.push(nextR * w + nextC)
                            grid[nextR][nextC] = 2
                            count++
                        }
                    }
                }
            }
            if (count == half) {
                printResult(grid)
            }
        }
    }

    static void printResult(int[][] arr) {
        for (int[] a : arr) {
            println(Arrays.toString(a))
        }
        println()
    }
}


sub curry{
  my ($func, @args) = @_;

  sub {
    #This @_ is later
    &$func(@args, @_);
  }
}

sub plusXY{
  $_[0] + $_[1];
}

my $plusXOne = curry(\&plusXY, 1);
print &$plusXOne(3), "\n";


with javascript_semantics
sequence curries = {}
function create_curried(integer rid, sequence partial_args)
    curries = append(curries,{rid,partial_args})
    return length(curries) -- (return an integer id)
end function

function call_curried(integer id, sequence args)
    {integer rid, sequence partial_args} = curries[id]
    return call_func(rid,partial_args&args)
end function

function add(atom a, b)
    return a+b
end function

integer curried = create_curried(routine_id("add"),{2})
printf(1,"2+5=%d\n",call_curried(curried,{5}))


import qualified Data.Vector.Unboxed.Mutable as V
import Data.STRef
import Control.Monad (forM_, when)
import Control.Monad.ST

dir :: [(Int, Int)]
dir = [(1, 0), (-1, 0), (0, -1), (0, 1)]

data Env = Env { w, h, len, count, ret :: !Int, next :: ![Int] }

cutIt :: STRef s Env -> ST s ()
cutIt env = do
    e <- readSTRef env
    when (odd $ h e) $ modifySTRef env $ \en -> en { h = w e,
        w = h e }
    e <- readSTRef env
    if odd (h e)
        then modifySTRef env $ \en -> en { ret = 0 }
        else
            if w e == 1
            then modifySTRef env $ \en -> en { ret = 1 }
            else do
                let blen = (h e + 1) * (w e + 1) - 1
                    t = (h e `div` 2) * (w e + 1) + (w e `div` 2)
                modifySTRef env $ \en -> en { len = blen,
                    count = 0,
                    next = [ w e + 1, (negate $ w e) - 1, -1, 1] }
                grid <- V.replicate (blen + 1) False
                case odd (w e) of
                    True -> do
                        V.write grid t True
                        V.write grid (t + 1) True
                        walk grid (h e `div` 2) (w e `div` 2 - 1)
                        e1 <- readSTRef env
                        let res1 = count e1
                        modifySTRef env $ \en -> en { count = 0 }
                        walk grid (h e `div` 2 - 1) (w e `div` 2)
                        modifySTRef env $ \en -> en { ret = res1 +
                            (count en * 2) }
                    False -> do
                        V.write grid t True
                        walk grid (h e `div` 2) (w e `div` 2 - 1)
                        e2 <- readSTRef env
                        let count2 = count e2
                        if h e == w e
                            then modifySTRef env $ \en -> en { ret =
                                count2 * 2 }
                            else do
                                walk grid (h e `div` 2 - 1)
                                    (w e `div` 2)
                                modifySTRef env $ \en -> en { ret =
                                    count en }
    where
        walk grid y x = do
            e <- readSTRef env
            if y <= 0 || y >= h e || x <= 0 || x >= w e
                then modifySTRef env $ \en -> en { count = count en + 1 }
                else do
                    let t = y * (w e + 1) + x
                    V.write grid t True
                    V.write grid (len e - t) True
                    forM_ (zip (next e) [0..3]) $ \(n, d) -> do
                        g <- V.read grid (t + n)
                        when (not g) $
                            walk grid (y + fst (dir !! d)) (x + snd (dir !! d))
                    V.write grid t False
                    V.write grid (len e - t) False

cut :: (Int, Int) -> Int
cut (x, y) = runST $ do
    env <- newSTRef $ Env { w = y, h = x, len = 0, count = 0, ret = 0, next = [] }
    cutIt env
    result <- readSTRef env
    return $ ret result

main :: IO ()
main = do
    mapM_ (\(x, y) -> when (even (x * y)) (putStrLn $
        show x ++ " x " ++ show y ++ ": " ++ show (cut (x, y))))
        [ (x, y) | x <- [1..10], y <- [1..x] ]


<?php

function curry($callable)
{
    if (_number_of_required_params($callable) === 0) {
        return _make_function($callable);
    }
    if (_number_of_required_params($callable) === 1) {
        return _curry_array_args($callable, _rest(func_get_args()));
    }
    return _curry_array_args($callable, _rest(func_get_args()));
}

function _curry_array_args($callable, $args, $left = true)
{
    return function () use ($callable, $args, $left) {
        if (_is_fullfilled($callable, $args)) {
            return _execute($callable, $args, $left);
        }
        $newArgs = array_merge($args, func_get_args());
        if (_is_fullfilled($callable, $newArgs)) {
            return _execute($callable, $newArgs, $left);
        }
        return _curry_array_args($callable, $newArgs, $left);
    };
}

function _number_of_required_params($callable)
{
    if (is_array($callable)) {
        $refl = new \ReflectionClass($callable[0]);
        $method = $refl->getMethod($callable[1]);
        return $method->getNumberOfRequiredParameters();
    }
    $refl = new \ReflectionFunction($callable);
    return $refl->getNumberOfRequiredParameters();
}

function _make_function($callable)
{
    if (is_array($callable))
        return function() use($callable) {
            return call_user_func_array($callable, func_get_args());
        };
    return $callable;
}

function _execute($callable, $args, $left)
{
    if (! $left) {
        $args = array_reverse($args);
    }
    $placeholders = _placeholder_positions($args);
    if (0 < count($placeholders)) {
        $n = _number_of_required_params($callable);
        if ($n <= _last($placeholders[count($placeholders) - 1])) {
            throw new \Exception('Argument Placeholder found on unexpected position!');
        }
        foreach ($placeholders as $i) {
            $args[$i] = $args[$n];
            array_splice($args, $n, 1);
        }
    }
    return call_user_func_array($callable, $args);
}

function _placeholder_positions($args)
{
    return array_keys(array_filter($args, '_is_placeholder'));
}

function _is_fullfilled($callable, $args)
{
    $args = array_filter($args, function($arg) {
        return ! _is_placeholder($arg);
    });
    return count($args) >= _number_of_required_params($callable);
}

function _is_placeholder($arg)
{
    return $arg instanceof Placeholder;
}

function _rest(array $args)
{
    return array_slice($args, 1);
}

function product($a, $b)
{
    return $a * $b;
}

echo json_encode(array_map(curry('product', 7), [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]));


init=: - {. 1:               NB. initial state: 1 square choosen
prop=: < {:,~2 ~:/\ ]        NB. propagate: neighboring squares (vertically)
poss=: [email protected],@(prop +. prop"1 +. prop&.|. +. prop&.|."1)
keep=: poss -. <:@#@, - [email protected], NB. symmetrically valid possibilities
N=: <:@-:@#@,                NB. how many neighbors to add
step=: [: [email protected];  <@(((= [email protected]$) +. ])"0 _~ keep)"2
all=: step^:[email protected]


import java.util.*;

public class CutRectangle {

    private static int[][] dirs = {{0, -1}, {-1, 0}, {0, 1}, {1, 0}};

    public static void main(String[] args) {
        cutRectangle(2, 2);
        cutRectangle(4, 3);
    }

    static void cutRectangle(int w, int h) {
        if (w % 2 == 1 && h % 2 == 1)
            return;

        int[][] grid = new int[h][w];
        Stack<Integer> stack = new Stack<>();

        int half = (w * h) / 2;
        long bits = (long) Math.pow(2, half) - 1;

        for (; bits > 0; bits -= 2) {

            for (int i = 0; i < half; i++) {
                int r = i / w;
                int c = i % w;
                grid[r][c] = (bits & (1 << i)) != 0 ? 1 : 0;
                grid[h - r - 1][w - c - 1] = 1 - grid[r][c];
            }

            stack.push(0);
            grid[0][0] = 2;
            int count = 1;
            while (!stack.empty()) {

                int pos = stack.pop();
                int r = pos / w;
                int c = pos % w;

                for (int[] dir : dirs) {

                    int nextR = r + dir[0];
                    int nextC = c + dir[1];

                    if (nextR >= 0 && nextR < h && nextC >= 0 && nextC < w) {

                        if (grid[nextR][nextC] == 1) {
                            stack.push(nextR * w + nextC);
                            grid[nextR][nextC] = 2;
                            count++;
                        }
                    }
                }
            }
            if (count == half) {
                printResult(grid);
            }
        }
    }

    static void printResult(int[][] arr) {
        for (int[] a : arr)
            System.out.println(Arrays.toString(a));
        System.out.println();
    }
}


: (de multiplier (@X)
   (curry (@X) (N) (* @X N)) )
-> multiplier
: (multiplier 7)
-> ((N) (* 7 N))
: ((multiplier 7) 3)
-> 21


function Add($x) { return { param($y) return $y + $x }.GetNewClosure() }


 ?- [library('lambda.pl')].
% library(lambda.pl) compiled into lambda 0,00 sec, 28 clauses
true.

 ?- N = 5, F = \X^Y^(Y is X+N), maplist(F, [1,2,3], L).
N = 5,
F = \X^Y^ (Y is X+5),
L = [6,7,8].


 def addN(n):
     def adder(x):
         return x + n
     return adder


  [ ' [ ' ] swap nested join
    ]'[ nested join ]        is curried ( x --> [ )


const count = [0]
const dir = [[0, -1], [-1, 0], [0, 1], [1, 0]]

function walk(y, x, h, w, grid, len, next)
    if y == 0 || y == h || x == 0 || x == w
        count[1] += 2
        return
    end
    t = y * (w + 1) + x
    grid[t + 1] += UInt8(1)
    grid[len - t + 1] += UInt8(1)
    for i in 1:4
        if grid[t + next[i] + 1] == 0
            walk(y + dir[i][1], x + dir[i][2], h, w, grid, len, next)
        end
    end
    grid[t + 1] -= 1
    grid[len - t + 1] -= 1
end

function cutrectangle(hh, ww, recur)
    if isodd(hh)
        h, w = ww, hh
    else
        h, w = hh, ww
    end
    if isodd(h)
        return 0
    elseif w == 1
        return 1
    elseif w == 2
        return h
    elseif h == 2
        return w
    end
    cy = div(h, 2)
    cx = div(w, 2)
    len = (h + 1) * (w + 1)
    grid = zeros(UInt8, len)
    len -= 1
    next = [-1, -w - 1, 1, w + 1]
    if recur
        count[1] = 0
    end
    for x in cx + 1:w - 1
        t = cy * (w + 1) + x
        grid[t + 1] = 1
        grid[len - t + 1] = 1
        walk(cy - 1, x, h, w, grid, len, next)
    end
    count[1] += 1
    if h == w
        count[1] *= 2
    elseif iseven(w) && recur
        cutrectangle(w, h, false)
    end
    return count[1]
end

function runtest()
    for y in 1:10, x in 1:y
        if iseven(x) || iseven(y)
            println("$y x $x: $(cutrectangle(y, x, true))")
        end
    end
end

runtest()


// version 1.0.6

object RectangleCutter {
    private var w: Int = 0
    private var h: Int = 0
    private var len: Int = 0
    private var cnt: Long = 0

    private lateinit var grid: ByteArray
    private val next = IntArray(4)
    private val dir = arrayOf(
        intArrayOf(0, -1),
        intArrayOf(-1, 0),
        intArrayOf(0, 1),
        intArrayOf(1, 0)
    )

    private fun walk(y: Int, x: Int) {
        if (y == 0 || y == h || x == 0 || x == w) {
            cnt += 2
            return
        }
        val t = y * (w + 1) + x
        grid[t]++
        grid[len - t]++
        (0..3).filter { grid[t + next[it]] == 0.toByte() }
            .forEach { walk(y + dir[it][0], x + dir[it][1]) }
        grid[t]--
        grid[len - t]--
    }

    fun solve(hh: Int, ww: Int, recur: Boolean): Long {
        var t: Int
        h = hh
        w = ww
        if ((h and 1) != 0) {
            t = w
            w = h
            h = t
        }
        if ((h and 1) != 0) return 0L
        if (w == 1) return 1L
        if (w == 2) return h.toLong()
        if (h == 2) return w.toLong()
        val cy = h / 2
        val cx = w / 2
        len = (h + 1) * (w + 1)
        grid = ByteArray(len)
        len--
        next[0] = -1
        next[1] = -w - 1
        next[2] = 1
        next[3] = w + 1
        if (recur) cnt = 0L
        for (x in cx + 1 until w) {
            t = cy * (w + 1) + x
            grid[t] = 1
            grid[len - t] = 1
            walk(cy - 1, x)
        }
        cnt++
        if (h == w) cnt *= 2
        else if ((w and 1) == 0 && recur) solve(w, h, false)
        return cnt
    }
}

fun main(args: Array<String>) {
    for (y in 1..10) {
        for (x in 1..y) {
            if ((x and 1) == 0 || (y and 1) == 0) {
                println("${"%2d".format(y)} x ${"%2d".format(x)}: ${RectangleCutter.solve(y, x, true)}")
            }
        }
    }
}


my &negative = &infix:<->.assuming(0);
say negative 1;


/*REXX program demonstrates a REXX    currying method    to perform addition.           */
say 'add 2 to 3:          '   add(2, 3)
say 'add 2 to 3 (curried):'   add2(3)
exit                                             /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
add:  procedure;  $= arg(1);       do j=2  to arg();   $= $ + arg(j);   end;      return $
add2: procedure;  return add( arg(1), 2)


function array1D(w, d)
    local t = {}
    for i=1,w do
        table.insert(t, d)
    end
    return t
end

function array2D(h, w, d)
    local t = {}
    for i=1,h do
        table.insert(t, array1D(w, d))
    end
    return t
end

function push(s, v)
    s[#s + 1] = v
end

function pop(s)
    return table.remove(s, #s)
end

function empty(s)
    return #s == 0
end

DIRS = {
    {0, -1},
    {-1, 0},
    {0, 1},
    {1, 0}
}

function printResult(aa)
    for i,u in pairs(aa) do
        io.write("[")
        for j,v in pairs(u) do
            if j > 1 then
                io.write(", ")
            end
            io.write(v)
        end
        print("]")
    end
end

function cutRectangle(w, h)
    if w % 2 == 1 and h % 2 == 1 then
        return nil
    end

    local grid = array2D(h, w, 0)
    local stack = {}

    local half = math.floor((w * h) / 2)
    local bits = 2 ^ half - 1

    while bits > 0 do
        for i=1,half do
            local r = math.floor((i - 1) / w)
            local c = (i - 1) % w
            if (bits & (1 << (i - 1))) ~= 0 then
                grid[r + 1][c + 1] = 1
            else
                grid[r + 1][c + 1] = 0
            end
            grid[h - r][w - c] = 1 - grid[r + 1][c + 1]
        end

        push(stack, 0)
        grid[1][1] = 2
        local count = 1
        while not empty(stack) do
            local pos = pop(stack)

            local r = math.floor(pos / w)
            local c = pos % w

            for i,dir in pairs(DIRS) do
                local nextR = r + dir[1]
                local nextC = c + dir[2]

                if nextR >= 0 and nextR < h and nextC >= 0 and nextC < w then
                    if grid[nextR + 1][nextC + 1] == 1 then
                        push(stack, nextR * w + nextC)
                        grid[nextR + 1][nextC + 1] = 2
                        count = count + 1
                    end
                end
            end
        end
        if count == half then
            printResult(grid)
            print()
        end

        -- loop end
        bits = bits - 2
    end
end

cutRectangle(2, 2)
cutRectangle(4, 3)


fn add_n(n : i32) -> impl Fn(i32) -> i32 {
    move |x| n + x
}

fn main() {
    let adder = add_n(40);
    println!("The answer to life is {}.", adder(2));
}


def add(a: Int)(b: Int) = a + b
val add5 = add(5) _
add5(2)


var adder = 1.method(:add);
say adder(3);                #=> 4


fun addnums (x:int) y = x+y  (* declare a curried function *)

val add1 = addnums 1         (* bind the first argument to get another function *)
add1 42                      (* apply to actually compute a result, 43 *)


func addN(n:Int)->Int->Int { return {$0 + n} }

var add2 = addN(2)
println(add2) // (Function)
println(add2(7)) // 9


import strformat

var
  w, h: int
  grid: seq[byte]
  next: array[4, int]
  count: int

const Dirs = [[0, -1], [-1, 0], [0, 1], [1, 0]]

template odd(n: int): bool = (n and 1) != 0

#------------------------------------------------------------------------------

proc walk(y, x: int) =

  if y == 0 or y == h or x == 0 or x == w:
    inc count, 2
    return

  let t = y * (w + 1) + x
  inc grid[t]
  inc grid[grid.high - t]

  for i, dir in Dirs:
    if grid[t + next[i]] == 0:
      walk(y + dir[0], x + dir[1])

  dec grid[t]
  dec grid[grid.high - t]

#------------------------------------------------------------------------------

proc solve(y, x: int; recursive: bool): int =

  h = y
  w = x
  if odd(h): swap w, h

  if odd(h): return 0
  if w == 1: return 1
  if w == 2: return h
  if h == 2: return w

  let cy = h div 2
  let cx = w div 2

  grid = newSeq[byte]((w + 1) * (h + 1))

  next[0] = -1
  next[1] = -w - 1
  next[2] = 1
  next[3] = w + 1

  if recursive: count = 0

  for x in (cx + 1)..<w:
    let t = cy * (w + 1) + x
    grid[t] = 1
    grid[grid.high - t] = 1
    walk(cy - 1, x)
  inc count

  if h == w:
    count *= 2
  elif not odd(w) and recursive:
    discard solve(w, h, false)

  result = count

#——————————————————————————————————————————————————————————————————————————————

for y in 1..10:
  for x in 1..y:
    if not odd(x) or not odd(y):
      echo &"{y:2d} x {x:2d}: {solve(y, x, true)}"


interp alias {} addone {} ::tcl::mathop::+ 1
puts [addone 6]; # => 7


delegate double Dbl_Op(double d);

Dbl_Op curried_add(double a) {
  return (b) => a + b;
}

void main() {
  print(@"$(curried_add(3.0)(4.0))\n");
  double sum2 = curried_add(2.0) (curried_add(3.0)(4.0)); //sum2 = 9
  print(@"$sum2\n");
}


Option Explicit On
Option Infer On
Option Strict On

Module Currying
    ' The trivial curry.
    Function Curry(Of T1, TResult)(func As Func(Of T1, TResult)) As Func(Of T1, TResult)
        ' At least satisfy the implicit contract that the result isn't reference-equal to the original function.
        Return Function(a) func(a)
    End Function

    Function Curry(Of T1, T2, TResult)(func As Func(Of T1, T2, TResult)) As Func(Of T1, Func(Of T2, TResult))
        Return Function(a) Function(b) func(a, b)
    End Function

    Function Curry(Of T1, T2, T3, TResult)(func As Func(Of T1, T2, T3, TResult)) As Func(Of T1, Func(Of T2, Func(Of T3, TResult)))
        Return Function(a) Function(b) Function(c) func(a, b, c)
    End Function

    ' And so on.
End Module


with javascript_semantics
integer show = 2,       -- max number to show
                        -- (nb mirrors are not shown)
        chance = 1000   -- 1=always, 2=50%, 3=33%, etc

sequence grid

integer gh, -- = length(grid),
        gw  -- = length(grid[1])

integer ty1, ty2, tx1, tx2  -- target {y,x}s

procedure mirror(integer y, x, ch)
-- plant/reset ch and the symmetric copy
    grid[y,x] = ch
    grid[gh-y+1,gw-x+1] = ch
end procedure

enum             RIGHT,  UP,   DOWN,  LEFT
constant dyx = {{0,+1},{-1,0},{+1,0},{0,-1}},
         chx = "-||-"

function search(integer y, x, d, level)
    integer count = 0
    if level=0 or grid[y,x]!='x' then
        mirror(y,x,'x')
        integer {dy,dx} = dyx[d],
                {ny,nx} = {y+dy,x+dx},
                {yy,xx} = {y+dy*2,x+dx*3}
        if grid[ny,nx]=' ' then
            integer c = chx[d]
            mirror(ny,nx,c)
            if c='-' then
                mirror(ny,nx+dx,c)
            end if
            integer meet = (yy=ty1 or yy=ty2) and (xx=tx1 or xx=tx2)
            if meet then
                count = 1
                if show and rand(chance)=chance then
                    show -= 1
                    sequence g = deep_copy(grid) -- (make copy/avoid reset)
                    -- fill in(/overwrite) the last cut, if any
                    if    ty1!=ty2 then g[ty1+1,tx1] = '|'
                    elsif tx1!=tx2 then g[ty1][tx1+1..tx1+2] = "--"
                    end if
                    puts(1,join(g,'\n')&"\n\n")
                end if
            else
                if grid[yy,xx]='+' then -- (minor gain)
                    for d=RIGHT to LEFT do -- (kinda true!)
                        count += search(yy,xx,d,level+1)
                    end for
                end if
            end if
            mirror(ny,nx,' ')
            if c='-' then
                mirror(ny,nx+dx,' ')
            end if
        end if
        if level!=0 then
            -- ((level=0)==leave outer edges 'x' for next iteration)
            mirror(y,x,'+')
        end if
    end if
    return count
end function

procedure make_grid(integer w,h)
-- The outer edges are 'x'; the inner '+' become 'x' when visited.
-- Likewise edges are cuts but the inner ones get filled in later.
sequence tb = join(repeat("x",w+1),"--"),
         hz = join('x'&repeat("+",w-1)&'x',"  ")&"\n",
         vt = "|"&repeat(' ',w*3-1)&"|\n"
    grid = split(tb&"\n"&join(repeat(vt,h),hz)&tb,'\n')
    -- set size (for mirroring) and target info:
    gh = length(grid)       gw = length(grid[1])
    ty1 = h+even(h)         ty2 = ty1+odd(h)*2
    tx1 = floor(w/2)*3+1    tx2 = tx1+odd(w)*3
end procedure

function side(integer w, h)
    make_grid(w,h)
    -- search top to mid-point
    integer count = 0, last = 0
    for r=3 to h+1 by 2 do
        last = search(r,1,RIGHT,0) -- left to right
        count += 2*last
    end for
    if even(h) then
        count -= last -- (un-double the centre line)
    end if
    return count
end function

--atom t0 = time()
-- nb sub-optimal: obviously "grid" was designed for easy display, rather than speed.
for y=1 to iff(platform()=JS?7:9) do        -- 24s
--for y=1 to 10 do      -- (gave up on >10x8)
    for x=1 to y do
--  for x=1 to min(y,8) do  -- 4 mins 16s (with y to 10)
        if even(x*y) then
            integer count = side(x,y)
            if x=y then
                count *= 2
            else
                count += side(y,x)
            end if
            printf(1,"%d x %d: %d\n", {y, x, count})
        end if
    end for
end for
--?elapsed(time()-t0)


@let {
  addOne \+ 1
  subtractFrom1 \- 1
  subtract1 \~- 1

  subtract1_2 &\- [. 1]

  add ^+
  ; partial apply to named functions
  addOne_2 \add 1

  ; testing
  [[
    !addOne 5 ; returns 6
    !subtractFrom1 5 ; returns -4
    !subtract1 5 ; returns 4
    !subtract1_2 5 ; returns 4
    !addOne_2 5 ; returns 6
  ]]
}


var addN = Fn.new { |n| Fn.new { |x| n + x } }

var adder = addN.call(40)
System.print("The answer to life is %(adder.call(2)).")


macro ResetCursors
ld hl,&0101
call &BB75
endm


addOne:= Op("+").fp(1); addOne(5) //-->6
minusOne:=Op("-").fp1(1); minusOne(5) //-->4, note that this fixed 1 as the second parameter
   // fix first and third parameters:
foo:=String.fpM("101","<foo>","</foo>"); foo("zkl"); //-->"<foo>zkl</foo>"
fcn g(x){x+1} f:=fcn(f,x){f(x)+x}.fp(g); f(5); //-->11
f:=fcn(f,x){f(x)+x}.fp(fcn(x){x+1}); // above with lambdas all the way down


def cut_it(h, w):
    dirs = ((1, 0), (-1, 0), (0, -1), (0, 1))
    if h % 2: h, w = w, h
    if h % 2: return 0
    if w == 1: return 1
    count = 0

    next = [w + 1, -w - 1, -1, 1]
    blen = (h + 1) * (w + 1) - 1
    grid = [False] * (blen + 1)

    def walk(y, x, count):
        if not y or y == h or not x or x == w:
            return count + 1

        t = y * (w + 1) + x
        grid[t] = grid[blen - t] = True

        if not grid[t + next[0]]:
            count = walk(y + dirs[0][0], x + dirs[0][1], count)
        if not grid[t + next[1]]:
            count = walk(y + dirs[1][0], x + dirs[1][1], count)
        if not grid[t + next[2]]:
            count = walk(y + dirs[2][0], x + dirs[2][1], count)
        if not grid[t + next[3]]:
            count = walk(y + dirs[3][0], x + dirs[3][1], count)

        grid[t] = grid[blen - t] = False
        return count

    t = h // 2 * (w + 1) + w // 2
    if w % 2:
        grid[t] = grid[t + 1] = True
        count = walk(h // 2, w // 2 - 1, count)
        res = count
        count = 0
        count = walk(h // 2 - 1, w // 2, count)
        return res + count * 2
    else:
        grid[t] = True
        count = walk(h // 2, w // 2 - 1, count)
        if h == w:
            return count * 2
        count = walk(h // 2 - 1, w // 2, count)
        return count

def main():
    for w in xrange(1, 10):
        for h in xrange(1, w + 1):
            if not((w * h) % 2):
                print "%d x %d: %d" % (w, h, cut_it(w, h))

main()


#lang racket

(define (cuts W H [count 0]) ; count = #f => visualize instead
  (define W1 (add1 W)) (define H1 (add1 H))
  (define B (make-vector (* W1 H1) #f))
  (define (fD d) (cadr (assq d '([U D] [D U] [L R] [R L] [#f #f] [#t #t]))))
  (define (fP p) (- (* W1 H1) p 1))
  (define (Bset! p d) (vector-set! B p d) (vector-set! B (fP p) (fD d)))
  (define center (/ (fP 0) 2))
  (when (integer? center) (Bset! center #t))
  (define (run c* d)
    (define p (- center c*))
    (Bset! p d)
    (let loop ([p p])
      (define-values [q r] (quotient/remainder p W1))
      (if (and (< 0 r W) (< 0 q H))
        (for ([d '(U D L R)])
          (define n (+ p (case d [(U) (- W1)] [(D) W1] [(L) -1] [(R) 1])))
          (unless (vector-ref B n) (Bset! n (fD d)) (loop n) (Bset! n #f)))
        (if count (set! count (add1 count)) (visualize B W H))))
    (Bset! p #f))
  (when (even? W) (run (if (odd? H) (/ W1 2) W1) 'D))
  (when (even? H) (run (if (odd? W) 1/2 1)       'R))
  (or count (void)))

(define (visualize B W H)
  (define W2 (+ 2 (* W 2))) (define H2 (+ 1 (* H 2)))
  (define str (make-string (* H2 W2) #\space))
  (define (Sset! i c) (string-set! str i c))
  (for ([i (in-range (- W2 1) (* W2 H2) W2)]) (Sset! i #\newline))
  (for ([i (in-range 0 (- W2 1))]) (Sset! i #\#) (Sset! (+ i (* W2 H 2)) #\#))
  (for ([i (in-range 0 (* W2 H2) W2)]) (Sset! i #\#) (Sset! (+ i W2 -2) #\#))
  (for* ([i (add1 W)] [j (add1 H)])
    (define p (* 2 (+ i (* j W2))))
    (define b (vector-ref B (+ i (* j (+ W 1)))))
    (cond [b (Sset! p #\#)
             (define d (case b [(U) (- W2)] [(D) W2] [(R) 1] [(L) -1]))
             (when (integer? d) (Sset! (+ p d) #\#))]
          [(equal? #\space (string-ref str p)) (Sset! p #\.)]))
  (display str) (newline))

(printf "Counts:\n")
(for* ([W (in-range 1 10)] [H (in-range 1 (add1 W))]
       #:unless (and (odd? W) (odd? H)))
  (printf "~s x ~s: ~s\n" W H (cuts W H)))

(newline)
(cuts 4 3 #f)


sub solve($hh, $ww, $recurse) {
    my ($h, $w, $t, @grid) = $hh, $ww, 0;
    state $cnt;
    $cnt = 0 if $recurse;

    ($t, $w, $h) = ($w, $h, $w) if $h +& 1;
    return 0  if $h == 1;
    return 1  if $w == 1;
    return $h if $w == 2;
    return $w if $h == 2;

    my ($cy, $cx) = ($h, $w) «div» 2;
    my $len = ($h + 1) × ($w + 1);
    @grid[$len--] = 0;
    my @next = -1, -$w-1, 1, $w+1;

    for $cx+1 ..^ $w -> $x {
        $t = $cy × ($w + 1) + $x;
        @grid[$_] = 1 for $t, $len-$t;
        walk($cy - 1, $x);
    }

    sub walk($y, $x) {
        constant @dir = <0 -1 0 1> Z <-1 0 1 0>;
        $cnt += 2 and return if not $y or $y == $h or not $x or $x == $w;
        my $t = $y × ($w+1) + $x;
        @grid[$_]++ for $t, $len-$t;
        walk($y + @dir[$_;0], $x + @dir[$_;1]) if not @grid[$t + @next[$_]] for 0..3;
        @grid[$_]-- for $t, $len-$t;
    }

    $cnt++;
    if    $h == $w                 { $cnt ×= 2            }
    elsif $recurse and not $w +& 1 { solve($w, $h, False) }
    $cnt
}

((1..9 X 1..9).grep:{ .[0] ≥ .[1] }).flat.map: -> $y, $x {
   say "$y × $x: " ~ solve $y, $x, True unless $x +& 1 and $y +& 1;
}


/*REXX program cuts rectangles into two symmetric pieces,  the rectangles are cut along */
/*────────────────────────────────────────────────── unit dimensions and may be rotated.*/
numeric digits 20                                /*be able to handle some big integers. */
parse arg N .;    if N=='' | N==","  then N= 10  /*N  not specified?   Then use default.*/
dir.= 0;   dir.0.1= -1;   dir.1.0= -1;   dir.2.1= 1;   dir.3.0= 1  /*the four directions*/

     do   y=2   to N;   say                      /*calculate rectangles up to size  NxN.*/
       do x=1  for y;   if x//2  &  y//2  then iterate            /*Both X&Y odd?  Skip.*/
       z= solve(y,x,1);  _= comma(z);  _= right(_, max(14, length(_)))   /*align output.*/
       say right(y, 9)    "x"    right(x, 2)    'rectangle can be cut'    _     "way"s(z).
       end   /*x*/
     end     /*y*/
exit                                             /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
comma: procedure; arg _;  do k=length(_)-3  to 1  by -3; _=insert(',',_,k); end;  return _
s:     if arg(1)=1  then return arg(3);   return word( arg(2) 's', 1)      /*pluralizer.*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
solve: procedure expose # @. dir. h len next. w;  @.= 0    /*zero rectangle coördinates.*/
       parse arg h,w,recur                                 /*get values for some args.  */
       if h//2  then do;    t= w;    w= h;    h= t;    if h//2  then return 0
                     end
       if w==1  then return 1
       if w==2  then return h
       if h==2  then return w                              /* [↓]  % is REXX's integer ÷*/
       cy= h % 2;       cx= w % 2;     wp= w + 1           /*cut the rectangle in half. */
       len= (h+1) * wp - 1                                 /*extend area of rectangle.  */
       next.0= '-1';    next.1= -wp;   next.2= 1;     next.3= wp  /*direction & distance*/
       if recur  then #= 0
       cywp= cy * wp                                              /*shortcut calculation*/
                        do x=cx+1  to  w-1;     t= cywp + x;          @.t= 1
                        _= len - t;             @._= 1;               call walk cy - 1,  x
                        end   /*x*/
       #= # + 1
       if h==w  then #= # + #                              /*double rectangle cut count.*/
                else if w//2==0  &  recur  then call solve w, h, 0
       return #
/*──────────────────────────────────────────────────────────────────────────────────────*/
walk:  procedure expose # @. dir. h len next. w wp;              parse arg y,x
       if y==h | x==0 | x==w | y==0  then do;   #= # + 2;        return;            end
       t= y*wp + x;     @.t= @.t + 1;           _= len - t
       @._= @._ + 1
                     do j=0  for 4;       _= t + next.j      /*try each of 4 directions.*/
                     if @._==0  then call walk  y + dir.j.0,     x + dir.j.1
                     end   /*j*/
       @.t= @.t - 1
       _= len - t;      @._= @._ - 1;           return


def cut_it(h, w)
  if h.odd?
    return 0  if w.odd?
    h, w = w, h
  end
  return 1  if w == 1

  nxt = [[w+1, 1, 0], [-w-1, -1, 0], [-1, 0, -1], [1, 0, 1]]  # [next,dy,dx]
  blen = (h + 1) * (w + 1) - 1
  grid = [false] * (blen + 1)

  walk = lambda do |y, x, count=0|
    return count+1  if y==0 or y==h or x==0 or x==w
    t = y * (w + 1) + x
    grid[t] = grid[blen - t] = true
    nxt.each do |nt, dy, dx|
      count += walk[y + dy, x + dx]  unless grid[t + nt]
    end
    grid[t] = grid[blen - t] = false
    count
  end

  t = h / 2 * (w + 1) + w / 2
  if w.odd?
    grid[t] = grid[t + 1] = true
    count = walk[h / 2, w / 2 - 1]
    count + walk[h / 2 - 1, w / 2] * 2
  else
    grid[t] = true
    count = walk[h / 2, w / 2 - 1]
    return count * 2  if h == w
    count + walk[h / 2 - 1, w / 2]
  end
end

for w in 1..9
  for h in 1..w
    puts "%d x %d: %d" % [w, h, cut_it(w, h)]  if (w * h).even?
  end
end


fn cwalk(mut vis: &mut Vec<Vec<bool>>, count: &mut isize, w: usize, h: usize, y: usize, x: usize, d: usize) {
    if x == 0 || y == 0 || x == w || y == h {
        *count += 1;
        return;
    }

    vis[y][x] = true;
    vis[h - y][w - x] = true;

    if x != 0 && ! vis[y][x - 1] {
        cwalk(&mut vis, count, w, h, y, x - 1, d | 1);
    }
    if d & 1 != 0 && x < w && ! vis[y][x+1] {
        cwalk(&mut vis, count, w, h, y, x + 1, d | 1);
    }
    if y != 0 && ! vis[y - 1][x] {
        cwalk(&mut vis, count, w, h, y - 1, x, d | 2);
    }
    if d & 2 != 0 && y < h && ! vis[y + 1][x] {
        cwalk(&mut vis, count, w, h, y + 1, x, d | 2);
    }

    vis[y][x] = false;
    vis[h - y][w - x] = false;
}

fn count_only(x: usize, y: usize) -> isize {
    let mut count = 0;
    let mut w = x;
    let mut h = y;

    if (h * w) & 1 != 0 {
        return count;
    }
    if h & 1 != 0 {
        std::mem::swap(&mut w, &mut h);
    }

    let mut vis = vec![vec![false; w + 1]; h + 1];
    vis[h / 2][w / 2] = true;

    if w & 1 != 0 {
        vis[h / 2][w / 2 + 1] = true;
    }
    let mut res;
    if w > 1 {
        cwalk(&mut vis, &mut count, w, h, h / 2, w / 2 - 1, 1);
        res = 2 * count - 1;
        count = 0;
        if w != h {
            cwalk(&mut vis, &mut count, w, h, h / 2 + 1, w / 2, if w & 1 != 0 { 3 } else { 2 });
        }
        res += 2 * count - if w & 1 == 0 { 1 } else { 0 };
    }
    else {
        res = 1;
    }

    if w == h {
        res = 2 * res + 2;
    }
    res
}

fn main() {
    for y in 1..10 {
        for x in 1..y + 1 {
            if x & 1 == 0 || y & 1 == 0 {
                println!("{} x {}: {}", y, x, count_only(x, y));
            }
        }
    }
}


package require Tcl 8.5

proc walk {y x} {
    global w ww h cnt grid len
    if {!$y || $y==$h || !$x || $x==$w} {
	incr cnt 2
	return
    }
    set t [expr {$y*$ww + $x}]
    set m [expr {$len - $t}]
    lset grid $t [expr {[lindex $grid $t] + 1}]
    lset grid $m [expr {[lindex $grid $m] + 1}]
    if {![lindex $grid [expr {$y*$ww + $x-1}]]} {
	walk $y [expr {$x-1}]
    }
    if {![lindex $grid [expr {($y-1)*$ww + $x}]]} {
	walk [expr {$y-1}] $x
    }
    if {![lindex $grid [expr {$y*$ww + $x+1}]]} {
	walk $y [expr {$x+1}]
    }
    if {![lindex $grid [expr {($y+1)*$ww + $x}]]} {
	walk [expr {$y+1}] $x
    }
    lset grid $t [expr {[lindex $grid $t] - 1}]
    lset grid $m [expr {[lindex $grid $m] - 1}]
}

# Factored out core of [solve]
proc SolveCore {} {
    global w ww h cnt grid len
    set ww [expr {$w+1}]
    set cy [expr {$h / 2}]
    set cx [expr {$w / 2}]

    set len [expr {($h+1) * $ww}]
    set grid [lrepeat $len 0]
    incr len -1

    for {set x $cx;incr x} {$x < $w} {incr x} {
	set t [expr {$cy*$ww+$x}]
	lset grid $t 1
	lset grid [expr {$len - $t}] 1
	walk [expr {$cy - 1}] $x
    }
    incr cnt
}
proc solve {H W} {
    global w h cnt
    set h $H
    set w $W
    if {$h & 1} {
	set h $W
	set w $H
    }
    if {$h & 1} {
	return 0
    }
    if {$w==1} {return 1}
    if {$w==2} {return $h}
    if {$h==2} {return $w}

    set cnt 0
    SolveCore
    if {$h==$w} {
	incr cnt $cnt
    } elseif {!($w & 1)} {
	lassign [list $w $h] h w
	SolveCore
    }
    return $cnt
}

apply {{limit} {
    for {set yy 1} {$yy <= $limit} {incr yy} {
	for {set xx 1} {$xx <= $yy} {incr xx} {
	    if {!($xx&1 && $yy&1)} {
		puts [format "%d x %d: %ld" $yy $xx [solve $yy $xx]]
	    }
	}
    }
}} 10


import "/fmt" for Fmt

var grid = []
var w = 0
var h = 0
var len = 0
var cnt = 0
var next = [0] * 4
var dir  = [[0, -1], [-1, 0], [0, 1], [1, 0]]

var walk // recursive
walk = Fn.new { |y, x|
    if (y == 0 || y == h || x == 0 || x == w) {
        cnt = cnt + 2
        return
    }
    var t = y * (w + 1) + x
    grid[t] = grid[t] + 1
    grid[len-t] = grid[len-t] + 1
    for (i in 0..3) {
        if (grid[t + next[i]] == 0) {
            System.write("") // guard against VM recursion bug
            walk.call(y + dir[i][0], x + dir[i][1])
        }
    }
    grid[t] = grid[t] - 1
    grid[len-t] = grid[len-t] - 1
}

var solve // recursive
solve = Fn.new { |hh, ww, recur|
    h = hh
    w = ww
    if (h&1 != 0) {
        var t = w
        w = h
        h = t
    }
    if (h&1 != 0) return 0
    if (w == 1) return 1
    if (w == 2) return h
    if (h == 2) return w
    var cy = (h/2).floor
    var cx = (w/2).floor
    len = (h + 1) * (w + 1)
    grid = List.filled(len, 0)
    len  = len - 1
    next[0] = -1
    next[1] = -w - 1
    next[2] = 1
    next[3] = w + 1
    if (recur) cnt = 0
    var x = cx + 1
    while (x < w) {
        var t = cy * (w + 1) + x
        grid[t] = 1
        grid[len-t] = 1
        walk.call(cy - 1, x)
        x = x + 1
    }
    cnt = cnt + 1
    if (h == w) {
        cnt = cnt * 2
    } else if ((w&1 == 0) && recur) {
        System.write("") // guard against VM recursion bug
        solve.call(w, h, false)
    }
    return cnt
}

for (y in 1..10) {
    for (x in 1..y) {
        if ((x&1 == 0) || (y&1 ==0)) {
            Fmt.print("$2d x $2d : $d", y, x, solve.call(y, x, true))
        }
    }
}


fcn cut_it(h,w){
   if(h.isOdd){
      if(w.isOdd) return(0);
      t,h,w=h,w,t;  // swap w,h: a,b=c,d --> a=c; b=d; so need a tmp
   }
   if(w==1) return(1);

   nxt :=T(T(w+1, 1,0), T(-w-1, -1,0), T(-1, 0,-1), T(1, 0,1)); #[next, dy,dx]
   blen:=(h + 1)*(w + 1) - 1;
   grid:=(blen + 1).pump(List(),False); //-->L(False,False...)

   walk:='wrap(y,x){ // lambda closure
      if(y==0 or y==h or x==0 or x==w) return(1);
      count,t:=0,y*(w + 1) + x;
      grid[t]=grid[blen - t]=True;
      foreach nt,dy,dx in (nxt){
         if(not grid[t + nt]) count+=self.fcn(y + dy, x + dx,vm.pasteArgs(2));
      }
      grid[t]=grid[blen - t]=False;
      count
   };

   t:=h/2*(w + 1) + w/2;
   if(w.isOdd){
      grid[t]=grid[t + 1]=True;
      count:=walk(h/2, w/2 - 1);
      count + walk(h/2 - 1, w/2)*2;
   }else{
      grid[t]=True;
      count:=walk(h/2, w/2 - 1);
      if(h==w) return(count*2);
      count + walk(h/2 - 1, w/2);
   }
}


F currency(units, subunits)
   R BigInt(units) * 100 + subunits

F currency_from_str(s)
   V (units, subunits) = s.split(‘.’)
   R BigInt(units) * 100 + Int(subunits)

F percentage(a, num, denom)
   R (a * num * 10 I/ denom + 5) I/ 10

F to_str(c)
   R String(c I/ 100)‘’‘.#02’.format(c % 100)

V hamburgers = currency(5, 50) * 4'000'000'000'000'000
V milkshakes = currency_from_str(‘2.86’) * 2
V beforeTax = hamburgers + milkshakes
V tax = percentage(beforeTax, 765, 10'000)
V total = beforeTax + tax

V maxlen = max(to_str(beforeTax).len, to_str(tax).len, to_str(total).len)

print(‘Total price before tax: ’to_str(beforeTax).rjust(maxlen))
print(‘Tax:                    ’to_str(tax).rjust(maxlen))
print(‘Total with tax:         ’to_str(total).rjust(maxlen))


with Ada.Text_IO;

procedure Currency is
   type Dollar is delta 0.01 range 0.0 .. 24_000_000_000_000_000.0;
   package Dollar_IO is new Ada.Text_IO.Fixed_IO(Dollar);

   hamburger_cost : constant := 5.50;
   milkshake_cost : constant := 2.86;
   tax_rate : constant := 0.0765;

   total_cost : constant := hamburger_cost * 4_000_000_000_000_000.0 + milkshake_cost * 2;
   total_tax : constant := total_cost * tax_rate;
   total_with_tax : constant := total_cost + total_tax;
begin
   Ada.Text_IO.Put("Price before tax:");
   Dollar_IO.Put(total_cost);
   Ada.Text_IO.New_Line;

   Ada.Text_IO.Put("Tax:             ");
   Dollar_IO.Put(total_tax);
   Ada.Text_IO.New_Line;

   Ada.Text_IO.Put("Total:           ");
   Dollar_IO.Put(total_with_tax);
   Ada.Text_IO.New_Line;
end Currency;


BEGIN
    # currency calculations                                              #
    # simple fixed point type, LONG INT is 64-bit in Algol 68G           #
    MODE FIXED    = STRUCT( LONG INT value
                          , INT      decimals
                          , INT      fraction modulus
                          );
    # make CURRENCY a synonym for FIXED                                  #
    MODE CURRENCY = FIXED;
    # dyadic operator so we can write e.g. 5 DOLLARS 50 to construct     #
    # a CURRENCY value with 2 decimal places                             #
    PRIO DOLLARS = 9;
    OP DOLLARS = ( LONG INT v, INT dp )CURRENCY: ( ( v * 100 ) + dp, 2, 100 );
    OP DOLLARS = (      INT v, INT dp )CURRENCY: LENG v DOLLARS dp;
    # issues an error message and stops the program if a has a different #
    # number of decimal places to b                                      #
    PROC check compatible = ( CURRENCY a, b )VOID:
         IF decimals OF a /= decimals OF b THEN print( ( "Incompatible CURRENCY values", newline ) ); stop FI;
    # operators to multiply CURRENCY values by integers                  #
    OP * = ( CURRENCY v, LONG INT m )CURRENCY: ( value OF v * m, decimals OF v, fraction modulus OF v );
    OP * = ( CURRENCY v,      INT m )CURRENCY: v * LENG m;
    # returns the CURRENCY value a + b                                   #
    OP + = ( CURRENCY a, CURRENCY b )CURRENCY:
         BEGIN
            check compatible( a, b );
            ( value OF a + value OF b, decimals OF a, fraction modulus OF a )
         END # + # ;
    # multiplies the CURRENCY value a by the FIXED value b,              #
    # rounding the result to the decimal places of a                     #
    OP * = ( CURRENCY a, FIXED b )CURRENCY:
         BEGIN
            LONG INT result := ( value OF a * value OF b );
            IF decimals OF b > 0 THEN
                INT d                = fraction modulus OF b;
                LONG INT abs result := ABS result;
                INT extra places     = SHORTEN ( abs result MOD d );
                abs result OVERAB d;
                IF extra places >= d OVER 2 THEN abs result +:= 1 FI;
                IF result < 0 THEN result := - abs result ELSE result := abs result FI
            FI;
            ( result, decimals OF a, fraction modulus OF a )
         END # * # ;
    # converts a FIXED value to a STRING with the appropriate number of  #
    # decimal places                                                     #
    OP TOSTRING = ( FIXED v )STRING:
         IF decimals OF v < 1 THEN
            whole( value OF v, 0 )
         ELSE
            INT    d       = fraction modulus OF v;
            STRING result := whole( value OF v OVER d, 0 );
            STRING dp     := whole( ( ABS value OF v ) MOD d, - decimals OF v );
            FOR i FROM LWB dp TO UPB dp DO IF dp[ i ] = " " THEN dp[ i ] := "0" FI OD;
            result + "." + dp
         FI # TOSTRING # ;
    # Task calculations                                                   #
    CURRENCY hb    = 5 DOLLARS 50 * LONG 4000000000000000;
    CURRENCY ms    = 2 DOLLARS 86 * 2;
    FIXED    rate  = ( 765, 4, 10 000 ); # 0.0765                         #
    CURRENCY net   = hb + ms;
    CURRENCY tax   = net * rate;
    CURRENCY total = net + tax;
    print( ( "before tax: ", TOSTRING net,   newline ) );
    print( ( "tax:        ", TOSTRING tax,   newline ) );
    print( ( "total:      ", TOSTRING total, newline ) )
END


use AppleScript version "2.4" -- OS X 10.10 (Yosemite) or later
use framework "Foundation"

-- Derive an NSDecimalNumber from an AppleScript number or numeric text.
-- NSDecimalNumbers also allow arithmetic and have a far greater range than AS numbers.
on decimalNumberFrom(n)
    return current application's class "NSDecimalNumber"'s decimalNumberWithString:(n as text)
end decimalNumberFrom

-- Multiply two NSDecimalNumbers.
on multiply(dn1, dn2)
    return dn1's decimalNumberByMultiplyingBy:(dn2)
end multiply

-- Add two NSDecimalNumbers.
on add(dn1, dn2)
    return dn1's decimalNumberByAdding:(dn2)
end add

on billTotal(quantitiesAndPrices, taxRate, currencySymbol)
    -- Set up an NSNumberFormatter for converting between currency strings and NSDecimalNumbers.
    set currencyFormatter to current application's class "NSNumberFormatter"'s new()
    tell currencyFormatter to setNumberStyle:(current application's NSNumberFormatterCurrencyStyle)
    tell currencyFormatter to setCurrencySymbol:(currencySymbol)
    tell currencyFormatter to setGeneratesDecimalNumbers:(true)

    -- Tot up the bill from the list of quantities (numbers or numeric strings) and unit prices (currency strings with symbols).
    set subtotal to decimalNumberFrom(0) -- or:  current application's class "NSDecimalNumber"'s zero()
    repeat with thisEntry in quantitiesAndPrices
        set {quantity:quantity, unitPrice:unitPrice} to thisEntry
        set entryTotal to multiply(decimalNumberFrom(quantity), currencyFormatter's numberFromString:(unitPrice))
        set subtotal to add(subtotal, entryTotal)
    end repeat
    -- Work out the tax and add it to the subtotal.
    set tax to multiply(subtotal, decimalNumberFrom(taxRate / 100))
    set total to add(subtotal, tax)

    -- Format and return the results.
    return (current application's class "NSString"'s stringWithFormat_("Subtotal:  %@
Tax:  %@
Total:  %@", ¬
        currencyFormatter's stringFromNumber:(subtotal), ¬
        currencyFormatter's stringFromNumber:(tax), ¬
        currencyFormatter's stringFromNumber:(total))) ¬
        as text
end billTotal

-- Demo code:
set currencySymbol to "$"
set quantitiesAndPrices to {{quantity:"4000000000000000", unitPrice:currencySymbol & "5.50"}, ¬
    {quantity:2, unitPrice:currencySymbol & 2.86}}
set taxRate to 7.65
return billTotal(quantitiesAndPrices, taxRate, currencySymbol)


# syntax: GAWK -M -f CURRENCY.AWK
# using GNU Awk 4.1.1, API: 1.1 (GNU MPFR 3.1.2, GNU MP 5.1.2)
BEGIN {
    PREC = 100
    hamburger_p = 5.50
    hamburger_q = 4000000000000000
    hamburger_v = hamburger_p * hamburger_q
    milkshake_p = 2.86
    milkshake_q = 2
    milkshake_v = milkshake_p * milkshake_q
    subtotal = hamburger_v + milkshake_v
    tax = subtotal * .0765
    printf("%-9s %8s %18s %22s\n","item","price","quantity","value")
    printf("hamburger %8.2f %18d %22.2f\n",hamburger_p,hamburger_q,hamburger_v)
    printf("milkshake %8.2f %18d %22.2f\n\n",milkshake_p,milkshake_q,milkshake_v)
    printf("%37s %22.2f\n","subtotal",subtotal)
    printf("%37s %22.2f\n","tax",tax)
    printf("%37s %22.2f\n","total",subtotal+tax)
    exit(0)
}


  div$((4000000000000000*550+2*286)+1/2,1):?before-tax
& div$(!before-tax*765/10000+1/2,1):?tax
& !before-tax+!tax:?after-tax
& ( fix
  =   cents dollars
    .   mod$(!arg.100):?cents
      & ( !cents:<10&0 !cents:?cents
        |
        )
      & div$(!arg.100):?dollars
      & str$(!dollars "." !cents)
  )
&   str
  $ ( "before-tax "
      fix$!before-tax
      "\ntax "
      fix$!tax
      \n
      "after-tax "
      fix$!after-tax
      \n
    )


Floating point number or Float for short, is an arbitrary precision mantissa with a limited precision exponent. The C data type for such objects is mpf_t. For example:

mpf_t fp;


using System;
using System.Collections.Generic;

namespace Currency
{
    class Program
    {
        static void Main(string[] args)
        {
            MenuItem hamburger = new MenuItem() { Name = "Hamburger", Price = 5.5M };
            MenuItem milkshake = new MenuItem() { Name = "Milkshake", Price = 2.86M };

            IList<CartItem> cart = new List<CartItem>();
            cart.Add(new CartItem() { item = hamburger, quantity = 4000000000000000 });
            cart.Add(new CartItem() { item = milkshake, quantity = 2 });

            decimal total = CalculateTotal(cart);

            Console.WriteLine(string.Format("Total before tax: {0:C}", total));

            // Add Tax
            decimal tax = total * 0.0765M;

            Console.WriteLine(string.Format("Tax: {0:C}", tax));

            total += tax;

            Console.WriteLine(string.Format("Total with tax: {0:C}", total));
        }

        private static decimal CalculateTotal(IList<CartItem> cart)
        {
            decimal total = 0M;

            foreach (CartItem item in cart)
            {
                total += item.quantity * item.item.Price;
            }

            return total;
        }

        private struct MenuItem
        {
            public string Name { get; set; }
            public decimal Price { get; set; }
        }

        private struct CartItem
        {
            public MenuItem item { get; set; }
            public decimal quantity { get; set; }
        }
    }
}


(require '[clojurewerkz.money.amounts    :as ma])
(require '[clojurewerkz.money.currencies :as mc])
(require '[clojurewerkz.money.format     :as mf])

(let [burgers (ma/multiply (ma/amount-of mc/USD 5.50) 4000000000000000)
      milkshakes (ma/multiply (ma/amount-of mc/USD 2.86) 2)
      pre-tax (ma/plus burgers milkshakes)
      tax (ma/multiply pre-tax 0.0765 :up)]
  (println "Total before tax: " (mf/format pre-tax))
  (println "             Tax: " (mf/format tax))
  (println "  Total with tax: " (mf/format (ma/plus pre-tax tax))))


       >>SOURCE FREE
IDENTIFICATION DIVISION.
PROGRAM-ID. currency-example.

DATA DIVISION.
WORKING-STORAGE SECTION.
01  Burger-Price                        CONSTANT 5.50.
01  Milkshake-Price                     CONSTANT 2.86.
01  num-burgers                         PIC 9(18) VALUE 4000000000000000.
01  num-milkshakes                      PIC 9(18) VALUE 2.
01  tax                                 PIC 9(18)V99.
01  tax-edited                          PIC $(17)9.99.
01  Tax-Rate                            CONSTANT 7.65.
01  total                               PIC 9(18)V99.
01  total-edited                        PIC $(17)9.99.

PROCEDURE DIVISION.
    COMPUTE total rounded, total-edited rounded =
        num-burgers * Burger-Price + num-milkshakes * Milkshake-Price
    DISPLAY "Total before tax: " total-edited

    COMPUTE tax rounded, tax-edited rounded = total * (Tax-Rate / 100)
    DISPLAY "             Tax: " tax-edited

    ADD tax TO total GIVING total-edited rounded
    DISPLAY "  Total with tax: " total-edited
    .
END PROGRAM currency-example.


program Currency;

{$APPTYPE CONSOLE}

uses
  System.SysUtils,
  Velthuis.BigRationals,
  Velthuis.BigDecimals,
  Velthuis.BigIntegers;

var
  one: BigInteger;
  hundred: BigInteger;
  half: BigRational;

type
  TDc = record
    value: BigInteger;
    function ToString: string;
    function Extend(n: BigInteger): TDc;
    class operator Add(a, b: TDc): TDc;
  end;

  TTR = record
    value: BigRational;
    function SetString(const s: string; var TR: TTR): boolean;
    function Tax(dc: TDc): TDc;
  end;

{ TDc }

// Extend returns extended price of a unit price.
class operator TDc.Add(a, b: TDc): TDc;
begin
  Result.value := a.value + b.value;
end;

function TDc.Extend(n: BigInteger): TDc;
begin
  Result.value := n * value;
end;

function TDc.ToString: string;
var
  d: BigInteger;
begin
  d := value.Divide(value, 100);
  if value < 0 then
    value := -value;
  Result := Format('%s.%2s', [d.ToString, (value mod 100).ToString]);
end;

// ParseDC parses dollars and cents as a string into a DC.
function ParseDC(s: string; var Dc: TDc): Boolean;
var
  r: BigRational;
  d: BigDecimal;
begin
  Result := d.TryParse(s, d);
  if not Result then
  begin
    Dc.value := 0;
    exit(false);
  end;

  r := r.Create(d);
  r := r.Multiply(r, 100);
  if BigInteger.Compare(r.Denominator, 1) <> 0 then
  begin
    Dc.value := 0;
    exit(false);
  end;
  Result := true;
  Dc.value := r.Numerator;
end;

{ TTR }

function TTR.SetString(const s: string; var TR: TTR): boolean;
var
  d: BigDecimal;
begin

  Result := d.TryParse(s, d);
  if Result then
    TR.value := BigRational.Create(d);
end;

function TTR.Tax(dc: TDc): TDc;
var
  r: BigRational;
  i: BigInteger;
begin
  r := BigRational.Create(dc.value, 1);
  r := r.Multiply(r, self.value);
  r := r.add(r, half);
  i := i.Divide(r.Numerator, r.Denominator);
  Result.value := i;
end;

var
  hamburgerPrice, milkshakePrice, totalBeforeTax, tax, total: TDc;
  taxRate: TTR;

begin
  one := 1;
  hundred := 100;
  half := BigRational.Create(1, 2);

  if not ParseDC('5.50', hamburgerPrice) then
  begin
    Writeln('Invalid hamburger price');
    halt(1);
  end;

  if not ParseDC('2.86', milkshakePrice) then
  begin
    Writeln('Invalid milkshake price');
    halt(2);
  end;

  if not taxRate.SetString('0.0765', taxRate) then
  begin
    Writeln('Invalid tax rat');
    halt(3);
  end;

  totalBeforeTax := hamburgerPrice.Extend(4000000000000000) + milkshakePrice.Extend(2);
  tax := taxRate.Tax(totalBeforeTax);
  total := totalBeforeTax + tax;
  Writeln('Total before tax: ', totalBeforeTax.ToString: 22);
  Writeln('             Tax: ', tax.ToString: 22);
  Writeln('           Total: ', total.ToString: 22);
  readln;
end.


open System

let hamburgers = 4000000000000000M
let hamburgerPrice = 5.50M
let milkshakes = 2M
let milkshakePrice = 2.86M
let taxRate = 0.0765M

let total = hamburgers * hamburgerPrice + milkshakes * milkshakePrice
let tax = total * taxRate
let totalWithTax = total + tax

printfn "Total before tax:\t$%M" <| Math.Round (total, 2)
printfn "             Tax:\t$%M" <| Math.Round (tax, 2)
printfn "           Total:\t$%M" <| Math.Round (totalWithTax, 2)


USING: combinators.smart io kernel math math.functions money ;

10 15 ^ 4 * 5+50/100 * ! hamburger subtotal
2 2+86/100 *           ! milkshake subtotal
+                      ! subtotal
dup DECIMAL: 0.0765 *  ! tax
[ + ] preserving       ! total

"Total before tax: " write [ money. ] 2dip
"Tax: " write [ money. ] dip
"Total with tax: " write money.


Dim As Longint hamburger_p = 550
Dim As Longint hamburger_q = 4000000000000000
Dim As Longint hamburger_v = hamburger_p * hamburger_q
Dim As Longint milkshake_p = 286
Dim As Longint milkshake_q = 2
Dim As Longint milkshake_v = milkshake_p * milkshake_q
Dim As Longint subtotal = hamburger_v + milkshake_v
Dim As Longint tax = subtotal * .765
Print Using "\   \       \     \          \       \                    \     \";"item";"price";"quantity";"value"
Print Using "hamburger   ##.##    ################  #####################.##";hamburger_p/100;hamburger_q;hamburger_v/100
Print Using "milkshake   ##.##    ################  #####################.##";milkshake_p/100;milkshake_q;milkshake_v/100
?
Print Using "                             subtotal  #####################.##";subtotal/10
Print Using "                                  tax  #####################.##";tax/100
Print Using "                                total  #####################.##";subtotal/10+tax/100
Sleep


st = 4000000000000000 * 5.50 dollars + 2 * 2.86 dollars
tax = round[st * 7.65 percent, cent]
total = st + tax
println["Subtotal: " + format[st, "dollars", 2]]
println["Tax: " + format[tax, "dollars", 2]]
println["Total: " + format[total, "dollars", 2]]


package main

import (
    "fmt"
    "log"
    "math/big"
)

// DC for dollars and cents.  Value is an integer number of cents.
type DC int64

func (dc DC) String() string {
    d := dc / 100
    if dc < 0 {
        dc = -dc
    }
    return fmt.Sprintf("%d.%02d", d, dc%100)
}

// Extend returns extended price of a unit price.
func (dc DC) Extend(n int) DC {
    return dc * DC(n)
}

var one = big.NewInt(1)
var hundred = big.NewRat(100, 1)

// ParseDC parses dollars and cents as a string into a DC.
func ParseDC(s string) (DC, bool) {
    r, ok := new(big.Rat).SetString(s)
    if !ok {
        return 0, false
    }
    r.Mul(r, hundred)
    if r.Denom().Cmp(one) != 0 {
        return 0, false
    }
    return DC(r.Num().Int64()), true
}

// TR for tax rate.  Value is an an exact rational.
type TR struct {
    *big.Rat
}
func NewTR() TR {
    return TR{new(big.Rat)}
}

// SetString overrides Rat.SetString to return the TR type.
func (tr TR) SetString(s string) (TR, bool) {
    if _, ok := tr.Rat.SetString(s); !ok {
        return TR{}, false
    }
    return tr, true
}

var half = big.NewRat(1, 2)

// Tax computes a tax amount, rounding to the nearest cent.
func (tr TR) Tax(dc DC) DC {
    r := big.NewRat(int64(dc), 1)
    r.Add(r.Mul(r, tr.Rat), half)
    return DC(new(big.Int).Div(r.Num(), r.Denom()).Int64())
}

func main() {
    hamburgerPrice, ok := ParseDC("5.50")
    if !ok {
        log.Fatal("Invalid hamburger price")
    }
    milkshakePrice, ok := ParseDC("2.86")
    if !ok {
        log.Fatal("Invalid milkshake price")
    }
    taxRate, ok := NewTR().SetString("0.0765")
    if !ok {
        log.Fatal("Invalid tax rate")
    }

    totalBeforeTax := hamburgerPrice.Extend(4000000000000000) +
        milkshakePrice.Extend(2)
    tax := taxRate.Tax(totalBeforeTax)
    total := totalBeforeTax + tax

    fmt.Printf("Total before tax: %22s\n", totalBeforeTax)
    fmt.Printf("             Tax: %22s\n", tax)
    fmt.Printf("           Total: %22s\n", total)
}


import Data.Fixed
import Text.Printf

type Percent = Centi
type Dollars = Centi

tax :: Percent -> Dollars -> Dollars
tax rate = MkFixed . round . (rate *)

printAmount :: String -> Dollars -> IO ()
printAmount name = printf "%-10s %20s\n" name . showFixed False

main :: IO ()
main = do
  let subtotal = 4000000000000000 * 5.50 + 2 * 2.86
      tx       = tax 7.65 subtotal
      total    = subtotal + tx
  printAmount "Subtotal" subtotal
  printAmount "Tax"      tx
  printAmount "Total"    total


require 'format/printf'

Items=:    ;:    'Hamburger     Milkshake'
Quantities=:   4000000000000000      2
Prices=:   x:        5.50          2.86
Tax_rate=: x:  0.0765

makeBill=: verb define
  'items prices quantities'=. y
  values=. prices * quantities
  subtotal=. +/ values
  tax=. Tax_rate * subtotal
  total=. subtotal + tax

  '%9s %8s %20s %22s' printf ;:'Item Price Quantity Value'
  '%9s %8.2f %20d %22.2f' printf"1 items ,. <"0 prices ,. quantities ,. values
  '%62s' printf <'-------------------------------'
  '%40s %21.2f' printf"1 (;:'Subtotal: Tax: Total:') ,. subtotal;tax;total
)

makeBill Items;Prices;Quantities


import java.math.*;
import java.util.*;

public class Currency {
    final static String taxrate = "7.65";

    enum MenuItem {

        Hamburger("5.50"), Milkshake("2.86");

        private MenuItem(String p) {
            price = new BigDecimal(p);
        }

        public final BigDecimal price;
    }

    public static void main(String[] args) {
        Locale.setDefault(Locale.ENGLISH);

        MathContext mc = MathContext.DECIMAL128;

        Map<MenuItem, BigDecimal> order = new HashMap<>();
        order.put(MenuItem.Hamburger, new BigDecimal("4000000000000000"));
        order.put(MenuItem.Milkshake, new BigDecimal("2"));

        BigDecimal subtotal = BigDecimal.ZERO;
        for (MenuItem it : order.keySet())
            subtotal = subtotal.add(it.price.multiply(order.get(it), mc));

        BigDecimal tax = new BigDecimal(taxrate, mc);
        tax = tax.divide(new BigDecimal("100"), mc);
        tax = subtotal.multiply(tax, mc);

        System.out.printf("Subtotal: %20.2f%n", subtotal);
        System.out.printf("     Tax: %20.2f%n", tax);
        System.out.printf("   Total: %20.2f%n", subtotal.add(tax));
    }
}


const money = require('money-math')

let hamburgers = 4000000000000000
let hamburgerPrice = 5.50

let shakes = 2
let shakePrice = 2.86

let tax = 7.65

let hamburgerTotal = money.mul(hamburgers.toFixed(0), money.floatToAmount(hamburgerPrice))
let shakeTotal = money.mul(shakes.toFixed(0), money.floatToAmount(shakePrice))

let subTotal = money.add(hamburgerTotal, shakeTotal)

let taxTotal = money.percent(subTotal, tax)

let total = money.add(subTotal, taxTotal)

console.log('Hamburger Total:', hamburgerTotal)
console.log('Shake Total:', shakeTotal)
console.log('Sub Total:', subTotal)
console.log('Tax:', taxTotal)
console.log('Total:', total)


def lpad($len): tostring | ($len - length) as $l | (" " * $l)[:$l] + .;

# print as dollars and cents
def dollars:
  (. % 100) as $c
  | "$\((. - $c) /100).\($c)";

def dollars($width):
  dollars | lpad($width);

def innerproduct($y):
  . as $x
  | reduce range(0;$x|length) as $i (0; . + ($x[$i]*$y[$i]));

def plus($y):
  . as $x
  | reduce range(0;$x|length) as $i ([]; .[$i] = ($x[$i]+$y[$i]));

# Round up or down
def integer_division($y):
  (. % $y) as $remainder
  | (. - $remainder) / $y
  | if $remainder * 2 > $y then . + 1 else . end;

# For computing taxes
def precision: 10000;
def cents: integer_division(precision);

### The task:

def p: [550, 286];
def q: [4000000000000000, 2];

def taxrate: 765;  # relative to `precision`

(p | innerproduct(q))         as $before_tax     # cents
| ($before_tax * taxrate)     as $taxes          # relative to precision
| ((($before_tax * precision) + $taxes) | cents) as $after_tax # cents
| ($after_tax|tostring|length + 2) as $width
|
  " Total before tax: \($before_tax    | dollars($width))",
  " -            tax: \($taxes | cents | dollars($width))",
  " Total after  tax: \($after_tax     | dollars($width))"


using Printf

p  = [big"5.50", big"2.86"]
q  = [4000000000000000, 2]
tr = big"0.0765"

beftax = p' * q
tax    = beftax * tr
afttax = beftax + tax

@printf " - tot. before tax: %20.2f \$\n" beftax
@printf " -             tax: %20.2f \$\n" tax
@printf " - tot. after  tax: %20.2f \$\n" afttax


// version 1.1.2

import java.math.BigDecimal
import java.math.MathContext

fun main(args: Array<String>) {
    val mc = MathContext.DECIMAL128
    val nHamburger  = BigDecimal("4000000000000000", mc)
    val pHamburger  = BigDecimal("5.50")
    val nMilkshakes = BigDecimal("2", mc)
    val pMilkshakes = BigDecimal("2.86")
    val taxRate     = BigDecimal("0.0765")
    val price = nHamburger * pHamburger + nMilkshakes * pMilkshakes
    val tax = price * taxRate
    val fmt = "%20.2f"
    println("Total price before tax : ${fmt.format(price)}")
    println("Tax thereon @ 7.65%    : ${fmt.format(tax)}")
    println("Total price after tax  : ${fmt.format(price + tax)}")
}


C = setmetatable(require("bc"), {__call=function(t,...) return t.new(...) end})
C.digits(6) -- enough for .nn * .nnnn ==> .nnnnnn, follow with trunc(2) to trim trailing zeroes

subtot = (C"4000000000000000" * C"5.50" + C"2" * C"2.86"):trunc(2) -- cosmetic trunc
tax = (subtot * C"0.0765" + C"0.005"):trunc(2) -- rounding trunc
total = (subtot + tax):trunc(2) -- cosmetic trunc

print(("Before tax:  %20s"):format(subtot:tostring()))
print(("Tax       :  %20s"):format(tax:tostring()))
print(("With tax  :  %20s"):format(total:tostring()))