Increment Bitwise

3

Make a function that increments a number using only bitwise, loops, and conditions.

Rules:

  1. All entries must be as per the language spec defined below.

  2. Scoring is not of code length, but of the points for each operation given below.

  3. The entry point is inc(a), for "increment and return a".

  4. Lowest score wins.

See the example to help with scoring.

Language Spec (strict JS subset):

All input is assumed to be signed 32-bit integers, with input being in the range [-231+1, 231-2] (interval notation), with the upper bound to give room for the increment. All output is assumed to be within the range [-231+2, 231-1].

Whitespace is never syntactically significant beyond separating literals, keywords, and newline-ended comments. Booleans for conditions can and may be implicitly converted to integers, with 1 == true and 0 == false. All variables are passed by value (as they are all primitives).

Cost is given for each element, with "per use" implied.

Comments: (0 pts)

/* like this */
// or this

Numeric or variable literal: (0 pts)

i, someVariable, 2, etc.

Boolean literal: (0 pts)

true  // == 1, implicit conversion
false // == 0, implicit conversion
  • Note: Integer to boolean conversion is as follows (in pseudocode):

    if 0: true
    else: false
    

Grouping: (0 pts)

(foo && bar);

Function declaration: (0 pts)

function foo() { ... } // braces required
function bar(a) { ... }

Declare variable: (0 pts)

var a;

Assignment: (1 pt)

var a = 1; // semicolon required to terminate statement
a = 2; // only needs declared once
var b = a;
// b = a = 3; // cannot assign in right side of statement
var c = a << 5;
var d = a ^ (c << 5);

Equality/Inequality: (1 pt)

x == 1; // equality
x != 1; // inequality
x > y; // greater than
x >= y; // greater than or equal to
x < y; // less than
x <= y; // less than or equal to

Logical operators: (1 pt)

  • !a (not)
  • a && b (and, returns 1 if both are true, 0 otherwise)
  • a || b (or, returns 1 if either are true, 0 otherwise)

Bitwise operators: (1 pt)

  • ~a (not)
  • a & b (and)
  • a | b (or)
  • a ^ b (exclusive or)
  • a << b (arithmetic left shift)
  • a >> b (arithmetic right shift)
  • a >>> b (logical right shift)

Augmented assignment: (2 pts)

a &= b; // example

If statement: (condition value + 1 pt)

if (condition) { ... }
if (x == 2) { ... } // worth 2 pts
if (x) { ... } // x is nonzero, worth 1 pt

If-Else statement: (condition value + 2 pts)

if (condition) { ... } else { ... }

While statement: (condition value + 2 pts)

while (condition) { ... }
while (x == 2) { ... } // worth 3 pts
while (x) { ... } // evaluation same as in if, worth 2 pts

Do-While statement: (condition value + 2 pts)

do { ... } while (condition); // semicolon required

Return statement: (number of points for statement on right + 1 pt)

return foo; // semicolon required, worth 1 pt
return a & b; // worth 2 pts

Function call: (number of parameters + 2 pts)

foo(); // worth 2 pts
bar(1, 2) // worth 2 + 2 = 4 pts

Operator precedence (first to last performed):

  1. ( ... )
  2. ~/! (right-to-left)
  3. <</>>/>>> (left-to-right)
  4. >/</>=/<= (left-to-right)
  5. ==/!= (left-to-right)
    • Note: 1 == 1 == 1 works out to 0 == 1 which is 0.
  6. & (left-to-right)
  7. ^ (left-to-right)
  8. | (left-to-right)
  9. && (left-to-right)
  10. || (left-to-right)

Example scoring:

This (ficticious) example would score 14 points. See comments for details.

function inc(a) {
  var b = a; // adds 1 pt for assignment
  if (!a) return 0; // adds 3 pts: 2 for if and 1 for return
  while (a & b) { // adds 3 pts: 2 for while and 1 for `&`
    b >>= a ^ b; // adds 3 pts: 2 for augmented assignment, 1 for `^`
    a = b << 1; // adds 2 pts: 1 for assignment, 1 for `<<`
  }
  return a ^ b; // adds 2 pts: 1 for return, 1 for `^`
}

Isiah Meadows

Posted 2014-06-22T07:23:00.330

Reputation: 1 546

4Is there a Javascript-only requirement? If so please make this explicit in the question and add a javascript tag. Note also that language-specific challenges are rather lame, especially given that many languages share this same set of operators. – Paul R – 2014-06-22T09:17:38.247

1@PaulR And even if they didn't, I think the wording is good enough the prevent any loopholes with, let's say, J. – seequ – 2014-06-22T10:06:18.407

Does this need to work for negatives? Are numbers limited to 32 bits? – xnor – 2014-06-22T17:20:03.490

Does JS implicitly cast between Booleans and numbers? – xnor – 2014-06-22T17:22:50.397

Yes, but treat them as integers in this context. – Isiah Meadows – 2014-06-23T02:19:17.450

@xnor No and yes. – Isiah Meadows – 2014-06-23T02:19:49.330

Answers

4

10

Works for negative numbers.

function inc(x) 
{ 
    if(x & 1)                       // 1 + 1
        return inc(x >>> 1) << 1;   // 1 + 3 + 1 + 1

    return x | 1;                   // 1 + 1
};

copy

Posted 2014-06-22T07:23:00.330

Reputation: 6 466

2

11 points (also works for negative numbers)

function inc(a) {
  var t = 1;             // 1 pt
  while (a & t) {        // 3 pts
    a &= (~t);           // 3 pts
    t <<= 1;             // 2 pts
  }
  return a|t;            // 2 pts
}

I thought this was supposed to actually increment the number it was called on, but I am not familiar with a way to pass integers by reference in JS.

Tal

Posted 2014-06-22T07:23:00.330

Reputation: 1 358

It works when converted to C/C++. Good answer – bacchusbeale – 2014-06-22T09:06:46.623

No. It only returns the incremented value. JS only has pass by reference for primitives. – Isiah Meadows – 2014-06-23T02:38:32.433

2

10 (works for negative numbers)

function inc(a)
{
    var c = 1;                   // 1 
    while (c)                    // 2
    {
        var s = a ^ c;           // 2
        c = (a & c) << 1;        // 3
        a = s;                   // 1
    }
    return a;                    // 1
}

Paul R

Posted 2014-06-22T07:23:00.330

Reputation: 2 893

The question mentions that the language spec you need to use is a JS subset, I understood that as a requirement to use JS... but I don't think there's much of a difference here anyway. – Tal – 2014-06-22T09:04:36.680

I've converted it to JS now (I think - I've never used JS before) - I'll also ask the OP to clarify the question. – Paul R – 2014-06-22T09:14:40.163

2

11 (Works for negatives)

function inc(a) {
    for(var b=1;a&b;b<<=1) {
        a=a^b;
    }
    return a^b
}

kitcar2000

Posted 2014-06-22T07:23:00.330

Reputation: 2 689

1How are for loops scored? – xnor – 2014-06-22T18:36:16.447

@xnor I treated them as 1 + (score for code in brackets). – kitcar2000 – 2014-06-23T17:50:10.237

0

10 (13 if it must work for negative numbers)

function inc(a){
  var m=1;             // 1pts
  while((a & m)==m){   // 4pts
    m=(m<<1)|1;        // 3pts
  }
  return a^m;          // 2pts
}

jimmy23013

Posted 2014-06-22T07:23:00.330

Reputation: 34 042

It is 13. I clarified...apparently that didn't get caught in the Sandbox phase – Isiah Meadows – 2014-06-23T02:40:32.290