Vermeiden Sie die bösen ganzen Zahlen! [geschlossen]

53

Sie entwickeln Code, um ID-Nummern zu generieren. Die Richtlinie erfordert, dass keine ID-Nummern die Ziffernfolge 666 enthalten .

Erstellen Sie eine Funktion (oder das Äquivalent Ihrer Sprache), die einen positiven Ganzzahlparameter verwendet und die nächste Ganzzahl zurückgibt, die 666 nicht enthält, wenn diese Ganzzahl in Dezimalzahl ausgedrückt wird. (60606 ist in Ordnung, 66600 nicht.)

Ihr Code darf keine Schleife verwenden, in der eine hinzugefügt wird, bis ein Ergebnis gefunden wird, das den Regeln entspricht.

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: Das
Ersetzen von 666 durch 667 funktioniert nicht, wenn mehr als ein 666 in der Eingabe vorhanden ist.

billpg
quelle
1
Was ist mit so etwas wie 456667? Sollte das 456670 zurückgeben, oder sind wir nur besorgt über eine führende 666?
Kyle Kanos
11
Ich denke, das wäre besser als Code-Golf als als Beliebtheitswettbewerb, da es so einfache Lösungen gibt.
Nate Eldredge
10
@ nyuszika7h aber das ergebnis sollte sein 66700.
Martin Ender
3
als echte herausforderung hätte es auch eine anforderung geben müssen, nirgendwo im code "666" zu haben
DLeh 30.04.14
2
Abhängig von Ihrer Regex-Implementierung können Sie '6 {3}' verwenden, um 666 zu erkennen.
celtschk

Antworten:

53

Python, keine Manipulation von Strings

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

Werke von Potenzen von 10 zu finden, pwo 666 erscheint, und das Hinzufügen p - n % pzu ndem ersetzt 666xxxxxmit 66700000.

Pappkarton
quelle
6
Das gefällt mir, dass diese Implementierung , wenn dies tatsächlich eine echte Kundenanforderung war, nicht hackig, sinnvoll und effizient ist.
RomanSt
Funktioniert dies mit Zahlen, die mehrere Instanzen von 666 enthalten?
Supercat
Ja. Der am weitesten links stehende 666 ist der einzige, der tatsächlich von Bedeutung ist, und dieser Algorithmus behebt den letzten.
cardboard_box
19
@romkyns Eine echte Kundenanforderung an Codegolf senden, um andere Leute dazu zu bringen, ihre Arbeit für sie zu tun? Das ist böse ( versteckt sich )
billpg
3
Für alle , die verwendeten Python 3: Dieser Code nicht auf Python funktioniert 3+, diesen Code auf Python 3 Sie ändern müssen , um laufen m /= 10zu m //= 10. Wenn Sie dies nicht tun, wird m ein Float und die Bedingung m % 1000 == 666wird fortwährend falsch und andere "666" in n bleiben unverändert.
Sirac
50

JavaScript (aktualisiert für alle Testfälle)

Die wenig bekannte Wahrheit ist, dass es tatsächlich vier 6s gibt, von denen jedoch eines die anderen verraten und in Codeform polymorphisiert hat, um sie aus den Ziffern der Welt auszurotten . Hier ist die verräterische Sechs:

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

Hier ist eine Erklärung. Verschönern Sie zuerst den Code und entfernen Sie unnötige Dinge wie ''+'string'und ((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)
);

Konvertieren Sie seltsame Notationen (wie ~indexOfund ['replace']) in häufigere:

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

Und jetzt verstehe einfach, dass der Algorithmus so abläuft:

  • Befindet sich bereits eine 666 in der Eingabe,

    • Ersetzen Sie ihn durch einen 667.
    • Ersetzen Sie danach jede Ziffer durch eine 0.
  • sonst,

    • addiere eins zu der Zahl.
    • HINWEIS: Wir haben jetzt garantiert entweder keine 666, keine 666 am Ende der Zeichenfolge oder keine 666 an einer anderen Stelle, an der bereits Nullen zum Ende führen (denken Sie an "Tragen", wenn Sie "manuell" addieren).
    • Wenn es einen 666 gibt, ersetzen Sie ihn durch einen 667.

