Evita i numeri cattivi! [chiuso]


53

Stai sviluppando del codice per generare numeri ID. La politica richiede che nessun numero ID includa la sequenza di cifre 666 .

Crea una funzione (o l'equivalente della tua lingua) che accetta un parametro intero positivo e restituisce il numero intero successivo che non include 666 quando tale numero intero è espresso in decimali. (60606 va bene, 66600 no.)

Il codice non deve utilizzare un ciclo che ne aggiunge uno fino a quando non trova un risultato adatto alle regole.

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.

AGGIORNAMENTO: la
sostituzione di 666 con 667 non funzionerà se c'è più di un 666 nell'input.


1
Che ne dici di qualcosa come 456667? Dovrebbe tornare 456670, o siamo solo preoccupati per un 666 leader?
Kyle Kanos,

11
Penso che questo sarebbe meglio come code-golf che concorso di popolarità poiché ci sono soluzioni così semplici.
Nate Eldredge,

10
@ nyuszika7h ma il risultato dovrebbe essere 66700.
Martin Ender,

3
come una vera sfida, avrebbe dovuto esserci anche l'obbligo di non avere "666" in nessun punto del codice
DLeh

2
A seconda dell'implementazione di regex, è possibile utilizzare '6 {3}' per rilevare 666.
celtschk,

Risposte:


53

Python, nessuna manipolazione di stringhe

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

Opere di trovare potenze di 10, pdove 666 appare, e aggiungendo p - n % pa nche sostituisce 666xxxxxcon 66700000.


6
Mi piace il fatto che se questo fosse effettivamente un reale requisito del cliente, questa implementazione è non complicata, ragionevole ed efficiente.
Roman,

Funzionerà con numeri che contengono più istanze di 666?
supercat

Sì. Il 666 più a sinistra è l'unico che conta davvero, e questo algoritmo lo risolve per ultimo.
cardboard_box

19
@romkyns Pubblica un reale reale requisito del cliente per codegolf per indurre altre persone a fare il loro lavoro per loro? Questo è male! ( nasconde )
billpg

3
Per tutti coloro che usano python 3: questo codice non funziona su python 3+, per eseguire questo codice su python 3 è necessario passare m /= 10a m //= 10. Altrimenti m diventerà un float e la condizione m % 1000 == 666sarà continuamente falsa e gli altri "666" in n rimarranno invariati.
Sirac,

50

JavaScript (aggiornato per funzionare con tutti i casi di test)

La verità poco nota è che in realtà ci sono quattro 6secondi, ma uno dei traditi è l'altro e polimorfizzato in forma di codice per sradicarli dalle cifre del mondo dei numeri. Ecco quel sei traditore:

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

Ecco una spiegazione Innanzitutto, abbellisci il codice e rimuovi elementi inutili come ''+'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)
);

Converti strane notazioni (come ~indexOfe ['replace']) in più comuni:

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 ora capisci semplicemente che l'algoritmo va così:

  • Se c'è già un 666 nell'input,

    • sostituirlo con un 667.
    • sostituire ogni cifra successiva con uno 0.
  • altro,

    • aggiungine uno al numero.
    • NOTA: ora ci viene garantito che non ci sono 666, 666 alla fine della stringa o 666 da qualche altra parte che ha già zero che vanno alla fine (pensa "portando" quando fai l'aggiunta "manuale").
    • se c'è un 666, sostituiscilo con un 667.

Vecchia versione (non funziona per 666666666) :

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

Per capirlo, prima abbelliamolo:

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

Ora rimuoviamo cose inutili come '' + stringe 'str' + 'ing', rimuoviamo la svariabile non necessaria e cambiamo le stranezze come -~![]in 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,'')è semplicemente "length":

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

Ed "undefined"[0]è "u"ed "u".lengthè 1:

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

Adesso abbiamo finito! Dovrebbe essere abbastanza facile da capire ora.


13
Mi piace la tua risposta ma non ci riesce666666666
Michael M.

3
@Michael Aggiunta nuova versione! Funziona per 666666666, e il carattere di 6è più elaborato;)
Maniglia della porta

