Evite os inteiros maus! [fechadas]


53

Você está desenvolvendo algum código para gerar números de identificação. A política exige que nenhum número de identificação inclua a sequência de dígitos 666 .

Crie uma função (ou equivalente do seu idioma) que aceite um parâmetro inteiro positivo e retorne o próximo número inteiro que não inclui 666 quando esse número inteiro é expresso em decimal. (60606 é bom, 66600 não é.)

Seu código não deve usar um loop que adicione um até encontrar um resultado que atenda às regras.

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.

ATUALIZAÇÃO:
Substituir 666 por 667 não funcionará se houver mais de um 666 na entrada.


11
Que tal algo como 456667? Isso deve retornar 456670, ou estamos preocupados apenas com os 666 principais?
Kyle Kanos

11
Eu acho que isso seria melhor como código-golfe do que concurso de popularidade, pois existem soluções tão diretas.
Nate Eldredge

10
@ nyuszika7h mas o resultado deve ser 66700.
Martin Ender

3
como um desafio real, não deveria ter também sido uma exigência para não ter "666" em qualquer lugar do código
DLeh

2
Dependendo da sua implementação de regex, você pode usar '6 {3}' para detectar 666.
#

Respostas:


53

Python, sem manipulação de string

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

Obras de encontrar potências de 10, ponde 666 exibido e adicionando p - n % ppara nque substitui 666xxxxxcom 66700000.


6
Gosto disso porque, se esse era realmente um requisito real do cliente, essa implementação não era invasiva, sensata e eficiente.
RomanSt

Isso funcionará com números que contêm várias instâncias do 666?
Supercat

Sim. O 666 mais à esquerda é o único que realmente importa, e esse algoritmo corrige esse último.
cardboard_box

19
@romkyns Publique um requisito real do cliente no codegolf para induzir outras pessoas a fazerem o trabalho por elas? Isso é mau! ( esconde )
billpg 29/04

3
Para todos que usam o python 3: este código não funciona no python 3+, para executar esse código no python 3, você deve mudar m /= 10para m //= 10. Caso contrário, m se tornará um flutuador e a condição m % 1000 == 666será continuamente falsa e outros "666" em n serão mantidos inalterados.
Sirac

50

JavaScript (atualizado para funcionar com todos os casos de teste)

A verdade pouco conhecida é que, na verdade, existem quatro 6s, mas um deles traiu os outros e polimorfou em forma de código para erradicá-los dos dígitos mundiais dos números. Aqui estão seis traidores:

    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)));

Aqui está uma explicação. Primeiro, embeleze o código e remova coisas inúteis como ''+'string'e ((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)
);

Converta notações estranhas (como ~indexOfe ['replace']) em mais comuns:

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)
);

E agora simplesmente entenda que o algoritmo é assim:

  • Se já houver um 666 na entrada,

    • substitua-o por um 667.
    • substitua todos os dígitos depois disso por um 0.
  • outro,

    • adicione um ao número.
    • NOTA: agora temos a garantia de não ter 666, 666 no final da string ou 666 em outro lugar que já tenha zeros até o final (pense em "carregar" ao fazer a adição "manual").
    • se houver um 666, substitua-o por um 667.

Versão antiga (não funciona 666666666) :

    s='Enter number';x
  =prompt(           ''+
 s);x=+x+
(-~![]);
x=(''+x).replace('666',
666+([][         +[]]+[])
[+[]]['l         ength'[
 'repla'+       'ce'](
  / /g,'')]);alert(x)

Para entender isso, primeiro vamos embelezá-lo:

s = 'Enter number';
x = prompt('' + s);
x = +x + (-~![]);
x = ('' + x).replace('666',666+([][+[]]+[])[+[]]['l         ength'['repla'+'ce'](/ /g,'')]);
alert(x);

Agora vamos remover coisas inúteis como '' + stringe 'str' + 'ing', remova o desnecessários svariável e mudança estranheza como -~![]em 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,'')é simplesmente "length":

x = prompt('Enter number');
x = +x + 1;
x = ('' + x).replace('666', 666+"undefined"[0].length);
alert(x);

E "undefined"[0]é "u", e "u".lengthé 1:

x = prompt('Enter number');
x = +x + 1;
x = ('' + x).replace('666', 666 + 1);
alert(x);

Agora terminamos! Deve ser bem fácil de entender agora.


13
Eu gosto da sua resposta, mas ela falha666666666
Michael M.

3
@Michael Adicionada nova versão! Trabalha para 666666666, e a fonte do 6é apreciador;)
Doorknob

