Évitez les entiers maléfiques! [fermé]

53

Vous développez du code pour générer des numéros d'identification. La politique exige qu'aucun numéro d'identification n'inclue la séquence de chiffres 666 .

Créez une fonction (ou l'équivalent de votre langue) qui prend un paramètre entier positif et retourne le prochain entier qui n'inclut pas 666 lorsque cet entier est exprimé en décimal. (60606 va bien, 66600 ne va pas.)

Votre code ne doit pas utiliser une boucle qui en ajoute une jusqu'à ce qu'il trouve un résultat conforme aux règles.

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: Le
remplacement de 666 par 667 ne fonctionnera pas s'il y a plus d'un 666 dans l'entrée.

billpg
la source
1
Qu'en est-il quelque chose comme 456667? Devrait-on renvoyer 456670, ou sommes-nous inquiets seulement d'un leader 666?
Kyle Kanos
11
Je pense que ce serait mieux en tant que code-golf que concours-popularité car il existe de telles solutions simples.
Nate Eldredge
10
@ nyuszika7h mais le résultat devrait être 66700.
Martin Ender
3
comme un véritable défi, il aurait également dû
exister l'
2
En fonction de votre implémentation regex, vous pouvez utiliser '6 {3}' pour détecter 666.
celtschk

Réponses:

53

Python, pas de manipulation de chaîne

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

Fonctionne en recherchant des puissances de 10 p,, où 666 apparaît et en ajoutant p - n % pà nqui remplace 666xxxxxpar 66700000.

boîte en carton
la source
6
Je aime ce en ce que si cela était en fait une réelle exigence de client, cette mise en œuvre est non-aki, sensible et efficace.
RomanSt
Cela fonctionnera-t-il avec des nombres contenant plusieurs instances de 666?
Supercat
Oui. Le 666 le plus à gauche est le seul qui compte réellement, et cet algorithme corrige ce dernier.
cardboard_box
19
@romkyns Publiez une demande réelle de client auprès de codegolf pour amener d'autres personnes à faire leur travail pour elles? C'est mal! ( peaux )
billpg
3
Pour tous ceux qui utilisent Python 3: Ce code ne fonctionne pas sur Python 3+, pour exécuter ce code sur Python 3, vous devez passer m /= 10à m //= 10. Si vous ne le faites pas, m deviendra un float et la condition m % 1000 == 666sera continuellement fausse et les autres "666" dans n resteront inchangés.
Sirac
50

JavaScript (mis à jour pour fonctionner avec tous les cas de test)

La vérité peu connue, c’est qu’il ya en fait quatre 6, mais l’un des trahis a été trahi et il a été transformé en code pour les éradiquer des chiffres du monde . Voici ces six traîtres:

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

Voici une explication. Tout d’abord, embellissez le code et supprimez les éléments inutiles tels que ''+'string'et ((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)
);

Convertissez les notations étranges (comme ~indexOfet ['replace']) en notations plus courantes:

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

Et maintenant, comprenez simplement que l’algorithme va comme ceci:

  • S'il y a déjà un 666 dans l'entrée,

    • remplacez-le par un 667.
    • remplacez chaque chiffre après cela par un 0.
  • autre,

    • ajouter un au nombre.
    • NOTE: nous sommes maintenant assurés d’avoir soit pas de 666, un 666 à la fin de la chaîne, soit un 666 quelque part qui a déjà des zéros allant à la fin (pensez "porter" lors de l’ajout "manuel").
    • s'il y a un 666, remplacez-le par un 667.

Ancienne version (ne fonctionne pas pour 666666666) :

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

Pour le comprendre, commençons par l'embellir:

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

Maintenant , nous allons supprimer les choses inutiles comme '' + stringet 'str' + 'ing', supprimer la inutile svariable et changement bizarreries comme -~![]dans 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,'')est simplement "length":

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

Et "undefined"[0]est "u"et "u".lengthest 1:

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

Maintenant nous avons fini! Cela devrait être assez facile à comprendre maintenant.

Poignée de porte
la source
13
J'aime votre réponse mais elle échoue pour666666666
Michael M.
3
@Michael Ajouté une nouvelle version! Fonctionne pour 666666666, et la police de caractères 6est la plus chère;)
Poignée de porte
1
Huh - utiliser ~1pour != -1c'est plutôt cool.
wchargin
@WChargin Dommage que cela ne fonctionne pas dans LiveScript. Je sais que ce n'est pas du code golf mais j'ai une version golfée dans mon post pour le plaisir.
Nyuszika7h
Cela fonctionne dans LiveScript :). ~a.indexOf('b')génère le bon JS, essayez-le sur livescript.net!
Ven
20

