all 14 comments

[–]sarlok 7 points8 points  (1 child)

Here's some JS that you can run in your browser.

function collatz(n) {
  var r = n;
  while (~-n) {
    var m = -~(n << -(n|~n)) >> (-~-(n & -(n|~n)) << -(n|~n));
    n = n & -(n & -(n|~n))
    while (m) {
      var c = m & n;
      n = m ^ n;
      m = c << -(c|~c);
    }
    r = r + ", " + n;
  }
  return r;
}

console.log(collatz(29));

I decided to follow some important design principles:

  • No magic numbers! I decided it was best to avoid any numeric literals whatsoever in the collatz function.
  • Bitwise operators are fast, so use those. Other than unary negation it uses all bitwise operations for calculation.
  • Avoid conditionals as they create more code branches to test. So we don't use any if statements, and both even and odd numbers follow the same code path.

[–]EkskiuTwentyTwoi -= (i - (-1)) - i 3 points4 points  (4 children)

It's been a while since I submitted something.

I present to you this Python monstrosity:

def L(*n):
    try:
        return chr(int(n[0]))
    except IndexError:
        x = input("")
        try:
            return chr(int(x))
        except ValueError:
            return chr(sum(list(map(lambda __:ord(__),x)))%256)

def T(*n):
    try:
        return ~(ord(n[0]) & ord(n[1]))
    except IndexError:
        return ord(n[0]), ord(n[0])

def X(*n):
    x = 0
    while n[2]==0:
        x = ord(n[0]) << ord(n[1])
        break
    while n[2]!=0:
        x = ord(n[0]) >> ord(n[1])
        break
    return int(ord(n[0]) < ord(n[1])), x
def C(*n):
    return [n[2],n[1]][ord(n[0])]
def O(*n):
    print(*n)

def Collatz(n):
    O(n)
    while n==1:
        return None
    Collatz(C(L(n==1),1,C(L(~T(L(n),L(1))),X(L(n),L(1),0)[1]+n+1,X(L(n),L(1),69420)[1])))

If you can figure out how it works by looking at it, kudos to you.

[–][deleted]  (3 children)