1
Huh - usare ~1per != -1è piuttosto bello.
wchargin,

@WChargin Peccato che non funziona in LiveScript. So che questo non è codice golf ma ho una versione giocata a golf nel mio post per divertimento.
nyuszika7h

Funziona in LiveScript :). ~a.indexOf('b')genera il JS corretto, provalo su livescript.net!
Ven

20

Applescript

Questo sito non ha abbastanza risposte su Applescript. Consente di bandire alcuni demoni!

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)

Uscita registro:

(* 667 *)
(* 66.700.000 *)
(* 1.266.700 *)
(* 1213 *)

Avrei voluto ottenere alcune delle citazioni più potenti da The Exorcist in questo, ma ciò avrebbe reso questo post decisamente NSFW. Puoi invece leggere la pagina IMDB.


Come si esegue questo senza avere OS X?
nyuszika7h

Penso che Applescript dipenda in gran parte da OSX stackoverflow.com/questions/7642299/… - Non sono a conoscenza di porte su altre piattaforme. OS 9 ha fatto avere una versione di AppleScript, anche se non ci sono garanzie che questo script sarebbe correre lì.
Trauma digitale

2
Avrebbe reso il post Not For Safe Work? Accidenti, il mio lavoro non è pericoloso
Cruncher,

1
@Cruncher oops ;-)
Digital Trauma

1
+1 per la scelta dei nomi delle variabili (e perché lo script di apple è interessante).
Floris,

15

Perl

Hai detto che non dobbiamo incrementare in un ciclo. Non sto usando alcun operatore matematico! Ecco un approccio di sostituzione regex puro (nessuna garanzia è sicura per la tua sanità mentale).

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

Le prime tre sostituzioni incrementano il numero di uno. Una volta ho risolto il problema da solo, ma includeva una sostituzione che doveva essere interrotta fino a quando non venivano fatte più sostituzioni, quindi ho usato invece l' approccio di Andrew Cheong .

La quarta sostituzione trasforma tutte le cifre che seguono a 666in zeri. La sostituzione finale trasforma il rimanente 666in a 667.

Come bonus funzionerà con più numeri interi nell'input, purché siano separati da caratteri non numerici.


8

LiveScript

Questo sta piegando le regole. Vedi, hai detto che non devo usare un ciclo che ne aggiunge uno finché non trova un risultato corretto. Quindi sottraggo meno uno !

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

Una versione giocata a golf in 53 48 45 byte per divertimento:

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

Grazie a user1737909 per aiutare a golf ulteriormente.

test

Richiede Node.js con il LiveScriptmodulo npm o una libreria di asserzioni compatibile.

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
Fallirà in modo orribile quando arriverai a 665999, poiché il tuo stack esploderà.
TimWolla,

9
Molto intelligente. Dovresti scrivere RFC per individuare scappatoie del genere.
billpg

1
@TimWolla È interessante. Come l'hai trovato?
nyuszika7h

1
@ nyuszika7h: se ci pensate, 666000 attraverso 666999 falliranno tutti ... ricorrete almeno 1000 volte.
Andrew Coonce,

1
Non ho un motivo particolare, immagino.
nyuszika7h

6

Rubino

Questa è (penso) la prima risposta che funziona per 666666666. (Tranne la sottrattiva sottrazione -1 risposta.;))

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

Ho fretta adesso; la spiegazione verrà aggiunta in seguito.

Aggiornamento : versione molto più efficiente (credo che il runtime sia quasi costante):

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

In realtà, la mia risposta funziona benissimo per 666666666.
Isaacg

Il runtime costante è impossibile. Anche verificare l'esistenza di un "666" è un problema lineare. Questo è un problema strettamente più difficile di così.
Cruncher,

4

PowerShell

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

4

J

Finalmente un buon uso per E.!

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

In sostanza, troviamo la prima posizione in cui l'argomento ha un pieno 666e sostituiamo quella sottostringa e tutto il resto con 66700000...fino alla fine.