Applescript

Ce site n'a pas assez de réponses Applescript. Permet de bannir certains démons!

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)

Journal de sortie:

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

J'avais envie de citer quelques-unes des citations les plus puissantes de The Exorcist , mais cela aurait certainement rendu ce post affiché sur NSFW. Vous pouvez lire la page IMDB à la place.

Trauma numérique
la source
Comment faites-vous cela sans avoir OS X?
Nyuszika7h
Je pense qu'Applescript est à peu près dépendant d'OSX stackoverflow.com/questions/7642299/ ... Je ne connais aucun port vers d'autres plates-formes. OS 9 avait une version d'Applescript, bien que rien ne garantisse que ce script serait exécuté là-bas.
Digital Trauma
2
Il aurait fait le post Not For Safe Work? Bon sang, mon travail n'est pas dangereux
Cruncher
1
@Cruncher oops ;-)
Digital Trauma
1
+1 pour le choix des noms de variables (et parce que le script Apple est cool).
Floris
15

Perl

Vous avez dit que nous ne devons pas incrémenter dans une boucle. Je n'utilise aucun opérateur mathématique du tout! Voici une approche de substitution purement rationnelle (rien ne garantit que votre santé mentale sera sans danger).

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

Les trois premières substitutions incrémentent le nombre d'un. J'ai déjà résolu ce problème moi-même une fois, mais cela incluait une substitution qui devait être bouclée jusqu'à ce qu'aucune autre substitution ne soit faite. J'ai donc utilisé l'approche d'Andrew Cheong à la place.

La quatrième substitution transforme tous les chiffres qui suivent un 666en zéros. La substitution finale transforme le reste 666en a 667.

En prime, cela fonctionnera avec plusieurs nombres entiers dans l'entrée, à condition qu'ils soient séparés par des caractères non numériques.

Martin Ender
la source
8

LiveScript

C'est plier les règles. Vous voyez, vous avez dit que je ne devais pas utiliser une boucle qui en ajoute une jusqu'à ce qu'elle trouve un résultat correct. Donc, je soustrais moins un à la place!

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

Une version de golf dans 53 48 45 octets pour le plaisir:

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

Merci à user1737909 pour l’avoir aidé à jouer au golf.

Des tests

Requiert Node.js avec le LiveScriptmodule npm ou une bibliothèque d'assert 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
la source
5
Cela va échouer horriblement quand vous arriverez à 665999, car votre pile va exploser.
TimWolla
9
Très intelligent. Vous devriez écrire des RFC pour repérer de telles failles.
billpg
1
@ Timwolla C'est intéressant. Comment as tu trouvé ça?
nyuszika7h
1
@ nyuszika7h: Si vous y réfléchissez, les échecs de 666000 à 666999 échoueront ... vous serez récursif au moins 1000 fois.
Andrew Coonce
1
Je n'ai pas de raison particulière, je suppose.
nyuszika7h
6

Rubis

C’est (je pense) la première réponse qui marche pour 666666666. (À l’exception de la soustraction cheaty -1 réponse;;))

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

Je suis pressé maintenant; l'explication sera ajoutée plus tard.

