# Avoid the evil integers! [closed]

You are developing some code to generate ID numbers. Policy requires that no ID numbers include the digit sequence 666.

Create a function (or your language's equivalent) which takes a positive integer parameter and returns the next integer that does not include 666 when that integer is expressed in decimal. (60606 is fine, 66600 is not.)

Your code must not use a loop that adds one until it finds a result that fits the rules.

f(1) returns 2.
f(665) returns 667.
f(665999999) returns 667000000 without having looped a million times.
(Following examples added since the question was first posed.)
f(666666666) also returns 667000000.
f(66600) returns 66700.
f(456667) returns 456670.


UPDATE:
Replacing 666 with 667 won't work if there's more than one 666 in the input.

• What about something like 456667? Should that return 456670, or are we only worried about a leading 666? – Kyle Kanos Apr 29 '14 at 14:18
• I think this would be better as code-golf than popularity-contest since there are such straightforward solutions. – Nate Eldredge Apr 29 '14 at 16:08
• @nyuszika7h but the result should be 66700. – Martin Ender Apr 29 '14 at 17:07
• as a real challenge, there should've also been a requirement to not have "666" anywhere in the code – DLeh Apr 30 '14 at 19:18
• Depending on your regex implementation, you could use '6{3}' to detect 666. – celtschk May 1 '14 at 19:33

# Python, no string manipulation

def f(n):
n += 1
p = 1
m = n
while m:
if m % 1000 == 666:
n += p - n % p
p *= 10
m /= 10
return n


Works by finding powers of 10, p, where 666 appears, and adding p - n % p to n which replaces 666xxxxx with 66700000.

• I like this in that if this was actually a real customer requirement, this implementation is non-hacky, sensible and efficient. – RomanSt Apr 29 '14 at 14:32
• Will this work with numbers that contain multiple instances of 666? – supercat Apr 29 '14 at 15:48
• Yes. The leftmost 666 is the only one that actually matters, and this algorithm fixes that one last. – cardboard_box Apr 29 '14 at 16:20
• @romkyns Post an actual real customer requirement to codegolf to trick other people into doing their work for them? That's evil! (hides) – billpg Apr 29 '14 at 16:37
• For everyone who uses python 3: This code does not work on python 3+, to run this code on python 3 you have to change m /= 10 to m //= 10. If you don't then m will become a float and the condition m % 1000 == 666 will continously be false and other "666" in n are left unchanged. – Sirac May 4 '14 at 12:36

# JavaScript (updated to work with all test cases)

The little-known truth is that there are actually four 6s, but one of the betrayed the others and polymorphed into code form to eradicate them from the world digits of the numbers. Here is that traitorous six:

    x=prompt(''+
'Enter number');
alert(      ( (~x[
'ind'+
'exOf']('666')))?(x
.replace(/666(.*)$/, function (mat,g){ return '667'+g ['re'+ 'place' ](/./g,0)})):((+x+ 1+'').replace( 666,667)));  Here is an explanation. First, beautify the code and remove useless stuff like ''+'string' and ((code)): x = prompt('Enter number'); alert( ~x['indexOf']('666') ? x.replace(/666(.*)$/, function(mat,g) {
return '667' + g['replace'](/./g,0)
})
:
(+x+1+'').replace(666, 667)
);


Convert weird notations (like ~indexOf and ['replace']) into more common ones:

x = prompt('Enter number');
alert(
x.indexOf('666') > -1
?
x.replace(/666(.*)$/, function(mat, g) { return '667' + g.replace(/./g, 0) }) : ((parseInt(x) + 1) + '').replace(666, 667) );  And now simply understand that the algorithm goes like this: • If there is already a 666 in the input, • replace it with a 667. • replace every digit after that with a 0. • else, • add one to the number. • NOTE: we are now guaranteed to have either no 666, a 666 at the end of the string, or a 666 somewhere else that already has zeroes going to the end (think "carrying" when doing "manual" addition). • if there's a 666, replace it with a 667. Old version (doesn't work for 666666666):  s='Enter number';x =prompt( ''+ s);x=+x+ (-~![]); x=(''+x).replace('666', 666+([][ +[]]+[]) [+[]]['l ength'[ 'repla'+ 'ce']( / /g,'')]);alert(x)  To understand this, let's first beautify it: s = 'Enter number'; x = prompt('' + s); x = +x + (-~![]); x = ('' + x).replace('666',666+([][+[]]+[])[+[]]['l ength'['repla'+'ce'](/ /g,'')]); alert(x);  Now let's remove useless things like '' + string and 'str' + 'ing', remove the unnecessary s variable, and change weirdness like -~![] into 1: x = prompt('Enter number'); x = +x + 1; x = ('' + x).replace('666', 666+"undefined"[0]['l ength'['replace'](/ /g,'')]); alert(x);  'l ength'['replace'](/ /g,'') is simply "length": x = prompt('Enter number'); x = +x + 1; x = ('' + x).replace('666', 666+"undefined"[0].length); alert(x);  And "undefined"[0] is "u", and "u".length is 1: x = prompt('Enter number'); x = +x + 1; x = ('' + x).replace('666', 666 + 1); alert(x);  Now we're done! It should be pretty easy to understand now. • I like your answer but it fails for 666666666 – Michael M. Apr 29 '14 at 13:18 • @Michael Added new version! Works for 666666666, and the font of the 6 is fancier ;) – Doorknob Apr 29 '14 at 21:14 • Huh - using ~1 for != -1 is pretty cool. – wchargin Apr 30 '14 at 2:02 • @WChargin Too bad that doesn't work in LiveScript. I know this isn't code golf but I have a golfed version in my post for fun. – nyuszika7h Apr 30 '14 at 9:14 • It does work in LiveScript :). ~a.indexOf('b') generates the correct JS, try it on livescript.net ! – Ven May 3 '14 at 20:51 # Applescript This site doesn't have enough Applescript answers. Lets banish some demons! property demon : "666" property trinity : 1 on exorcise above possessed set possessed to possessed as text set relic to AppleScript's text item delimiters set AppleScript's text item delimiters to demon set deliverance to possessed's first text item if possessed is deliverance then set deliverance to possessed + trinity else set AppleScript's text item delimiters to trinity set compellingPower to ¬ (count of possessed's characters) - ¬ (count of deliverance's characters) - ¬ (count of demon's characters) set deliverance to ¬ deliverance & ¬ demon + trinity & ¬ last text item of (((10 ^ compellingPower) as integer) as text) end if set AppleScript's text item delimiters to relic return deliverance end exorcise log (exorcise above 666) log (exorcise above 66666666) log (exorcise above 1266612) log (exorcise above 1212)  Log output: (*667*) (*66700000*) (*1266700*) (*1213*)  I'd wanted to get some of the more powerful quotes from The Exorcist into this, but that would have made this posted decidedly NSFW. You can read the IMDB page instead. • How do you run this without having OS X? – nyuszika7h Apr 30 '14 at 9:44 • I think Applescript is pretty much dependent on OSX stackoverflow.com/questions/7642299/… - I'm not aware of any ports to other platforms. OS 9 did have a version of Applescript, though no guarantees that this script would run there. – Digital Trauma Apr 30 '14 at 14:23 • It would have made the post Not For Safe Work? Dammit, my job isn't dangerous – Cruncher Apr 30 '14 at 17:39 • @Cruncher oops ;-) – Digital Trauma Apr 30 '14 at 17:43 • +1 for the choice of variable names (and because apple script is cool). – Floris Apr 30 '14 at 20:50 ## Perl You said we must not increment in a loop. I'm not using any mathematical operators at all! Here is a pure regex-substitution approach (no guarantees it's safe for your sanity). #!/usr/bin/perl$_ = <>;