Alte Version (funktioniert nicht für 666666666) :

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

Um dies zu verstehen, verschönern wir es zuerst:

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

Jetzt entfernen wir nutzlose Dinge wie '' + stringund 'str' + 'ing', entfernen die unnötige sVariable und ändern die Verrücktheit -~![]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,'')ist einfach "length":

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

Und "undefined"[0]ist "u"und "u".lengthist 1:

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

Jetzt sind wir fertig! Es sollte jetzt ziemlich einfach zu verstehen sein.

Türknauf
quelle
13
Ich mag Ihre Antwort, aber es schlägt fehl für666666666
Michael M.
3
@Michael Neue Version hinzugefügt! Funktioniert für 666666666und die Schriftart des 6ist schicker;)
Türklinke
1
Huh - Verwenden ~1für != -1ist ziemlich cool.
wchargin
@WChargin Schade, dass das in LiveScript nicht funktioniert. Ich weiß, dass dies kein Codegolf ist, aber ich habe zum Spaß eine Golfversion in meinem Beitrag.
nyuszika7h
Es funktioniert in LiveScript :). ~a.indexOf('b')generiert das richtige JS, probiere es auf livescript.net aus!
Ven
20

Applescript

Diese Seite hat nicht genügend Applescript-Antworten. Lasst uns einige Dämonen verbannen!

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)

Protokollausgabe:

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

Ich wollte einige der mächtigeren Zitate von The Exorcist dazu bringen, aber das hätte dazu geführt, dass dies entschieden NSFW geschrieben hätte. Sie können stattdessen die IMDB-Seite lesen.

Digitales Trauma
quelle
Wie läuft das ohne OS X?
nyuszika7h
Ich denke, Applescript ist ziemlich abhängig von OSX stackoverflow.com/questions/7642299/… - mir sind keine Ports zu anderen Plattformen bekannt. OS 9 hatte eine Version von Applescript, obwohl es keine Garantie dafür gibt, dass dieses Skript dort ausgeführt wird.
Digital Trauma
2
Es hätte den Beitrag Not For Safe Work gemacht? Verdammt, mein Job ist nicht gefährlich
Cruncher
1
@ Cruncher oops ;-)
Digital Trauma
1
+1 für die Wahl der Variablennamen (und weil Apple Script cool ist).
Floris
15

Perl

Sie sagten, wir dürfen nicht in einer Schleife inkrementieren. Ich verwende überhaupt keine mathematischen Operatoren! Hier ist ein reiner Regex-Substitutionsansatz (keine Garantie für Ihre Gesundheit).

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

Die ersten drei Ersetzungen erhöhen die Zahl um eins. Ich habe dieses Problem selbst einmal gelöst, aber es enthielt eine Substitution, die wiederholt werden musste, bis keine Substitutionen mehr vorgenommen wurden, sodass ich stattdessen Andrew Cheongs Ansatz verwendete.

Die vierte Ersetzung verwandelt alle Ziffern nach a 666in Nullen. Die endgültige Auswechslung macht den Rest 666zu einem 667.

Als Bonus funktioniert dies mit mehreren Ganzzahlen in der Eingabe, solange diese durch nicht-stellige Zeichen getrennt sind.

Martin Ender
quelle
8

LiveScript

Das verbiegt die Regeln. Sie haben gesagt, ich darf keine Schleife verwenden, die eine hinzufügt, bis ein korrektes Ergebnis gefunden wird. Also ziehe ich stattdessen minus eins ab !

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

Eine Golfversion in 53 48 45 Bytes zum Spaß:

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

Vielen Dank an user1737909 für die weitere Unterstützung beim Golfen.

Tests