Mise à jour : version beaucoup plus efficace (durée d'exécution presque constante, je crois):

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
Poignée de porte
la source
En fait, ma réponse fonctionne très bien pour 666666666.
isaacg
Une exécution constante est impossible. Même vérifier si un "666" existe est un problème linéaire. C'est un problème strictement plus difficile que cela.
Cruncher
4

PowerShell

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

J

Enfin, un bon usage pour E.!

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

Essentiellement, nous trouvons la première position dans laquelle l'argument a une valeur complète 666, et nous remplaçons cette sous-chaîne et tout ce qui suit par 66700000...jusqu'à la fin.

Expliqué en détail:

  • ":@>: - Incrémenter de un et convertir en chaîne.
  • '666'&E. - Créez un vecteur de booléens, vrai à chaque endroit qui commence par «666» dans la chaîne.
  • i.1: - Trouver l'index du premier vrai dans le vecteur, sinon renvoyer la longueur du vecteur.
  • #@[-]- Longueur de la chaîne (qui est aussi la longueur du vecteur) moins le résultat de i..
  • '667'{.!.'0'~ - Prenez une sous-chaîne de '667' avec une longueur de ce résultat, en complétant à droite par '0' si nécessaire.
  • {.~- Prenez une sous-chaîne avec la longueur du résultat original de i..
  • , - Ajouter les deux ensemble.

Utilisé:

   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

Et comme il ne s’agit pas d’un code de golf, il n’est pas nécessaire de jouer au golf avec des optimisations loufoques. Tout le monde gagne!

algorithmeshark
la source
3

C #

148 137 caractères

A été capable de raser quelques caractères grâce à @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')); 
}

Violon: http://dotnetfiddle.net/XB83bf

En essayant
la source
1
Les crochets dans votre expression rationnelle sont inutiles et il existe également de nombreux espaces syntaxiquement inutiles.
récursive
Oh, et Int32peut être remplacé par int.
récursive
@recursive Vous avez raison, merci!
Essayer le
Notez qu'il s'agit d'un concours de popularité et non de code-golf . Cela dit, si vous pensez que le fait de raser des personnages rendra votre réponse plus populaire, alors foncez!
Digital Trauma
2
J'ai d'abord vu de dotnetfiddle.net =) IMPRESSIONNANT!
Coops
2

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)
isaacg
la source
2

Perl

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

Code en ligne qui modifie le contenu à l'intérieur $_, une idéologie assez standard en Perl. Peut être utilisé avec un -pdrapeau comme ceci:

$ perl -p % <<< 66666
66700
mniip
la source
2

J

Aucune ficelle, boucle ou conditionnel:

   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 la même manière que la solution de cardboard_box, cela divise le nombre en groupes de trois chiffres en divisant par dix. Il utilise l'indice de la première occurrence de 666 pour arrondir le nombre correctement.

grc
la source
2

Haskell (70 caractères)

Voici une implémentation 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 []         = []
  • Premièrement, il map digitToInt . showconvertit un identifiant éventuellement diabolique en une liste de chiffres.
  • Ensuite, purgecorrespond au modèle pervers et le remplace par son bon équivalent.
  • Enfin, foldl' ((+).(*10)) 0réduit la liste des chiffres à un Integer.

Voyons si ça marche!

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

Cela semble bon. Et juste pour le plaisir une version golfée.

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

Java

N'est-ce pas suffisant de faire ça?

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
la source
Fermer, mais ça devrait être String.valueOf(currentId + 1).
Nyuszika7h
Oh oui, j'ai oublié ce +1 truc! : D
Valentin Grégoire
Ce conditionnel est inutile. la solution originale légèrement modifiée selon ma suggestion fonctionnera aussi:return Integer.parseInt(String.valueOf(currentId + 1).replace("666", "667"));
nyuszika7h
1
Pas vrai ... 66600 serait retourné comme 66701, ce qui est 1 trop élevé.
Valentin Grégoire
1

R

Remplacement de 666 par 667 œuvres.

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

Résultats

> 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
la source
1

3 réponses JavaScript différentes:

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)

Convertit le nombre à une chaîne itère ensuite sur chaque caractère jusqu'à ce qu'il trouve 666alors il change cette dernière 6à un 7et les sorties 0pour tous les caractères suivants.

2. JavaScript (projet ECMAScript 6)

Fonction récursive sans manipulation de chaîne:

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 plus verbalement:

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

En utilisant des expressions régulières:

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

Ou (le même mais en utilisant ECMAScript 6)

h=x=>(""+(x+1)).replace(/^(.*?)(666)(.*)$/,(a,b,c,d)=>b+667+d.replace(/./g,0))*1
MT0
la source
Avec votre première version, si vous entrez 6 septillions, 666 sextillions, vous obtenez une valeur de retour 6.667tellement techniquement, elle est toujours là. Ne pensez pas que cela puisse être aidé cependant.
Spedwards
1e20est à peu près le plus grand ordre de grandeur que JavaScript (du moins dans FireFox) imprimera sous forme d’entier sans recourir à la notation scientifique.
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_

donne

2
667
667000000
667000000
66700

edit: 2ème 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_

les rendements