Spiegato in dettaglio:

  • ":@>: - Incrementa di uno e converti in stringa.
  • '666'&E. - Crea un vettore di booleani, vero in ogni punto in cui "666" inizia nella stringa.
  • i.1: - Trova l'indice del primo vero nel vettore, altrimenti restituisce la lunghezza del vettore.
  • #@[-]- Lunghezza della stringa (che è anche la lunghezza del vettore) meno il risultato di i..
  • '667'{.!.'0'~ - Prendi una sottostringa di '667' con una lunghezza di quel risultato, imbottitura a destra con '0' se necessario.
  • {.~- Prendi una sottostringa con la lunghezza del risultato originale da i..
  • , - Aggiungi i due insieme.

In 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 dal momento che questo non è un codice golf, questo non deve essere portato all'inferno con ottimizzazioni folli. Tutti vincono!


3

C #

148 137 caratteri

È stato in grado di radere alcuni caratteri grazie 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


1
Le parentesi quadre nella tua regex non sono necessarie e ci sono anche molti spazi sintatticamente inutili.
ricorsivo il

Oh, e Int32può essere sostituito con int.
ricorsivo il

@recursive Hai ragione, grazie!
Prova il

Nota che questo è un concorso di popolarità e non di golf di codice . Detto questo, se ti senti rasare i personaggi renderai la tua risposta più popolare, quindi provaci!
Trauma digitale

2
Prima ho visto dotnetfiddle.net =) INCREDIBILE!
Coops il

2

Pitone

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

Codice inline che modifica il contenuto all'interno $_, un'ideologia piuttosto standard in perl. Può essere utilizzato insieme a -pflag in questo modo:

$ perl -p % <<< 66666
66700

2

J

Nessuna stringa, loop o condizionali:

   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

Analogamente alla soluzione di box_box, questo separa il numero in gruppi di tre cifre dividendo per potenze di dieci. Utilizza l'indice della prima occorrenza di 666 per arrotondare il numero in modo appropriato.


2

Haskell (70 caratteri)

Ecco una semplice implementazione 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 []         = []
  • In primo luogo, utilizza map digitToInt . showper convertire un ID eventualmente malvagio in un elenco di cifre.
  • Successivamente, purgeabbina il modello malvagio e lo sostituisce con il suo equivalente buono.
  • Infine, foldl' ((+).(*10)) 0riduce l'elenco delle cifre a una Integer.

Vediamo se funziona!

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

Sembra buono. E solo per divertimento una versione da golf.

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

1

Giava

Non è abbastanza per farlo?

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

Chiudi, ma dovrebbe essere String.valueOf(currentId + 1).
nyuszika7h

Oh giusto, ho dimenticato quel +1! : D
Valentin Grégoire,

Quel condizionale è inutile; funzionerà anche la soluzione originale leggermente modificata secondo il mio suggerimento:return Integer.parseInt(String.valueOf(currentId + 1).replace("666", "667"));
nyuszika7h

1
Non vero ... 66600 verrebbe restituito come 66701, che è 1 troppo alto.
Valentin Grégoire,

1

R

Sostituendo 666 con 667 opere.

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

risultati

> 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 diverse risposte 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)

Converte il numero in una stringa, quindi scorre ogni carattere fino a quando non trova, 666quindi cambia quello che dura 6in a 7e viene emesso 0per tutti i caratteri seguenti.

2. JavaScript (bozza ECMAScript 6)

Funzione ricorsiva senza manipolazione di stringhe:

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 più verbalmente:

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

test:

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

3. JavaScript

Usando le espressioni regolari:

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

Oppure (lo stesso ma usando ECMAScript 6)

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

Con la tua prima versione, se inserisci 6 settilioni, 666 sextillion otterrai un valore di ritorno di 6.667così tecnicamente che è ancora lì. Non pensare che possa essere aiutato però.
Spedwards

1e20è circa il più grande ordine di grandezza che JavaScript (almeno in FireFox) stamperà come intero senza ricorrere alla notazione scientifica.
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

modifica: seconda soluzione

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_

i rendimenti

2
667
667000000
667000000
66700
1236670