Benötigt Node.js mit dem LiveScriptnpm-Modul oder einer kompatiblen Assert-Bibliothek.

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
quelle
5
Es wird schrecklich scheitern, wenn Sie 665999 erreichen, da Ihr Stapel explodieren wird.
TimWolla
9
Sehr schlau. Sie sollten RFCs schreiben, um solche Schlupflöcher zu erkennen.
billpg
1
@ TimWolla Das ist interessant. Wie hast du das gefunden?
Nyuszika7h
1
@ nyuszika7h: Wenn Sie darüber nachdenken, werden 666000 bis 666999 alle fehlschlagen ... Sie werden mindestens 1000 Mal rekursiv sein.
Andrew Coonce
1
Ich glaube, ich habe keinen bestimmten Grund.
nyuszika7h
6

Rubin

Dies ist (glaube ich) die erste Antwort, die für 666666666 funktioniert. (Außer der betrügerischen Subtraktion von -1-Antwort.;))

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

Ich bin jetzt in Eile; Erklärung wird später hinzugefügt.

Update : wesentlich effizientere Version (fast konstante Laufzeit, glaube ich):

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
Türknauf
quelle
Eigentlich funktioniert meine Antwort gut für 666666666.
Isaacg
Eine konstante Laufzeit ist nicht möglich. Selbst die Überprüfung, ob ein "666" existiert, ist ein lineares Problem. Dies ist ein streng schwierigeres Problem.
Cruncher
4

Power Shell

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

J

Endlich eine gute Verwendung für E.!

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

Im Wesentlichen finden wir die erste Position, an der das Argument voll ist 666, und ersetzen diese Teilzeichenfolge und alles weitere durch 66700000...bis zum Ende.

Im Detail erklärt:

  • ":@>: - Inkrementiere um eins und konvertiere in einen String.
  • '666'&E. - Machen Sie einen Vektor aus Booleschen Werten, der an jeder Stelle wahr ist, an der '666' in der Zeichenfolge beginnt.
  • i.1: - Finden Sie den Index des ersten wahren im Vektor, sonst geben Sie die Länge des Vektors zurück.
  • #@[-]- Länge der Zeichenkette (die auch die Länge des Vektors ist) abzüglich des Ergebnisses von i..
  • '667'{.!.'0'~ - Nehmen Sie einen Teilstring von '667' mit der Länge dieses Ergebnisses und füllen Sie ihn bei Bedarf rechts mit '0' auf.
  • {.~- Nehmen Sie einen Teilstring mit der Länge des Originalergebnisses aus i..
  • , - Fügen Sie die beiden zusammen.

In Benutzung:

   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

Und da dies kein Code-Golf ist, muss dies nicht mit verrückten Optimierungen zur Hölle golfen. Jeder gewinnt!

algorithmshark
quelle
3

C #

148 137 Zeichen

Konnte dank @recursive ein paar Zeichen abschneiden

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

Geige: http://dotnetfiddle.net/XB83bf

Versuchen
quelle
1
Die eckigen Klammern in Ihrer Regex sind nicht erforderlich, und es gibt auch viele syntaktisch unnötige Leerzeichen.
rekursiver
Oh, und Int32kann durch ersetzt werden int.
rekursive
@recursive Du hast recht, danke!
Versucht am
Beachten Sie, dass dies ein Beliebtheitswettbewerb und kein Code-Golf ist . Das heißt, wenn Sie das Gefühl haben, dass Zeichen abgeschnitten werden, wird Ihre Antwort populärer, dann probieren Sie es aus!
Digital Trauma
2
Zuerst habe ich von dotnetfiddle.net gesehen =) AWESOME!
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
quelle
2

Perl

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

Inline-Code, der den Inhalt ändert $_, eine hübsche Standardideologie in Perl. Kann in Verbindung mit folgender -pFlagge verwendet werden:

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

J

Keine Saiten, Schleifen oder Bedingungen:

   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

Ähnlich wie bei der Lösung von cardboard_box wird die Zahl durch Division durch Zehnerpotenzen in Dreiergruppen unterteilt. Es verwendet den Index des ersten Vorkommens von 666, um die Zahl entsprechend aufzurunden.

grc
quelle
2

Haskell (70 Zeichen)

Hier ist eine einfache Implementierung 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 []         = []
  • Erstens wird map digitToInt . showeine möglicherweise böse ID in eine Liste von Ziffern konvertiert.
  • Als nächstes wird purgedas böse Muster abgeglichen und durch sein gutes Äquivalent ersetzt.
  • Schließlich foldl' ((+).(*10)) 0reduziert die Liste der Stellen ein Integer.

Mal sehen, ob es funktioniert!

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

Sieht gut aus. Und nur zum Spaß eine Golfversion.

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

Java

Reicht das nicht aus?

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
quelle
Nah dran, aber das sollte sein String.valueOf(currentId + 1).
nyuszika7h
Oh richtig, ich habe das +1 Ding vergessen! : D
Valentin Grégoire
Diese Bedingung ist nutzlos; Die ursprüngliche Lösung, die gemäß meinem Vorschlag leicht modifiziert wurde, funktioniert auch:return Integer.parseInt(String.valueOf(currentId + 1).replace("666", "667"));
nyuszika7h
1
Nicht wahr ... 66600 würde als 66701 zurückgegeben, was 1 zu hoch ist.
Valentin Grégoire
1

R

Das Ersetzen von 666 durch 667 funktioniert.

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

Ergebnisse

> 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
quelle
1

3 verschiedene JavaScript-Antworten:

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)

