Iterate/Math

From Esolang
Jump to navigation Jump to search

Back to Iterate

For convenience, these examples are listed as macros for inclusion within a program. See Iterate/Compilation on how to use these.

Arithmetic

A + B

((add*))A B<
  $result
  *?A< (result*)<> > // increment result
  *?B< (result*)<> > // increment result again
>

A - B

Note: Results lower than one will not output anything.

((sub*))A B<
  $result
  *?A< (result*)<> > // result = A
  *?B<               // decrement the result, B times
    $decrement
    *=result<               // store result-1 in decrement
      *~n< (decrement*)<> > // ~n acts as result-1
      !
    >
    $result
    *=decrement< (result*)<> >   // copy from decrement to result
  >
>

A * B

((mul*))A B<
  $result
  *?A<
    *?B<
      (result*)<>   // visited A*B times as an intrinsic property of nested loops
    >
  >
>

A % B and A / B (floored)

The same algorithm is able to calculate both modulus and division.

((div*))A B<
  $initial $countdown $remainder $quotient
  *?B< (initial*)<> (countdown*)<> >
  (calc_div*)?A<              // increment remainder A times
    (remainder*)<>      // remainder += 1
    $decrement
    *=countdown< (decrement*)<> > // decrement = countdown
    $countdown
    *=decrement<
      *~n< (countdown*)<> >   // countdown = decrement - 1
      !
    >
    *=countdown< &calc_div >         // if countdown == 0 (or when modulus returns 0)...
    $remainder                  // remainder = 0
    *=initial< (countdown*)<> > // countdown = initial (reset counter)
    (quotient*)<>               // count every time the remainder is reset for quotient
  >
>

AB

((power*))A B<
  $result $base $exponent
  *?A< (result*)<> (base*)<> >
  *?B< *~n< (exponent*)<> > ! > // B-1
  *=exponent< // calculate A*A a bunch
    $temp
    *=result<
      *=base<
        (temp*)<> // result*base
      >
    >
    $result
    *=temp< (result*)<> > // set result to temp (current *= base)
  >
  (zero*)1< // extra case if B is 0
    *=B< !zero >
    $result (result*)<> // result = 1
  > 

B√A (floored)

A combination of the exponential and conditional algorithms.

((root*))A B<
  $radicand $index $result
  *?A< (radicand*)<> >
  *?B< *~n< (index*)<> > ! >
  (calc_root*)∞<               // we'll increment up until we find n^B >= A
    $base *n< (base*)<> > // initialize n^B
    *=index<              // n^B
      $temp
      *=base< *n:calc_root< (temp*)<> > >
      $base
      *=temp< (base*)<> >
    >
    (root_(compare*))<=base><=radicand>
    *=root_greater< *n:calc_root< *~n< (result*)<> > ! > !calc_root > // output n-1 if n^B > A
    *=root_equal  < *n:calc_root<      (result*)<>     > !calc_root > // output n if n^B == A
  >
>

logB A (floored)

The logic is almost the same as the Nth root algorithm.

((log*))A B<
  $arg $base $current $result
  *?A< (arg*)<> >
  *?B< (base*)<> >
  *1< (current*)<> > // initialize n
  (calc_log*)∞<      // we'll repeatedly multiply by B until B^n >= A
    $temp
    *=current< *=base< (temp*)<> > > // B * B
    $current
    *=temp< (current*)<> >
    (log_(compare*))<=current><=arg>
    *=log_greater< *n:calc_log< *~n< (result*)<> > ! > !calc_log > // output n-1 if B^n > A
    *=log_equal  < *n:calc_log<      (result*)<>     > !calc_log > // output n if B^n == A
  >
>

Minimum/maximum of A and B

((min*))A B<
  (min_(compare*))<?A><?B>
  (min_(if_else*))<=min_greater><
    *?B< (result_min*)<> >
    *?A< (result_max*)<> >
  ><
    *?A< (result_min*)<> >
    *?B< (result_max*)<> >
  >
>
((max*))A B<
  (max_(compare*))<?A><?B>
  (max_(if_else*))<=max_less><
    *?B< (result_max*)<> >
    *?A< (result_min*)<> >
  ><
    *?A< (result_max*)<> >
    *?B< (result_min*)<> >
  >
>

Logic

Value is not zero

((is_not_0*))value code<
  (check*)?value<
    // implicit, as loops with an amount of zero do not run
    ?code
    !check // to prevent further loops
  >
>

Value is zero

((is_0*))value code<
  (check*)1<
    *?value< !check > // the loop will not run if A is zero, therefore never breaking the parent loop
    ?code
  >
>

If else

((if_else*))value true false<
  (check*)1<
    (is0*)1<
      *?value< !is0 >
      ?false
      !check
    >
    ?true
  >
>

// alternate version which accounts for values greater than one
((is_0_1_else*))value zero one else<
  (check*)1<
    (is0*)1<
      *?value< !is0 >
      ?zero
      !check
    >
    (is1*)?value<
      *~n< !is1 > // if A is 1, then the remaining loops of a loop that only runs once is zero, so the code doesn't break
      ?one
      !check
    >
    ?else
  >
>

Comparisons

This module provides cases for if A is equal to, greater than, or less than B.

((compare*))A B<
  $value1 $value2 $equal $less $greater
  *?A< (value1*)<> > // value1 = A
  *?B< (value2*)<> > // value2 = B
                     // result will be 1 if A == B
                     // we'll continuously decrement A and B until either reaches 0
                     // if either reaches 0 first before the other, they're not equal
                     // otherwise they are equal
  (comparison*)∞<
    (check*)1<        // we check FIRST for the edge case where either A or B starts as 0
      *=value1<
        *=value2< !check >       // case 1: neither A nor B are 0 -> continue
        (greater*)<> !comparison // case 2: B reached 0 first     -> A > B
      >
      *=value2<
        *=value1< !check >       // case 1: neither A nor B are 0 -> continue
        (less*)<> !comparison    // case 3: A reached 0 first     -> A < B
      >
      (equal*)<> !comparison     // case 4: both reached 0 at the same time -> A == B
    >
    $value1_dec $value2_dec
    *=value1< (value1_dec*)<> >
    *=value2< (value2_dec*)<> >
    $value1 $value2
    *=value1_dec< *~n< (value1*)<> > ! > // L1 -= 1
    *=value2_dec< *~n< (value2*)<> > ! > // L2 -= 1
  >
>

Logic gates

((not*))A<
  $result (result*)<>
  *?A< $result >
>
((and*))A B<
  $result
  *?A< *?B< (result*)<> ! > ! >
>
((nand*))A B<
  $result (result*)<>
  *?A< *?B< $result ! > ! >
>
((or*))A B<
  $result
  *?A< (result*)<> >
  *?B< $result (result*)<> >
>
((nor*))A B<
  $result (result*)<>
  *?A< $result >
  *?B< $result >
>
((xor*))A<
  $result
  (ab*)?A< *?B< !ab > (result*)<> >
  (ba*)?B< *?A< !ba > (result*)<> >
>
((xnor*))A<
  $result (result*)<>
  (ab*)?A< *?B< !ab > $result >
  (ba*)?B< *?A< !ba > $result >
>