11
Huh - usar ~1para != -1é bem legal.
usar o seguinte comando

@WChargin Pena que não funcione no LiveScript. Eu sei que isso não é código de golfe, mas tenho uma versão em golfe no meu post por diversão.
precisa saber é o seguinte

Funciona em LiveScript :). ~a.indexOf('b')gera o JS correto, tente no livescript.net!
Ven

20

Applescript

Este site não possui respostas suficientes do Applescript. Vamos banir alguns demônios!

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)

Saída de log:

(* 667 *)
(* 66700000 *)
(* 1266700 *)
(* 1213 *)

Eu queria incluir algumas das citações mais poderosas do The Exorcist nisso, mas isso teria tornado esse post decididamente NSFW. Você pode ler a página do IMDB.


Como você executa isso sem ter o OS X?
precisa saber é o seguinte

Eu acho que o Applescript depende bastante do OSX stackoverflow.com/questions/7642299/… - não conheço nenhuma porta para outras plataformas. O OS 9 tinha uma versão do Applescript, embora não haja garantias de que esse script seja executado lá.
Digital Trauma

2
Teria feito o post Not For Safe Work? Droga, meu trabalho não é perigoso
Cruncher

11
@Cruncher oops ;-)
Digital Trauma

11
+1 para a escolha de nomes de variáveis ​​(e porque o script apple é legal).
Floris

15

Perl

Você disse que não devemos incrementar em um loop. Não estou usando nenhum operador matemático! Aqui está uma abordagem pura de substituição de regex (não há garantias de que seja seguro para sua sanidade).

#!/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($_)

As três primeiras substituições incrementam o número em um. Eu resolvi esse problema sozinho uma vez, mas incluiu uma substituição que precisava ser repetida até que não houvesse mais substituições, então usei a abordagem de Andrew Cheong .

A quarta substituição transforma todos os dígitos após a 666em zeros. A substituição final transforma o restante 666em a 667.

Como bônus, isso funcionará com vários números inteiros na entrada, desde que separados por caracteres que não sejam dígitos.


8

LiveScript

Isso está dobrando as regras. Veja bem, você disse que não devo usar um loop que adicione um até encontrar o resultado correto. Então, subtraio menos um !

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

Uma versão de golfe em 53 48 45 bytes por diversão:

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

Agradecemos a user1737909 por ajudar no golfe.

Testes

Requer Node.js com o LiveScriptmódulo npm ou uma biblioteca de afirmações compatível.

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

5
Vai falhar terrivelmente quando você chegar a 665999, pois sua pilha explodirá.
precisa saber é o seguinte

9
Muito esperto. Você deve escrever RFCs para detectar brechas como essa.
billpg

11
@ TimWolla Isso é interessante. Como você achou aquilo?
precisa saber é o seguinte

11
@ nyuszika7h: Se você pensar bem, 666000 a 666999 falharão ... você estará recorrendo pelo menos 1000 vezes.
Andrew Coonce

11
Eu não tenho uma razão específica, eu acho.
usar o seguinte código

6

Rubi

Esta é (eu acho) a primeira resposta que funciona para 666666666. (Exceto a subtração barata -1 da resposta.;))

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

Estou com pressa agora; explicação será adicionada mais tarde.

Atualização : versão muito mais eficiente (tempo de execução quase constante, acredito):

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

Na verdade, a minha resposta funciona bem para 666666666.
isaacg

Tempo de execução constante é impossível. Mesmo verificar se existe um "666" é um problema linear. Este é um problema estritamente mais difícil do que isso.
Cruncher

4

PowerShell

($args[0]+1 -replace '(?<=666.*).','0') -replace '666', '667'

4

J

Finalmente, um bom uso para E.!

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

Em essência, encontramos a primeira posição na qual o argumento está cheio 666e substituímos essa substring e tudo o que temos depois 66700000...até o final.