Wandelt die Zahl in eine Zeichenfolge um und durchläuft jedes Zeichen, bis festgestellt 666wird, dass die letzte 6in a geändert 7und 0für alle folgenden Zeichen ausgegeben wird.

2. JavaScript (ECMAScript 6-Entwurf)

Rekursive Funktion ohne Stringmanipulation:

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

Oder ausführlicher:

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

Reguläre Ausdrücke verwenden:

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

Oder (das gleiche, aber mit ECMAScript 6)

h=x=>(""+(x+1)).replace(/^(.*?)(666)(.*)$/,(a,b,c,d)=>b+667+d.replace(/./g,0))*1
MT0
quelle
Bei Ihrer ersten Version erhalten Sie, wenn Sie 6, 666, 666, 666, 666 eingeben, einen Rückgabewert von 6.667, der technisch gesehen immer noch vorhanden ist. Glaube aber nicht, dass es geholfen werden kann.
Spedwards
1e20ist ungefähr die größte Größenordnung, die JavaScript (zumindest in FireFox) als Ganzzahl ausgibt, ohne auf wissenschaftliche Notation zurückzugreifen.
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_

gibt

2
667
667000000
667000000
66700

edit: 2. lösung

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_

Ausbeuten

2
667
667000000
667000000
66700
1236670
mschilli
quelle
1
Das scheint keine richtige Antwort zu sein. 665 sollte 667 geben, 66600 sollte 66700 usw. geben
ace_HongKongIndependence
1
Ihre Ergebnisse enthalten eine Menge "666" Teilzeichenfolgen.
Glenn Randers-Pehrson
Das ist peinlich. Ich habe die 2 (!) Fence-Post-Fehler behoben, die ich gemacht habe, weil ich vergessen habe, dass awkIndexe Strings 1-basiert sind.
Mschilli
@Cruncher Wie in der Frage explizit angegeben, f(665) returns 667wird nach "der nächsten Ganzzahl ohne 666"
gefragt
Ich habe einen zweiten Weg hinzugefügt, der a) mehr awkish und b) die Verwendung von String-Funktionen minimiert.
mschilli
0

Python:

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

Oder:

 f=lambda b:int(`b+1`.replace('666','667'))
ɐɔıɐɔuʇǝɥʇs
quelle
Ich verstehe nicht, wie das funktioniert. Wäre das nicht drehen 666666in 667667statt 667000?
Martin Ender
@m.buettner Guter Punkt, ich denke ich habe schon eine Lösung.
ɐɔıɐɔ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
    }
}

