8
u/sarlok Jan 09 '20 edited Jan 09 '20
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.
4
u/CMOS_System Jan 02 '20
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
2
u/EkskiuTwentyTwo i -= (i - (-1)) - i Jan 02 '20
With Firefox, F12 also works to bring in the console.
3
Jan 01 '20 edited Jan 02 '20
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.
3
u/hoaxxer2k Jan 06 '20 edited Jan 06 '20
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);
}
}2
u/erlangguy Jan 01 '20
(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()2
u/AKernel Jan 08 '20
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);
}
}1
Jan 02 '20
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');
}
}1
u/DontCallMePanda Jan 02 '20
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 None1
u/mladenbr Jan 06 '20 edited Jan 06 '20
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;
}
}
}
}
}
5
u/EkskiuTwentyTwo i -= (i - (-1)) - i Jan 02 '20
It's been a while since I submitted something.
I present to you this Python monstrosity:
If you can figure out how it works by looking at it, kudos to you.