import java.util.List;

public class Zeckendorf implements Comparable<Zeckendorf> {
    private static List<String> dig = List.of("00", "01", "10");
    private static List<String> dig1 = List.of("", "1", "10");

    private String x;
    private int dVal = 0;
    private int dLen = 0;

    public Zeckendorf() {
        this("0");
    }

    public Zeckendorf(String x) {
        this.x = x;

        int q = 1;
        int i = x.length() - 1;
        dLen = i / 2;
        while (i >= 0) {
            dVal += (x.charAt(i) - '0') * q;
            q *= 2;
            i--;
        }
    }

    private void a(int n) {
        int i = n;
        while (true) {
            if (dLen < i) dLen = i;
            int j = (dVal >> (i * 2)) & 3;
            switch (j) {
                case 0:
                case 1:
                    return;
                case 2:
                    if (((dVal >> ((i + 1) * 2)) & 1) != 1) return;
                    dVal += 1 << (i * 2 + 1);
                    return;
                case 3:
                    int temp = 3 << (i * 2);
                    temp ^= -1;
                    dVal = dVal & temp;
                    b((i + 1) * 2);
                    break;
            }
            i++;
        }
    }

    private void b(int pos) {
        if (pos == 0) {
            Zeckendorf thiz = this;
            thiz.inc();
            return;
        }
        if (((dVal >> pos) & 1) == 0) {
            dVal += 1 << pos;
            a(pos / 2);
            if (pos > 1) a(pos / 2 - 1);
        } else {
            int temp = 1 << pos;
            temp ^= -1;
            dVal = dVal & temp;
            b(pos + 1);
            b(pos - (pos > 1 ? 2 : 1));
        }
    }

    private void c(int pos) {
        if (((dVal >> pos) & 1) == 1) {
            int temp = 1 << pos;
            temp ^= -1;
            dVal = dVal & temp;
            return;
        }
        c(pos + 1);
        if (pos > 0) {
            b(pos - 1);
        } else {
            Zeckendorf thiz = this;
            thiz.inc();
        }
    }

    public Zeckendorf inc() {
        dVal++;
        a(0);
        return this;
    }

    public void plusAssign(Zeckendorf other) {
        for (int gn = 0; gn < (other.dLen + 1) * 2; gn++) {
            if (((other.dVal >> gn) & 1) == 1) {
                b(gn);
            }
        }
    }

    public void minusAssign(Zeckendorf other) {
        for (int gn = 0; gn < (other.dLen + 1) * 2; gn++) {
            if (((other.dVal >> gn) & 1) == 1) {
                c(gn);
            }
        }
        while ((((dVal >> dLen * 2) & 3) == 0) || (dLen == 0)) {
            dLen--;
        }
    }

    public void timesAssign(Zeckendorf other) {
        Zeckendorf na = other.copy();
        Zeckendorf nb = other.copy();
        Zeckendorf nt;
        Zeckendorf nr = new Zeckendorf();
        for (int i = 0; i < (dLen + 1) * 2; i++) {
            if (((dVal >> i) & 1) > 0) {
                nr.plusAssign(nb);
            }
            nt = nb.copy();
            nb.plusAssign(na);
            na = nt.copy();
        }
        dVal = nr.dVal;
        dLen = nr.dLen;
    }

    private Zeckendorf copy() {
        Zeckendorf z = new Zeckendorf();
        z.dVal = dVal;
        z.dLen = dLen;
        return z;
    }

    @Override
    public int compareTo(Zeckendorf other) {
        return ((Integer) dVal).compareTo(other.dVal);
    }

    @Override
    public String toString() {
        if (dVal == 0) {
            return "0";
        }

        int idx = (dVal >> (dLen * 2)) & 3;
        StringBuilder stringBuilder = new StringBuilder(dig1.get(idx));
        for (int i = dLen - 1; i >= 0; i--) {
            idx = (dVal >> (i * 2)) & 3;
            stringBuilder.append(dig.get(idx));
        }
        return stringBuilder.toString();
    }

    public static void main(String[] args) {
        System.out.println("Addition:");
        Zeckendorf g = new Zeckendorf("10");
        g.plusAssign(new Zeckendorf("10"));
        System.out.println(g);
        g.plusAssign(new Zeckendorf("10"));
        System.out.println(g);
        g.plusAssign(new Zeckendorf("1001"));
        System.out.println(g);
        g.plusAssign(new Zeckendorf("1000"));
        System.out.println(g);
        g.plusAssign(new Zeckendorf("10101"));
        System.out.println(g);

        System.out.println("\nSubtraction:");
        g = new Zeckendorf("1000");
        g.minusAssign(new Zeckendorf("101"));
        System.out.println(g);
        g = new Zeckendorf("10101010");
        g.minusAssign(new Zeckendorf("1010101"));
        System.out.println(g);

        System.out.println("\nMultiplication:");
        g = new Zeckendorf("1001");
        g.timesAssign(new Zeckendorf("101"));
        System.out.println(g);
        g = new Zeckendorf("101010");
        g.plusAssign(new Zeckendorf("101"));
        System.out.println(g);
    }
}


is_open = [false for door = 1,100]

for pass = 1,100
    for door = pass,100,pass
        is_open[door] = not is_open[door]

for i,v in ipairs is_open
    print "Door #{i}: " .. if v then 'open' else 'closed'


import Base.*, Base.+, Base.-, Base./, Base.show, Base.!=, Base.==, Base.<=, Base.<, Base.>, Base.>=, Base.divrem

const z0 = "0"
const z1 = "1"
const flipordered = (z1 < z0)

mutable struct Z s::String end
Z() = Z(z0)
Z(z::Z) = Z(z.s)

pairlen(x::Z, y::Z) = max(length(x.s), length(y.s))
tolen(x::Z, n::Int) = (s = x.s; while length(s) < n s = z0 * s end; s)

<(x::Z, y::Z) = (l = pairlen(x, y); flipordered ? tolen(x, l) > tolen(y, l) : tolen(x, l) < tolen(y, l))
>(x::Z, y::Z) = (l = pairlen(x, y); flipordered ? tolen(x, l) < tolen(y, l) : tolen(x, l) > tolen(y, l))
==(x::Z, y::Z) = (l = pairlen(x, y); tolen(x, l) == tolen(y, l))
<=(x::Z, y::Z) = (l = pairlen(x, y); flipordered ? tolen(x, l) >= tolen(y, l) : tolen(x, l) <= tolen(y, l))
>=(x::Z, y::Z) = (l = pairlen(x, y); flipordered ? tolen(x, l) <= tolen(y, l) : tolen(x, l) >= tolen(y, l))
!=(x::Z, y::Z) = (l = pairlen(x, y); tolen(x, l) != tolen(y, l))

function tocanonical(z::Z)
    while occursin(z0 * z1 * z1, z.s)
        z.s = replace(z.s, z0 * z1 * z1 => z1 * z0 * z0)
    end
    len = length(z.s)
    if len > 1 && z.s[1:2] == z1 * z1
        z.s = z1 * z0 * z0 * ((len > 2) ? z.s[3:end] : "")
    end
    while (len = length(z.s)) > 1 && string(z.s[1]) == z0
        if len == 2
            if z.s == z0 * z0
                z.s = z0
            elseif z.s == z0 * z1
                z.s = z1
            end
        else
            z.s = z.s[2:end]
        end
    end
    z
end

function inc(z)
    if z.s[end] == z0[1]
        z.s = z.s[1:end-1] * z1[1]
    elseif z.s[end] == z1[1]
        if length(z.s) > 1
            if z.s[end-1:end] == z0 * z1
                z.s = z.s[1:end-2] * z1 * z0
            end
        else
            z.s = z1 * z0
        end
    end
    tocanonical(z)
end

function dec(z)
    if z.s[end] == z1[1]
        z.s = z.s[1:end-1] * z0
    else
        if (m = match(Regex(z1 * z0 * '+' * '$'), z.s)) != nothing
            len = length(m.match)
            if iseven(len)
                z.s = z.s[1:end-len] * (z0 * z1) ^ div(len, 2)
            else
                z.s = z.s[1:end-len] * (z0 * z1) ^ div(len, 2) * z0
            end
        end
    end
    tocanonical(z)
    z
end

function +(x::Z, y::Z)
    a = Z(x.s)
    b = Z(y.s)
    while b.s != z0
        inc(a)
        dec(b)
    end
    a
end

function -(x::Z, y::Z)
    a = Z(x.s)
    b = Z(y.s)
    while b.s != z0
        dec(a)
        dec(b)
    end
    a
end

function *(x::Z, y::Z)
    if (x.s == z0) || (y.s == z0)
        return Z(z0)
    elseif x.s == z1
        return Z(y.s)
    elseif y.s == z1
        return Z(x.s)
    end
    a = Z(x.s)
    b = Z(z1)
    while b != y
        c = Z(z0)
        while c != x
            inc(a)
            inc(c)
        end
        inc(b)
    end
    a
end

function divrem(x::Z, y::Z)
    if y.s == z0
        throw("Zeckendorf division by 0")
    elseif (y.s == z1) || (x.s == z0)
        return Z(x.s)
    end
    a = Z(x.s)
    b = Z(y.s)
    c = Z(z0)
    while a > b
        a = a - b
        inc(c)
    end
    tocanonical(c), tocanonical(a)
end

function /(x::Z, y::Z)
    a, _ = divrem(x, y)
    a
end

show(io::IO, z::Z) = show(io, parse(BigInt, tocanonical(z).s))

function zeckendorftest()
    a = Z("10")
    b = Z("1001")
    c = Z("1000")
    d = Z("10101")

    println("Addition:")
    x = a
    println(x += a)
    println(x += a)
    println(x += b)
    println(x += c)
    println(x += d)

    println("\nSubtraction:")
    x = Z("1000")
    println(x - Z("101"))
    x = Z("10101010")
    println(x - Z("1010101"))

    println("\nMultiplication:")
    x = Z("1001")
    y = Z("101")
    println(x * y)
    println(Z("101010") * y)

    println("\nDivision:")
    x = Z("1000101")
    y = Z("101")
    println(x / y)
    println(divrem(x, y))
end

zeckendorftest()


// version 1.1.51

class Zeckendorf(x: String = "0") : Comparable<Zeckendorf> {

    var dVal = 0
    var dLen = 0

    private fun a(n: Int) {
        var i = n
        while (true) {
            if (dLen < i) dLen = i
            val j = (dVal shr (i * 2)) and 3
            when (j) {
                0, 1 -> return

                2 -> {
                    if (((dVal shr ((i + 1) * 2)) and 1) != 1) return
                    dVal += 1 shl (i * 2 + 1)
                    return
                }

                3 -> {
                    dVal = dVal and (3 shl (i * 2)).inv()
                    b((i + 1) * 2)
                }
            }
            i++
        }
    }

    private fun b(pos: Int) {
        if (pos == 0) {
            var thiz = this
            ++thiz
            return
        }
        if (((dVal shr pos) and 1) == 0) {
            dVal += 1 shl pos
            a(pos / 2)
            if (pos > 1) a(pos / 2 - 1)
        }
        else {
            dVal = dVal and (1 shl pos).inv()
            b(pos + 1)
            b(pos - (if (pos > 1) 2 else 1))
        }
    }

    private fun c(pos: Int) {
        if (((dVal shr pos) and 1) == 1) {
            dVal = dVal and (1 shl pos).inv()
            return
        }
        c(pos + 1)
        if (pos > 0) b(pos - 1) else { var thiz = this; ++thiz }
    }

    init {
        var q = 1
        var i = x.length - 1
        dLen = i / 2
        while (i >= 0) {
            dVal += (x[i] - '0').toInt() * q
            q *= 2
            i--
        }
    }

    operator fun inc(): Zeckendorf {
        dVal += 1
        a(0)
        return this
    }

    operator fun plusAssign(other: Zeckendorf) {
        for (gn in 0 until (other.dLen + 1) * 2) {
            if (((other.dVal shr gn) and 1) == 1) b(gn)
        }
    }

    operator fun minusAssign(other: Zeckendorf) {
        for (gn in 0 until (other.dLen + 1) * 2) {
            if (((other.dVal shr gn) and 1) == 1) c(gn)
        }
        while ((((dVal shr dLen * 2) and 3) == 0) || (dLen == 0)) dLen--
    }

    operator fun timesAssign(other: Zeckendorf) {
        var na = other.copy()
        var nb = other.copy()
        var nt: Zeckendorf
        var nr = "0".Z
        for (i in 0..(dLen + 1) * 2) {
            if (((dVal shr i) and 1) > 0) nr += nb
            nt = nb.copy()
            nb += na
            na = nt.copy()
        }
        dVal = nr.dVal
        dLen = nr.dLen
    }

    override operator fun compareTo(other: Zeckendorf) = dVal.compareTo(other.dVal)

    override fun toString(): String {
        if (dVal == 0) return "0"
        val sb = StringBuilder(dig1[(dVal shr (dLen * 2)) and 3])
        for (i in dLen - 1 downTo 0) {
            sb.append(dig[(dVal shr (i * 2)) and 3])
        }
        return sb.toString()
    }

    fun copy(): Zeckendorf {
        val z = "0".Z
        z.dVal = dVal
        z.dLen = dLen
        return z
    }

    companion object {
        val dig = listOf("00", "01", "10")
        val dig1 = listOf("", "1", "10")
    }
}

val String.Z get() = Zeckendorf(this)

fun main(args: Array<String>) {
    println("Addition:")
    var g = "10".Z
    g += "10".Z
    println(g)
    g += "10".Z
    println(g)
    g += "1001".Z
    println(g)
    g += "1000".Z
    println(g)
    g += "10101".Z
    println(g)
    println("\nSubtraction:")
    g = "1000".Z
    g -= "101".Z
    println(g)
    g = "10101010".Z
    g -= "1010101".Z
    println(g)
    println("\nMultiplication:")
    g = "1001".Z
    g *= "101".Z
    println(g)
    g = "101010".Z
    g += "101".Z
    println(g)
}


doors	new door,pass
	For door=1:1:100 Set door(door)=0
	For pass=1:1:100 For door=pass:pass:100 Set door(door)='door(door)
	For door=1:1:100 If door(door) Write !,"Door",$j(door,4)," is open"
	Write !,"All other doors are closed."
	Quit