Verwenden der rekursiven Funktion, um 666 ganz links zu finden, und Berechnen, um wie viel die Nummer angepasst werden muss, wenn der Call-Stack erneut abgerufen wird.

Roger Lindsjö
quelle
Ich denke nicht, dass dieser Code korrekt ist. Welches Ergebnis gibt es für den Eingang 666666666?
Algorithmushai
Sie haben Recht, haben nicht bemerkt, dass die Eingabe bereits böse Zahlen enthalten kann. Also f (666666666) -> 667667667?
Roger Lindsjö
f(666666666) -> 667000000
Djhurio
@djhurio Scheint, ich kann heute keine Tests für Randfälle generieren. Glaube, ich habe es jetzt behoben, aber der Code ist nicht mehr so ​​kurz.
Roger Lindsjö
1
@ RogerLindsjö Dies ist ein popularity-contest, kein code-golf.
Nyuszika7h
0

Stapel

Einfache iterierte String-Manipulation.

@echo off

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

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

:break

echo %inp%

Es beginnt bei den ersten drei Zeichen der Zahl (als Zeichenfolge) und arbeitet sich bis zum Ende vor, bis 666 gefunden wird. Anschließend wird diese 666 durch 667 ersetzt und eine Schleife bis zur Länge der Zeichenfolge ausgeführt, wobei Nullen hinzugefügt werden.

Die Testfälle liefern alle die richtigen Ergebnisse.

unclemeat
quelle
0

Perl, 45 Bytes

Ein einzelner regulärer Ausdruck mit dem Flag / e erledigt hier die ganze Arbeit:

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

SQL

Um genau zu sein, 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
quelle
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
quelle
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-Ergebnisse

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
quelle
0

C #

Mache ich das richtig

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
quelle
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 Aktion:

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

Ergebnis:

2 
667 
667000000 
667000000 
66700 
456670 
SeanC
quelle
0

C ++

Ich weiß, dass dies kein Code-Golf ist, aber (a) einige Leute haben vorgeschlagen, dass es eine gute Golf-Herausforderung ist, und (b) dies ist meine erste Herausforderung / Golf-Antwort, ich dachte, es würde Spaß machen, und wenn ich es tue Dies hier Ich werde nicht in einer tatsächlichen Golf-Herausforderung für einen schrecklichen Golfer auftauchen. X)

Grundsätzlich funktioniert das Ersetzen von '666' durch '667', wenn Sie dies zum ersten Mal in der Zahl tun und dann die nachstehenden Nullen ausschreiben.

Golf ( 175 155 Zeichen):

#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
quelle
Ich denke, du brauchst nicht x+=c=='6'?1:0, du kannst damit durchkommen x+=c=='6'. Hab es aber nicht ausprobiert.
nyuszika7h
Auch hast du das std::vorher ausgelassen stringstream. Ohne das kompiliert es nicht.
nyuszika7h
Hinzugefügt std ::, danke für das @ nyuszika7h. Ich habe den Fehler gemacht, eine IDE zu verwenden, die automatisch "using namespace std" generiert hat. Um es zu testen. -_- Ich werde versuchen, die x+=c=='6'Reduzierung sowie dies mit Int-Ziffern anstelle von Sstream-Zeichen zu tun suchen ...
Mike32
0

Rubin

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
dein Gesicht
quelle
0

Perl, 36 nur ein Unter, keine Bytes

Eine kürzere Version als meine letzte Lösung, die eine Mischung aus arithmetischen und regulären Operationen verwendet.

sub{($_[0]+1)=~s/666(.*)/667$1/r-$1}
Skibrianski
quelle
print + (<> + 1) = ~ s / 666 (. *) / 667 $ 1 / r- $ 1 (Sie haben ein Byte gespeichert) (zwei weitere, wenn Sie say verwenden) - obwohl die Anfrage nach einer Funktion lautete, entfernen Sie print + und verwenden 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 - keine Einschränkungen und viel zu viel Leerzeichen, aber es ist kein Golf. Auch ein bisschen Spaß beim Formatieren in "while (d -> 0)".

Alchymist
quelle