¡Evita los enteros malvados! [cerrado]

53

Estás desarrollando un código para generar números de identificación. La política requiere que ningún número de identificación incluya la secuencia de dígitos 666 .

Cree una función (o el equivalente de su idioma) que tome un parámetro entero positivo y devuelva el siguiente entero que no incluye 666 cuando ese entero se expresa en decimal. (60606 está bien, 66600 no lo está).

Su código no debe usar un bucle que agregue uno hasta que encuentre un resultado que se ajuste a las reglas.

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.

ACTUALIZACIÓN:
Reemplazar 666 con 667 no funcionará si hay más de un 666 en la entrada.

billpg
fuente
1
¿Qué tal algo como 456667? ¿Debería eso devolver 456670, o solo estamos preocupados por un 666 líder?
Kyle Kanos
11
Creo que esto sería mejor como código golf que concurso de popularidad, ya que existen soluciones tan sencillas.
Nate Eldredge
10
@ nyuszika7h pero el resultado debería ser 66700.
Martin Ender
3
como un verdadero desafío, también debería haber un requisito de no tener "666" en ninguna parte del código
DLeh
2
Dependiendo de su implementación de expresiones regulares, puede usar '6 {3}' para detectar 666.
celtschk

Respuestas:

53

Python, sin manipulación de cadenas

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

Funciona encontrando poderes de 10, pdonde aparece 666, y agregando p - n % pa los nque reemplaza 666xxxxxcon 66700000.

caja de cartón
fuente
66
Me gusta esto porque si esto fuera realmente un requisito real del cliente, esta implementación no es hacky, sensata y eficiente.
RomanSt
¿Funcionará esto con números que contienen múltiples instancias de 666?
supercat
Si. El 666 más a la izquierda es el único que realmente importa, y este algoritmo corrige ese último.
cardboard_box
19
@romkyns ¿Publica un requisito real de un cliente real para codegolf para engañar a otras personas para que hagan su trabajo por ellos? Eso es malo! ( oculta )
billpg
3
Para todos los que usan Python 3: Este código no funciona en Python 3+, para ejecutar este código en Python 3 que tiene que cambiar m /= 10a m //= 10. Si no lo hace, m se convertirá en un flotador y la condición m % 1000 == 666será continuamente falsa y otros "666" en n no se modificarán.
Sirac
50

JavaScript (actualizado para funcionar con todos los casos de prueba)

La verdad poco conocida es que en realidad hay cuatro 6s, pero uno de los traicionó a los demás y se transformó en forma de código para erradicarlos de los dígitos mundiales de los números. Aquí está ese traidor seis:

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

Aquí hay una explicación. Primero, embellezca el código y elimine cosas inútiles como ''+'string'y ((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)
);

Convierta anotaciones extrañas (como ~indexOfy ['replace']) en otras más comunes:

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

Y ahora simplemente entienda que el algoritmo es así:

  • Si ya hay un 666 en la entrada,

    • reemplácelo con un 667.
    • reemplace cada dígito después de eso con un 0.
  • más,

    • agregue uno al número.
    • NOTA: ahora se garantiza que no tenemos 666, un 666 al final de la cadena o un 666 en otro lugar que ya tiene ceros al final (piense en "llevar" al hacer la adición "manual").
    • Si hay un 666, reemplácelo con un 667.

Versión anterior (no funciona 666666666) :

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

Para entender esto, primero hay que embellecerlo:

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

Ahora vamos a quitar cosas inútiles como '' + stringy 'str' + 'ing', eliminar lo innecesario svariable y rarezas como el cambio -~![]en 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,'')es simplemente "length":

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

Y "undefined"[0]es "u", y "u".lengthes 1:

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

Ahora hemos terminado! Debería ser bastante fácil de entender ahora.

Pomo de la puerta
fuente
13
Me gusta tu respuesta, pero falla666666666
Michael M.
3
@Michael ¡Nueva versión agregada! Funciona para 666666666, y la fuente de la 6es más elegante;)
Pomo de la puerta
1
Huh: usar ~1para != -1es muy bueno.
wchargin
@WChargin Lástima que no funcione en LiveScript. Sé que esto no es código golf, pero tengo una versión de golf en mi publicación por diversión.
nyuszika7h
Funciona en LiveScript :). ~a.indexOf('b')genera el JS correcto, ¡pruébalo en livescript.net!
Ven
20

