Countable

From Esolang
Jump to navigation Jump to search
Countable
Paradigm(s) imperative
Designed by User:Aadenboy
Appeared in 2026
Memory system accumulator-based
Dimensions one-dimensional
Computational class Turing tarpit
Major implementations [1]
Influenced by Iterate
Influenced USI

Countable is a Turing tarpit based on Iterate's accumulative model.

Memory

Countable consists of an infinitely large set of accumulators, which can be incremented and read from, with no additional interactions. All accumulators can store a single positive integer from 0 to infinity. There is no mechanism to reset or decrement an accumulator after it has been incremented.

Commands

n and x refer to a numeric value, which can be a positive integer or infinity. Dereferencing may be done by prefixing a value with one or more a's. Registers 0 and infinity are valid registers. Incrementing infinity results in infinity.

Command Action
x+n Increment accumulator x by n.
x*n< ... > Repeat the inner contents n times, with an optional label x. Multiple loops may share a label, and the label may be dynamic.
x& Jump to the end of label x if you are inside it, skipping to the next iteration of the loop.
x@ (Optional) Read a byte, storing it in accumulator x.
%n (Optional) Output n modulo 256 as a byte.

Completeness

Countable is Turing-complete. See Countable/Turing-completeness proof.

Examples

Cat

1+2         // This will be used to track the current accumulator.
1*1<        // Outer loop to act as a breaking mechanism
  2*∞<      // Actual read-write loop
    a1@     // Store input into the current accumulator
    *aa1<   // If that input isn't zero...
      %aa1  // Print it
      1+1   // Update the pointer to point to the next empty accumulator
      2&    // Skip the break
    >
    1&      // If the input is zero, break
  >
>

Decrement

1+VALUE   // Where VALUE is any numeric value
1*a1<     // Increment a2 to equal a1 minus one
  *a3<    // Doesn't run on the first step, since a3 == 0 then
    2+1   // Increment a2
    1&    // Skip more increments of a3
  >
  3+1     // Set a3 to 1
>

Subtraction

5+VALUE1 // Value 1
1+VALUE2 // Value 2
2+5      // Value tracker
3+6      // Flag tracker
4+7      // Result tracker

*a1<       // Decrement loop
  1*aa2<
    *aa3<
      a4+1
      1&
    >
    a3+1
  >
  2+2
  3+2
  4+2
>

/*
initial
flag
result -> initial
          flag
          result -> initial
                    flag
                    result -> ...
                               */

Subtraction can also be done more efficiently by using labels, however may be unsafe if improperly managed.

1+VALUE1 // Value 1
2+VALUE2 // Value 2
3+a2     // Temporary variable

a1*1<    // Same equality check as demonstrated later
  *a1<   // Increment the result by value 2
    a3&  // This will jump to the outer loop when the temp variable equals value 1
    3+1  // Since the temp variable already equals value 2, this will be true after Value 1 - Value 2 incremnets
    4+1  // And we just track every increment
  >
>

Division

1+VALUE1 // Value 1
2+VALUE2 // Value 2
3+0      // Result
4+6      // Equal flag
5+6      // Pointer
4+a1 // Move the equal flag to the value
a4+1 // and set it

/*
Example: 7 / 3
= = = = = = = =
0 0 0 0 0 0 0 1
\ _ / \ _ / \ _
0 0 0 1 1 1 2 2
*/

1*1<
  *∞<       // Repeatedly increment until the value is met
    *a2<    // Division
      *aa5< // Is the current value equal?
        1&  // Exit
      >
      5+1   // Otherwise, keep going
    >
    3+1     // Every N steps, count up the result by one
  >
>

Equality

1+VALUE1 // value 1
2+VALUE2 // value 2
3+5      // ruler
4+5      // pointer

// A B r p < = < = < = ... < = > ...
// a b 5 5 1 0 1 0 1 0 ... 0 1 0 ...

*a1<   // the ruler creates a set of two pointers for each value 0 to value 1
  a3+1 // all values less than value 1 have a lesser flag set
  3+2  // and their equal flag is unset
>
3+1    // the last value has the lesser flag unset
a3+1   // and the equal flag set
*a2<   // the pointer will travel rightwards N times
  4+2
>
1*1<
  *aa4< // if it lands on a pair with the lesser flag set
    %76 %101 %115 %115 // it is less
    1&
  >
  4+1   // now checking equal flag...
  *aa4< // if it lands on a pair with the equal flag set
    %69 %113 %117 %97 %108 // it is equal
    1&
  >
  %71 %114 %101 %97 %116 %101 %114 // otherwise it is greater
>

Inequality can also be checked by using labels, however may be unsafe if improperly managed.

1+VALUE1
2+VALUE2

a1*<
  a2&
  // this portion runs only if a1 ≠ a2
>

The check above can be used to set one accumulator to equal another, assuming the value you want to equal is greater than your current value.

1+VALUE1
2+VALUE2

a1*1<
  *∞<
    a2&
    2+1
  >
>

Kolakoski sequence

1+3 // Current digit
2+3 // End of stack
3+1 // Kolakoski digit 3 (2 is stored as 1 for ease of processing)
%49 %50 // 1, 2
*∞<
  1*1<
    *aa1< // if the current digit is 2...
      *aa2< // if the last digit is 2...
        2+2  // set next 2 digits to 1
        1&
      >     // else...
      *2<   // if the last digit is 1...
        2+1  // set next 2 digits to 2
        a2+1 // ^^^
      >
      1&
    >      // else...
    *1<   // if the current digit is 1...
      *aa2< // if the last digit is 2...
        2+1  // set next digits to 1
        1&
      >     // else if the last digit is 1...
      2+1    // set next digits to 2
      a2+1   // ^^^
    >
  >
  a1+49 // move the current digit to its corresponding character
  %aa1  // print it
  1+1   // advance to the next digit