s/$/ ~0123456789/; s/(?=\d)(?:([0-8])(?=.*\1(\d)\d*$)|(?=.*(1)))(?:(9+)(?=.*(~))|)(?!\d)/$2$3$4$5/g;
s/9(?=9*~)(?=.*(0))|~| ~0123456789$/$1/g;
s/(?!^)\G\d|(666)\d/${1}0/g; s/666/667/g; print($_)


The first three substitutions increment the number by one. I did solve that problem myself once, but it included a substitution that had to be looped until no more substitutions were made, so I used Andrew Cheong's approach instead.

The fourth substitution turns all digits following a 666 into zeros. The final substitution turns the remaining 666 into a 667.

As a bonus this will work with multiple integers in the input as long as they are separated by non-digit characters.

# LiveScript

This is bending the rules. You see, you said I must not use a loop that adds one until it finds a correct result. So I subtract minus one instead!

nextId = (id) ->
while (id + 1).toString!indexOf('666') != -1
id -= -1
id + 1


A golfed version in 53 48 45 bytes for fun:

n=(i)->(while~(i+1+'')indexOf(\666)=>i-=-1);i+1


Thanks to user1737909 for helping golf it further.

## Tests

Requires Node.js with the LiveScript npm module or a compatible assert library.

assert = require \assert