2
667
667000000
667000000
66700
1236670
mschilli
la source
1
qui ne semble pas être des réponses correctes. 665 devrait donner 667, 66600 devrait donner 66700 etc.
ace_HongKongIndependence
1
Vos résultats contiennent beaucoup de "666" sous-chaînes.
Glenn Randers-Pehrson
C'est embarrassant. J'ai corrigé les 2 (!) Erreurs post-clôture que j'ai faites parce que j'avais oublié que awkles chaînes basées sur 1 indexaient.
mschilli
@Cruncher Comme explicitement indiqué dans la question, f(665) returns 667il demande "le prochain nombre entier ne comprenant pas 666"
ace_HongKongIndependence
J'ai ajouté une deuxième manière qui est a) plus awkish et b) minimise l'utilisation de fonctions de chaîne.
mschilli
0

Python:

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'))
ıʇǝɥʇuʎs
la source
Je ne vois pas comment ça marche. Cela ne deviendrait-il pas 666666au 667667lieu de 667000?
Martin Ender
@ m.buettner Bon point, je pense avoir déjà une solution.
Samedi,
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
    }
}

Utilisation de la fonction récursive pour trouver le 666 le plus à gauche et calculer le montant à ajuster lors de la reprise de la pile d’appels.

Roger Lindsjö
la source
Je ne pense pas que ce code est correct. Quel résultat donne-t-il pour l'entrée 666666666?
algorithmshark
Vous avez raison, vous n'avez pas réalisé que l'entrée pouvait déjà contenir des nombres maléfiques. Donc, f (666666666) -> 667667667?
Roger Lindsjö
f(666666666) -> 667000000
Djhurio
@djhurio semble que je ne peux pas générer de tests pour les cas extrêmes aujourd'hui. Croyez-le corrigé maintenant, mais le code n’est plus aussi bref.
Roger Lindsjö
1
@ RogerLindsjö Ceci est un popularity-contest, pas un code-golf.
Nyuszika7h
0

Lot

Manipulation simple de chaîne itérée.

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

Il commence aux trois premiers caractères du nombre (sous forme de chaîne) et continue jusqu'à la fin jusqu'à ce qu'il trouve 666, il remplace ensuite 666 par 667 et boucle à la longueur de la chaîne ajoutant des zéros.

Les cas de test produisent tous les résultats corrects.

dépouiller
la source
0

perl, 45 octets

Une seule expression rationnelle avec le drapeau / e fait tout le travail ici:

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

SQL

Pour être précis, 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
Greenstone Walker
la source
0

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)
Οurous
la source
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

REPL résultats

julia> f(1)
2

julia> f(665)
667

julia> f(665999999)
667000000

julia> f(666666666)
667000000

julia> f(66600)
66700

julia> f(456667) 
456670
Milktrader
la source
0

C #

Est-ce que je le fais 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
la source
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 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

résultat:

2 
667 
667000000 
667000000 
66700 
456670 
SeanC
la source
0

C ++

Je sais que ce n'est pas du code-golf, mais (a) certaines personnes ont suggéré que c'était un bon défi de golf et (b) c'est ma première réponse au défi / golf, je pensais que ce serait amusant et Ici, je ne me vois pas dans un véritable défi de golf parce que je suis un terrible golfeur. X)

Fondamentalement, remplacer «666» par «667» fonctionne si vous le faites pour la première instance du nombre puis écrivez les 0 finaux.

Golfé ( 175 155 caractères):

#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;
}
mike32
la source
Je pense que vous n'avez pas besoin x+=c=='6'?1:0, vous pouvez vous en tirer x+=c=='6'. Je n'ai pas essayé, cependant.
Nyuszika7h
En outre, vous avez laissé de côté std::avant stringstream. Il ne compile pas sans cela.
Nyuszika7h
Ajout de std ::, merci pour cela @ nyuszika7h. J'ai commis l'erreur d'utiliser un environnement de développement intégré (IDE) auto-généré "using namespace std;" pour essayer. -_- Je vais essayer la x+=c=='6'réduction, en plus de regarder cela avec int digits plutôt qu'avec les caractères sstream ...
mike32
0

Rubis

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
ton visage
la source
0

perl, 36 juste un sous, pas d'octets

Une version plus courte que ma dernière solution, utilisant un mélange d'arithmétique et de regex ops.

sub{($_[0]+1)=~s/666(.*)/667$1/r-$1}
skibrianski
la source
print + (<> + 1) = ~ s / 666 (. *) / 667 $ 1 / r- $ 1 (vous avez sauvegardé un octet) (deux de plus si vous utilisez say) - bien que la demande concerne une fonction, supprimez donc print + et utilisez 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 - pas de limite à vérifier et beaucoup trop d’espace, mais ce n’est pas du golf. Aussi un peu amusant de formatage dans "while (d -> 0)".

Alchimiste
la source