Explicado em detalhes:

  • ":@>: - Incremente por um e converta em string.
  • '666'&E. - Faça um vetor de booleanos, verdadeiro em cada lugar que '666' começar na string.
  • i.1: - Encontre o índice do primeiro verdadeiro no vetor, caso contrário, retorne o comprimento do vetor.
  • #@[-]- Comprimento da string (que também é o comprimento do vetor) menos o resultado de i..
  • '667'{.!.'0'~ - Pegue uma substring de '667' com um comprimento desse resultado, preenchendo à direita com '0', se necessário.
  • {.~- Pegue uma substring com o comprimento do resultado original de i..
  • , - Anexe os dois juntos.

Em uso:

   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

E como esse não é um código de golfe, isso não precisa ser jogado no inferno com otimizações malucas. Todo mundo ganha!


3

C #

148 137 chars

Conseguiu cortar alguns caracteres graças a @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')); 
}

Fiddle: http://dotnetfiddle.net/XB83bf


11
Os colchetes no seu regex são desnecessários e também existem muitos espaços sintaticamente desnecessários.
recursivo

Ah, e Int32pode ser substituído por int.
recursivo

@ recursive Você está correto, obrigado!
Tentando

Observe que este é um concurso de popularidade e não um código de golfe . Dito isto, se você sente que se barbear com os personagens tornará sua resposta mais popular, faça isso!
Digital Trauma

2
Primeiro eu vi o dotnetfiddle.net =) INCRÍVEL!
Coops

2

Pitão

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)

2

Perl

$_++;$_.=$/;s:666(.*):667 .'0'x($+[1]-$-[1]):e

Código embutido que altera o conteúdo interno $_, uma ideologia bastante padrão em perl. Pode ser usado em conjunto com -psinalizador como este:

$ perl -p % <<< 66666
66700

2

J

Sem strings, loops ou condicionais:

   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

Da mesma forma que a solução de paper_box, isso separa o número em grupos de três dígitos, dividindo por potências de dez. Ele usa o índice da primeira ocorrência de 666 para arredondar o número adequadamente.


2

Haskell (70 caracteres)

Aqui está uma implementação simples no 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 []         = []
  • Em primeiro lugar, ele usa map digitToInt . showpara converter uma identificação possivelmente incorreta em uma lista de dígitos.
  • Em seguida, purgecorresponde ao padrão do mal e o substitui pelo seu equivalente bom.
  • Por fim, foldl' ((+).(*10)) 0reduz a lista de dígitos para um Integer.

Vamos ver se funciona!

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

Parece bom. E apenas por diversão, uma versão para golfe.

f=read.w.show.(+1);w('6':'6':'6':t)="667"++(t>>"0");w(h:t)=h:w t;w t=t

1

Java

Não é o suficiente para fazer isso?

private static int nextId(int currentId) {
    String currentIdStr = String.valueOf(currentId);
    return currentIdStr.contains("666") ? Integer.parseInt(currentIdStr.replace("666", "667")) : ++currentId;
}

Feche, mas deve ser String.valueOf(currentId + 1).
precisa saber é o seguinte

Ah, claro, eu esqueci esse +1! : D
Valentin Grégoire

Essa condicional é inútil; a solução original ligeiramente modificada de acordo com a minha sugestão também funcionará:return Integer.parseInt(String.valueOf(currentId + 1).replace("666", "667"));
nyuszika7h 29/04

11
Não é verdade ... 66600 seria retornado como 66701, que é 1 alto demais.
Valentin Grégoire

1

R

Substituindo 666 por 667 obras.

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)
}

Resultados

> f(1)
2
> f(665)
667
> f(665999999)
667000000
> f(666666666)
667000000
> f(66600)
66700
> f(126660)
126670
> f(126661)
126670
> f(666666666)
667000000

1

3 respostas JavaScript diferentes:

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)

Converte o número em uma sequência de caracteres e itera sobre cada caractere até encontrar, e 666depois muda o último 6para a 7e gera 0todos os caracteres a seguir.

2. JavaScript (rascunho do ECMAScript 6)

Função recursiva sem manipulação de string:

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

Ou mais detalhadamente:

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 );
}

Testes:

g(5) // 6
g(65) // 66
g(665) // 667
g(66599) // 66700
g(66666) // 66700
g(6656665665) // 6656670000

3. JavaScript

Usando expressões regulares:

function h(x)(""+(x+1)).replace( /^(.*?)(666)(.*)$/, function(a,b,c,d)(b+667+d.replace(/./g,0)) )*1

Ou (o mesmo, mas usando o ECMAScript 6)

h=x=>(""+(x+1)).replace(/^(.*?)(666)(.*)$/,(a,b,c,d)=>b+667+d.replace(/./g,0))*1

Com a sua primeira versão, se você digitar 6 septilhões, 666 sextilhões, obtém um valor de retorno, 6.667então tecnicamente ele ainda está lá. Não pense que isso pode ser ajudado.
Spedwards

1e20é a maior ordem de magnitude que o JavaScript (pelo menos no FireFox) imprimirá como um número inteiro sem recorrer à notação científica.
MT0