assert.equal nextId(1), 2
assert.equal nextId(665), 667
assert.equal nextId(665999999), 667000000
assert.equal nextId(66600), 66700
assert.equal nextId(456667), 456670

• It is going to fail horribly when you get to 665999, as your stack will explode. – TimWolla Apr 29 '14 at 12:48
• Very clever. You should be writing RFCs to spot loopholes like that. – billpg Apr 29 '14 at 12:59
• @TimWolla That's interesting. How did you find that? – nyuszika7h Apr 29 '14 at 14:52
• @nyuszika7h: If you think about it, 666000 through 666999 will all fail... you'll be recursing at least 1000 times. – Andrew Coonce Apr 29 '14 at 14:58
• I don't have a particular reason, I guess. – nyuszika7h Apr 29 '14 at 16:28

# Ruby

This is (I think) the first answer that works for 666666666. (Except the cheaty subtracting -1 answer. ;) )

x = gets.chomp.to_i + 1
p (x..x.to_s.gsub('666', '667').to_i).select{|i| !(i.to_s.index '666') }.min


I'm in a hurry now; explanation will be added later.

Update: much more efficient version (almost constant runtime I believe):

x = gets.chomp
if x.index '666'
# replace ex. 6661234 with 6670000
puts x.sub(/666(.*)/){ "667#{"0" * $1.length}" } else # old algorithm (guaranteed to result in # 0 or 1 666s now) puts (x.to_i+1).to_s.sub(/666/, "667") end  • Actually, my answer works fine for 666666666. – isaacg Apr 29 '14 at 13:56 • Constant runtime is impossible. Even checking if a "666" exists is a linear problem. This is a strictly harder problem than that. – Cruncher Apr 30 '14 at 17:36 PowerShell ($args[0]+1 -replace '(?<=666.*).','0') -replace '666', '667'


# J

Finally, a good use for E.!

