A couple of years ago, my friend wanted to learn programming, so I was giving her a hand with resources and reviewing her code. She got to the part on adding code comments, and wrote the now-infamous line,
i = i + 1 #this increments i
We’ve all written superflouous comments, especially as beginners. And it’s not even really funny, but for whatever reason, somehow we both remember this specific line years later and laugh at it together.
Years later (this week), to poke fun, I started writing sillier and sillier ways to increment i
:
Beginner level:
# this increments i:
x = i
x = x + int(True)
i = x
Beginner++ level:
# this increments i:
def increment(val):
for i in range(val):
output = i
output = i + 1
return output
Intermediate level:
# this increments i:
class NumIncrementor:
def __init__(self, initial_num):
self.internal_num = initial_num
def increment_number(self):
incremented_number = 0
# we add 1 each iteration for indexing reasons
for i in list(range(self.internal_num)) + [len(range(self.internal_num))]:
incremented_number = i + 1 # fix obo error by incrementing i. I won't use recursion, I won't use recursion, I won't use recursion
self.internal_num = incremented_number
def get_incremented_number(self):
return self.internal_num
i = input("Enter a number:")
incrementor = NumIncrementor(i)
incrementor.increment_number()
i = incrementor.get_incremented_number()
print(i)
Since I’m obviously very bored, I thought I’d hear your take on the “best” way to increment an int in your language of choice - I don’t think my code is quite expert-level enough. Consider it a sort of advent of code challenge? Any code which does not contain the comment “this increments i:” will produce a compile error and fail to run.
No AI code pls. That’s no fun.
C++:
int i = 5; i ^= printf("The initial value of i is %d\n", i)^ printf("i=i+1; // this increments i\n")^ printf("Trigger very obscure FPU bug %c",(int)((float)8.5953287712*(double)8.5953287713-'?'))/10; printf("i has now been incremented by 1 : %d\n", i);
Output:
The initial value of i is 5 i=i+1; // this increments i Trigger very obscure FPU bug i has now been incremented by 1 : 6
I didn’t test other values but they’re probably OK.
C++ templates my beloved
#pragma pack(1) template <size_t i> struct increment; template <> struct increment<0> { char _plusone; constexpr static size_t value = 1; }; template <size_t i> struct increment<i> { increment<i - 1> _base; char _plusone; // this increments i constexpr static size_t value = sizeof(increment<i - 1>); }; template <size_t i> using increment_v<i> = increment<i>::value;
This could even be made generic to any integer type with a little more effort
Bonus : to use it without knowing i at compile-time :
template <size_t current_value = 0> size_t& inc(size_t& i) { if (i == current_value) { i = increment<current_value>::value; return i; } else { if constexpr (current_value != std::numeric_limits<size_t>::max()) { return inc<increment<current_value>::value>(i); } } } int main() { int i; std::cin >> i; inc(i); // this increments i std::cout << i << std::endl; return 0; }
Hope you’re not in a hurry
Conditional adder:
if x==1: return 2 else if x==2: return 3 ...
Can’t increment negative numbers or zero smh.
Fix:
if x==0: return 1 else x==1: return 2 else if x==-1: return 0 else if x==2 return 3 else if x==-2 return -1 ...
Hard to heat this. If you ever manage to finish the code that is…
There is a finite number of integers in this context. For 32-bit it, it’s 4 billion or so (2^32).
And you could write a script to write the code for you
But that’s what TDD is for. If the test fails for 55, you just add a
return 56
, and then all is well.I let ChatGPT write it for me. The code and the test suite 💪
C# .NET using reflection, integer underflow, and a touch of LINQ. Should work for all integer types. (edit: also works with
char
values)// this increments i private static T Increment<T>(T i) { var valType = typeof(T); var maxField = valType.GetField("MaxValue"); var minField = valType.GetField("MinValue"); if (maxField != null) { T maxValue = (T)maxField.GetValue(i); T minValue = (T)minField.GetValue(i); var methods = valType.GetTypeInfo().DeclaredMethods; var subMethod = methods.Where(m => m.Name.EndsWith("op_Subtraction")).First(); T interim = (T)subMethod.Invoke( null, [i, maxValue]); return (T)subMethod.Invoke( null, [interim, minValue]); } throw new ArgumentException("Not incrementable."); }
C:
int increment(int i) { return (int) (1[(void*) i])
However, if you wanna go blazingly fast you gotta implement O(n) algorithms in rust. Additionally you want safety in case of integer overflows.
use std::error::Error; #[derive(Debug, Error)] struct IntegerOverflowError; struct Incrementor { lookup_table: HashMap<i32, i33> } impl Incrementor { fn new() -> Self { let mut lut = HashMap::new(); for i in 0..i32::MAX { lut.insert(i, i+1) } Incrementor { lookup_table: lut } } fn increment(&self, i: i32) -> Result<i32, IntegerOverflowError> { self.lookup_table.get(i) .map(|i| *i) .ok_or(IntegerOverflowError) }
On mobile so I don’t even know if they compile though.
Using i33 for that extra umpf!
I guess that’s another way to avoid the overflow problem
Trying to avoid using any arithmetic operators, and sticking just to binary (extending beyond 16 bit unsigned ints is left as an exercise for the interested reader):
#!/usr/bin/perl # This increments $i my $i=1; print "Start: $i "; if (($i & 0b1111111111111111) == 0b1111111111111111) {die "Overflow";} if (($i & 0b0000000000000001) == 0b0000000000000000) {$i=(($i & 0b1111111111111110) | 0b0000000000000001);} else { if (($i & 0b0111111111111111) == 0b0111111111111111) {$i=(($i & 0b0000000000000000) | 0b1000000000000000);} if (($i & 0b0011111111111111) == 0b0011111111111111) {$i=(($i & 0b1000000000000000) | 0b0100000000000000);} if (($i & 0b0001111111111111) == 0b0001111111111111) {$i=(($i & 0b1100000000000000) | 0b0010000000000000);} if (($i & 0b0000111111111111) == 0b0000111111111111) {$i=(($i & 0b1110000000000000) | 0b0001000000000000);} if (($i & 0b0000011111111111) == 0b0000011111111111) {$i=(($i & 0b1111000000000000) | 0b0000100000000000);} if (($i & 0b0000001111111111) == 0b0000001111111111) {$i=(($i & 0b1111100000000000) | 0b0000010000000000);} if (($i & 0b0000000111111111) == 0b0000000111111111) {$i=(($i & 0b1111110000000000) | 0b0000001000000000);} if (($i & 0b0000000011111111) == 0b0000000011111111) {$i=(($i & 0b1111111000000000) | 0b0000000100000000);} if (($i & 0b0000000001111111) == 0b0000000001111111) {$i=(($i & 0b1111111100000000) | 0b0000000010000000);} if (($i & 0b0000000000111111) == 0b0000000000111111) {$i=(($i & 0b1111111110000000) | 0b0000000001000000);} if (($i & 0b0000000000011111) == 0b0000000000011111) {$i=(($i & 0b1111111111000000) | 0b0000000000100000);} if (($i & 0b0000000000001111) == 0b0000000000001111) {$i=(($i & 0b1111111111100000) | 0b0000000000010000);} if (($i & 0b0000000000000111) == 0b0000000000000111) {$i=(($i & 0b1111111111110000) | 0b0000000000001000);} if (($i & 0b0000000000000011) == 0b0000000000000011) {$i=(($i & 0b1111111111111000) | 0b0000000000000100);} if (($i & 0b0000000000000001) == 0b0000000000000001) {$i=(($i & 0b1111111111111100) | 0b0000000000000010);} } print "End: $i\n";
C++
bool increment(uint8_t& i) { switch (i) { case 0: i = 1; return true; case 1: i = 2; return true; case 2: i = 3; return true; case 3: i = 4; return true; case 4: i = 5; return true; case 5: i = 6; return true; case 6: i = 7; return true; case 7: i = 8; return true; case 8: i = 9; return true; case 9: i = 10; return true; case 10: i = 11; return true; case 11: i = 12; return true; case 12: i = 13; return true; case 13: i = 14; return true; case 14: i = 15; return true; case 15: i = 16; return true; case 16: i = 17; return true; case 17: i = 18; return true; case 18: i = 19; return true; case 19: i = 20; return true; case 20: i = 21; return true; case 21: i = 22; return true; case 22: i = 23; return true; case 23: i = 24; return true; case 24: i = 25; return true; case 25: i = 26; return true; case 26: i = 27; return true; case 27: i = 28; return true; case 28: i = 29; return true; case 29: i = 30; return true; case 30: i = 31; return true; case 31: i = 32; return true; case 32: i = 33; return true; case 33: i = 34; return true; case 34: i = 35; return true; case 35: i = 36; return true; case 36: i = 37; return true; case 37: i = 38; return true; case 38: i = 39; return true; case 39: i = 40; return true; case 40: i = 41; return true; case 41: i = 42; return true; case 42: i = 43; return true; case 43: i = 44; return true; case 44: i = 45; return true; case 45: i = 46; return true; case 46: i = 47; return true; case 47: i = 48; return true; case 48: i = 49; return true; case 49: i = 50; return true; case 50: i = 51; return true; case 51: i = 52; return true; case 52: i = 53; return true; case 53: i = 54; return true; case 54: i = 55; return true; case 55: i = 56; return true; case 56: i = 57; return true; case 57: i = 58; return true; case 58: i = 59; return true; case 59: i = 60; return true; case 60: i = 61; return true; case 61: i = 62; return true; case 62: i = 63; return true; case 63: i = 64; return true; case 64: i = 65; return true; case 65: i = 66; return true; case 66: i = 67; return true; case 67: i = 68; return true; case 68: i = 69; return true; case 69: i = 70; return true; case 70: i = 71; return true; case 71: i = 72; return true; case 72: i = 73; return true; case 73: i = 74; return true; case 74: i = 75; return true; case 75: i = 76; return true; case 76: i = 77; return true; case 77: i = 78; return true; case 78: i = 79; return true; case 79: i = 80; return true; case 80: i = 81; return true; case 81: i = 82; return true; case 82: i = 83; return true; case 83: i = 84; return true; case 84: i = 85; return true; case 85: i = 86; return true; case 86: i = 87; return true; case 87: i = 88; return true; case 88: i = 89; return true; case 89: i = 90; return true; case 90: i = 91; return true; case 91: i = 92; return true; case 92: i = 93; return true; case 93: i = 94; return true; case 94: i = 95; return true; case 95: i = 96; return true; case 96: i = 97; return true; case 97: i = 98; return true; case 98: i = 99; return true; case 99: i = 100; return true; case 100: i = 101; return true; case 101: i = 102; return true; case 102: i = 103; return true; case 103: i = 104; return true; case 104: i = 105; return true; case 105: i = 106; return true; case 106: i = 107; return true; case 107: i = 108; return true; case 108: i = 109; return true; case 109: i = 110; return true; case 110: i = 111; return true; case 111: i = 112; return true; case 112: i = 113; return true; case 113: i = 114; return true; case 114: i = 115; return true; case 115: i = 116; return true; case 116: i = 117; return true; case 117: i = 118; return true; case 118: i = 119; return true; case 119: i = 120; return true; case 120: i = 121; return true; case 121: i = 122; return true; case 122: i = 123; return true; case 123: i = 124; return true; case 124: i = 125; return true; case 125: i = 126; return true; case 126: i = 127; return true; case 127: i = 128; return true; case 128: i = 129; return true; case 129: i = 130; return true; case 130: i = 131; return true; case 131: i = 132; return true; case 132: i = 133; return true; case 133: i = 134; return true; case 134: i = 135; return true; case 135: i = 136; return true; case 136: i = 137; return true; case 137: i = 138; return true; case 138: i = 139; return true; case 139: i = 140; return true; case 140: i = 141; return true; case 141: i = 142; return true; case 142: i = 143; return true; case 143: i = 144; return true; case 144: i = 145; return true; case 145: i = 146; return true; case 146: i = 147; return true; case 147: i = 148; return true; case 148: i = 149; return true; case 149: i = 150; return true; case 150: i = 151; return true; case 151: i = 152; return true; case 152: i = 153; return true; case 153: i = 154; return true; case 154: i = 155; return true; case 155: i = 156; return true; case 156: i = 157; return true; case 157: i = 158; return true; case 158: i = 159; return true; case 159: i = 160; return true; case 160: i = 161; return true; case 161: i = 162; return true; case 162: i = 163; return true; case 163: i = 164; return true; case 164: i = 165; return true; case 165: i = 166; return true; case 166: i = 167; return true; case 167: i = 168; return true; case 168: i = 169; return true; case 169: i = 170; return true; case 170: i = 171; return true; case 171: i = 172; return true; case 172: i = 173; return true; case 173: i = 174; return true; case 174: i = 175; return true; case 175: i = 176; return true; case 176: i = 177; return true; case 177: i = 178; return true; case 178: i = 179; return true; case 179: i = 180; return true; case 180: i = 181; return true; case 181: i = 182; return true; case 182: i = 183; return true; case 183: i = 184; return true; case 184: i = 185; return true; case 185: i = 186; return true; case 186: i = 187; return true; case 187: i = 188; return true; case 188: i = 189; return true; case 189: i = 190; return true; case 190: i = 191; return true; case 191: i = 192; return true; case 192: i = 193; return true; case 193: i = 194; return true; case 194: i = 195; return true; case 195: i = 196; return true; case 196: i = 197; return true; case 197: i = 198; return true; case 198: i = 199; return true; case 199: i = 200; return true; case 200: i = 201; return true; case 201: i = 202; return true; case 202: i = 203; return true; case 203: i = 204; return true; case 204: i = 205; return true; case 205: i = 206; return true; case 206: i = 207; return true; case 207: i = 208; return true; case 208: i = 209; return true; case 209: i = 210; return true; case 210: i = 211; return true; case 211: i = 212; return true; case 212: i = 213; return true; case 213: i = 214; return true; case 214: i = 215; return true; case 215: i = 216; return true; case 216: i = 217; return true; case 217: i = 218; return true; case 218: i = 219; return true; case 219: i = 220; return true; case 220: i = 221; return true; case 221: i = 222; return true; case 222: i = 223; return true; case 223: i = 224; return true; case 224: i = 225; return true; case 225: i = 226; return true; case 226: i = 227; return true; case 227: i = 228; return true; case 228: i = 229; return true; case 229: i = 230; return true; case 230: i = 231; return true; case 231: i = 232; return true; case 232: i = 233; return true; case 233: i = 234; return true; case 234: i = 235; return true; case 235: i = 236; return true; case 236: i = 237; return true; case 237: i = 238; return true; case 238: i = 239; return true; case 239: i = 240; return true; case 240: i = 241; return true; case 241: i = 242; return true; case 242: i = 243; return true; case 243: i = 244; return true; case 244: i = 245; return true; case 245: i = 246; return true; case 246: i = 247; return true; case 247: i = 248; return true; case 248: i = 249; return true; case 249: i = 250; return true; case 250: i = 251; return true; case 251: i = 252; return true; case 252: i = 253; return true; case 253: i = 254; return true; case 254: i = 255; return true; default: return false; } }
Unfortunately only works for 8 bit unsigned integers, but should be easy to expand.
But at least it’s safe from overflows, which few of the solutions I see in this thread can claim.Note: first I started with an if/else chain, but then I realized I could make the code more concise with switch/case!
writing code on my phone on the train with three minutes of time, let’s go and think of the worst possible solution!
int i = 1337; for (byte x = 0; x < 32; x++) { if (i & (1 << x) == 1) { i &= 0xFFFFFFFF ^ ( // dangit I'm out of time } else { i |= 1 << x; break; } }
Instead of a loop, you’d use 32 of these copy-pasted if statements and a goto :p
Use bitwise operations to simulate an adder. Bonus points if you only use NOR
I decided to use NAND instead of NOR, but it’s effectively the same thing.
Scala:
//main @main def main(): Unit = var i = 15 //Choose any number here i = add(i, 1) //this increments i println(i) //Adds 2 numbers in the most intuitive way def add(a: Int, b: Int): Int = val pairs = split(a).zip(split(b)) val sumCarry = pairs.scanLeft(false, false)((last, current) => fullAdder(current._1, current._2, last._2)) return join(sumCarry.map(_._1).tail.reverse) //Converts an integer to a list of booleans def join(list: Seq[Boolean]): Int = BigInt(list.map(if (_) '1' else '0').mkString, 2).toInt //Converts a list of booleans to an integer def split(num: Int): Seq[Boolean] = num.toBinaryString.reverse.padTo(32, '0').map(_ == '1') //Adds 2 booleans and a carry in, returns a sum and carry out def fullAdder (a: Boolean, b: Boolean, c: Boolean): (Boolean, Boolean) = (NAND(NAND(NAND(NAND(a, NAND(a, b)), NAND(NAND(a, b), b)), NAND(NAND(NAND(a, NAND(a, b)), NAND(NAND(a, b), b)), c)), NAND(NAND(NAND(NAND(a, NAND(a, b)), NAND(NAND(a, b), b)), c), c)), NAND(NAND(NAND(NAND(a, NAND(a, b)), NAND(NAND(a, b), b)), c), NAND(a, b))) //The basis for all operations def NAND(a: Boolean, b: Boolean): Boolean = !a || !b
EDIT: replaced
Integer.parseInt
withBigInt(...).toInt
to fixNumberFormatException
with negative numbers.try it online here
I like to shake the bytes around a little
i = ( i << 1 + 2 ) >> 1
Wait, why does it multiply by 4? (apparently addition takes precedence over bitwise operations)
This is such hax
My favourite one is:
i -=- 1
This is actually the correct way to do it in JavaScript, especially if the right hand side is more than
1
.If JavaScript thinks
i
contains a string, and let’s say its value is27
,i += 1
will result ini
containing271
.Subtraction doesn’t have any weird string-versus-number semantics and neither does unary minus, so
i -=- 1
guarantees28
in this case.For the increment case,
++
works properly whether JavaScript thinksi
is a string or not, but since the joke is to avoid it, here we are.The solution is clear: Don’t use any strings
Every day, JS strays further from gods light :D
The hot dog-operator
The near symmetry, ah, I see weve found the true Vorin solution.
Upvote for the stormlight archives reference.
It looks kinda symmetrical, I can dig it!
Isn’t beginner++ gonna leave it unchanged?
range(val)
iterates from 0 to val-1, so the final i+1 is valYour CPU has big registers, so why not use them!
#include <x86intrin.h> #include <stdio.h> static int increment_one(int input) { int __attribute__((aligned(32))) result[8]; __m256i v = _mm256_set_epi32(0, 0, 0, 0, 0, 0, 1, input); v = (__m256i)_mm256_hadd_ps((__m256)v, (__m256)v); _mm256_store_si256((__m256i *)result, v); return *result; } int main(void) { int input = 19; printf("Input: %d, Incremented output: %d\n", input, increment_one(input)); return 0; }
I didn’t wake up expecting to hate someone today
Typing on mobile please excuse.
i = 0 while i != 1: pass # i is now 1
Ah yes, the wait for a random bit flip to magically increment your counter method. Takes a very long time
Unless your machine has error correcting memory. Then it will take literally forever.
The time it takes for the counter to increment due to cosmic rays or background radiation is approximately constant, therefore same order as adding one. Same time complexity.
Constant time solution. Highly efficient.
If you do it on a quantum computer, it goes faster because the random errors pile up quicker.
Finally, a useful real world application for quantum computing!
Reminds me of http://www.thecodelesscode.com/case/21
Something like that should do it:
i = ~((~i + 1) + ~0) + 1