Do doors
Door   1 is open
Door   4 is open
Door   9 is open
Door  16 is open
Door  25 is open
Door  36 is open
Door  49 is open
Door  64 is open
Door  81 is open
Door 100 is open
All other doors are closed.


type Zeckendorf = object
  dVal: Natural
  dLen: Natural

const
  Dig = ["00", "01", "10"]
  Dig1 = ["", "1", "10"]

# Forward references.
func b(z: var Zeckendorf; pos: Natural)
func inc(z: var Zeckendorf)

func a(z: var Zeckendorf; n: Natural) =
  var i = n
  while true:

    if z.dLen < i: z.dLen = i
    let j = z.dVal shr (i * 2) and 3

    case j
    of 0, 1:
      return
    of 2:
      if (z.dVal shr ((i + 1) * 2) and 1) != 1: return
      z.dVal += 1 shl (i * 2 + 1)
      return
    of 3:
      z.dVal = z.dVal and not (3 shl (i * 2))
      z.b((i + 1) * 2)
    else:
        assert(false)

    inc i

func b(z: var Zeckendorf; pos: Natural) =
  if pos == 0:
    inc z
    return

  if (z.dVal shr pos and 1) == 0:
    z.dVal += 1 shl pos
    z.a(pos div 2)
    if pos > 1: z.a(pos div 2 - 1)
  else:
    z.dVal = z.dVal and not(1 shl pos)
    z.b(pos + 1)
    z.b(pos - (if pos > 1: 2 else: 1))

func c(z: var Zeckendorf; pos: Natural) =
  if (z.dVal shr pos and 1) == 1:
    z.dVal = z.dVal and not(1 shl pos)
    return

  z.c(pos + 1)
  if pos > 0:
    z.b(pos - 1)
  else:
    inc z

func initZeckendorf(s = "0"): Zeckendorf =
  var q = 1
  var i = s.high
  result.dLen = i div 2
  while i >= 0:
    result.dVal += (ord(s[i]) - ord('0')) * q
    q *= 2
    dec i

func inc(z: var Zeckendorf) =
  inc z.dVal
  z.a(0)

func `+=`(z1: var Zeckendorf; z2: Zeckendorf) =
  for gn in 0 .. (2 * z2.dLen + 1):
    if (z2.dVal shr gn and 1) == 1:
      z1.b(gn)

func `-=`(z1: var Zeckendorf; z2: Zeckendorf) =
  for gn in 0 .. (2 * z2.dLen + 1):
    if (z2.dVal shr gn and 1) == 1:
      z1.c(gn)

  while z1.dLen > 0 and (z1.dVal shr (z1.dLen * 2) and 3) == 0:
    dec z1.dLen

func `*=`(z1: var Zeckendorf; z2: Zeckendorf) =
  var na, nb = z2
  var nr: Zeckendorf
  for i in 0 .. (z1.dLen + 1) * 2:
    if (z1.dVal shr i and 1) > 0: nr += nb
    let nt = nb
    nb += na
    na = nt
  z1 = nr

func`$`(z: var Zeckendorf): string =
  if z.dVal == 0: return "0"
  result.add Dig1[z.dVal shr (z.dLen * 2) and 3]
  for i in countdown(z.dLen - 1, 0):
    result.add Dig[z.dVal shr (i * 2) and 3]

when isMainModule:

  var g: Zeckendorf

  echo "Addition:"
  g = initZeckendorf("10")
  g += initZeckendorf("10")
  echo g
  g += initZeckendorf("10")
  echo g
  g += initZeckendorf("1001")
  echo g
  g += initZeckendorf("1000")
  echo g
  g += initZeckendorf("10101")
  echo g

  echo "\nSubtraction:"
  g = initZeckendorf("1000")
  g -= initZeckendorf("101")
  echo g
  g = initZeckendorf("10101010")
  g -= initZeckendorf("1010101")
  echo g

  echo "\nMultiplication:"
  g = initZeckendorf("1001")
  g *= initZeckendorf("101")
  echo g
  g = initZeckendorf("101010")
  g += initZeckendorf("101")
  echo g


#!/usr/bin/perl

use strict; # https://rosettacode.org/wiki/Zeckendorf_arithmetic
use warnings;

for ( split /\n/, <<END ) # test cases
  1 + 1
  10 + 10
  10100 + 1010
  10100 - 1010
  10100 * 1010
  100010 * 100101
  10100 / 1010
  101000 / 1000
  100001000001 / 100010
  100001000001 / 100101
END
  {
  my ($left, $op, $right) = split;
  my ($x, $y) = map Zeckendorf->new($_), $left, $right;
  my $answer =
    $op eq '+' ? $x + $y :
    $op eq '-' ? $x - $y :
    $op eq '*' ? $x * $y :
    $op eq '/' ? $x / $y :
    die "bad op <$op>";
  printf "%12s %s %-9s => %12s  in Zeckendorf\n", $x, $op, $y, $answer;
  printf "%12d %s %-9d => %12d  in decimal\n\n",
    $x->asdecimal, $op, $y->asdecimal, $answer->asdecimal;
  }

package Zeckendorf;
use overload qw("" zstring + zadd - zsub ++ zinc -- zdec * zmul / zdiv ge zge);

sub new
  {
  my ($class, $value) = @_;
  bless \$value, ref $class || $class;
  }

