Countable

From Esolang
(Redirected from User:Aadenboy/Countable)
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 a set of accumulators, which can be created, incremented, and read from, with no additional interactions. All accumulators can store a single positive integer from 0 to infinity.

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.

Command Action
x+n Increment accumulator x by n. n must be a positive integer, and may be omitted if it is equal to 1.
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 -> ...
                               */

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

Interpreter