1

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_

2
667
667000000
667000000
66700

editar: 2ª solução

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_

rendimentos

2
667
667000000
667000000
66700
1236670

11
que não parecem ser as respostas corretas. 665 deve dar 667, 66600 66700 deve dar etc
ace_HongKongIndependence

11
Seus resultados contêm muitas substratos "666".
precisa saber é o seguinte

É embaraçoso. Corrigi os 2 (!) Erros pós-cerca que cometi porque esqueci que os awkíndices eram baseados em 1.
mschilli

@Cruncher Como explicitamente afirmado na pergunta, f(665) returns 667como ele está pedindo "o próximo inteiro que não inclui 666"
ace_HongKongIndependence

Eu adicionei uma segunda maneira que é a) mais awkish eb) minimiza o uso de funções de string.
Mschilli

0

Pitão:

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

Ou:

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

Não vejo como isso funciona. Isso não se transformaria 666666em 667667vez de 667000?
Martin Ender

@ m.buettner Bom ponto, acho que já tenho uma solução.
precisa saber é o seguinte

0

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
    }
}

Usando a função recursiva para encontrar o 666 mais à esquerda e calculando quanto ajustar o número ao exibir a pilha de chamadas novamente.


Não acho que esse código esteja correto. Que resultado ele fornece para a entrada 666666666?
algorithmshark

Você está certo, não percebeu que a entrada já poderia conter números do mal. Então f (666666666) -> 667667667?
Roger Lindsjö

f(666666666) -> 667000000
djhurio

@djhurio Parece que não posso gerar testes para casos extremos hoje. Acredite, eu o consertei agora, mas o código não é mais tão curto.
Roger Lindsjö 29/04

11
@ RogerLindsjö Este é um popularity-contest, não um code-golf.
precisa saber é o seguinte

0

Lote

Manipulação de string iterada simples.

@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%

Inicia nos três primeiros caracteres do número (como uma sequência) e segue até o final até encontrar 666, substitui-o por 667 e faz um loop no comprimento da sequência adicionando zeros.

Todos os casos de teste produzem os resultados corretos.


0

perl, 45 bytes

Um único regex com o sinalizador / e faz todo o trabalho aqui:

$_=<>+1;s/666(.*)$/"667".0 x length$1/e;print

0

SQL

Para ser mais preciso, o 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

0

Pitão

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)

0

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

Resultados REPL

julia> f(1)
2

julia> f(665)
667

julia> f(665999999)
667000000

julia> f(666666666)
667000000

julia> f(66600)
66700

julia> f(456667) 
456670

0

C #

Eu estou fazendo a coisa certa

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;
}

0

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

Em ação:

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

resultado:

2 
667 
667000000 
667000000 
66700 
456670 

0

C ++

Sei que isso não é código-golfe, mas (a) algumas pessoas sugeriram que é um bom desafio de golfe e (b) esta é minha primeira resposta de desafio / golfe, achei que seria divertido e, se o fizer isso aqui não aparece em um desafio real de golfe por ser um péssimo jogador de golfe. X)

Basicamente, '666' substituído por '667' funciona se você o fizer pela primeira instância no número e depois escrever 0s à direita.

Golfe ( 175 155 caracteres):

#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;
}

Eu acho que você não precisa x+=c=='6'?1:0, você pode se safar x+=c=='6'. Ainda não tentei.
Nyuszika7h

Além disso, você deixou de fora o std::antes stringstream. Não compila sem isso.
Nyuszika7h

Adicionado std ::, obrigado por isso @ nyuszika7h. Cometi o erro de usar um IDE que gerou automaticamente 'using namespace std;' . Para testá-lo em -_- vou tentar a x+=c=='6'redução, bem como olhando para fazer isso com dígitos int em vez de caracteres sstream ...
mike32

0

Rubi

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

0

perl, 36 apenas um sub, sem bytes

Uma versão mais curta que a minha última solução, usando uma mistura de operações aritméticas e de expressões regulares.

sub{($_[0]+1)=~s/666(.*)/667$1/r-$1}

print + (<> + 1) = ~ s / 666 (. *) / 667 $ 1 / r- $ 1 (economizou um byte) (mais dois se você usar o say) - embora a solicitação tenha sido para uma função, remova print + e use sub {...}
Altreus 30/04

0

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 - sem verificação de limites e muito espaço em branco, mas não é golfe. Também é um pouco divertido de formatar "while (d -> 0)".

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.