Applescript

Este sitio no tiene suficientes respuestas de Applescript. ¡Vamos a desterrar a algunos demonios!

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)

Salida de registro:

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

Quería obtener algunas de las citas más poderosas de The Exorcist en esto, pero eso habría hecho que esto se publicara decididamente NSFW. Puede leer la página IMDB en su lugar.

Trauma digital
fuente
¿Cómo ejecutas esto sin tener OS X?
nyuszika7h
Creo que Applescript depende en gran medida de OSX stackoverflow.com/questions/7642299/… - No conozco ningún puerto a otras plataformas. OS 9 hizo tener una versión de Applescript, aunque no hay garantías de que este script se ejecute allí.
Trauma digital
2
¿Habría hecho la publicación Not For Safe Work? Maldita sea, mi trabajo no es peligroso
Cruncher
1
@Cruncher oops ;-)
Digital Trauma
1
+1 para la elección de nombres de variables (y porque el script de Apple es genial).
Floris
15

Perl

Dijiste que no debemos incrementar en un bucle. ¡No estoy usando ningún operador matemático en absoluto! Aquí hay un enfoque puro de sustitución de expresiones regulares (no hay garantías de que sea seguro para su cordura).

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

Las primeras tres sustituciones incrementan el número en uno. Resolví ese problema yo mismo una vez, pero incluía una sustitución que tenía que colocarse en bucle hasta que no se realizaran más sustituciones, así que utilicé el enfoque de Andrew Cheong .

La cuarta sustitución convierte todos los dígitos que siguen a a 666en ceros. La sustitución final convierte el resto 666en a 667.

Como beneficio adicional, esto funcionará con múltiples enteros en la entrada, siempre que estén separados por caracteres que no sean dígitos.

Martin Ender
fuente
8

LiveScript

Esto está doblando las reglas. Verás, dijiste que no debo usar un bucle que agregue uno hasta que encuentre un resultado correcto. ¡Entonces resto menos uno en su lugar!

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

Una versión de golf en 53 48 45 bytes para divertirse:

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

Gracias a user1737909 por ayudarnos a seguir jugando al golf.

Pruebas

Requiere Node.js con el LiveScriptmódulo npm o una biblioteca de aserciones compatible.

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
nyuszika7h
fuente
55
Va a fallar horriblemente cuando llegue a 665999, ya que su pila explotará.
TimWolla
99
Muy inteligente. Debería escribir RFC para detectar lagunas como esa.
billpg
1
@TimWolla Eso es interesante. ¿Cómo encontraste eso?
nyuszika7h
1
@ nyuszika7h: Si lo piensas bien, 666000 a 666999 fallarán ... recurrirás al menos 1000 veces.
Andrew Coonce
1
No tengo una razón particular, supongo.
nyuszika7h
6

Rubí

Esta es (creo) la primera respuesta que funciona para 666666666. (Excepto la trampa restando -1 respuesta.)

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

Tengo prisa ahora; La explicación se agregará más tarde.

Actualización : versión mucho más eficiente (tiempo de ejecución casi constante, creo):

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
Pomo de la puerta
fuente
En realidad, mi respuesta funciona bien para 666666666.
isaacg
El tiempo de ejecución constante es imposible. Incluso comprobar si existe un "666" es un problema lineal. Este es un problema estrictamente más difícil que eso.
Cruncher
4

Potencia Shell

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

J

Finalmente, un buen uso para E.!

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

En esencia, encontramos la primera posición en la que el argumento tiene una posición completa 666, y reemplazamos esa subcadena y todo lo posterior con 66700000...hasta el final.