>

A+B problem

This program showcases multiple constructs and procedures in one.

// populating lookup table
256+48 256+48
a256+1 256+1 a256+0 256+1
a256+1 256+1 a256+1 256+1
a256+1 256+1 a256+2 256+1
a256+1 256+1 a256+3 256+1
a256+1 256+1 a256+4 256+1
a256+1 256+1 a256+5 256+1
a256+1 256+1 a256+6 256+1
a256+1 256+1 a256+7 256+1
a256+1 256+1 a256+8 256+1
a256+1 256+1 a256+9 256+1

// 257 = number A
// 258 = number B
259+271 // previous value
260+274 // cur value
261+275 // input
262+276 // lookup
263+256 // current number

1*2<
  263+1 // advance to next number
  2*∞<
    a261@    // get input
    *aa261<  // find the corresponding value in the lookup table 
      a262+2
    >
    *aaa262< // is it a number?
      a262+1 // get the literal value
      *10<   // multiply the last value by 10
        a260+aa259
      >
      a260+aaa262 // append the new digit
      259+3
      260+3
      261+3
      262+3
      2&
    >
    a263+aa259 // if not, output the result
    259+3
    260+3
    261+3
    262+3
    1&
  >
>

264+a262 264+1 // previous current value
a264+a257 a264+a258 // A + B
265+a262 265+2 // previous reversed value

266+a262 266+aa264 266+aa264 266+1 // current value
267+a262 267+aa264 267+aa264 267+2 // reversed value
268+a262 268+aa264 268+aa264 268+4 // equal flag
269+a262 269+aa264 269+aa264 269+3 // previous mod
270+a262 270+aa264 270+aa264 270+4 // pointer

// reverse the result for printing
0*1<
  *∞<
    1*1<
      *aa264<
        *aa264< // move the equal flag to the end
          268+2
        >
        1& // check if current value isn't zero here
      >
      0& // otherwise the first step is done
    >
    a268+1 // set it
    a269+9 // for modulo calculation
    10*1<
      *∞< // calculate division + mod
        *10<
          *aa270<
            10&
          >
          270+1
          9*1<
            0*1< // preventing early exit
              aa269& // check if mod will surpass 10
            >
            a270+aa269 a270+1 // increment otherwise
          >
          270+1
          269+2
        >
        a266+1
      >
    >
    270+1
    9*1< // one last pass
      0*1< // preventing early exit
        aa269& // check if mod will surpass 10
      >
      a270+aa269 a270+1 // increment otherwise
    >
    *10< // push to the reversed string
      a267+aa265
    >
    a267+aa270
    // shift right
    268+5
    269+5
    270+4
    a266*1< // move last reverse pointer to current value pointer
      *∞<
        a265&
        265+1
      >
    >
    266+aa264 266+aa264 266+5
    267+aa264 267+aa264 267+5
    a265*1< // move last value pointer to last reverse pointer
      *∞<
        a264&
        264+1
      >
    >
    265+1
  >
>

// output the result (same logic as before)
a264+aa265
0*1<
  *∞<
    1*1<
      *aa264<
        *aa264< // move the equal flag to the end
          268+2
        >
        1& // check if current value isn't zero here
      >
      0& // otherwise the first step is done
    >
    a268+1 // set it
    a269+9 // for modulo calculation
    10*1<
      *∞< // calculate division + mod
        *10<
          *aa270<
            10&
          >
          270+1
          9*1<
            0*1< // preventing early exit
              aa269& // check if mod will surpass 10
            >
            a270+aa269 a270+1 // increment otherwise
          >
          270+1
          269+2
        >
        a266+1
      >
    >
    270+1
    9*1< // one last pass
      0*1< // preventing early exit
        aa269& // check if mod will surpass 10
      >
      a270+aa269 a270+1 // increment otherwise
    >
    a270+48
    %aa270 // output digit
    // shift right
    268+5
    269+5
    270+4
    a266*1< // move last reverse pointer to current value pointer
      *∞<
        a265&
        265+1
      >
    >
    266+aa264 266+aa264 266+5
    267+aa264 267+aa264 267+5
    a265*1< // move last value pointer to last reverse pointer
      *∞<
        a264&
        264+1
      >
    >
    265+1
  >
>

Rule 110

0+0   // width
1+0   // left
2+0   // center
3+0   // right
4+6   // builder
5+6   // postprocessor

// use input as field
0*1< // null case
  10*1< // newline case
    *∞<
      a4@ // get character
      aa4& // if it is null or a newline, this exits the loop
      0+1
      4+1
    >
  >
>
4+1 // padding
*a0< // process input
  32*1< // check for space
    aa5& // this skips incrementing if the character is a space
    a4+1
  >
  4+1 5+1
>
1+a5     // left
2+a5 2+1 // center
3+a5 3+2 // right
4+1 // padding

*∞<
  *a0<
    // (c | r) & !(l & c & r)
    1*1<
      2*1< // (c | r)
        *aa2< 2& >
        *aa3< 2& >
        %32 1&
      >
      // !(l & c & r)
      *aa1< *aa2< *aa3< %32 1& > > >
      a4+1 // is true!
      %35
    >
    1+1 2+1 3+1 4+1
  >
  1+1 2+1 3+1 4+1
  %10
>

Interpreter