1
che non sembra essere una risposta corretta. 665 dovrebbe dare 667, 66600 dovrebbe dare 66700 ecc.
ace_HongKongIndipendenza

1
I risultati contengono molte sottostringhe "666".
Glenn Randers-Pehrson,

Questo è imbarazzante. Ho corretto i 2 (!) Errori post-fence che ho fatto perché ho dimenticato che awkindicizza le stringhe in base 1.
mschilli,

@Cruncher Come esplicitamente affermato nella domanda, f(665) returns 667in quanto chiede "il prossimo numero intero che non include 666"
ace_HongKongIndependence

Ho aggiunto un secondo modo che è a) più awkish eb) minimizza l'uso delle funzioni di stringa.
mschilli,

0

Pitone:

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

Non vedo come funziona. Non si trasformerebbe 666666in 667667invece di 667000?
Martin Ender,

@ m.buettner Un buon punto, penso di avere già una soluzione.
Aprıʇǝɥʇuʎs

0

Giava

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

Utilizzando la funzione ricorsiva per trovare 666 all'estrema sinistra e calcolare quanto regolare il numero quando si fa scattare di nuovo lo stack di chiamate.


Non penso che questo codice sia corretto. Quale risultato fornisce per l'ingresso 666666666?
algoritmo

Hai ragione, non avevo capito che l'input poteva già contenere numeri Evil. Quindi f (666666666) -> 667667667?
Roger Lindsjö,

f(666666666) -> 667000000
djhurio,

@djhurio Sembra che non riesca a generare test per casi limite oggi. Credo di averlo corretto ora, ma il codice non è più così breve.
Roger Lindsjö,

1
@ RogerLindsjö Questo è un popularity-contest, non un code-golf.
nyuszika7h

0

Lotto

Manipolazione di stringhe iterata semplice.

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

Inizia dai primi tre caratteri del numero (come una stringa), e arriva fino alla fine fino a quando non trova 666, quindi sostituisce quel 666 con 667 e si sposta alla lunghezza della stringa aggiungendo zeri.

Tutti i casi di test producono i risultati corretti.


0

perl, 45 byte

Un unico regex con il flag / e fa tutto il lavoro qui:

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

0

SQL

Per essere precisi, 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

Pitone

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

Risultati 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 #

Lo sto facendo bene

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

In azione:

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

risultato:

2 
667 
667000000 
667000000 
66700 
456670 

0

C ++

So che questo non è code-golf, ma (a) alcune persone hanno suggerito che è una buona sfida di golf, e (b) questa è la mia prima sfida / risposta golf, ho pensato che sarebbe stato divertente, e se lo facessi questo qui non mi viene mostrato in una vera sfida di golf per essere un terribile giocatore di golf. X)

Fondamentalmente, sostituito '666' con '667' funziona se lo si fa per la prima istanza nel numero e quindi si scrivono gli 0 finali.

Golfato ( 175 155 caratteri):

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

Penso che non ti serva x+=c=='6'?1:0, puoi cavartela x+=c=='6'. Non l'ho provato, però.
nyuszika7h,

Inoltre, hai lasciato fuori il std::prima stringstream. Non si compila senza quello.
nyuszika7h,

Aggiunto std ::, grazie per quello @ nyuszika7h. Ho fatto l'errore di usare un IDE che generava automaticamente "usando lo spazio dei nomi std;" per provarlo. -_- Proverò la x+=c=='6'riduzione, oltre a guardare a questo con cifre int piuttosto che caratteri a valle ...
mike32

0

Rubino

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 solo un sub, nessun byte

Una versione più breve della mia ultima soluzione, usando un mix di operazioni aritmetiche e regex.

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

print + (<> + 1) = ~ s / 666 (. *) / 667 $ 1 / r- $ 1 (ti ha salvato un byte) (altri due se usi dire) - sebbene la richiesta fosse per una funzione quindi rimuovi print + e usa 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 - nessun controllo dei limiti e spazio bianco troppo ma non è golf. Anche un po 'divertente di formattazione in "while (d -> 0)".

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.