We are currently working on new rules for what content should and shouldn't be allowed on this website, and are looking for feedback! See Esolang:2026 topicality proposal to view and give feedback on the current draft.

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, Mhm!

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, adding it to accumulator x.
%n (Optional) Output n modulo 256 as a byte.

Completeness

Countable is Turing-complete. See Countable/Turing-completeness proof (Bitwise Cyclic Tag), Countable#Rule 110, and Countable/brainfuck interpreter.

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 -> ...
                               */

Optimized subtraction

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
>

Optimized inequality

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

1+VALUE1
2+VALUE2

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

This can be turned into an equality check by wrapping it in a secondary loop, but only if you know what the bounds of your counters are. 0 and ∞ should be suitable in most cases.

1+VALUE1
2+VALUE2

∞*1<
  a1*1<
    a2&
    ∞&
  >
  // this portion runs only if a1 = a2
>

Copy register value

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
  >
>

Switch case

Nesting multiple of these inside one another also allows the creation of a switch case.

1@ // Any input

256*1< // Outer loop for breaking
  // Nest all possible cases here
  48*1<
    49*1<
      50*1<
        51*1<
          a1& // This jumps to the case with the same value
          // Default behavior goes here
          256& // Break
        >
        // Code for case 51 goes here
        256& // Break
      >
      // Code for case 50 goes here
      256& // Break
    >
    // Code for case 49 goes here
    256& // Break
  >
  // Code for case 48 goes here
>

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+272 // previous value
260+275 // cur value
261+276 // input
262+277 // 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
// 271 = length

// 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
    >
    271+1
    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
*a271<
  *aa264< // move the equal flag to the end
    268+2
  >
  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
>

Encrypting into User:Aadenboy/Miscellanium 2's cipher

/*
0 - 255 = Unique lookup (global)
256 - 511 = Unique lookup (local)
512 = Input/ID string end
513 = Input string length
514 = Current character
515 = SUBID string end
516 = SUBID string length
517 = Unique lookup index

The first table is for counting unique occurences everywhere.
The second table is for counting unique occurences between
two characters; the unique lookup key allows reuse of this
table by checking if each entry is equal to this value.
*/

512+525 // Input/ID string end
513+0   // Input string length
514+524 // Current character
515+525 // SUBID string end
516+0   // SUBID string length
517+524 // Unique lookup index

1*1< // Get input
  2*∞<
    a512@
    *aa512<
      512+1
      513+1
      515+1 // Just to save effort, we'll move the SUBID end alongside it
      517+1 // Also this one
      2&
    >
    1&
  >
>
// We can reuse pointer 512 as it now points to the start of ID
515+a513 // ID will be the same length as the original string (ignoring digit length)
517+a513 517+a513 // SUBID will be either the same length as or shorter than the original string

0*a513< // Cipher the string
  514+1
  *aaa514< // Check if character has been seen before
    0*1<
      *∞<
        aa514+1 // We can reuse the table entry as a second counter from its last instance
        ∞*1<
          aaa514*1< // Check if we are at the current character
            a514&
            ∞& // We are not, continue
          >
          0& // We are, stop checking
        >
        517+1
        a517+256 a517+aaaa514 // Access the second lookup table
        ∞*1<
          a514*1< // Check if the value is equal to the lookup key (current index in string)
            0*1< aaa517& >
            // Not equal
            a512+1 // Increment the digit in ID by one
            a514*1< // Set the value to equal the key
              *∞<
                aa517+1
                aaa517&
              >
            >
            ∞&
          >
          // Equal
        >
      >
    >
    512+1 // Next character
    0&
  >
  // Unique character
  a515+aa514 515+1 // Append to SUBID
  516+1 // Update length
  a512+a516 512+1 // Length of SUBID corresponds to the same digit used for ID
  aa514+a514 // The entry in the table will be the index of the character for easier use later
>

518+a517
519+a517
520+a517
521+a517
522+a517
523+a517
524+a517

∞*a513< // Print ID
  514+1 // Move to next character in ID
  *1<
    0*1< 1*1< 2*1< 3*1< 4*1< 5*1< 6*1< 7*1< 8*1< 9*1< // Check if single digit
      aa514&
      // More than one digit
      %40 // Left parenthesis
      517+1 // Length
      a517*1< *∞< a518& 518+1 > > 518+1 // Previous current value
      a518+aa514 // Value to print
      a517*1< *∞< a519& 519+1 > > 519+2 // Previous reversed value

      a517*1< *∞< a520& 520+1 > > 520+aa518 520+aa518 520+1 // Current value
      a517*1< *∞< a521& 521+1 > > 521+aa518 521+aa518 521+2 // Reversed value
      a517*1< *∞< a522& 522+1 > > 522+aa518 522+aa518 522+4 // Equal flag
      a517*1< *∞< a523& 523+1 > > 523+aa518 523+aa518 523+3 // Previous mod
      a517*1< *∞< a524& 524+1 > > 524+aa518 524+aa518 524+4 // Pointer

      // This is the same reverse-then-print algorithm used by the A+B program.
      0*1<
        *∞<
          1*1<
            *aa518<
              *aa518<
                522+2
              >
              1&
            >
            0&
          >
          a517+1
          a522+1
          a523+9
          10*1<
            *∞<
              *10<
                *aa524<
                  10&
                >
                524+1
                9*1<
                  0*1< 1*1< 2*1< 3*1< 4*1< 5*1< 6*1< 7*1< 8*1<
                    aa523&
                  > > > > > > > > >
                  a524+aa523 a524+1
                >
                524+1
                523+2
              >
              a520+1
            >
          >
          524+1
          9*1<
            0*1< 1*1< 2*1< 3*1< 4*1< 5*1< 6*1< 7*1< 8*1<
              aa523&
            > > > > > > > > >
            a524+aa523 a524+1
          >
          *10<
            a521+aa519
          >
          a521+aa524
        
          522+5
          523+5
          524+4
          a520*1<
            *∞<
              a519&
              519+1
            >
          >
          520+aa518 520+aa518 520+5
          521+aa518 521+aa518 521+5
          a519*1<
            *∞<
              a518&
              518+1
            >
          >
          519+1
        >
      >

      a518+aa519
      *aa517<
        *aa518<
          522+2
        >
        a522+1
        a523+9
        10*1<
          *∞<
            *10<
              *aa524<
                10&
              >
              524+1
              9*1<
                0*1< 1*1< 2*1< 3*1< 4*1< 5*1< 6*1< 7*1< 8*1<
                  aa523&
                > > > > > > > > >
                a524+aa523 a524+1
              >
              524+1
              523+2
            >
            a520+1
          >
        >
        524+1
        9*1<
          0*1< 1*1< 2*1< 3*1< 4*1< 5*1< 6*1< 7*1< 8*1<
            aa523&
          > > > > > > > > >
          a524+aa523 a524+1
        >
        a524+48
        %aa524
      
        522+5
        523+5
        524+4
        a520*1<
          *∞<
            a519&
            519+1
          >
        >
        520+aa518 520+aa518 520+5
        521+aa518 521+aa518 521+5
        a519*1<
          *∞<
            a518&
            518+1
          >
        >
        519+1
      >
      %41 // Right parenthesis
      a523*1< *∞< a517& 517+1 > > // Move to new register
      ∞&
    > > > > > > > > > >
    // Single digit, simply transform and output
    a514+48
    %aa514
  >
>
%35 // Hashtag
*a516< // Print SUBID
  514+1 %aa514
>

See also

Interpreter