sub zinc
  {
  my ($self, $other, $swap) = @_;
  local $_ = $$self;
  s/0$/1/ or s/(?:^|0)1$/10/;
  1 while s/(?:^|0)11/100/;
  $_[0] = $self->new( s/^0+\B//r );
  }

sub zdec
  {
  my ($self, $other, $swap) = @_;
  local $_ = $$self;
  1 while s/100(?=0*$)/011/;
  s/1$/0/ or s/10$/01/;
  $_[0] = $self->new( s/^0+\B//r );
  }

sub zstring { ${ shift() } }

sub zadd
  {
  my ($self, $other, $swap) = @_;
  my ($x, $y) = map $self->new($$_), $self, $other; # copy
  ++$x, $y-- while $$y ne 0;
  return $x;
  }

sub zsub
  {
  my ($self, $other, $swap) = @_;
  my ($x, $y) = map $self->new($$_), $self, $other; # copy
  --$x, $y-- while $$y ne 0;
  return $x;
  }

sub zmul
  {
  my ($self, $other, $swap) = @_;
  my ($x, $y) = map $self->new($$_), $self, $other; # copy
  my $product = Zeckendorf->new(0);
  $product = $product + $x, --$y while "$y" ne 0;
  return $product;
  }

sub zdiv
  {
  my ($self, $other, $swap) = @_;
  my ($x, $y) = map $self->new($$_), $self, $other; # copy
  my $quotient = Zeckendorf->new(0);
  ++$quotient, $x = $x - $y while $x ge $y;
  return $quotient;
  }

sub zge
  {
  my ($self, $other, $swap) = @_;
  my $l = length( $$self | $$other );
  0 x ($l - length $$self) . $$self ge 0 x ($l - length $$other) . $$other;
  }

sub asdecimal
  {
  my ($self) = @_;
  my $n = 0;
  my $aa = my $bb = 1;
  for ( reverse split //, $$self )
    {
    $n += $bb * $_;
    ($aa, $bb) = ($bb, $aa + $bb);
    }
  return $n;
  }

sub fromdecimal
  {
  my ($self, $value) = @_;
  my $z = $self->new(0);
  ++$z for 1 .. $value;
  return $z;
  }


use std

const main = {
	var isopen	: bool[100]

	std.slfill(isopen[:], false)
	for var i = 0; i < isopen.len; i++
		for var j = i; j < isopen.len; j += i + 1
			isopen[j] = !isopen[j]
		;;
	;;

	for var i = 0; i < isopen.len; i++
		if isopen[i]
			std.put("door {} is open\n", i + 1)
		;;
	;;
}


with javascript_semantics

sequence fib = {1,1}

function zeckendorf(atom n)
-- Same as Zeckendorf_number_representation#Phix
    atom r = 0
    while fib[$]<n do
        fib &= fib[$] + fib[$-1]
    end while
    integer k = length(fib)
    while k>2 and n<fib[k] do
        k -= 1
    end while
    for i=k to 2 by -1 do
        integer c = n>=fib[i]
        r += r+c
        n -= c*fib[i]
    end for
    return r
end function

function decimal(object z)
-- Convert Zeckendorf number(s) to decimal
    if sequence(z) then
        sequence res = repeat(0,length(z))
        for i=1 to length(z) do
            res[i] = decimal(z[i])
        end for
        return res
    end if
    atom dec = 0, bit = 2
    while z do
        if and_bits(z,1) then
            dec += fib[bit]
        end if
        bit += 1
        if bit>length(fib) then
            fib &= fib[$] + fib[$-1]
        end if
        z = floor(z/2)
    end while
    return dec
end function

function to_bits(integer x)
-- Simplified copy of int_to_bits(), but in reverse order,
-- and +ve only but (also only) as many bits as needed, and
-- ensures there are *two* trailing 0 (most significant)
    if x<0 then ?9/0 end if     -- sanity/avoid infinite loop
    sequence bits = {}
    while 1 do
        bits &= remainder(x,2)
        if x=0 then exit end if
        x = floor(x/2)
    end while
    bits &= 0 -- (since eg 101+101 -> 10000)
    return bits
end function

function to_bits2(integer a,b)
-- Apply to_bits() to a and b, and pad to the same length
    sequence sa = to_bits(a),
             sb = to_bits(b)
    integer diff = length(sa)-length(sb)
    if diff!=0 then
        if diff<0 then  sa &= repeat(0,-diff)
                  else  sb &= repeat(0,+diff)
        end if
    end if
    return {sa,sb}
end function

function to_int(sequence bits)
-- Copy of bits_to_int(), but in reverse order (lsb last)
    atom val = 0, p = 1
    for i=length(bits) to 1 by -1 do
        if bits[i] then
            val += p
        end if
        p += p
    end for
    return val
end function

function zstr(object z)
    if sequence(z) then
        sequence res = repeat(0,length(z))
        for i=1 to length(z) do
            res[i] = zstr(z[i])
        end for
        return res
    end if
    return sprintf("%b",z)
end function

function rep(sequence res, integer ds, sequence was, wth)
-- helper for cleanup, validates replacements
    integer de = ds+length(was)-1
    if res[ds..de]!=was then ?9/0 end if
    if length(was)!=length(wth) then ?9/0 end if
    res = deep_copy(res)
    res[ds..de] = wth
    return res
end function

function zcleanup(sequence res)
-- (shared by zadd and zsub)
    integer l = length(res)
    res = deep_copy(res)
    -- first stage, left to right, {020x -> 100x', 030x -> 110x', 021x->110x, 012x->101x}
    for i=1 to l-3 do
        sequence s3 = res[i..i+2]
           if s3={0,2,0} then res[i..i+2] = {1,0,0} res[i+3] += 1
        elsif s3={0,3,0} then res[i..i+2] = {1,1,0} res[i+3] += 1
        elsif s3={0,2,1} then res[i..i+2] = {1,1,0}
        elsif s3={0,1,2} then res[i..i+2] = {1,0,1}
        end if
    end for
    -- first stage cleanup
    if l>1 then
        if res[l-1]=3 then      res = rep(res,l-2,{0,3,0},{1,1,1})      -- 030 -> 111
        elsif res[l-1]=2 then
            if res[l-2]=0 then  res = rep(res,l-2,{0,2,0},{1,0,1})      -- 020 -> 101
                          else  res = rep(res,l-3,{0,1,2,0},{1,0,1,0})  -- 0120 -> 1010
            end if
        end if
    end if
    if res[l]=3 then            res = rep(res,l-1,{0,3},{1,1})          -- 03 -> 11
    elsif res[l]=2 then
        if res[l-1]=0 then      res = rep(res,l-1,{0,2},{1,0})          -- 02 -> 10
                      else      res = rep(res,l-2,{0,1,2},{1,0,1})      -- 012 -> 101
        end if
    end if
    -- second stage, pass 1, right to left, 011 -> 100
    for i=length(res)-2 to 1 by -1 do
        if res[i..i+2]={0,1,1} then res[i..i+2] = {1,0,0} end if
    end for
    -- second stage, pass 2, left to right, 011 -> 100
    for i=1 to length(res)-2 do
        if res[i..i+2]={0,1,1} then res[i..i+2] = {1,0,0} end if
    end for
    return to_int(res)
end function

function zadd(integer a, b)
    sequence {sa,sb} = to_bits2(a,b)
    return zcleanup(reverse(sq_add(sa,sb)))
end function

function zinc(integer a)
    return zadd(a,0b1)
end function

function zsub(integer a, b)
    sequence {sa,sb} = to_bits2(a,b)
    sequence res = reverse(sq_sub(sa,sb))
    -- (/not/ combined with the first pass of the add routine!)
    for i=1 to length(res)-2 do
        sequence s3 = res[i..i+2]
           if s3={1, 0, 0} then res[i..i+2] = {0,1,1}
        elsif s3={1,-1, 0} then res[i..i+2] = {0,0,1}
        elsif s3={1,-1, 1} then res[i..i+2] = {0,0,2}
        elsif s3={1, 0,-1} then res[i..i+2] = {0,1,0}
        elsif s3={2, 0, 0} then res[i..i+2] = {1,1,1}
        elsif s3={2,-1, 0} then res[i..i+2] = {1,0,1}
        elsif s3={2,-1, 1} then res[i..i+2] = {1,0,2}
        elsif s3={2, 0,-1} then res[i..i+2] = {1,1,0}
        end if
    end for
    -- copied from PicoLisp: {1,-1} -> {0,1} and {2,-1} -> {1,1}
    for i=1 to length(res)-1 do
        sequence s2 = res[i..i+1]
           if s2={1,-1} then res[i..i+1] = {0,1}
        elsif s2={2,-1} then res[i..i+1] = {1,1}
        end if
    end for
    if find(-1,res) then ?9/0 end if -- sanity check
    return zcleanup(res)
end function

function zdec(integer a)
    return zsub(a,0b1)
end function

function zmul(integer a, b)
    sequence mult = {a,zadd(a,a)}   -- (as per task desc)
    integer bits = 2
    while bits<b do
        mult = append(mult,zadd(mult[$],mult[$-1]))
        bits *= 2
    end while
    integer res = 0,
            bit = 1
    while b do
        if and_bits(b,1) then
            res = zadd(res,mult[bit])
        end if
        b = floor(b/2)
        bit += 1
    end while
    return res
end function

function zdiv(integer a, b)
    sequence mult = {b,zadd(b,b)}
    integer bits = 2
    while mult[$]<a do
        mult = append(mult,zadd(mult[$],mult[$-1]))
        bits *= 2
    end while
    integer res = 0
    for i=length(mult) to 1 by -1 do
        integer mi = mult[i]
        if mi<=a then
            res = zadd(res,bits)
            a = zsub(a,mi)
            if a=0 then exit end if
        end if
        bits = floor(bits/2)
    end for
    return {res,a} -- (a is the remainder)
end function

for i=0 to 20 do
    integer zi = zeckendorf(i)
    atom d = decimal(zi)
    printf(1,"%2d: %7b (%d)\n",{i,zi,d})
end for

procedure test(atom a, string op, atom b, object res, string expected)
    string zres = iff(atom(res)?zstr(res):join(zstr(res)," rem ")),
           dres = sprintf(iff(atom(res)?"%d":"%d rem %d"),decimal(res)),
           aka = sprintf("aka %d %s %d = %s",{decimal(a),op,decimal(b),dres}),
           ok = iff(zres=expected?"":" *** ERROR ***!!")
    printf(1,"%s %s %s = %s, %s %s\n",{zstr(a),op,zstr(b),zres,aka,ok})
end procedure

test(0b0,"+",0b0,zadd(0b0,0b0),"0")
test(0b101,"+",0b101,zadd(0b101,0b101),"10000")
test(0b10100,"-",0b1000,zsub(0b10100,0b1000),"1001")
test(0b100100,"-",0b1000,zsub(0b100100,0b1000),"10100")
test(0b1001,"*",0b101,zmul(0b1001,0b101),"1000100")
test(0b1000101,"/",0b101,zdiv(0b1000101,0b101),"1001 rem 1")

test(0b10,"+",0b10,zadd(0b10,0b10),"101")
test(0b101,"+",0b10,zadd(0b101,0b10),"1001")
test(0b1001,"+",0b1001,zadd(0b1001,0b1001),"10101")
test(0b10101,"+",0b1000,zadd(0b10101,0b1000),"100101")
test(0b100101,"+",0b10101,zadd(0b100101,0b10101),"1010000")
test(0b1000,"-",0b101,zsub(0b1000,0b101),"1")
test(0b10101010,"-",0b1010101,zsub(0b10101010,0b1010101),"1000000")
test(0b1001,"*",0b101,zmul(0b1001,0b101),"1000100")
test(0b101010,"+",0b101,zadd(0b101010,0b101),"1000100")

test(0b10100,"+",0b1010,zadd(0b10100,0b1010),"101000")
test(0b101000,"-",0b1010,zsub(0b101000,0b1010),"10100")

test(0b100010,"*",0b100101,zmul(0b100010,0b100101),"100001000001")
test(0b100001000001,"/",0b100,zdiv(0b100001000001,0b100),"101010001 rem 0")
test(0b101000101,"*",0b101001,zmul(0b101000101,0b101001),"101010000010101")
test(0b101010000010101,"/",0b100,zdiv(0b101010000010101,0b100),"1001010001001 rem 10")

test(0b10100010010100,"+",0b1001000001,zadd(0b10100010010100,0b1001000001),"100000000010101")
test(0b10100010010100,"-",0b1001000001,zsub(0b10100010010100,0b1001000001),"10010001000010")
test(0b10000,"*",0b1001000001,zmul(0b10000,0b1001000001),"10100010010100")
test(0b1010001010000001001,"/",0b100000000100000,zdiv(0b1010001010000001001,0b100000000100000),"10001 rem 10100001010101")

test(0b10100,"+",0b1010,zadd(0b10100,0b1010),"101000")
test(0b10100,"-",0b1010,zsub(0b10100,0b1010),"101")
test(0b10100,"*",0b1010,zmul(0b10100,0b1010),"101000001")
test(0b10100,"/",0b1010,zdiv(0b10100,0b1010),"1 rem 101")
integer m = zmul(0b10100,0b1010)
test(m,"/",0b1010,zdiv(m,0b1010),"10100 rem 0")


DROP PROCEDURE IF EXISTS one_hundred_doors;

DELIMITER |

CREATE PROCEDURE one_hundred_doors (n INT)
BEGIN
  DROP TEMPORARY TABLE IF EXISTS doors;
  CREATE TEMPORARY TABLE doors (
    id INTEGER NOT NULL,
    open BOOLEAN DEFAULT FALSE,
    PRIMARY KEY (id)
  );

  SET @i = 1;
  create_doors: LOOP
    INSERT INTO doors (id, open) values (@i, FALSE);
    SET @i = @i + 1;
    IF @i > n THEN
      LEAVE create_doors;
    END IF;
  END LOOP create_doors;

  SET @i = 1;
  toggle_doors: LOOP
    UPDATE doors SET open = NOT open WHERE MOD(id, @i) = 0;
    SET @i = @i + 1;
    IF @i > n THEN
      LEAVE toggle_doors;
    END IF;
  END LOOP toggle_doors;

  SELECT id FROM doors WHERE open;
END|

DELIMITER ;

CALL one_hundred_doors(100);


(seed (in "/dev/urandom" (rd 8)))

(de unpad (Lst)
   (while (=0 (car Lst))
      (pop 'Lst) )
   Lst )

(de numz (N)
   (let Fibs (1 1)
      (while (>= N (+ (car Fibs) (cadr Fibs)))
         (push 'Fibs (+ (car Fibs) (cadr Fibs))) )
      (make
         (for I (uniq Fibs)
            (if (> I N)
               (link 0)
               (link 1)
               (dec 'N I) ) ) ) ) )

(de znum (Lst)
   (let Fibs (1 1)
      (do (dec (length Lst))
         (push 'Fibs (+ (car Fibs) (cadr Fibs))) )
      (sum
         '((X Y) (unless (=0 X) Y))
         Lst
         (uniq Fibs) ) ) )

(de incz (Lst)
   (addz Lst (1)) )

(de decz (Lst)
   (subz Lst (1)) )

(de addz (Lst1 Lst2)
   (let Max (max (length Lst1) (length Lst2))
      (reorg
         (mapcar + (need Max Lst1 0) (need Max Lst2 0)) ) ) )

(de subz (Lst1 Lst2)
   (use (@A @B)
      (let
         (Max (max (length Lst1) (length Lst2))
            Lst (mapcar - (need Max Lst1 0) (need Max Lst2 0)) )
         (loop
            (while (match '(@A 1 0 0 @B) Lst)
               (setq Lst (append @A (0 1 1) @B)) )
            (while (match '(@A 1 -1 0 @B) Lst)
               (setq Lst (append @A (0 0 1) @B)) )
            (while (match '(@A 1 -1 1 @B) Lst)
               (setq Lst (append @A (0 0 2) @B)) )
            (while (match '(@A 1 0 -1 @B) Lst)
               (setq Lst (append @A (0 1 0) @B)) )
            (while (match '(@A 2 0 0 @B) Lst)
               (setq Lst (append @A (1 1 1) @B)) )
            (while (match '(@A 2 -1 0 @B) Lst)
               (setq Lst (append @A (1 0 1) @B)) )
            (while (match '(@A 2 -1 1 @B) Lst)
               (setq Lst (append @A (1 0 2) @B)) )
            (while (match '(@A 2 0 -1 @B) Lst)
               (setq Lst (append @A (1 1 0) @B)) )
            (while (match '(@A 1 -1) Lst)
               (setq Lst (append @A (0 1))) )
            (while (match '(@A 2 -1) Lst)
               (setq Lst (append @A (1 1))) )
            (NIL (match '(@A -1 @B) Lst)) )
         (reorg (unpad Lst)) ) ) )

(de mulz (Lst1 Lst2)
   (let (Sums (list Lst1) Mulz (0))
      (mapc
         '((X)
            (when (= 1 (car X))
               (setq Mulz (addz (cdr X) Mulz)) )
            Mulz )
         (mapcar
            '((X)
               (cons
                  X
                  (push 'Sums (addz (car Sums) (cadr Sums))) ) )
            (reverse Lst2) ) ) ) )

(de divz (Lst1 Lst2)
   (let Q 0
      (while (lez Lst2 Lst1)
         (setq Lst1 (subz Lst1 Lst2))
         (setq Q (incz Q)) )
      (list Q (or Lst1 (0))) ) )

(de reorg (Lst)
   (use (@A @B)
      (let Lst (reverse Lst)
         (loop
            (while (match '(@A 1 1 @B) Lst)
               (if @B
                  (inc (nth @B 1))
                  (setq @B (1)) )
               (setq Lst (append @A (0 0) @B) ) )
            (while (match '(@A 2 @B) Lst)
               (inc
                  (if (cdr @A)
                     (tail 2 @A)
                     @A ) )
               (if @B
                  (inc (nth @B 1))
                  (setq @B (1)) )
               (setq Lst (append @A (0) @B)) )
            (NIL
               (or
                  (match '(@A 1 1 @B) Lst)
                  (match '(@A 2 @B) Lst) ) ) )
         (reverse Lst) ) ) )

(de lez (Lst1 Lst2)
   (let Max (max (length Lst1) (length Lst2))
      (<= (need Max Lst1 0) (need Max Lst2 0)) ) )

(let (X 0 Y 0)
   (do 1024
      (setq X (rand 1 1024))
      (setq Y (rand 1 1024))
      (test (numz (+ X Y)) (addz (numz X) (numz Y)))
      (test (numz (* X Y)) (mulz (numz X) (numz Y)))
      (test (numz (+ X 1)) (incz (numz X))) )

   (do 1024
      (setq X (rand 129 1024))
      (setq Y (rand 1 128))
      (test (numz (- X Y)) (subz (numz X) (numz Y)))
      (test (numz (/ X Y)) (car (divz (numz X) (numz Y))))
      (test (numz (% X Y)) (cadr (divz (numz X) (numz Y))))
      (test (numz (- X 1)) (decz (numz X))) ) )

(bye)


import copy

class Zeckendorf:
    def __init__(self, x='0'):
        q = 1
        i = len(x) - 1
        self.dLen = int(i / 2)
        self.dVal = 0
        while i >= 0:
            self.dVal = self.dVal + (ord(x[i]) - ord('0')) * q
            q = q * 2
            i = i -1

    def a(self, n):
        i = n
        while True:
            if self.dLen < i:
                self.dLen = i
            j = (self.dVal >> (i * 2)) & 3
            if j == 0 or j == 1:
                return
            if j == 2:
                if (self.dVal >> ((i + 1) * 2) & 1) != 1:
                    return
                self.dVal = self.dVal + (1 << (i * 2 + 1))
                return
            if j == 3:
                temp = 3 << (i * 2)
                temp = temp ^ -1
                self.dVal = self.dVal & temp
                self.b((i + 1) * 2)
            i = i + 1

    def b(self, pos):
        if pos == 0:
            self.inc()
            return
        if (self.dVal >> pos) & 1 == 0:
            self.dVal = self.dVal + (1 << pos)
            self.a(int(pos / 2))
            if pos > 1:
                self.a(int(pos / 2) - 1)
        else:
            temp = 1 << pos
            temp = temp ^ -1
            self.dVal = self.dVal & temp
            self.b(pos + 1)
            self.b(pos - (2 if pos > 1 else 1))

    def c(self, pos):
        if (self.dVal >> pos) & 1 == 1:
            temp = 1 << pos
            temp = temp ^ -1
            self.dVal = self.dVal & temp
            return
        self.c(pos + 1)
        if pos > 0:
            self.b(pos - 1)
        else:
            self.inc()

    def inc(self):
        self.dVal = self.dVal + 1
        self.a(0)

    def __add__(self, rhs):
        copy = self
        rhs_dVal = rhs.dVal
        limit = (rhs.dLen + 1) * 2
        for gn in range(0, limit):
            if ((rhs_dVal >> gn) & 1) == 1:
                copy.b(gn)
        return copy

    def __sub__(self, rhs):
        copy = self
        rhs_dVal = rhs.dVal
        limit = (rhs.dLen + 1) * 2
        for gn in range(0, limit):
            if (rhs_dVal >> gn) & 1 == 1:
                copy.c(gn)
        while (((copy.dVal >> ((copy.dLen * 2) & 31)) & 3) == 0) or (copy.dLen == 0):
            copy.dLen = copy.dLen - 1
        return copy

    def __mul__(self, rhs):
        na = copy.deepcopy(rhs)
        nb = copy.deepcopy(rhs)
        nr = Zeckendorf()
        dVal = self.dVal
        for i in range(0, (self.dLen + 1) * 2):
            if ((dVal >> i) & 1) > 0:
                nr = nr + nb
            nt = copy.deepcopy(nb)
            nb = nb + na
            na = copy.deepcopy(nt)
        return nr

    def __str__(self):
        dig = ["00", "01", "10"]
        dig1 = ["", "1", "10"]

        if self.dVal == 0:
            return '0'
        idx = (self.dVal >> ((self.dLen * 2) & 31)) & 3
        sb = dig1[idx]
        i = self.dLen - 1
        while i >= 0:
            idx = (self.dVal >> (i * 2)) & 3
            sb = sb + dig[idx]
            i = i - 1
        return sb

# main
print "Addition:"
g = Zeckendorf("10")
g = g + Zeckendorf("10")
print g
g = g + Zeckendorf("10")
print g
g = g + Zeckendorf("1001")
print g
g = g + Zeckendorf("1000")
print g
g = g + Zeckendorf("10101")
print g
print

print "Subtraction:"
g = Zeckendorf("1000")
g = g - Zeckendorf("101")
print g
g = Zeckendorf("10101010")
g = g - Zeckendorf("1010101")
print g
print

print "Multiplication:"
g = Zeckendorf("1001")
g = g * Zeckendorf("101")
print g
g = Zeckendorf("101010")
g = g + Zeckendorf("101")
print g


// allocate a boolean array with all closed doors (false)
// we need 101 since there will technically be a door 0
doors = {false} * 101

// loop through all the step lengths (1-100)
for step in range(1, 100)
	// loop through all the doors, stepping by step
	for door in range(0, len(doors) - 1, step)
		// change the state of the current door
		doors[door] = !doors[door]
	end for
end for

// loop through and print the doors that are open, skipping door 0
for i in range(1, len(doors) - 1)
	// if the door is open, display it
	if doors[i]
		println "Door " + i + " is open."
	end if
end for


#lang racket (require math)

(define sqrt5 (sqrt 5))
(define phi (* 0.5 (+ 1 sqrt5)))

;; What is the nth fibonnaci number, shifted by 2 so that
;; F(0) = 1, F(1) = 2, ...?
;;
(define (F n)
  (fibonacci (+ n 2)))

;; What is the largest n such that F(n) <= m?
;;
(define (F* m)
  (let ([n (- (inexact->exact (round (/ (log (* m sqrt5)) (log phi)))) 2)])
    (if (<= (F n) m) n (sub1 n))))

(define (zeck->natural z)
  (for/sum ([i (reverse z)]
            [j (in-naturals)])
    (* i (F j))))

(define (natural->zeck n)
  (if (zero? n)
      null
      (for/list ([i (in-range (F* n) -1 -1)])
        (let ([f (F i)])
          (cond [(>= n f) (set! n (- n f))
                          1]
                [else 0])))))

; Extend list to the right to a length of len with repeated padding elements
;
(define (pad lst len [padding 0])
  (append lst (make-list (- len (length lst)) padding)))

; Strip padding elements from the left of the list
;
(define (unpad lst [padding 0])
  (cond [(null? lst) lst]
        [(equal? (first lst) padding) (unpad (rest lst) padding)]
        [else lst]))

;; Run a filter function across a window in a list from left to right
;;
(define (left->right width fn)
  (λ (lst)
    (let F ([a lst])
      (if (< (length a) width)
          a
          (let ([f (fn (take a width))])
            (cons (first f) (F (append (rest f) (drop a width)))))))))

;; Run a function fn across a window in a list from right to left
;;
(define (right->left width fn)
  (λ (lst)
    (let F ([a lst])
      (if (< (length a) width)
          a
          (let ([f (fn (take-right a width))])
            (append (F (append (drop-right a width) (drop-right f 1)))
                    (list (last f))))))))

;; (a0 a1 a2 ... an) -> (a0 a1 a2 ... (fn ... an))
;;
(define (replace-tail width fn)
  (λ (lst)
    (append (drop-right lst width) (fn (take-right lst width)))))

(define (rule-a lst)
  (match lst
    [(list 0 2 0 x) (list 1 0 0 (add1 x))]
    [(list 0 3 0 x) (list 1 1 0 (add1 x))]
    [(list 0 2 1 x) (list 1 1 0 x)]
    [(list 0 1 2 x) (list 1 0 1 x)]
    [else lst]))

(define (rule-a-tail lst)
  (match lst
    [(list x 0 3 0) (list x 1 1 1)]
    [(list x 0 2 0) (list x 1 0 1)]
    [(list 0 1 2 0) (list 1 0 1 0)]
    [(list x y 0 3) (list x y 1 1)]
    [(list x y 0 2) (list x y 1 0)]
    [(list x 0 1 2) (list x 1 0 0)]
    [else lst]))

(define (rule-b lst)
  (match lst
    [(list 0 1 1) (list 1 0 0)]
    [else lst]))

(define (rule-c lst)
  (match lst
    [(list 1 0 0) (list 0 1 1)]
    [(list 1 -1 0) (list 0 0 1)]
    [(list 1 -1 1) (list 0 0 2)]
    [(list 1 0 -1) (list 0 1 0)]
    [(list 2 0 0) (list 1 1 1)]
    [(list 2 -1 0) (list 1 0 1)]
    [(list 2 -1 1) (list 1 0 2)]
    [(list 2 0 -1) (list 1 1 0)]
    [else lst]))

(define (zeck-combine op y z [f identity])
  (let* ([bits (max (add1 (length y)) (add1 (length z)) 4)]
         [f0 (λ (x) (pad (reverse x) bits))]
         [f1 (left->right 4 rule-a)]
         [f2 (replace-tail 4 rule-a-tail)]
         [f3 (right->left 3 rule-b)]
         [f4 (left->right 3 rule-b)])
    ((compose1 unpad f4 f3 f2 f1 f reverse) (map op (f0 y) (f0 z)))))

(define (zeck+ y z)
  (zeck-combine + y z))

(define (zeck- y z)
  (when (zeck< y z) (error (format "~a" `(zeck-: cannot subtract since ,y < ,z))))
  (zeck-combine - y z (left->right 3 rule-c)))

(define (zeck* y z)
  (define (M ry Zn Zn_1 [acc null])
    (if (null? ry)
        acc
        (M (rest ry) (zeck+ Zn Zn_1) Zn
           (if (zero? (first ry)) acc (zeck+ acc Zn)))))
  (cond [(zeck< z y) (zeck* z y)]
        [(null? y) null]               ; 0 * z -> 0
        [else (M (reverse y) z z)]))

(define (zeck-quotient/remainder y z)
  (define (M Zn acc)
    (if (zeck< y Zn)
        (drop-right acc 1)
        (M (zeck+ Zn (first acc)) (cons Zn acc))))
  (define (D x m [acc null])
    (if (null? m)
        (values (reverse acc) x)
        (let* ([v (first m)]
               [smaller (zeck< v x)]
               [bit (if smaller 1 0)]
               [x_ (if smaller (zeck- x v) x)])
          (D x_ (rest m) (cons bit acc)))))
  (D y (M z (list z))))

(define (zeck-quotient y z)
  (let-values ([(quotient _) (zeck-quotient/remainder y z)])
    quotient))

(define (zeck-remainder y z)
  (let-values ([(_ remainder) (zeck-quotient/remainder y z)])
    remainder))

(define (zeck-add1 z)
  (zeck+ z '(1)))

(define (zeck= y z)
  (equal? (unpad y) (unpad z)))

(define (zeck< y z)
  ; Compare equal-length unpadded zecks
  (define (LT a b)
    (if (null? a)
        #f
        (let ([a0 (first a)] [b0 (first b)])
          (if (= a0 b0)
              (LT (rest a) (rest b))
              (= a0 0)))))

  (let* ([a (unpad y)] [len-a (length a)]
         [b (unpad z)] [len-b (length b)])
    (cond [(< len-a len-b) #t]
          [(> len-a len-b) #f]
          [else (LT a b)])))

(define (zeck> y z)
  (not (or (zeck= y z) (zeck< y z))))

;; Examples
;;
(define (example op-name op a b)
  (let* ([y (natural->zeck a)]
         [z (natural->zeck b)]
         [x (op y z)]
         [c (zeck->natural x)])
    (printf "~a ~a ~a = ~a ~a ~a = ~a = ~a\n"
            a op-name b y op-name z x c)))

(example '+ zeck+ 888 111)
(example '- zeck- 888 111)
(example '* zeck* 8 111)
(example '/ zeck-quotient 9876 1000)
(example '% zeck-remainder 9876 1000)


 addition: +z
 subtraction: -z
 multiplication: *z
 division: /z (more of a divmod really)
 post increment: ++z
 post decrement: --z


/* NetRexx */
options replace format comments java crossref symbols binary

True  = Rexx(1 == 1)
False = Rexx(\True)

doors = False

loop i_ = 1 to 100
  loop j_ = 1 to 100
    if 0 = (j_ // i_) then doors[j_] = \doors[j_]
    end j_
  end i_

loop d_ = 1 to 100
  if doors[d_] then  state = 'open'
  else  state = 'closed'

  say 'Door Nr.' Rexx(d_).right(4) 'is' state
  end d_


(define (status door-num)
    (let ((x (int (sqrt door-num))))
     (if
       (= (* x x) door-num) (string "Door " door-num " Open")
       (string "Door " door-num " Closed"))))

(dolist (n (map status (sequence 1 100)))
  (println n))


namespace eval zeckendorf {
    # Want to use alternate symbols? Change these
    variable zero "0"
    variable one "1"

    # Base operations: increment and decrement
    proc zincr var {
	upvar 1 $var a
	namespace upvar [namespace current] zero 0 one 1
	if {![regsub "$0$" $a $1$0 a]} {append a $1}
	while {[regsub "$0$1$1" $a "$1$0$0" a]
		|| [regsub "^$1$1" $a "$1$0$0" a]} {}
	regsub ".$" $a "" a
	return $a
    }
    proc zdecr var {
	upvar 1 $var a
	namespace upvar [namespace current] zero 0 one 1
	regsub "^$0+(.+)$" [subst [regsub "${1}($0*)$" $a "$0\[
		string repeat {$1$0} \[regsub -all .. {\\1} {} x]]\[
		string repeat {$1} \[expr {\$x ne {}}]]"]
	    ] {\1} a
	return $a
    }

    # Exported operations
    proc eq {a b} {
	expr {$a eq $b}
    }
    proc add {a b} {
	variable zero
	while {![eq $b $zero]} {
	    zincr a
	    zdecr b
	}
	return $a
    }
    proc sub {a b} {
	variable zero
	while {![eq $b $zero]} {
	    zdecr a
	    zdecr b
	}
	return $a
    }
    proc mul {a b} {
	variable zero
	variable one
	if {[eq $a $zero] || [eq $b $zero]} {return $zero}
	if {[eq $a $one]} {return $b}
	if {[eq $b $one]} {return $a}
	set c $a
	while {![eq [zdecr b] $zero]} {
	    set c [add $c $a]
	}
	return $c
    }
    proc div {a b} {
	variable zero
	variable one
	if {[eq $b $zero]} {error "div zero"}
	if {[eq $a $zero] || [eq $b $one]} {return $a}
	set r $zero
	while {![eq $a $zero]} {
	    if {![eq $a [add [set a [sub $a $b]] $b]]} break
	    zincr r
	}
	return $r
    }
    # Note that there aren't any ordering operations in this version

    # Assemble into a coherent API
    namespace export \[a-y\]*
    namespace ensemble create
}


     n:=100;reduce xor (count n eachright mod count n eachall<1)
looloooolooooooloooooooolooooooooooloooooooooooolooooooooooooooloooooooooooooooo

looooooooooooooooool


from strutils import `%`

const numDoors = 100
var doors: array[1..numDoors, bool]

for pass in 1..numDoors:
  for door in countup(pass, numDoors, pass):
    doors[door] = not doors[door]

for door in 1..numDoors:
  echo "Door $1 is $2." % [$door, if doors[door]: "open" else: "closed"]


Imports System.Text

Module Module1

    Class Zeckendorf
        Implements IComparable(Of Zeckendorf)

        Private Shared ReadOnly dig As String() = {"00", "01", "10"}
        Private Shared ReadOnly dig1 As String() = {"", "1", "10"}

        Private dVal As Integer = 0
        Private dLen As Integer = 0

        Public Sub New(Optional x As String = "0")
            Dim q = 1
            Dim i = x.Length - 1
            dLen = i \ 2

            Dim z = Asc("0")
            While i >= 0
                Dim a = Asc(x(i))
                dVal += (a - z) * q
                q *= 2
                i -= 1
            End While
        End Sub

        Private Sub A(n As Integer)
            Dim i = n
            While True
                If dLen < i Then
                    dLen = i
                End If
                Dim j = (dVal >> (i * 2)) And 3
                If j = 0 OrElse j = 1 Then
                    Return
                ElseIf j = 2 Then
                    If ((dVal >> ((i + 1) * 2)) And 1) <> 1 Then
                        Return
                    End If
                    dVal += 1 << (i * 2 + 1)
                    Return
                ElseIf j = 3 Then
                    Dim temp = 3 << (i * 2)
                    temp = temp Xor -1
                    dVal = dVal And temp
                    B((i + 1) * 2)
                End If
                i += 1
            End While
        End Sub

        Private Sub B(pos As Integer)
            If pos = 0 Then
                Inc()
                Return
            End If
            If ((dVal >> pos) And 1) = 0 Then
                dVal += 1 << pos
                A(pos \ 2)
                If pos > 1 Then
                    A(pos \ 2 - 1)
                End If
            Else
                Dim temp = 1 << pos
                temp = temp Xor -1
                dVal = dVal And temp
                B(pos + 1)
                B(pos - If(pos > 1, 2, 1))
            End If
        End Sub

        Private Sub C(pos As Integer)
            If ((dVal >> pos) And 1) = 1 Then
                Dim temp = 1 << pos
                temp = temp Xor -1
                dVal = dVal And temp
                Return
            End If
            C(pos + 1)
            If pos > 0 Then
                B(pos - 1)
            Else
                Inc()
            End If
        End Sub

        Public Function Inc() As Zeckendorf
            dVal += 1
            A(0)
            Return Me
        End Function

        Public Function Copy() As Zeckendorf
            Dim z As New Zeckendorf With {
                .dVal = dVal,
                .dLen = dLen
            }
            Return z
        End Function

        Public Sub PlusAssign(other As Zeckendorf)
            Dim gn = 0
            While gn < (other.dLen + 1) * 2
                If ((other.dVal >> gn) And 1) = 1 Then
                    B(gn)
                End If
                gn += 1
            End While
        End Sub

        Public Sub MinusAssign(other As Zeckendorf)
            Dim gn = 0
            While gn < (other.dLen + 1) * 2
                If ((other.dVal >> gn) And 1) = 1 Then
                    C(gn)
                End If
                gn += 1
            End While
            While (((dVal >> dLen * 2) And 3) = 0) OrElse dLen = 0
                dLen -= 1
            End While
        End Sub

        Public Sub TimesAssign(other As Zeckendorf)
            Dim na = other.Copy
            Dim nb = other.Copy
            Dim nt As Zeckendorf
            Dim nr As New Zeckendorf
            Dim i = 0
            While i < (dLen + 1) * 2
                If ((dVal >> i) And 1) > 0 Then
                    nr.PlusAssign(nb)
                End If
                nt = nb.Copy
                nb.PlusAssign(na)
                na = nt.Copy
                i += 1
            End While
            dVal = nr.dVal
            dLen = nr.dLen
        End Sub

        Public Function CompareTo(other As Zeckendorf) As Integer Implements IComparable(Of Zeckendorf).CompareTo
            Return dVal.CompareTo(other.dVal)
        End Function

        Public Overrides Function ToString() As String
            If dVal = 0 Then
                Return "0"
            End If

            Dim idx = (dVal >> (dLen * 2)) And 3
            Dim sb As New StringBuilder(dig1(idx))
            Dim i = dLen - 1
            While i >= 0
                idx = (dVal >> (i * 2)) And 3
                sb.Append(dig(idx))
                i -= 1
            End While
            Return sb.ToString
        End Function
    End Class

    Sub Main()
        Console.WriteLine("Addition:")
        Dim g As New Zeckendorf("10")
        g.PlusAssign(New Zeckendorf("10"))
        Console.WriteLine(g)
        g.PlusAssign(New Zeckendorf("10"))
        Console.WriteLine(g)
        g.PlusAssign(New Zeckendorf("1001"))
        Console.WriteLine(g)
        g.PlusAssign(New Zeckendorf("1000"))
        Console.WriteLine(g)
        g.PlusAssign(New Zeckendorf("10101"))
        Console.WriteLine(g)
        Console.WriteLine()

        Console.WriteLine("Subtraction:")
        g = New Zeckendorf("1000")
        g.MinusAssign(New Zeckendorf("101"))
        Console.WriteLine(g)
        g = New Zeckendorf("10101010")
        g.MinusAssign(New Zeckendorf("1010101"))
        Console.WriteLine(g)
        Console.WriteLine()

        Console.WriteLine("Multiplication:")
        g = New Zeckendorf("1001")
        g.TimesAssign(New Zeckendorf("101"))
        Console.WriteLine(g)
        g = New Zeckendorf("101010")
        g.PlusAssign(New Zeckendorf("101"))
        Console.WriteLine(g)
    End Sub

End Module


MODULE Doors;
  IMPORT Out;

  PROCEDURE Do*;  (* In Oberon an asterisk after an identifier is an export mark *)
    CONST N = 100; len = N + 1;
    VAR i, j: INTEGER;
      closed: ARRAY len OF BOOLEAN;  (* Arrays in Oberon always start with index 0; closed[0] is not used *)
  BEGIN
    FOR i := 1 TO N DO closed[i] := TRUE END;
    FOR i := 1 TO N DO
      j := 1;
      WHILE j < len DO
        IF j MOD i = 0 THEN closed[j] := ~closed[j] END; INC(j)  (* ~ = NOT *)
      END
    END;
    (* Print a state diagram of all doors *)
    FOR i := 1 TO N DO
      IF (i - 1) MOD 10 = 0 THEN Out.Ln END;
      IF closed[i] THEN Out.String("- ") ELSE Out.String("+ ") END
    END;  Out.Ln;
    (* Print the numbers of the open doors *)
    FOR i := 1 TO N DO
      IF ~closed[i] THEN Out.Int(i, 0); Out.Char(" ") END
    END;  Out.Ln
  END Do;

END Doors.


bundle Default {
  class Doors {
    function : Main(args : String[]) ~ Nil {
      doors := Bool->New[100];

      for(pass := 0; pass < 10; pass += 1;) {
        doors[(pass + 1) * (pass + 1) - 1] := true;
      };

      for(i := 0; i < 100; i += 1;) {
        IO.Console->GetInstance()->Print("Door #")->Print(i + 1)->Print(" is ");
        if(doors[i]) {
          "open."->PrintLine();
        }
        else {
          "closed."->PrintLine();
        };
      };
    }
  }
}


import strings
const (
    dig  = ["00", "01", "10"]
    dig1 = ["", "1", "10"]
)

struct Zeckendorf {
mut:
    d_val int
    d_len int
}

fn new_zeck(xx string) Zeckendorf {
    mut z := Zeckendorf{}
    mut x := xx
    if x == "" {
        x = "0"
    }
    mut q := 1
    mut i := x.len - 1
    z.d_len = i / 2
    for ; i >= 0; i-- {
        z.d_val += int(x[i]-'0'[0]) * q
        q *= 2
    }
    return z
}

fn (mut z Zeckendorf) a(ii int) {
    mut i:=ii
    for ; ; i++ {
        if z.d_len < i {
            z.d_len = i
        }
        j := (z.d_val >> u32(i*2)) & 3
        if j in [0, 1] {
            return
        } else if j==2 {
            if ((z.d_val >> (u32(i+1) * 2)) & 1) != 1 {
                return
            }
            z.d_val += 1 << u32(i*2+1)
            return
        } else {// 3
            z.d_val &= ~(3 << u32(i*2))
            z.b((i + 1) * 2)
        }
    }
}

fn (mut z Zeckendorf) b(p int) {
    mut pos := p
    if pos == 0 {
        z.inc()
        return
    }
    if ((z.d_val >> u32(pos)) & 1) == 0 {
        z.d_val += 1 << u32(pos)
        z.a(pos / 2)
        if pos > 1 {
            z.a(pos/2 - 1)
        }
    } else {
        z.d_val &= ~(1 << u32(pos))
        z.b(pos + 1)
        mut temp := 1
        if pos > 1 {
            temp = 2
        }
        z.b(pos - temp)
    }
}

fn (mut z Zeckendorf) c(p int) {
    mut pos := p
    if ((z.d_val >> u32(pos)) & 1) == 1 {
        z.d_val &= ~(1 << u32(pos))
        return
    }
    z.c(pos + 1)
    if pos > 0 {
        z.b(pos - 1)
    } else {
        z.inc()
    }
}

fn (mut z Zeckendorf) inc() {
    z.d_val++
    z.a(0)
}

fn (mut z1 Zeckendorf) plus_assign(z2 Zeckendorf) {
    for gn := 0; gn < (z2.d_len+1)*2; gn++ {
        if ((z2.d_val >> u32(gn)) & 1) == 1 {
            z1.b(gn)
        }
    }
}

fn (mut z1 Zeckendorf) minus_assign(z2 Zeckendorf) {
    for gn := 0; gn < (z2.d_len+1)*2; gn++ {
        if ((z2.d_val >> u32(gn)) & 1) == 1 {
            z1.c(gn)
        }
    }

    for z1.d_len > 0 && ((z1.d_val>>u32(z1.d_len*2))&3) == 0 {
        z1.d_len--
    }
}

fn (mut z1 Zeckendorf) times_assign(z2 Zeckendorf) {
    mut na := z2.copy()
    mut nb := z2.copy()
    mut nr := Zeckendorf{}
    for i := 0; i <= (z1.d_len+1)*2; i++ {
        if ((z1.d_val >> u32(i)) & 1) > 0 {
            nr.plus_assign(nb)
        }
        nt := nb.copy()
        nb.plus_assign(na)
        na = nt.copy()
    }
    z1.d_val = nr.d_val
    z1.d_len = nr.d_len
}

fn (z Zeckendorf) copy() Zeckendorf {
    return Zeckendorf{z.d_val, z.d_len}
}

fn (z1 Zeckendorf) compare(z2 Zeckendorf) int {
    if z1.d_val < z2.d_val {
        return -1
    } else if z1.d_val > z2.d_val {
        return 1
    } else {
        return 0
    }
}

fn (z Zeckendorf) str() string {
    if z.d_val == 0 {
        return "0"
    }
    mut sb := strings.new_builder(128)
    sb.write_string(dig1[(z.d_val>>u32(z.d_len*2))&3])
    for i := z.d_len - 1; i >= 0; i-- {
        sb.write_string(dig[(z.d_val>>u32(i*2))&3])
    }
    return sb.str()
}

fn main() {
    println("Addition:")
    mut g := new_zeck("10")
    g.plus_assign(new_zeck("10"))
    println(g)
    g.plus_assign(new_zeck("10"))
    println(g)
    g.plus_assign(new_zeck("1001"))
    println(g)
    g.plus_assign(new_zeck("1000"))
    println(g)
    g.plus_assign(new_zeck("10101"))
    println(g)

    println("\nSubtraction:")
    g = new_zeck("1000")
    g.minus_assign(new_zeck("101"))
    println(g)
    g = new_zeck("10101010")
    g.minus_assign(new_zeck("1010101"))
    println(g)

    println("\nMultiplication:")
    g = new_zeck("1001")
    g.times_assign(new_zeck("101"))
    println(g)
    g = new_zeck("101010")
    g.plus_assign(new_zeck("101"))
    println(g)
}


import "/trait" for Comparable

class Zeckendorf is Comparable {
    static dig  { ["00", "01", "10"] }
    static dig1 { ["", "1", "10"] }

    construct new(x) {
        var q = 1
        var i = x.count - 1
        _dLen = (i / 2).floor
        _dVal = 0
        while (i >= 0) {
            _dVal = _dVal + (x[i].bytes[0] - 48) * q
            q = q * 2
            i = i - 1
        }
    }

    dLen { _dLen }
    dVal { _dVal }

    dLen=(v) { _dLen = v }
    dVal=(v) { _dVal = v }

    a(n) {
        var i = n
        while (true) {
            if (_dLen < i) _dLen = i
            var j = (_dVal >> (i * 2)) & 3
            if (j == 0 || j == 1) return
            if (j == 2) {
                if (((_dVal >> ((i + 1) * 2)) & 1) != 1) return
                _dVal = _dVal + (1 << (i * 2 + 1))
                return
            }
            if (j == 3) {
                _dVal = _dVal & ~(3 << (i * 2))
                b((i + 1) * 2)
            }
            i = i + 1
        }
    }

    b(pos) {
        if (pos == 0) {
            var thiz = this
            thiz.inc
            return
        }
        if (((_dVal >> pos) & 1) == 0) {
            _dVal = _dVal + (1 << pos)
            a((pos / 2).floor)
            if (pos > 1) a((pos / 2).floor - 1)
        } else {
            _dVal = _dVal & ~(1 << pos)
            b(pos + 1)
            b(pos - ((pos > 1) ? 2 : 1))
        }
    }

    c(pos) {
        if (((_dVal >> pos) & 1) == 1) {
            _dVal = _dVal & ~(1 << pos)
            return
        }
        c(pos + 1)
        if (pos > 0) {
            b(pos - 1)
        } else {
            var thiz = this
            thiz.inc
        }
    }

    inc {
        _dVal = _dVal + 1
        a(0)
        return this
    }

    plusAssign(other) {
        for (gn in 0...(other.dLen + 1) * 2) {
            if (((other.dVal >> gn) & 1) == 1) b(gn)
        }
    }

    minusAssign(other) {
        for (gn in 0...(other.dLen + 1) * 2) {
            if (((other.dVal >> gn) & 1) == 1) c(gn)
        }
        while ((((_dVal >> _dLen * 2) & 3) == 0) || (_dLen == 0)) _dLen = _dLen - 1
    }

    timesAssign(other) {
        var na = other.copy()
        var nb = other.copy()
        var nr = Zeckendorf.new("0")
        for (i in 0..(_dLen + 1) * 2) {
            if (((_dVal >> i) & 1) > 0) nr.plusAssign(nb)
            var nt = nb.copy()
            nb.plusAssign(na)
            na = nt.copy()
        }
        _dVal = nr.dVal
        _dLen = nr.dLen
    }

    compare(other) { (_dVal - other.dVal).sign }

    toString {
        if (_dVal == 0) return "0"
        var sb = Zeckendorf.dig1[(_dVal >> (_dLen * 2)) & 3]
        if (_dLen > 0) {
            for (i in _dLen - 1..0) {
                sb = sb + Zeckendorf.dig[(_dVal >> (i * 2)) & 3]
            }
        }
        return sb
    }

    copy() {
        var z = Zeckendorf.new("0")
        z.dVal = _dVal
        z.dLen = _dLen
        return z
    }
}

var Z = Zeckendorf // type alias
System.print("Addition:")
var g = Z.new("10")
g.plusAssign(Z.new("10"))
System.print(g)
g.plusAssign(Z.new("10"))
System.print(g)
g.plusAssign(Z.new("1001"))
System.print(g)
g.plusAssign(Z.new("1000"))
System.print(g)
g.plusAssign(Z.new("10101"))
System.print(g)
System.print("\nSubtraction:")
g = Z.new("1000")
g.minusAssign(Z.new("101"))
System.print(g)
g = Z.new("10101010")
g.minusAssign(Z.new("1010101"))
System.print(g)
System.print("\nMultiplication:")
g = Z.new("1001")
g.timesAssign(Z.new("101"))
System.print(g)
g = Z.new("101010")
g.plusAssign(Z.new("101"))
System.print(g)


@import Foundation;

int main(int argc, const char * argv[]) {
    @autoreleasepool {

        // Create a mutable array
        NSMutableArray *doorArray = [@[] mutableCopy];

        // Fill the doorArray with 100 closed doors
        for (NSInteger i = 0; i < 100; ++i) {
            doorArray[i] = @NO;
        }

        // Do the 100 passes
        for (NSInteger pass = 0; pass < 100; ++pass) {
            for (NSInteger door = pass; door < 100; door += pass+1) {
                doorArray[door] = [doorArray[door]  isEqual: @YES] ? @NO : @YES;
            }
        }

        // Print the results
        [doorArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
            if ([obj isEqual: @YES]) {
                NSLog(@"Door number %lu is open", idx + 1);
            }
        }];
    }
}


let max_doors = 100

let show_doors =
  Array.iteri (fun i x -> Printf.printf "Door %d is %s\n" (i+1)
                                        (if x then "open" else "closed"))

let flip_doors doors =
  for i = 1 to max_doors do
    let rec flip idx =
      if idx < max_doors then begin
        doors.(idx) <- not doors.(idx);
        flip (idx + i)
      end
    in flip (i - 1)
  done;
  doors

let () =
  show_doors (flip_doors (Array.make max_doors false))


doors = false(100,1);
for i = 1:100
  for j = i:i:100
    doors(j) = !doors(j);
  endfor
endfor
for i = 1:100
  if ( doors(i) )
    s = "open";
  else
    s = "closed";
  endif
  printf("%d %s\n", i, s);
endfor


: doors
| i j l |
   100 false Array newWith dup ->l
   100 loop: i [
      i 100 i step: j [ l put ( j , j l at not ) ]
      ]
;


(define (flip doors every)
   (map (lambda (door num)
            (mod (+ door (if (eq? (mod num every) 0) 1 0)) 2))
      doors
      (iota (length doors) 1)))

(define doors
   (let loop ((doors (repeat 0 100)) (n 1))
      (if (eq? n 100)
         doors
         (loop (flip doors n) (+ n 1)))))

(print "100th doors: " doors)


$Door dict def
1 1 100 {Door exch false put} for
$Toggle {dup Door exch get not Door up put} def
$EveryNthDoor {dup 100 {Toggle} for} def
$Run {1 1 100 {EveryNthDoor} for} def
$ShowDoor {dup `Door no. ' exch cvs cat ` is ' cat
  exch Door exch get {`open.\n'}{`shut.\n'} ifelse cat
  print flush} def
Run 1 1 100 {ShowDoor} for


doors = .array~new(100)    -- array containing all of the doors
do i = 1 to doors~size     -- initialize with a collection of closed doors
   doors[i] = .door~new(i)
end

do inc = 1 to doors~size
  do d = inc to doors~size by inc
    doors[d]~toggle
  end
end
say "The open doors after 100 passes:"
do door over doors
  if door~isopen then say door
end

::class door           -- simple class to represent a door
::method init          -- initialize an instance of a door
  expose id state      -- instance variables of a door
  use strict arg id    -- set the id
  state = .false       -- initial state is closed

::method toggle        -- toggle the state of the door
  expose state
  state = \state

::method isopen        -- test if the door is open
  expose state
  return state

::method string        -- return a string value for a door
  expose state id
  if state then return "Door" id "is open"
  else return "Door" id "is closed"

::method state         -- return door state as a descriptive string
  expose state
  if state then return "open"
  else return "closed"


DEFINE VARIABLE lopen   AS LOGICAL     NO-UNDO EXTENT 100.
DEFINE VARIABLE idoor   AS INTEGER     NO-UNDO.
DEFINE VARIABLE ipass   AS INTEGER     NO-UNDO.
DEFINE VARIABLE cresult AS CHARACTER   NO-UNDO.

DO ipass = 1 TO 100:
   idoor = 0.
   DO WHILE idoor <= 100:
      idoor = idoor + ipass.
      IF idoor <= 100 THEN
         lopen[ idoor ] = NOT lopen[ idoor ].
   END.
END.

DO idoor = 1 TO 100:
   cresult = cresult + STRING( lopen[ idoor ], "1  /0  " ).
   IF idoor MODULO 10 = 0 THEN
      cresult = cresult + "~r":U.
END.

MESSAGE cresult VIEW-AS ALERT-BOX.


def    doors 100
int    door[doors],i ,j, c
string cr,tab,pr
'
for i=1 to doors
  for j=i to doors step i
    door[j]=1-door[j]
    if door[j] then c++ else c--
  next
next
'
cr=chr(13) chr(10)
pr="Doors Open: " c cr cr
'
for i=1 to doors
   if door[i] then pr+=i cr
next
print pr


declare
  NumDoors = 100
  NumPasses = 100

  fun {NewDoor} closed end

  fun {Toggle Door}
     case Door of closed then open
     [] open then closed
     end
  end

  fun {Pass Doors I}
     {List.mapInd Doors
      fun {$ Index Door}
         if Index mod I == 0 then {Toggle Door}
         else Door
         end
      end}
  end

  Doors0 = {MakeList NumDoors}
  {ForAll Doors0 NewDoor}

  DoorsN = {FoldL {List.number 1 NumPasses 1} Pass Doors0}
in
  %% print open doors
  {List.forAllInd DoorsN
   proc {$ Index Door}
      if Door == open then
	 {System.showInfo "Door "#Index#" is open."}
      end
   end
  }


v=vector(d=100);/*set 100 closed doors*/
for(i=1,d,forstep(j=i,d,i,v[j]=1-v[j]));
for(i=1,d,if(v[i],print("Door ",i," is open.")))


Program OneHundredDoors;

var
   doors : Array[1..100] of Boolean;
   i, j	 : Integer;

begin
   for i := 1 to 100 do
      doors[i] := False;
   for i := 1 to 100 do begin
      j := i;
      while j <= 100 do begin
	 doors[j] := not doors[j];
	 j := j + i
      end
   end;
   for i := 1 to 100 do begin
      Write(i, ' ');
      if doors[i] then
	 WriteLn('open')
      else
	 WriteLn('closed');
   end
end.


use perl5i::2;

package doors {

  use perl5i::2;
  use Const::Fast;

  const my $OPEN   => 1;
  const my $CLOSED => 0;

  # ----------------------------------------
  # Constructor: door->new( @args );
  # input: N - how many doors?
  # returns: door object
  #
  method new($class: @args ) {
    my $self = bless {}, $class;
    $self->_init( @args );
    return $self;
  }

  # ----------------------------------------
  # class initializer.
  # input: how many doors?
  # sets N, creates N+1 doors ( door zero is not used ).
  #
  method _init( $N ) {
    $self->{N} = $N;
    $self->{doors} = [ ($CLOSED) x ($N+1) ];
  }

  # ----------------------------------------
  # $self->toggle( $door_number );
  # input: number of door to toggle.
  # OPEN a CLOSED door; CLOSE an OPEN  door.
  #
  method toggle( $which ) {
    $self->{doors}[$which] = ( $self->{doors}[$which] == $OPEN
                               ? $CLOSED
                               : $OPEN
        		     );
  }

  # ----------------------------------------
  # $self->toggle_n( $cycle );
  # input: number.
  # Toggle doors 0, $cycle, 2 * $cycle, 3 * $cycle, .. $self->{N}
  #
  method toggle_n( $n ) {
    $self->toggle($_)
      for map { $n * $_ }
          ( 1 .. int( $self->{N} / $n) );

  }

  # ----------------------------------------
  # $self->toggle_all();
  # Toggle every door, then every other door, every third door, ...
  #
  method toggle_all() {
    $self->toggle_n( $_ ) for ( 1 .. $self->{N} );
  }

  # ----------------------------------------
  # $self->print_open();
  # Print list of which doors are open.
  #
  method print_open() {
    say join ', ', grep { $self->{doors}[$_] == $OPEN } ( 1 ... $self->{N} );
  }
}

# ----------------------------------------------------------------------
# Main Thread
#
my $doors = doors->new(100);
$doors->toggle_all();
$doors->print_open();


sequence doors = repeat(false,100)

for i=1 to 100 do
    for j=i to 100 by i do
        doors[j] = not doors[j]
    end for
end for

for i=1 to 100 do
    if doors[i] == true then
        printf(1,"Door #%d is open.\n", i)
    end if
end for


101 var l
0 l repeat

l for
    var s
    s l s 3 tolist
    for
        var i
        i get not i set
    endfor
endfor

l for
    var i
    i get
    if
        i print " " print
    endif
endfor


module doors;

extern printf;

@Integer main [
	@Array<@Boolean> doors = new @Array<@Boolean>.init(100);
	var i = 1;
	while (i <= 100) {
		var j = i-1;
		while (j < 100) {
			doors.set(j, doors.get(j)::not);
			j = j + i;
		}
		i = i::inc;
	}
	i = 0;
	while (i < 100) {
		printf("%i %s\n", i+1, iif(doors.get(i), "open", "closed"));
		i = i::inc;
	}
	return 0;
]


<?php
for ($i = 1; $i <= 100; $i++) {
	$root = sqrt($i);
	$state = ($root == ceil($root)) ? 'open' : 'closed';
	echo "Door {$i}: {$state}\n";
}
?>


doors(N) =>
   Doors = new_array(N),
   foreach(I in 1..N) Doors[I] := 0 end,
   foreach(I in 1..N)
     foreach(J in I..I..N)
        Doors[J] := 1^Doors[J]
     end,
     if N <= 10 then
        print_open(Doors)
     end
   end,
   println(Doors),
   print_open(Doors),
   nl.

print_open(Doors) => println([I : I in 1..Doors.length, Doors[I] == 1]).


(let Doors (need 100)
   (for I 100
      (for (D (nth Doors I)  D  (cdr (nth D I)))
         (set D (not (car D))) ) )
   (println Doors) )


array onehundreddoors()
{
    array doors = allocate(100);
    foreach(doors; int i;)
        for(int j=i; j<100; j+=i+1)
            doors[j] = !doors[j];
    return doors;
}


declare door(100) bit (1) aligned;
declare closed bit (1) static initial ('0'b),
        open   bit (1) static initial ('1'b);
declare (i, inc) fixed binary;

door = closed;
inc = 1;
do until (inc >= 100);
   do i = inc to 100 by inc;
      door(i) = ^door(i); /* close door if open; open it if closed. */
   end;
   inc = inc+1;
end;

do i = 1 to 100;
   put skip edit ('Door ', trim(i), ' is ') (a);
   if door(i) then put edit (' open.') (a);
   else put edit (' closed.') (a);
end;


100H: /* FIND THE FIRST FEW SQUARES VIA THE UNOPTIMISED DOOR FLIPPING METHOD */

    /* BDOS SYSTEM CALL */
    BDOS: PROCEDURE( FN, ARG );
        DECLARE FN BYTE, ARG ADDRESS;
        GO TO 5;
    END BDOS;

    /* PRINTS A BYTE AS A CHARACTER */
    PRINT$CHAR: PROCEDURE( CH );
        DECLARE CH BYTE;
        CALL BDOS( 2, CH );
    END PRINT$CHAR;

    /* PRINTS A BYTE AS A NUMBER */
    PRINT$BYTE: PROCEDURE( N );
        DECLARE N BYTE;
        DECLARE ( V, D3, D2 ) BYTE;
        V  = N;
        D3 = V MOD 10;
        IF ( V := V / 10 ) <> 0 THEN DO;
            D2 = V MOD 10;
            IF ( V := V / 10 ) <> 0 THEN CALL PRINT$CHAR( '0' + V );
            CALL PRINT$CHAR( '0' + D2 );
        END;
        CALL PRINT$CHAR( '0' + D3 );
    END PRINT$BYTE;

    DECLARE DOOR$DCL LITERALLY '101';
    DECLARE FALSE    LITERALLY '0';
    DECLARE CR       LITERALLY '0DH';
    DECLARE LF       LITERALLY '0AH';

    /* ARRAY OF DOORS - DOOR( I ) IS TRUE IF OPEN, FALSE IF CLOSED */
    DECLARE DOOR( DOOR$DCL ) BYTE;
    DECLARE ( I, J )         BYTE;

    /* SET ALL DOORS TO CLOSED */
    DO I = 0 TO LAST( DOOR ); DOOR( I ) = FALSE; END;
    /* REPEATEDLY FLIP THE DOORS */
    DO I = 1 TO LAST( DOOR );
       DO J = I TO LAST( DOOR ) BY I;
          DOOR( J ) = NOT DOOR( J );
       END;
    END;
    /* DISPLAY THE RESULTS */
    DO I = 1 TO LAST( DOOR );
       IF DOOR( I ) THEN DO;
          CALL PRINT$CHAR( ' ' );
          CALL PRINT$BYTE( I );
       END;
    END;
    CALL PRINT$CHAR( CR );
    CALL PRINT$CHAR( LF );
EOF


DECLARE
  TYPE doorsarray IS VARRAY(100) OF BOOLEAN;
  doors doorsarray := doorsarray();
BEGIN

doors.EXTEND(100);  --ACCOMMODATE 100 DOORS

FOR i IN 1 .. doors.COUNT  --MAKE ALL 100 DOORS FALSE TO INITIALISE
  LOOP
     doors(i) := FALSE;
  END LOOP;

FOR j IN 1 .. 100 --ITERATE THRU USING MOD LOGIC AND FLIP THE DOOR RIGHT OPEN OR CLOSE
 LOOP
      FOR k IN 1 .. 100
        LOOP
                  IF MOD(k,j)=0 THEN
                     doors(k) := NOT doors(k);
                  END IF;
        END LOOP;
 END LOOP;

FOR l IN 1 .. doors.COUNT  --PRINT THE STATUS IF ALL 100 DOORS AFTER ALL ITERATION
  LOOP
       DBMS_OUTPUT.PUT_LINE('DOOR '||l||' IS -->> '||CASE WHEN SYS.DBMS_SQLTCB_INTERNAL.I_CONVERT_FROM_BOOLEAN(doors(l)) = 'TRUE'
                                                                THEN 'OPEN'
                                                              ELSE 'CLOSED'
                                                        END);
  END LOOP;

END;


output =
  range(1, 100)
  |> map(visit(100))
  |> println

----------------------------------------------------------

toggle(state) =
  if state == Closed then Open else Closed

----------------------------------------------------------
-- Door state on iteration i is recursively
-- defined in terms of previous door state

visit(i, index) = cond {
  case (i == 0) Closed
  case (index % i == 0) toggle(lastState)
  else lastState
} where lastState = visit(i - 1, index)


/* FIND THE FIRST FEW SQUARES VIA THE UNOPTIMISED DOOR FLIPPING METHOD */
doors_100H: procedure options                                                   (main);

/* PROGRAM-SPECIFIC %REPLACE STATEMENTS MUST APPEAR BEFORE THE %INCLUDE AS */
/* E.G. THE CP/M PL/I COMPILER DOESN'T LIKE THEM TO FOLLOW PROCEDURES      */
   /* PL/I                                                                      */
      %replace dcldoors by         100;
   /* PL/M */                                                                   /*
      DECLARE  DCLDOORS LITERALLY '101';
   /* */

/* PL/I DEFINITIONS                                                             */
%include 'pg.inc';
/* PL/M DEFINITIONS: CP/M BDOS SYSTEM CALL AND CONSOLE I/O ROUTINES, ETC. */    /*
   DECLARE BINARY LITERALLY 'ADDRESS', CHARACTER LITERALLY 'BYTE';
   DECLARE FIXED  LITERALLY ' ',       BIT       LITERALLY 'BYTE';
   DECLARE STATIC LITERALLY ' ',       RETURNS   LITERALLY ' ';
   DECLARE FALSE  LITERALLY '0',       TRUE LITERALLY '1';
   DECLARE HBOUND LITERALLY 'LAST',    SADDR  LITERALLY '.';
   BDOSF: PROCEDURE( FN, ARG )BYTE;
                               DECLARE FN BYTE, ARG ADDRESS; GOTO 5;   END;
   BDOS: PROCEDURE( FN, ARG ); DECLARE FN BYTE, ARG ADDRESS; GOTO 5;   END;
   PRCHAR:   PROCEDURE( C );   DECLARE C BYTE;      CALL BDOS( 2, C ); END;
   PRSTRING: PROCEDURE( S );   DECLARE S ADDRESS;   CALL BDOS( 9, S ); END;
   PRNL:     PROCEDURE;        CALL PRCHAR( 0DH ); CALL PRCHAR( 0AH ); END;
   PRNUMBER: PROCEDURE( N );
      DECLARE N ADDRESS;
      DECLARE V ADDRESS, N$STR( 6 ) BYTE, W BYTE;
      N$STR( W := LAST( N$STR ) ) = '$';
      N$STR( W := W - 1 ) = '0' + ( ( V := N ) MOD 10 );
      DO WHILE( ( V := V / 10 ) > 0 );
         N$STR( W := W - 1 ) = '0' + ( V MOD 10 );
      END;
      CALL BDOS( 9, .N$STR( W ) );
   END PRNUMBER;
   MODF:     PROCEDURE( A, B )ADDRESS;
      DECLARE ( A, B ) ADDRESS;
      RETURN A MOD B;
   END MODF;
/* END LANGUAGE DEFINITIONS */

   /* TASK */

   /* ARRAY OF DOORS - DOOR( I ) IS TRUE IF OPEN, FALSE IF CLOSED */
   DECLARE DOOR( DCLDOORS )  BIT;
   DECLARE ( I, J, MAXDOOR ) FIXED BINARY;

   MAXDOOR = HBOUND( DOOR                                                       ,1
                   );

   /* SET ALL DOORS TO CLOSED */
   DO I = 0 TO MAXDOOR; DOOR( I ) = FALSE; END;
   /* REPEATEDLY FLIP THE DOORS */
   DO I = 1 TO MAXDOOR;
      DO J = I TO MAXDOOR BY I;
         DOOR( J ) = NOT( DOOR( J ) );
      END;
   END;
   /* DISPLAY THE RESULTS */
   DO I = 1 TO MAXDOOR;
      IF DOOR( I ) THEN DO;
         CALL PRCHAR( ' ' );
         CALL PRNUMBER( I );
      END;
   END;
   CALL PRNL;

EOF: end doors_100H;


actor Toggler
    let doors:Array[Bool]
    let env: Env
    new create(count:USize,_env:Env) =>
        var i:USize=0
        doors=Array[Bool](count)
        env=_env
        while doors.size() < count do
            doors.push(false)
        end
    be togglin(interval : USize)=>
        var i:USize=0
        try
            while i < doors.size() do
                doors.update(i,not doors(i)?)?
                i=i+interval
            end
        else
            env.out.print("Errored while togglin'!")
        end
    be printn(onlyOpen:Bool)=>
        try
            for i in doors.keys() do
                if onlyOpen and not doors(i)? then
                    continue
                end
                env.out.print("Door " + i.string() + " is " +
                    if doors(i)? then
                        "Open"
                    else
                        "closed"
                    end)
            end
        else
            env.out.print("Error!")
        end
        true

actor OptimizedToggler
    let doors:Array[Bool]
    let env:Env
    new create(count:USize,_env:Env)=>
        env=_env
        doors=Array[Bool](count)
        while doors.size()<count do
            doors.push(false)
        end
    be togglin()=>
        var i:USize=0
        if alreadydone then
            return
        end
        try
            doors.update(0,true)?
            doors.update(1,true)?
            while i < doors.size() do
                i=i+1
                let z=i*i
                let x=z*z
                if z > doors.size() then
                    break
                else
                    doors.update(z,true)?
                end
                if x < doors.size() then
                    doors.update(x,true)?
                end
            end
        end
    be printn(onlyOpen:Bool)=>
        try
            for i in doors.keys() do
                if onlyOpen and not doors(i)? then
                    continue
                end
                env.out.print("Door " + i.string() + " is " +
                    if doors(i)? then
                        "Open"
                    else
                        "closed"
                    end)
            end
        else
            env.out.print("Error!")
        end
        true
actor Main
    new create(env:Env)=>
        var count: USize =100
        try
            let index=env.args.find("-n",0,0,{(l,r)=>l==r})?
            try
            match env.args(index+1)?.read_int[USize]()?
                | (let x:USize, _)=>count=x
                end
            else
                env.out.print("You either neglected to provide an argument after -n or that argument was not an integer greater than zero.")
                return
            end
        end
        if env.args.contains("optimized",{(l,r)=>r==l}) then
            let toggler=OptimizedToggler(count,env)
            var i:USize = 1
            toggler.togglin()
            toggler.printn(env.args.contains("onlyopen", {(l,r)=>l==r}))
        else
            let toggler=Toggler(count,env)
            var i:USize = 1
            while i < count do
                toggler.togglin(i)
                i=i+1
            end
            toggler.printn(env.args.contains("onlyopen", {(l,r)=>l==r}))
        end


lvars i;
lvars doors = {% for i from 1 to 100 do false endfor %};
for i from 1 to 100 do
   for j from i by i to 100 do
      not(doors(j)) -> doors(j);
   endfor;
endfor;
;;; Print state
for i from 1 to 100 do
   printf('Door ' >< i >< ' is ' ><
            if doors(i) then 'open' else 'closed' endif, '%s\n');
endfor;


/doors [ 100 { false } repeat ] def

1 1 100 { dup 1 sub exch 99 {
        dup doors exch get not doors 3 1 roll put
} for } for
doors pstack


square=1, i=3
1 to 100(door):
  if (door == square):
    ("door", door, "is open") say
    square += i
    i += 2.
.


$doors = @(0..99)
for($i=0; $i -lt 100; $i++) {
  $doors[$i] = 0  # start with all doors closed
}
for($i=0; $i -lt 100; $i++) {
  $step = $i + 1
  for($j=$i; $j -lt 100; $j = $j + $step) {
    $doors[$j] = $doors[$j] -bxor 1
  }
}
foreach($doornum in 1..100) {
  if($doors[($doornum-1)] -eq $true) {"$doornum open"}
  else {"$doornum closed"}
}


boolean[] doors = new boolean[100];

void setup() {
  for (int i = 0; i < 100; i++) {
    doors[i] = false;
  }
  for (int i = 1; i < 100; i++) {
    for (int j = 0; j < 100; j += i) {
      doors[j] = !doors[j];
    }
  }
  println("Open:");
  for (int i = 1; i < 100; i++) {
    if (doors[i]) {
      println(i);
    }
  }
  exit();
}


enableextensions
enabledelayedexpansion
editvar /newvar /value=0 /title=closed
editvar /newvar /value=1 /title=open
editvar /newvar /range=1-100 /increment=1 /from=2
editvar /newvar /value=2 /title=next
:doors
for /alloccurrences (!next!-!102!) do editvar /modify /value=-open-
editvar /modify /value=-next-=+1
if -next- /hasvalue=100 goto :cont else goto :doors
:cont
printline !1!-!102!
stoptask


main :-
    forall(between(1,100,Door), ignore(display(Door))).

% show output if door is open after the 100th pass
display(Door) :-
    status(Door, 100, open),
    format("Door ~d is open~n", [Door]).

% true if Door has Status after Pass is done
status(Door, Pass, Status) :-
    Pass > 0,
    Remainder is Door mod Pass,
    toggle(Remainder, OldStatus, Status),
    OldPass is Pass - 1,
    status(Door, OldPass, OldStatus).
status(_Door, 0, closed).

toggle(Remainder, Status, Status) :-
    Remainder > 0.
toggle(0, open, closed).
toggle(0, closed, open).


using system;

// initialize doors as pairs: number, status where 0 means open
let doors = zip (1..100) (repeat 1);

toogle (x,y) = x,~y;

toogleEvery n d = map (tooglep n) d with
                    tooglep n [email protected]((x,_)) = toogle d if ~(x mod n);
                                        = d otherwise; end;

// show description of given doors
status (n,x) = (str n) + (case x of
                            1 = " close";
                            0 = " open"; end);

let result = foldl (\a n -> toogleEvery n a) doors (1..100);

// pretty print the result (only open doors)
showResult = do (puts.status) final when
               final = filter open result with
                         open (_,x) = ~x;
                       end; end;


100Doors.pd

#N canvas 241 375 414 447 10;
#X obj 63 256 expr doors[$f1] = doors[$f1] ^ 1;
#X msg 83 118 \; doors const 0;
#X msg 44 66 bang;
#X obj 44 92 t b b b;
#X obj 43 28 table doors 101;
#X obj 44 360 sel 0;
#X obj 44 336 expr if (doors[$f1] == 1 \, $f1 \, 0);
#X obj 63 204 t b f f;
#X text 81 66 run;
#X obj 71 384 print -n;
#X text 132 310 print results (open doors);
#X obj 63 179 loop 1 100 1;
#X obj 63 231 loop 1 100 1;
#X obj 44 310 loop 1 100 1;
#X text 148 28 create array;
#X text 151 180 100 passes;
#X text 179 123 set values to 0;
#X connect 2 0 3 0;
#X connect 3 0 13 0;
#X connect 3 1 11 0;
#X connect 3 2 1 0;
#X connect 5 1 9 0;
#X connect 6 0 5 0;
#X connect 7 0 12 0;
#X connect 7 1 12 1;
#X connect 7 2 12 3;
#X connect 11 0 7 0;
#X connect 12 0 0 0;
#X connect 13 0 6 0;

loop.pd

#N canvas 656 375 427 447 10;
#X obj 62 179 until;
#X obj 102 200 f;
#X obj 62 89 inlet;
#X obj 303 158 f \$3;
#X obj 270 339 outlet;
#X obj 223 89 inlet;
#X obj 138 89 inlet;
#X obj 324 89 inlet;
#X obj 117 158 f \$1;
#X text 323 68 step;
#X obj 202 158 f \$2;
#X obj 62 118 t b b b b;
#X obj 270 315 spigot;
#X obj 89 314 sel 0;
#X obj 137 206 +;
#X obj 102 237 expr $f1 \; if ($f3 > 0 \, if ($f1 > $f2 \, 0 \, 1)
\, if ($f3 < 0 \, if ($f1 < $f2 \, 0 \, 1) \, 0)), f 34;
#X text 63 68 run;
#X text 136 68 start;
#X text 227 68 end;
#X text 58 31 loop (abstraction);
#X connect 0 0 1 0;
#X connect 1 0 14 0;
#X connect 1 0 15 0;
#X connect 2 0 11 0;
#X connect 3 0 14 1;
#X connect 3 0 15 2;
#X connect 5 0 10 1;
#X connect 6 0 8 1;
#X connect 7 0 3 1;
#X connect 8 0 1 1;
#X connect 10 0 15 1;
#X connect 11 0 0 0;
#X connect 11 1 8 0;
#X connect 11 2 10 0;
#X connect 11 3 3 0;
#X connect 12 0 4 0;
#X connect 13 0 0 1;
#X connect 14 0 1 1;
#X connect 15 0 12 0;
#X connect 15 1 12 1;
#X connect 15 1 13 0;


Dim doors.i(100)

For x = 1 To 100
  y = x
  While y <= 100
    doors(y) = 1 - doors(y)
    y + x
  Wend
Next

OpenConsole()
PrintN("Following Doors are open:")
For x = 1 To 100
  If doors(x)
    Print(Str(x) + ", ")
  EndIf
Next
Input()


data Door:
  | open
  | closed
end

fun flip-door(d :: Door) -> Door:
  cases(Door) d:
    | open => closed
    | closed => open
  end
end

fun flip-doors(doors :: List<Door>) -> List<Door>:
  doc:```Given a list of door positions, repeatedly switch the positions of
      every nth door for every nth pass, and return the final list of door
      positions```
  for fold(flipped-doors from doors, n from range(1, doors.length() + 1)):
    for map_n(m from 1, d from flipped-doors):
      if num-modulo(m, n) == 0:
        flip-door(d)
      else:
        d
      end
    end
  end
where:
    flip-doors([list: closed, closed, closed]) is
  [list: open, closed, closed]

  flip-doors([list: closed, closed, closed, closed]) is
  [list: open, closed, closed, open]

  flip-doors([list: closed, closed, closed, closed, closed, closed]) is
  [list: open, closed, closed, open, closed, closed]

  closed-100 = for map(_ from range(1, 101)): closed end
  answer-100 = for map(n from range(1, 101)):
    if num-is-integer(num-sqrt(n)): open
    else: closed
    end
  end

  flip-doors(closed-100) is answer-100
end

fun find-indices<A>(pred :: (A -> Boolean), xs :: List<A>) -> List<Number>:
    doc:```Given a list and a predicate function, produce a list of index
      positions where there's a match on the predicate```
  ps = map_n(lam(n,e): if pred(e): n else: -1 end end, 1, xs)
  ps.filter(lam(x): x >= 0 end)
where:
  find-indices((lam(i): i == true end), [list: true,false,true]) is [list:1,3]
end

fun run(n):
  doc:```Given a list of doors that are closed, make repeated passes
      over the list, switching the positions of every nth door for
      each nth pass. Return a list of positions in the list where the
      door is Open.```
  doors = repeat(n, closed)
  ys = flip-doors(doors)
  find-indices((lam(y): y == open end), ys)
where:
  run(4) is [list: 1,4]
end

run(100)


doors = [False] * 100
for i in range(100):
   for j in range(i, 100, i+1):
       doors[j] = not doors[j]
   print("Door %d:" % (i+1), 'open' if doors[i] else 'close')


Const Opened = -1, Closed = 0
Dim Doors(1 To 100) As Integer, Passes As Integer, Index As Integer
Rem Normal implementation
Print "100doors Normal method"
For Passes = 1 To 100 Step 1
    Doors(Passes) = Closed
Next Passes
For Passes = 1 To 100 Step 1
    For Index = 0 To 100 Step Passes
        If Index > 100 Then Exit For
        If Index > 0 Then If Doors(Index) = Opened Then Doors(Index) = Closed Else Doors(Index) = Opened
    Next Index
Next Passes
Print "OPEN DOORS after 100th passes"
For Passes = 1 To 100 Step 1
    If Doors(Passes) = Opened Then Print Passes; " ";
Next

Rem Alternative solution of perfect squares

Print "Alternative method"
Passes = 0
For Passes = 1 To 100 Step 1
    Doors(Passes) = Closed
Next Passes
For Passes = 1 To 100 Step 1
    If Sqr(Passes) = Int(Sqr(Passes)) Then Doors(Passes) = Opened
Next
Print "Opened doors found by SQR method"
For Passes = 1 To 100 Step 1
    If Doors(Passes) = Opened Then Print Passes; " ";
Next Passes
End


/O>  [ bit ^ ]                       is toggle      ( f n --> f )
...
...  [ 0
...    100 times
...      [ i^ 1+ swap
...        101 times
...          [ i^ toggle over step ]
...      nip ] ]                     is toggledoors (     --> f )
...
...   [ 100 times
...        [ 1 >> dup 1 &
...          if [ i^ 1+ echo sp ] ]
...     drop ]                       is echodoors   (   f -->   )
...
...  toggledoors
...  say " These doors are open: " echodoors cr
...  say " The rest are closed." cr
...
 These doors are open: 1 4 9 16 25 36 49 64 81 100
 The rest are closed.

Stack empty.


doors_puzzle <- function(ndoors, passes = ndoors) {
    doors <- logical(ndoors)
    for (ii in seq(passes)) {
        mask <- seq(ii, ndoors, ii)
        doors[mask] <- !doors[mask]
    }
    which(doors)
}

doors_puzzle(100)


#lang racket

;; Applies fun to every step-th element of seq, leaving the others unchanged.
(define (map-step fun step seq)
  (for/list ([elt seq] [i (in-naturals)])
    ((if (zero? (modulo i step)) fun values) elt)))

(define (toggle-nth n seq)
  (map-step not n seq))

(define (solve seq)
  (for/fold ([result seq]) ([_ seq] [pass (in-naturals 1)])
    (toggle-nth pass result)))

(for ([door (solve (make-vector 101 #f))] [index (in-naturals)]
      #:when (and door (> index 0)))
  (printf "~a is open~%" index))


my @doors = False xx 101;

(.=not for @doors[0, $_ ... 100]) for 1..100;

say "Door $_ is ", <closed open>[ @doors[$_] ] for 1..100;


dim x as integer, y as integer
dim door(1 to 100) as byte

'initialize array
for x = 1 to 100 : door(x) = 0 : next

'set door values
for y = 1 to 100
    for x = y to 100 step y
        door(x) = not door(x)
    next x
next y

'print result
for x = 1 to 100
    if door(x) then print "Door " + str$(x) + " = open"
next

while inkey$="":wend
end


doors: array/initial 100 'closed
repeat i 100 [
    door: at doors i
    forskip door i [change door either 'open = first door ['closed] ['open]]
]


Red [
  Purpose: "100 Doors Problem (Perfect Squares)"
  Author: "Barry Arthur"
  Date: "07-Oct-2016"
]
doors: make vector! [char! 8 100]
repeat i 100 [change at doors i #"."]

repeat i 100 [
    j: i
    while [j <= 100] [
      door: at doors j
      change door either #"O" = first door [#"."] [#"O"]
      j: j + i
    ]
]

repeat i 10 [
  print copy/part at doors (i - 1 * 10 + 1) 10
]


relation door, state
set i = 1
while i <= 100
insert i, 1
set i = i+1
end while
set i = 2
while i <= 100
update state = 1-state where not (door mod i)
set i = i+1
end while
update state = "open" where state
update state = "closed" where state !== "open"
print


F zigzag(n)
   F compare(xy)
      V (x, y) = xy
      R (x + y, I (x + y) % 2 {-y} E y)
   V xs = 0 .< n
   R Dict(enumerate(sorted((multiloop(xs, xs, (x, y) -> (x, y))), key' compare)), (n, index) -> (index, n))

F printzz(myarray)
   V n = Int(myarray.len ^ 0.5 + 0.5)
   V xs = 0 .< n
   print((xs.map(y -> @xs.map(x -> ‘#3’.format(@@myarray[(x, @y)])).join(‘’))).join("\n"))

printzz(zigzag(6))


:doors (n-) [ #1 repeat dup-pair n:square gt? 0; drop dup n:square n:put sp n:inc again ] do drop-pair ;
#100 doors


*        Zig-zag matrix            15/08/2015
ZIGZAGMA CSECT
         USING  ZIGZAGMA,R12       set base register
         LR     R12,R15            establish addressability
         LA     R9,N               n : matrix size
         LA     R6,1               i=1
         LA     R7,1               j=1
         LR     R11,R9             n
         MR     R10,R9             *n
         BCTR   R11,0              R11=n**2-1
         SR     R8,R8              k=0
LOOPK    CR     R8,R11             do k=0 to n**2-1
         BH     ELOOPK             k>limit
         LR     R1,R6              i
         BCTR   R1,0               -1
         MR     R0,R9              *n
         LR     R2,R7              j
         BCTR   R2,0               -1
         AR     R1,R2              (i-1)*n+(j-1)
         SLA    R1,1               index=((i-1)*n+j-1)*2
         STH    R8,T(R1)           t(i,j)=k
         LR     R2,R6              i
         AR     R2,R7              i+j
         LA     R1,2               2
         SRDA   R2,32              shift right r1 to r2
         DR     R2,R1              (i+j)/2
         LTR    R2,R2              if mod(i+j,2)=0
         BNZ    ELSEMOD
         CR     R7,R9              if j<n
         BNL    ELSE1
         LA     R7,1(R7)           j=j+1
         B      EIF1
ELSE1    LA     R6,2(R6)           i=i+2
EIF1     CH     R6,=H'1'           if i>1
         BNH    NOT1
         BCTR   R6,0               i=i-1
NOT1     B      NOT2
ELSEMOD  CR     R6,R9              if i<n
         BNL    ELSE2
         LA     R6,1(R6)           i=i+1
         B      EIF2
ELSE2    LA     R7,2(R7)           j=j+2
EIF2     CH     R7,=H'1'           if j>1
         BNH    NOT2
         BCTR   R7,0               j=j-1
NOT2     LA     R8,1(R8)           k=k+1
         B      LOOPK
ELOOPK   LA     R6,1               end k; i=1
LOOPI    CR     R6,R9              do i=1 to n
         BH     ELOOPI             i>n
         LA     R10,0              ibuf=0  buffer index
         MVC    BUFFER,=CL80' '
         LA     R7,1               j=1
LOOPJ    CR     R7,R9              do j=1 to n
         BH     ELOOPJ             j>n
         LR     R1,R6              i
         BCTR   R1,0               -1
         MR     R0,R9              *n
         LR     R2,R7              j
         BCTR   R2,0               -1
         AR     R1,R2              (i-1)*n+(j-1)
         SLA    R1,1               index=((i-1)*n+j-1)*2
         LH     R2,T(R1)           t(i,j)
         LA     R3,BUFFER
         AR     R3,R10
         XDECO  R2,XDEC            edit t(i,j) length=12
         MVC    0(4,R3),XDEC+8     move in buffer length=4
         LA     R10,4(R10)         ibuf=ibuf+1
         LA     R7,1(R7)           j=j+1
         B      LOOPJ
ELOOPJ   XPRNT  BUFFER,80          end j
         LA     R6,1(R6)           i=i+1
         B      LOOPI
ELOOPI   XR     R15,R15            end i; return_code=0
         BR     R14                return to caller
N        EQU    5                  matrix size
BUFFER   DS     CL80
XDEC     DS     CL12
T        DS     (N*N)H             t(n,n) matrix
         YREGS
         END    ZIGZAGMA


DEFINE MAX_SIZE="10"
DEFINE MAX_MATRIX_SIZE="100"

INT FUNC Index(BYTE size,x,y)
RETURN (x+y*size)

PROC PrintMatrix(BYTE ARRAY a BYTE size)
  BYTE i,j,v

  FOR j=0 TO size-1
  DO
    FOR i=0 TO size-1
    DO
      v=a(Index(size,i,j))
      IF v<10 THEN
        Print("  ")
      ELSE
        Print(" ")
      FI
      PrintB(v)
    OD
    PutE()
  OD
RETURN

PROC FillMatrix(BYTE ARRAY a BYTE size)
  BYTE start,end
  INT dir,i,j

  start=0 end=size*size-1
  i=0 j=0 dir=1

  DO
    a(Index(size,i,j))=start
    a(Index(size,size-1-i,size-1-j))=end
    start==+1 end==-1
    i==+dir j==-dir
    IF i<0 THEN
      i==+1 dir=-dir
    ELSEIF j<0 THEN
      j==+1 dir=-dir
    FI
  UNTIL start>=end
  OD

  IF start=end THEN
    a(Index(size,i,j))=start
  FI
RETURN

PROC Test(BYTE size)
  BYTE ARRAY mat(MAX_MATRIX_SIZE)

  PrintF("Matrix size: %B%E",size)
  FillMatrix(mat,size)
  PrintMatrix(mat,size)
  PutE()
RETURN

PROC Main()
  Test(5)
  Test(6)
RETURN


/*REXX pgm solves the  100 doors puzzle, doing it the hard way by opening/closing doors.*/
parse arg doors .                                /*obtain the optional argument from CL.*/
if doors=='' | doors==","  then doors=100        /*not specified?  Then assume 100 doors*/
                                                 /*        0 =  the door is  closed.    */
                                                 /*        1 =   "    "   "  open.      */
door.=0                                          /*assume all doors are closed at start.*/
                do #=1  for doors                /*process a pass─through for all doors.*/
                    do j=#  by #  to doors       /*  ··· every Jth door from this point.*/
                    door.j= \door.j              /*toggle the  "openness"  of the door. */
                    end   /*j*/
                end       /*#*/

say 'After '                doors          " passes, the following doors are open:"
say
                do k=1  for doors
                if door.k  then say right(k, 20) /*add some indentation for the output. */
                end    /*k*/                     /*stick a fork in it,  we're all done. */


package
{
   public class ZigZagMatrix extends Array
   {

      private var height:uint;
      private var width:uint;
      public var mtx:Array = [];

      public function ZigZagMatrix(size:uint)
      {
         this.height = size;
         this.width = size;

         this.mtx = [];
         for (var i:uint = 0; i < size; i++) {
            this.mtx[i] = [];
         }
         i = 1;
         var j:uint = 1;
         for (var e:uint = 0; e < size*size; e++) {
            this.mtx[i-1][j-1] = e;
            if ((i + j) % 2 == 0) {
               // Even stripes
               if (j < size) j ++;
               else       i += 2;
               if (i > 1) i --;
            } else {
               // Odd stripes
               if (i < size) i ++;
               else       j += 2;
               if (j > 1) j --;
            }
         }
      }
   }
}


with Ada.Text_IO;  use Ada.Text_IO;

procedure Test_Zig_Zag is

   type Matrix is array (Positive range <>, Positive range <>) of Natural;
   function Zig_Zag (Size : Positive) return Matrix is
      Data : Matrix (1..Size, 1..Size);
      I, J : Integer := 1;
   begin
      Data (1, 1) := 0;
      for Element in 1..Size**2 - 1 loop
         if (I + J) mod 2 = 0 then
            -- Even stripes
            if J < Size then
               J := J + 1;
            else
               I := I + 2;
            end if;
            if I > 1 then
               I := I - 1;
            end if;
         else
            -- Odd stripes
            if I < Size then
               I := I + 1;
            else
               J := J + 2;
            end if;
            if J > 1 then
               J := J - 1;
            end if;
         end if;
         Data (I, J) := Element;
      end loop;
      return Data;
   end Zig_Zag;

   procedure Put (Data : Matrix) is
   begin
      for I in Data'Range (1) loop
         for J in Data'Range (2) loop
            Put (Integer'Image (Data (I, J)));
         end loop;
         New_Line;
      end loop;
   end Put;

begin
   Put (Zig_Zag (5));
end Test_Zig_Zag;


doors = list(100)
for i = 1 to 100
doors[i] = false
next

For pass = 1 To 100
         For door = pass To 100
             if doors[door] doors[door] = false else doors[door] = true ok
         door += pass-1
         Next
Next

For door = 1 To 100
     see "Door (" + door + ") is "
     If doors[door] see "Open" else see "Closed" ok
     see nl
Next


doors = Array.new(101,0)
print "Open doors "
(1..100).step(){ |i|
(i..100).step(i) { |d|
    doors[d] = doors[d]^= 1
    if i == d and doors[d] == 1 then
      print "#{i} "
    end
  }
}


# zig-zag matrix

makeZigZag := proc( n :: number ) :: table is

    local move := proc( x :: number, y :: number, upRight :: boolean ) is
        if   y = n then
            upRight := not upRight;
            x := x + 1
        elif x = 1 then
            upRight := not upRight;
            y := y + 1
        else
            x := x - 1;
            y := y + 1
        fi;
        return x, y, upRight
    end ;

    # create empty table
    local result := [];
    for i to n do
        result[ i ] := [];
        for j to n do result[ i, j ] := 0 od
    od;

    # fill the table
    local x, y, upRight := 1, 1, true;
    for i to n * n do
        result[ x, y ] := i - 1;
        if upRight then
            x, y, upRight := move( x, y, upRight )
        else
            y, x, upRight := move( y, x, upRight )
        fi
    od;

    return result
end;

scope
    local m := makeZigZag( 5 );
    for i to size m do
        for j to size m do
            printf( " %3d", m[ i, j ] )
        od;
        print()
    od
epocs


PROC zig zag = (INT n)[,]INT: (
    PROC move = (REF INT i, j)VOID: (
        IF j < n THEN
            i := ( i <= 1 | 1 | i-1 );
            j +:= 1
        ELSE
            i +:= 1
        FI
    );

    [n, n]INT a;
    INT x:=LWB a, y:=LWB a;

    FOR v FROM 0 TO n**2-1 DO
        a[y, x] := v;
        IF ODD (x + y) THEN
            move(x, y)
        ELSE
            move(y, x)
        FI
    OD;
    a
);

INT dim = 5;
#IF formatted transput possible THEN
  FORMAT d = $z-d$;
  FORMAT row = $"("n(dim-1)(f(d)",")f(d)")"$;
  FORMAT block = $"("n(dim-1)(f(row)","lx)f(row)")"l$;

  printf((block, zig zag(dim)))
ELSE#
  [,]INT result = zig zag(dim);
  FOR i TO dim DO
    print((result[i,], new line))
  OD
#FI#


dim doors(100)
print "Open doors ";
for i = 1 to 100
    for door = i to 100 step i
        doors(door) = (doors(door) <> 1)
        if i = door and doors(door) = 1 then   print i;" ";
    next door
next i


fn main() {
    let mut door_open = [false; 100];
    for pass in 1..101 {
        let mut door = pass;
        while door <= 100 {
            door_open[door - 1] = !door_open[door - 1];
            door += pass;
        }
    }
    for (i, &is_open) in door_open.iter().enumerate() {
        println!("Door {} is {}.", i + 1, if is_open {"open"} else {"closed"});
    }
}