(({.~ , '667' {.!.'0'~ #@[ - ]) '666'&E. i. 1:) @ ": @ >:


In essence, we find the first position in which the argument has a full 666, and we replace that substring and everything after with 66700000... until the end.

Explained in detail:

• ":@>: - Increment by one and convert to string.
• '666'&E. - Make a vector of booleans, true in each place that '666' begins in the string.
• i.1: - Find the index of the first true in the vector, else return the length of the vector.
• #@[-] - Length of the string (which is also the length of the vector) minus the result of i..
• '667'{.!.'0'~ - Take a substring of '667' with a length of that result, padding on the right with '0' if necessary.
• {.~ - Take a substring with the length of the original result from i..
• , - Append the two together.

In use:

   f =: (({.~,'667'{.!.'0'~#@[-])'666'&E.i.1:)@":@>:
f 1              NB. this leaves okay numbers untouched
2
f 665999999      NB. properly handles multiple increments
667000000
f 16266366646666 NB. only takes effect at sets of 3 sixes
16266366700000


And since this isn't a code golf, this doesn't have to get golfed to hell with crazy optimizations. Everybody wins!

# C#

## 148 137 chars

Was able to shave off a few chars thanks to @recursive

public static int f(int b){b++;var z=new Regex("666\\d*");var q=z.Replace(b+"","667",1);return int.Parse(q.PadRight((b+"").Length,'0'));}


Ungolfed:

public static int f(int b)
{
b++;
var z = new Regex("666[\\d]*");
var q = z.Replace(b+"", "667", 1);
return Int32.Parse(q.PadRight((b+"").Length, '0'));
}

• The square brackets in your regex are unnecessary, and there are also a lot of syntactically unnecessary spaces. – recursive Apr 29 '14 at 16:00
• Oh, and Int32 can be replaced with int. – recursive Apr 29 '14 at 16:01
• @recursive You are correct, thanks! – Trying Apr 29 '14 at 16:07
• Note this is a popularity-contest and not code-golf. Having said that if you feel shaving off characters will make your answer more popular, then go for it! – Digital Trauma Apr 29 '14 at 18:14
• First I have seen of dotnetfiddle.net =) AWESOME! – Coops Apr 30 '14 at 15:48

# Python

def next_id(id_num):
id_num_p1=str(id_num+1)
pieces=id_num_p1.split('666')
if len(pieces)==1:
return id_num+1
next_id_str=pieces[0]+'667'+'0'*(len(id_num_p1)-len(pieces[0])-3)
return int(next_id_str)


# Perl

$_++;$_.=$/;s:666(.*):667 .'0'x($+[1]-$-[1]):e  Inline code which changes the content inside $_, a pretty standard ideology in perl. Can be used in conjunction with -p flag like this:

$perl -p % <<< 66666 66700  # J No strings, loops or conditionals:  next =: 3 :'<.(y+1)(+-|~)10^<:666 i:~666,1000|<.(y+1)%10^i.<.10^.>:y' next 1 2 next 665 667 next 665999999 667000000 next 666666666 667000000 next 66600 66700  Similarly to cardboard_box's solution, this separates the number into groups of three digits by dividing by powers of ten. It uses the index of the first occurrence of 666 to round the number up appropriately. # Haskell (70 characters) Here is a simple implementation in Haskell. import Data.List import Data.Char nextid :: Integer -> Integer nextid = foldl' ((+).(*10)) 0 . purge . map digitToInt . show . (+1) where purge (6:6:6:xs) = 6 : 6 : 7 : map (const 0) xs purge (x:xs) = fromIntegral x : purge xs purge [] = []  • Firstly, it uses map digitToInt . show to convert a possibly evil ID to a list of digits. • Next, purge matches the evil pattern and replaces it with its good equivalent. • Finally, foldl' ((+).(*10)) 0 reduces the list of digits to one Integer. Let's see if it works! ghci> nextid 1 2 ghci> nextid 665 667 ghci> nextid 665999999 667000000 ghci> nextid 666666666 667000000 ghci> nextid 66600 66700 ghci> nextid 456667 456670 ghci> nextid 6660239486660239466 6670000000000000000  Looks good. And just for fun a golfed version. f=read.w.show.(+1);w('6':'6':'6':t)="667"++(t>>"0");w(h:t)=h:w t;w t=t  # Java Isn't it enough to do this? private static int nextId(int currentId) { String currentIdStr = String.valueOf(currentId); return currentIdStr.contains("666") ? Integer.parseInt(currentIdStr.replace("666", "667")) : ++currentId; }  • Close, but that should be String.valueOf(currentId + 1). – nyuszika7h Apr 29 '14 at 12:10 • Oh right, I forgot that +1 thingy! :D – Valentin Grégoire Apr 29 '14 at 12:12 • That conditional is useless; the original solution slightly modified per my suggestion will work too: return Integer.parseInt(String.valueOf(currentId + 1).replace("666", "667")); – nyuszika7h Apr 29 '14 at 12:23 • Not true... 66600 would be returned as 66701, which is 1 too high. – Valentin Grégoire Apr 29 '14 at 12:39 ## R Replacing 666 with 667 works. f <- function(x) { x <- as.integer(x + 1) if (grepl(666, x)) { k <- regexpr(666, x) cat(substring(x, 1, k + 1), 7, rep(0, nchar(x) - k - 2), sep = "") } else cat(x) }  Results > f(1) 2 > f(665) 667 > f(665999999) 667000000 > f(666666666) 667000000 > f(66600) 66700 > f(126660) 126670 > f(126661) 126670 > f(666666666) 667000000  3 Different JavaScript answers: # 1. JavaScript (ECMAScript 6) f=x=>(a=b=c=0,[c?'0':a+(a=b)+(b=i)==666?(c='7'):i for(i of ""+(x+1))].join('')*1)  Converts the number to a string then iterates over each character until it finds 666 then it changes that last 6 to a 7 and outputs 0 for all following characters. # 2. JavaScript (ECMAScript 6 Draft) Recursive function without string manipulation: g=(x,y=x+1,p=1)=>y?g(y%1e3==666?y*p+p:y>x?y:x,y/10|0,p*10):x  Or more verbosely: function g(x,y=x+1,p=1) { if ( y == 0 ) return x; else if ( y % 1000 == 666 ) return g( y*p+p, Math.floor(y/10), p*10 ); else return g( Math.max(y, x), Math.floor(y/10), p*10 ); }  Tests: g(5) // 6 g(65) // 66 g(665) // 667 g(66599) // 66700 g(66666) // 66700 g(6656665665) // 6656670000  # 3. JavaScript Using regular expressions: function h(x)(""+(x+1)).replace( /^(.*?)(666)(.*)$/, function(a,b,c,d)(b+667+d.replace(/./g,0)) )*1


Or (the same but using ECMAScript 6)

h=x=>(""+(x+1)).replace(/^(.*?)(666)(.*)$/,(a,b,c,d)=>b+667+d.replace(/./g,0))*1  • With your first version, if you enter 6 septillion, 666 sextillion you get a return value of 6.667 so technically it's still there. Don't think it can be helped though. – Spedwards May 4 '14 at 14:01 • 1e20 is about the largest order of magnitude that JavaScript (at least in FireFox) will print as an integer without resorting to scientific notation. – MT0 May 4 '14 at 16:24 AWK awk '{i=index(++$0,"666")}
i{a=substr($0,1,i-1) b=substr($0,i+3)
gsub(/./,0,b)
$0=a"667"b} 1 ' <<_INPUT_ 1 665 665999999 666666666 66600 _INPUT_  gives 2 667 667000000 667000000 66700  edit: 2nd solution awk -F666 -vOFS=667 '{++$0;$1=$1}
NF-1{for(gsub(/./,0,$2);NF>2;--NF){$2=$2 0 0 0 for(i=length($NF);i;--i)$2=$2 0}}1
' <<_INPUT_
1
665
665999999
666666666
66600
1236661
_INPUT_


yields

2
667
667000000
667000000
66700
1236670

• which doesn't seem to be correct answers. 665 should give 667, 66600 should give 66700 etc – user12205 Apr 29 '14 at 14:25
• Your results contain a lot of "666" substrings. – Glenn Randers-Pehrson Apr 29 '14 at 14:28
• That's embarrassing. I fixed the 2(!) fence-post-errors I made because I forgot that awk indexes strings 1-based. – mschilli Apr 29 '14 at 15:56
• @Cruncher As explicitly stated in the question, f(665) returns 667 as it is asking for "the next integer that does not include 666" – user12205 Apr 30 '14 at 17:48
• I added a 2nd way that is a) more awkish and b) minimizes the use of string functions. – mschilli May 4 '15 at 7:25

# Python:

def f(b):
b = b+1
while '666' in b: b = b.replace('666','667',1)
return int(b)


Or:

 f=lambda b:int(b+1.replace('666','667'))

• I don't see how that works. Wouldn't that turn 666666 into 667667 instead of 667000? – Martin Ender Apr 29 '14 at 16:35
• @m.buettner Good point, I think I already have an solution. – ɐɔıʇǝɥʇuʎs Apr 29 '14 at 16:56

## Java

public static int f(int i) {
i++;
i += findAdjustment(i);
return i;
}

private static int findAdjustment(int i) {
if (i < 666) {
return 0;
}
int adjustment = findAdjustment(i / 10);
if (adjustment != 0) {
// Leftmost 666 found, fix adjustment by current last digit
return adjustment * 10 - i % 10;
} else if (i % 1000 == 666) {
return 1; // This is leftmost 666, need to be corrected by 1
} else {
return 0; // no adjustment needed
}
}


Using recursive function to find leftmost 666 and calculation how much to adjust the number when popping the call stack again.

• I don't think this code is correct. What result does it give for input 666666666? – algorithmshark Apr 29 '14 at 13:09
• You are right, didn't realise that the input already could contain Evil numbers. So f(666666666) -> 667667667? – Roger Lindsjö Apr 29 '14 at 13:28
• f(666666666) -> 667000000 – djhurio Apr 29 '14 at 13:34
• @djhurio Seems I can not generate tests for edge cases today. Believe I have it fixed now, but the code is not so short any more. – Roger Lindsjö Apr 29 '14 at 14:01
• @RogerLindsjö This is a popularity-contest, not a code-golf. – nyuszika7h Apr 29 '14 at 18:39

## Batch

Simple iterated string manipulation.

@echo off

setLocal enableDelayedExpansion
set /a inp=%1+1
for /f usebackq %%a in (powershell "&{'%inp%'.length-1}") do (
set a len=%%a-2
set chars=%%a
)

for /l %%b in (0, 1, %len%) do (
if "!inp:~%%b,3!"=="666" (
set inp=!inp:~0,%%b!667
set /a a=%%b+3
for /l %%c in (!a!, 1, %chars%) do set inp=!inp!0
goto :break
)
)

:break

echo %inp%


It starts at the first three characters of the number (as a string), and works its way to the end until it finds 666, it then replaces that 666 with 667, and loops to the length of the string adding zeros.

The test cases all produce the correct results.

# perl, 45 bytes

A single regex with the /e flag does all the work here:

$_=<>+1;s/666(.*)$/"667".0 x length$1/e;print  ## SQL To be precise, SQL Server 2012 Transact-SQL. create function dbo.GoodIntegers( @i bigint ) returns bigint as begin declare @s varchar(20) = cast( @i+1 as varchar(20) ) ; declare @badindex int = charindex( '666', @s ) ; declare @rv bigint = cast ( iif( @badindex = 0 , @s , concat( left( @s, @badindex - 1 ), '667', replicate( '0', len( @s ) - @badindex - 2 ) ) ) as bigint ) ; return @rv ; end ; -- function dbo.GoodIntegers  # Python import re def exorcise(number): number = str(number+1) i = re.compile("^(\d*?)(666)(\d*)$")
if re.match(i,number):
n = re.match(i,number).groups()
return int(n[0]+"667"+"".join(["0"*len(n[2])]))
return int(number)


# Julia

function f(x::Int)
y = string(x+1)
n = length(y)
z = string(^("0",n))
~ismatch(r"6{3}", y) ?
int(y) :
while ismatch(r"6{3}",y)
m = match(r"6{3}", y)
y = string(y[1:m.offset+1], '7', z[m.offset+3:n])
end
int(y)
end


REPL results

julia> f(1)
2

julia> f(665)
667

julia> f(665999999)
667000000

julia> f(666666666)
667000000

julia> f(66600)
66700

julia> f(456667)
456670


# C#

Am I doing it right

static int F(int n)
{
n++;

int a = 666;
int b = 1;

while (n >= b)
{
if (((n - a) / b) % 1000 == 0)
{
n += b;
}

a *= 10;
b *= 10;
}

return n;
}


## vba

Function f(num As Long) As Long
Dim SixPos As Long
Dim s As String
s = CStr(num)
SixPos = InStr(s, "666")
If SixPos = 0 Then
s = CStr(num + 1)
SixPos = InStr(s, "666")
End If
If SixPos Then
Mid(s, SixPos + 2, 1) = "7"
If Len(s) > SixPos + 2 Then
Mid(s, SixPos + 3, Len(s) - SixPos + 3) = String$(Len(s) - SixPos + 3, "0") End If End If f = CLng(s) End Function  In action: Sub demo() Debug.Print f(1) 'returns 2. Debug.Print f(665) 'returns 667. Debug.Print f(665999999) 'returns 667000000 without having looped a million times. '(Following examples added since the question was first posed.) Debug.Print f(666666666) 'also returns 667000000. Debug.Print f(66600) 'returns 66700. Debug.Print f(456667) 'returns 456670. End Sub  result: 2 667 667000000 667000000 66700 456670  ## C++ I know this isn't code-golf, but (a) some people have suggested that it is a good golf challenge, and (b) this is my first challenge/golf answer, I thought it would be fun, and if I do this here I don't get shown up in an actual golf challenge for being a terrible golfer. X) Basically, replaced '666' with '667' works if you do it for the first instance in the number and then write out trailing 0s. Golfed (175 155 chars): #include<sstream> int f(int x){std::stringstream s,o;s<<++x;x=0;for(char c=s.get();!s.eof();c=s.get())o<<((x+=c=='6')++==3?'7':--x>3?'0':c);o>>x;return x;}  Ungolfed: #include<sstream> int f(int x){ std::stringstream s,o; s<<++x; // Increment to next int. x=0; // Reusing this to count 6s for(char c=s.get();!s.eof();c=s.get()){ // For each digit if (c=='6'){ ++x; // Count sixes... } if(x==3) { // Devil's number! c='7'; // Output 7 here. ++x; // Increment once more. } else if (x > 3) { c='0'; // Already replaced 666 with 667, so write out 0s } o<<c; // Append digit } o>>x; // Get int return x; }  • I think you don't need x+=c=='6'?1:0, you can get away with x+=c=='6'. Haven't tried it, though. – nyuszika7h May 1 '14 at 15:29 • Also, you left out the std:: before stringstream. It doesn't compile without that. – nyuszika7h May 1 '14 at 15:32 • Added std::, thanks for that @nyuszika7h. I made the mistake of using an IDE that autogenerated 'using namespace std;' to test it in. -_- I will try the x+=c=='6' reduction, as well as looking at doing this with int digits rather than sstream chars... – mike32 May 1 '14 at 18:27 # Ruby n=(gets.chomp.to_i+1).to_s i=n.index("666") if i!=nil n=n[0..i+1]+"7"+"0"*(n.length-i-3) end puts n  # perl, 36 just a sub, no bytes A shorter version than my last solution, using a mix of arithmetic and regex ops. sub{($_[0]+1)=~s/666(.*)/667$1/r-$1}

• print+(<>+1)=~s/666(.*)/667$1/r-$1 (saved you a byte)(two more if you use say) - although the request was for a function so remove print+ and use sub{ ... } – Altreus Apr 30 '14 at 12:06

C

#include <stdlib.h>
#include <stdio.h>

int next(int a)
{
for(int b=a+1,c=0,d=0; b>665 ;b/=10, c++)
if(b%1000==666) {d=c; a=b;}

a++;
while(d --> 0) a*=10;

return a;
}

void main(int a, char *v[])
{
int c = a>1?atoi(v[1]):0;

printf("%d\n",next(c));
}


OK - no bounds checking and far too much whitespace but it's not golf. Also a fun bit of formatting in "while (d --> 0)".