Explicado en detalle:

  • ":@>: - Incrementar en uno y convertir a cadena.
  • '666'&E. - Haga un vector de booleanos, verdadero en cada lugar que '666' comience en la cadena.
  • i.1: - Encuentra el índice del primer verdadero en el vector, de lo contrario, devuelve la longitud del vector.
  • #@[-]- Longitud de la cadena (que también es la longitud del vector) menos el resultado de i..
  • '667'{.!.'0'~ - Tome una subcadena de '667' con una longitud de ese resultado, rellenando a la derecha con '0' si es necesario.
  • {.~- Tome una subcadena con la longitud del resultado original de i..
  • , - Agregar los dos juntos.

En 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

Y dado que este no es un código de golf, no es necesario jugar golf con optimizaciones locas. ¡Todos ganan!

Algoritmo de tiburón
fuente
3

C#

148 137 caracteres

Pude eliminar algunos caracteres gracias 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'));}

Sin golf:

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

Violín: http://dotnetfiddle.net/XB83bf

Molesto
fuente
1
Los corchetes en su expresión regular son innecesarios, y también hay muchos espacios sintácticamente innecesarios.
recursivo el
Ah, y Int32puede ser reemplazado por int.
recursivo
@recursivo Tienes razón, ¡gracias!
Intentando
Tenga en cuenta que este es un concurso de popularidad y no un código de golf . Una vez dicho esto, si sientes que afeitarte a los personajes hará que tu respuesta sea más popular, ¡entonces adelante!
Trauma digital
2
Primero he visto de dotnetfiddle.net =) ¡IMPRESIONANTE!
Coops
2

Pitón

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)
isaacg
fuente
2

Perl

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

Código en línea que cambia el contenido dentro $_, una ideología bastante estándar en perl. Se puede usar junto con una -pbandera como esta:

$ perl -p % <<< 66666
66700
mniip
fuente
2

J

Sin cadenas, bucles o condicionales:

   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

De manera similar a la solución de cartón_box, esto separa el número en grupos de tres dígitos dividiéndolo por potencias de diez. Utiliza el índice de la primera aparición de 666 para redondear el número adecuadamente.

grc
fuente
2

Haskell (70 caracteres)

Aquí hay una implementación simple en 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 []         = []
  • En primer lugar, se utiliza map digitToInt . showpara convertir una identificación posiblemente malvada en una lista de dígitos.
  • A continuación, purgecoincide con el patrón malvado y lo reemplaza por su buen equivalente.
  • Finalmente, foldl' ((+).(*10)) 0reduce la lista de dígitos a uno Integer.

¡A ver si 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

Se ve bien. Y solo por diversión, una versión de golf.

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

Java

¿No es suficiente hacer esto?

private static int nextId(int currentId) {
    String currentIdStr = String.valueOf(currentId);
    return currentIdStr.contains("666") ? Integer.parseInt(currentIdStr.replace("666", "667")) : ++currentId;
}
Valentin Grégoire
fuente
Cerca, pero eso debería ser String.valueOf(currentId + 1).
nyuszika7h
Oh cierto, olvidé esa cosa +1! : D
Valentin Grégoire
Ese condicional es inútil; la solución original ligeramente modificada por mi sugerencia también funcionará:return Integer.parseInt(String.valueOf(currentId + 1).replace("666", "667"));
nyuszika7h
1
No es cierto ... 66600 se devolvería como 66701, que es 1 demasiado alto.
Valentin Grégoire
1

R

Sustitución de 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
djhurio
fuente
1

3 respuestas diferentes de JavaScript:

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)

Convierte el número en una cadena, luego itera sobre cada carácter hasta que encuentra y 666luego cambia lo último 6a 7ay genera 0los siguientes caracteres.

2. JavaScript (borrador de ECMAScript 6)

Función recursiva sin manipulación de cadenas:

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

O más detalladamente:

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

Pruebas:

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

3. JavaScript

Usando expresiones regulares:

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

O (lo mismo pero usando ECMAScript 6)

h=x=>(""+(x+1)).replace(/^(.*?)(666)(.*)$/,(a,b,c,d)=>b+667+d.replace(/./g,0))*1
MT0
fuente
Con su primera versión, si ingresa 6 septillones, 666 sextillones obtendrá un valor de retorno de 6.667modo que técnicamente todavía está allí. Sin embargo, no creo que se pueda evitar.
Spedwards
1e20es el orden de magnitud más grande que JavaScript (al menos en Firefox) imprimirá como un entero sin recurrir a la notación 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_

da

2
667
667000000
667000000
66700

editar: segunda solución

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_

rendimientos