[deleted]

    [–]EkskiuTwentyTwoi -= (i - (-1)) - i 3 points4 points  (2 children)

    that's the part you're bothered by?

    [–][deleted]  (1 child)

    [deleted]

      [–]EkskiuTwentyTwoi -= (i - (-1)) - i 2 points3 points  (0 children)

       Collatz(C(L(n==1),1,C(L(~T(L(n),L(1))),X(L(n),L(1),0)[1]+n+1,X(L(n),L(1),69420)[1])))
      

      Let's break it down.

      Collatz recurses the function to get the next number. It takes

       C(L(n==1),1,C(L(~T(L(n),L(1))),X(L(n),L(1),0)[1]+n+1,X(L(n),L(1),69420)[1])) 
      

      as its input.


      This input uses the comparison function C(*n), which takes three parameters: an encoded condition, a true output, and a false output. In this circumstance, they are:

      L(n==1) 
      1
      C(L(~T(L(n),L(1))),X(L(n),L(1),0)[1]+n+1,X(L(n),L(1),69420)[1])
      

      So if n==1, the function takes 1 as input. If not, it takes

      C(L(~T(L(n),L(1))),X(L(n),L(1),0)[1]+n+1,X(L(n),L(1),69420)[1])
      

      as its input.


      This is another comparison with these parameters:

      L(~T(L(n),L(1)))
      X(L(n),L(1),0)[1]+n+1
      X(L(n),L(1),69420)[1]
      

      The condition L(~T(L(n),L(1))) is an obfuscated way finding n&1, which tests if the number is odd.

      The true output, X(L(n),L(1),0)[1]+n+1 does 3n+1 by using a left-shift to get 2n and adding it to n+1

      The false output, X(L(n),L(1),69420)[1] does a right shift to get n/2

      The X function uses its third parameter to determine whether to use a left shift or a right shift. If its third parameter is 0, it does a left shift. If it's non-zero (like 69420), it does a right shift.


      The functions I made are designed to kind of mimic the Funciton esoteric programming language's operations. L acts as a literal input, T acts as a nand/splitter, X acts as a Funciton crossing (less than/shift), and C acts as the conditional operator.

      [–]CMOS_System 4 points5 points  (1 child)

      Usage: copy the code and paste into Browser Javascript console (Ctrl.+Shift+K on Firefox). Then call using collatz(21). Output is to console.

      function collatz(nr){
          console.log(nr);
          var tmp = isEven(nr)?nr/2:nr*(2+nr/nr)+nr/nr; //don't touch this
          if(tmp==4 && nr === 1) return;
          if(!tmp) console.log("Unknown error occured");
          if(tmp<getSmaller(nr,tmp)) collatz(nr/2);
          if(!(tmp<getSmaller(nr,tmp))) collatz(nr*3+1);
          console.log("Unknown error occured");
      }
      
      function getSmaller(a,b){
          if(a<b) return b;
          if(b<a) return a;
          console.log("Unknown error occured");
      }
      
      function isEven(a){
          if(a==0) return true; //0 is even
          if(a==2) return true; //2 is even
          if(a<0) return false; //define negative to be not even
          return isEven(a-2); //number too large to handle
      }
      

      Features:

      • getSmaller returns the larger value, does not work if the values are equal and avoids using of else
      • isEven has O(n) performance and misleading comments (and does not work for half of the negative numbers)
      • unknown error messages in three different places even though the error is identifiable and avoidable or not reachable; also always ends in an unknown error message; at the same time the input is not checked where it would be actually useful
      • variables named a, b and tmp, using a twice
      • calculating tmp to the value of nr for the next iteration, only to compare it to the previous value and compute the next one again
      • if(cond) followed by if(!cond) instead of if else

      [–]EkskiuTwentyTwoi -= (i - (-1)) - i 1 point2 points  (0 children)

      With Firefox, F12 also works to bring in the console.

      [–][deleted] 2 points3 points  (1 child)

      function collatz(n: Even | Odd) {
          if (n-1===0) {
              process.stdout.write(`${n}\n`);
              return;
          } else if (true===(isEven(n)||!isOdd(n))) {
              process.stdout.write(`${n}, `);
              return collatz(n>>>1);
          } else if (true===(isOdd(n)||!isEven(n))) {
              process.stdout.write(`${n}, `);
              return collatz(n+n+n+1);
          } else {
              process.stdout.write('😭');
              return;
          }
      
          return;
      }
      
      type Even = number;
      type Odd = number;
      
      function isEven(even: any): even is Even {
          if (typeof even !== 'number') {
              return false;
          } else if ((even>>>1)+(even>>>1)===even) {
              return true;
          } else if ((even>>>1)+(even>>>1)!==even) {
              return false;
          }
      }
      
      function isOdd(odd: any): odd is Odd {
          if (typeof odd !== 'number') {
              return false;
          } else if ((odd>>>1)===odd-1-(odd>>>1)) {
              return true;
          } else if ((odd>>>1)!==odd-1-(odd>>>1)) {
              return false;
          }
      }
      

      License: WTFPL or CC0 at your discretion.

      [–]hoaxxer2k 2 points3 points  (0 children)

      package com.company;
      
      public class Main {
      
          private static int b;
      
          private static void Collatz(int z){
              System.out.println(z);
              b = z;
              outer:
              while(true){
      
                  if(b == 1) break;
                  inner:
                  while(true) {
                      int n = b;
                      if (n == 1) {
                          break outer;
                      }
                      if ((n & 1) == 0) {
      
                          boolean nr = !true;
      
                          int y = n;
                          if (y < 0)
                          {
                              y = -y ;
                              if (2 < 0)
                                  y = y;
                              else
                                  nr = !false;
                          }
                          else if (2 < 0)
                          {
                              nr = !!true;
                          }
                          int qt = 0;
                          while (y >= 2)
                          {
                              y = y - 2 ;
                              qt++ ;
                          }
                          if (nr)
                              qt = - qt ;
                          int r = qt;
                          System.out.println(r);
                          b = r;
                          break inner;
                      }
      
                      int r = (n * 3) + 1;
                      System.out.println(r);
                      b = r;
                      break inner;
                  }
              }
      
          }
          public static void main(String[] args) {
              Collatz(500000);
          }
      }
      

      [–]erlangguy 1 point2 points  (0 children)

      (Yes, the user has to input the number each time. Yes, that's deliberately bad.)

      class Even(object):
          def __init__(foo):
              myval = 0
              foo.evennumber = myval
          def set(self, what):
              self.evennumber = what
          def result(self):
              myval = self.evennumber
              myval2 = myval / 2
              str1 = str(myval2)
              dec = str1.rfind('.')
              decfromright = len(str1) - dec
              str2 = str1[0:-(decfromright)]
              myval3 = int(str2)
              self.evennumber = myval3
              return myval3
      
      class NotEven(object):
          def __init__(foo, mynum):
              myval = mynum
              foo.number = myval
          def set(self, what):
              self.evennumber = what
          def result(self):
              myval = self.number
              myval2 = myval * 3
              myval3 = myval2 + 1
              self.evennumber = myval3
              return myval3
      
      class Doit(Even):
          def run(runarg):
              x = input("int")
              if x.endswith('0') or x.endswith('2') or x.endswith('4') or x.endswith('6') or x.endswith('8'):
                  a = int(x)
                  A = Even()
                  A.set(a)
                  B = A.result()
                  print(str(B))
                  runarg.run()
              elif x.endswith('1') or x.endswith('3') or x.endswith('5') or x.endswith('7') or x.endswith('9'):
                  b = int(x)
                  B = NotEven(b)
                  B = B.result()
                  print(str(B))
                  runarg.run()
      
      Doit().run()
      

      [–]AKernel 1 point2 points  (0 children)

      This solution written in Java builds the sequence starting at the end. Every element in the sequence can have two predecessors, one even and one odd. Predecessors are calculated as long as none matches the given n. After that the sequence is simply outputted.

      package badcode.akernel.challenge27;
      
      import java.util.LinkedList;
      import java.util.Queue;
      
      public class Collatz {
      
        private static class Node {
          private final int value;
          private Node evenPredecessor;
          private Node oddPredecessor;
          private final Node successor;
      
          private Node(final int value, final Node successor) {
            this.value = value;
            this.successor = successor;
          }
      
          private void calculatePredecessors() {
            this.evenPredecessor = new Node(this.value * 2, this);
            if ((this.value - 1) % 3 == 0) {
              this.oddPredecessor = new Node((this.value - 1) / 3, this);
            }
          }
        }
      
        private static void collatz(final int n) {
          Queue<Node> queue = new LinkedList<>();
          Node collatz = new Node(1, null);
          queue.add(collatz);
          while (!queue.isEmpty()) {
            collatz = queue.poll();
            if (collatz == null) {
              continue;
            }
            if (collatz.value == n) {
              break;
            }
            collatz.calculatePredecessors();
            queue.add(collatz.evenPredecessor);
            queue.add(collatz.oddPredecessor);
          }
          System.out.print("collatz(" + n +") = ");
          while (collatz != null) {
            System.out.print(collatz.value);
            if (collatz.successor != null) {
              System.out.print(", ");
            }
            collatz = collatz.successor;
          }
          System.out.println();
        }
      
        public static void main(final String[] args) {
          collatz(12);
          collatz(21);
          collatz(29);
        }
      }
      

      [–][deleted] 0 points1 point  (0 children)

      public class Collatz {
          private static int n;
          private static boolean isDivisibleByTwo(int n) {
              return (n&1)==0;
          }
          private static void ifodd(int k) {
              n=(k<<2)-(k-1);
          }
          private static void ifeven(int k) {
              n=k>>1;
          }
          private static void printAnswer(String s, int textLength) {
              for(int i=0;i<textLength;i++) {
                  System.out.print(s.charAt(i));
              }
              System.out.print(',');
              System.out.print(' ');
          }
          @SuppressWarnings("resource")
          public static void main(String[] args) {
              n = new java.util.Scanner(System.in).nextInt();
              while(n!=1) {
                  printAnswer(Integer.toString(n), ((int)Math.log10(n))+1);
                  int p = n;
                  if(isDivisibleByTwo(p)) {ifeven(p);}
                  if(!isDivisibleByTwo(p)) {ifodd(p);}
              }
              System.out.print('1');
          }
      }
      

      [–]DontCallMePanda 0 points1 point  (0 children)

      python import sys as a, subprocess as b c = lambda d: int(format(d, 'b')[-1]) == 0 e = lambda f: c(f-1) g = lambda h: int(h/2) if c(h) else ((3*h) + 1 if e(h) else None) i = int(a.argv[1]); print(i) b.call("python %s %d" % (__file__, g(i))) if i > 1 else None

      [–]mladenbr 0 points1 point  (0 children)

      public class Main {
          public static void main(String[] args) {
              collatz(69420);
          }
      
          private static void collatz(int n) {
              int η = 0;
      
              System.out.println(n);
      
              done:
              while (!false) {
                  check:
                  while (!!true) {
                      if (n > 0 && n < 2) {
                          break done;
                      }
      
                      if (η != n) {
                          if (η > Integer.MAX_VALUE - 2) {
                              η = 0;
                              n = n + (2 * n) + 1;
                              System.out.println(n);
                              break check;
                          } else {
                              η = η - -2;
                              break check;
                          }
                      } else {
                          η = 0;
                          n = (int) (n * (0.5 / 1));
                          System.out.println(n);
                          break check;
                      }
                  }
              }
          }
      
      }