2
667
667000000
667000000
66700
1236670
mschilli
fuente
1
lo cual no parece ser respuestas correctas. 665 debería dar 667, 66600 debería dar 66700, etc.
ace_HongKongIndependence
1
Sus resultados contienen muchas subcadenas "666".
Glenn Randers-Pehrson
Eso es vergonzoso. Arreglé los 2 (!) Cercas-errores posteriores que cometí porque olvidé que awkindexa cadenas basadas en 1.
mschilli
@Cruncher Como se indicó explícitamente en la pregunta, f(665) returns 667ya que pide "el próximo entero que no incluye 666"
ace_HongKongIndependence
Agregué una segunda forma que es a) más awkish yb) minimiza el uso de funciones de cadena.
mschilli
0

Pitón:

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

O:

 f=lambda b:int(`b+1`.replace('666','667'))
ɐɔıʇǝɥʇuʎs
fuente
No veo cómo funciona eso. ¿No se convertiría eso 666666en 667667lugar de 667000?
Martin Ender
@ m.buettner Buen punto, creo que ya tengo una solución.
Aprıʇǝɥʇuʎs
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 la función recursiva para encontrar el 666 más a la izquierda y calcular cuánto ajustar el número al volver a abrir la pila de llamadas.

Roger Lindsjö
fuente
No creo que este código sea correcto. ¿Qué resultado da para la entrada 666666666?
algorithmshark
Tiene razón, no se dio cuenta de que la entrada ya podría contener números malvados. Entonces f (666666666) -> 667667667?
Roger Lindsjö
f(666666666) -> 667000000
djhurio
@djhurio parece que no puedo generar pruebas para casos extremos hoy. Creo que lo tengo arreglado ahora, pero el código ya no es tan corto.
Roger Lindsjö
1
@ RogerLindsjö Esto es un popularity-contest, no un code-golf.
nyuszika7h
0

Lote

Manipulación de cadena iterada simple.

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

Comienza en los primeros tres caracteres del número (como una cadena) y avanza hasta el final hasta que encuentra 666, luego reemplaza ese 666 con 667 y recorre la longitud de la cadena agregando ceros.

Todos los casos de prueba producen los resultados correctos.

carne sin carne
fuente
0

perl, 45 bytes

Una expresión regular única con la bandera / e hace todo el trabajo aquí:

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

SQL

Para ser precisos, 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
Caminante de piedra verde
fuente
0

Pitón

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)
Οurous
fuente
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
Comerciante de leche
fuente
0

C#

Lo estoy haciendo bien

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

En acción:

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 
SeanC
fuente
0

C ++

Sé que esto no es código golf, pero (a) algunas personas han sugerido que es un buen desafío de golf, y (b) esta es mi primera respuesta de desafío / golf, pensé que sería divertido, y si lo hago esto aquí no me aparece en un desafío de golf real por ser un golfista terrible. X)

Básicamente, reemplazar '666' por '667' funciona si lo hace por primera vez en el número y luego escribe ceros al final.

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

Sin golf:

#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;
}
mike32
fuente
Creo que no necesitas x+=c=='6'?1:0, puedes salirte con la tuya x+=c=='6'. Sin embargo, no lo he probado.
nyuszika7h
Además, omitiste el std::antes stringstream. No se compila sin eso.
nyuszika7h
Agregado std ::, gracias por eso @ nyuszika7h. Cometí el error de usar un IDE que autogeneraba 'usando el espacio de nombres estándar'; . probarlo en -_- Voy a tratar la x+=c=='6'reducción, así como el cuidado en hacer esto con los dígitos int en lugar de caracteres sstream ...
mike32
0

Rubí

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
tu cara
fuente
0

perl, 36 solo un sub, sin bytes

Una versión más corta que mi última solución, usando una combinación de operaciones aritméticas y expresiones regulares.

sub{($_[0]+1)=~s/666(.*)/667$1/r-$1}
skibrianski
fuente
print + (<> + 1) = ~ s / 666 (. *) / 667 $ 1 / r- $ 1 (le guardó un byte) (dos más si usa say) - aunque la solicitud fue para una función, así que elimine print + y use sub {...}
Altreus
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, no hay verificación de límites y demasiado espacio en blanco, pero no es golf. También un poco divertido de formateo en "while (d -> 0)".

Alquimista
fuente