Unikaj złych liczb całkowitych! [Zamknięte]


53

Pracujesz nad kodem do generowania numerów identyfikacyjnych. Zasady wymagają, aby żadne numery identyfikacyjne nie zawierały sekwencji cyfr 666 .

Utwórz funkcję (lub odpowiednik twojego języka), która przyjmuje dodatni parametr liczby całkowitej i zwraca następną liczbę całkowitą, która nie zawiera 666, gdy liczba ta jest wyrażona w postaci dziesiętnej. (60606 jest w porządku, 66600 nie.)

Twój kod nie może używać pętli, która ją dodaje, dopóki nie znajdzie wyniku zgodnego z regułami.

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.

AKTUALIZACJA:
Zastąpienie 666 667 nie będzie działać, jeśli na wejściu jest więcej niż jeden 666.


1
Co powiesz na coś takiego jak 456667? Czy to powinno zwrócić 456670, czy martwimy się tylko o wiodącą 666?
Kyle Kanos

11
Myślę, że byłoby to lepsze jako konkurs golfa niż konkurs popularności, ponieważ istnieją tak proste rozwiązania.
Nate Eldredge

10
@ nyuszika7h, ale wynik powinien być 66700.
Martin Ender

3
prawdziwym wyzwaniem powinien być również wymóg, aby w kodzie nigdzie nie było „666”
DLeh

2
W zależności od implementacji wyrażenia regularnego możesz użyć „6 {3}” do wykrycia 666.
celtschk

Odpowiedzi:


53

Python, bez manipulacji ciągami

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

Prace znalezienie moce 10, pgdzie pojawia się 666, a dodając p - n % pdo nktórego zastępuje 666xxxxxsię 66700000.


6
Lubię to, że jeśli to był faktycznie realne zapotrzebowanie klienta, to realizacja jest non-hacky, rozsądny i skuteczny.
RomanSt

Czy to zadziała z liczbami zawierającymi wiele wystąpień 666?
supercat

Tak. Najbardziej wysunięty w lewo 666 jest jedynym, który faktycznie ma znaczenie, a ten algorytm naprawia ten ostatni.
cardboard_box

19
@romkyns Opublikować rzeczywiste wymaganie klienta dotyczące codegolf, aby oszukać innych ludzi, aby wykonali dla nich swoją pracę? To jest złe! ( ukrywa się )
billpg

3
Dla każdego, kto używa Pythona 3: Ten kod nie działa na Pythonie 3+, aby uruchomić ten kod na Pythonie 3, musisz zmienić m /= 10na m //= 10. Jeśli tego nie zrobisz, m stanie się liczbą zmiennoprzecinkową, a warunek m % 1000 == 666będzie stale fałszywy, a pozostałe „666” in pozostaną niezmienione.
Sirac

50

JavaScript (zaktualizowany do pracy ze wszystkimi testami)

Mało znaną prawdą jest to, że w rzeczywistości są cztery 6, ale jedna zdradziła pozostałych i zamieniła się w formę kodu, aby usunąć je ze światowych cyfr liczb. Oto ta zdradziecka szóstka:

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

Oto wyjaśnienie. Najpierw upiększ kod i usuń niepotrzebne rzeczy, takie jak ''+'string'i ((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)
);

Konwertuj dziwne notacje (jak ~indexOfi ['replace']) na bardziej popularne:

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

A teraz po prostu zrozum, że algorytm wygląda następująco:

  • Jeśli na wejściu jest już 666,

    • zastąp go 667.
    • zamień każdą cyfrę później na 0.
  • jeszcze,

    • dodaj jeden do numeru.
    • UWAGA: gwarantujemy, że nie będziemy mieć ani 666, 666 na końcu łańcucha, ani 666 w innym miejscu, które już ma zera idące do końca (pomyśl o „przenoszeniu” podczas dodawania „ręcznie”).
    • jeśli jest 666, zamień go na 667.

Stara wersja (nie działa 666666666) :

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

Aby to zrozumieć, najpierw upiększmy to:

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

Teraz usuńmy niepotrzebne rzeczy, takie jak '' + stringi 'str' + 'ing', usuń niepotrzebną szmienną i zmień dziwność jak -~![]na 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,'')jest po prostu "length":

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

I "undefined"[0]jest "u"i "u".lengthjest 1:

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

Teraz skończone! Teraz powinno być dość łatwo to zrozumieć.


13
Podoba mi się twoja odpowiedź, ale się nie udaje666666666
Michael M.

3
@Michael Dodano nową wersję! Działa dla 666666666, a czcionka 6jest bardziej wyszukana;)
Klamka

1
Huh - używanie ~1do != -1jest całkiem fajne.
wchargin

@WChargin Szkoda, że ​​nie działa w LiveScript. Wiem, że to nie jest golf golfowy, ale dla zabawy mam wersję gry w golfa.
nyuszika7h

Działa w LiveScript :). ~a.indexOf('b')generuje poprawny JS, wypróbuj go na livescript.net!
Ven

20

Jabłkowy

Ta strona nie ma wystarczającej liczby odpowiedzi na Applescript. Wyrzućmy demony!

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)

Dane wyjściowe dziennika:

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

Chciałem zamieścić w tym niektóre z mocniejszych cytatów z Egzorcysty , ale to zdecydowanie sprawiłoby, że ten post został opublikowany jako NSFW. Zamiast tego możesz przeczytać stronę IMDB.


Jak to uruchomić bez OS X?
nyuszika7h

Myślę, że Applescript jest w dużej mierze zależny od OSX stackoverflow.com/questions/7642299/... - Nie znam portów dla innych platform. OS 9 nie mają wersję Applescript, choć nie ma gwarancji, że ten skrypt będzie działać tam.
Cyfrowa trauma

2
Byłby to post Nie dla bezpiecznej pracy? Cholera, moja praca nie jest niebezpieczna
Cruncher

1
@Cruncher oops ;-)
Digital Trauma

1
+1 za wybór nazw zmiennych (i ponieważ skrypt Apple jest fajny).
Floris,

15

Perl

Powiedziałeś, że nie wolno inkrementować w pętli. W ogóle nie używam żadnych operatorów matematycznych! Oto podejście polegające na zastępowaniu wyrażeń regularnych (nie ma gwarancji, że jest bezpieczne dla twojego zdrowia psychicznego).

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

Pierwsze trzy podstawienia zwiększają liczbę o jeden. Raz sam rozwiązałem ten problem, ale obejmował on zamianę, która musiała być zapętlona, ​​aż nie będzie więcej podstawień, więc zamiast tego zastosowałem podejście Andrew Cheonga .

Czwarte podstawienie zamienia wszystkie cyfry następujące po 666zerach. Ostateczne zastąpienie zamienia pozostałe 666w 667.

Jako bonus będzie to działać z wieloma liczbami całkowitymi na wejściu, o ile są one oddzielone znakami niecyfrowymi.


8

LiveScript

To nagina zasady. Widzisz, powiedziałeś, że nie wolno mi używać pętli, która dodaje jedną, dopóki nie znajdzie poprawnego wyniku. Więc odjąć minus jeden zamiast!

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

Wersja golfowa dla 53 48 45 bajtów dla zabawy:

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

Dziękujemy użytkownikowi1737909 za dalszą pomoc w grze w golfa.

Testy

Wymaga Node.js z LiveScriptmodułem npm lub kompatybilną biblioteką asercji.

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
Okropnie zawiedzie, gdy dojdziesz do 665999, ponieważ twój stos eksploduje.
TimWolla

9
Bardzo mądry. Powinieneś pisać RFC, aby wykryć takie luki.
billpg

1
@TimWolla To ciekawe. Jak to znalazłeś?
nyuszika7h

1
@ nyuszika7h: Jeśli się nad tym zastanowić, od 666000 do 666999 wszystko zawiedzie ... będziesz się powtarzać co najmniej 1000 razy.
Andrew Coonce,

1
Chyba nie mam konkretnego powodu.
nyuszika7h

6

Rubin

To (jak sądzę) pierwsza odpowiedź, która działa dla 666666666. (Z wyjątkiem oszukańczego odejmowania odpowiedzi -1;))

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

Spieszy mi się teraz; wyjaśnienie zostanie dodane później.

Aktualizacja : znacznie bardziej wydajna wersja (uważam, że prawie stały czas pracy):

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

Właściwie moja odpowiedź działa dobrze dla 666666666.
isaacg

Stały czas działania jest niemożliwy. Nawet sprawdzenie, czy istnieje „666”, stanowi problem liniowy. Jest to o wiele trudniejszy problem.
Cruncher

4

PowerShell

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

4

jot

Wreszcie dobre zastosowanie E.!

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

Zasadniczo znajdujemy pierwszą pozycję, w której argument jest pełny 666, i zastępujemy to podciąg i wszystko po nim 66700000...do końca.

Szczegółowo wyjaśnione:

  • ":@>: - Przyrost o jeden i konwersja na ciąg.
  • '666'&E. - Zrób wektor boolanów, prawdziwy w każdym miejscu, w którym ciąg „666” zaczyna się w ciągu.
  • i.1: - Znajdź indeks pierwszej prawdy w wektorze, w przeciwnym razie zwróć długość wektora.
  • #@[-]- Długość łańcucha (która jest również długością wektora) minus wynik i..
  • '667'{.!.'0'~ - Weź podciąg „667” o długości tego wyniku, w razie potrzeby dopełnij po prawej stronie „0”.
  • {.~- Weź podciąg o długości oryginalnego wyniku i..
  • , - Dołącz dwa razem.

W użyciu:

   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

A ponieważ nie jest to golf kodowy, nie trzeba go grać w piekło z szalonymi optymalizacjami. Wszyscy wygrywają!


3

DO#

148 137 znaków

Był w stanie zgolić kilka znaków dzięki @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'));}

Nie golfowany:

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
Nawiasy kwadratowe w wyrażeniu regularnym są niepotrzebne, a ponadto istnieje wiele niepotrzebnych składniowo spacji.
rekurencyjny

Och, i Int32można je zastąpić int.
rekurencyjny

@recursive Masz rację, dzięki!
Próbowanie

Uwaga: jest to konkurs popularności, a nie golfowy . Powiedziawszy to, jeśli czujesz, że golenie postaci sprawi, że Twoja odpowiedź będzie bardziej popularna, to idź!
Digital Trauma

2
Najpierw widziałem dotnetfiddle.net =) NIESAMOWITE!
Coops

2

Pyton

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

Wbudowany kod, który zmienia zawartość w środku $_, dość standardowa ideologia w perlu. Może być używany w połączeniu z -ptaką flagą:

$ perl -p % <<< 66666
66700

2

jot

Bez ciągów, pętli lub warunków warunkowych:

   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

Podobnie jak w rozwiązaniu karton_boks, dzieli to liczbę na grupy po trzy cyfry, dzieląc przez potęgi dziesięciu. Wykorzystuje wskaźnik pierwszego wystąpienia 666, aby odpowiednio zaokrąglić liczbę w górę.


2

Haskell (70 znaków)

Oto prosta implementacja w 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 []         = []
  • Po pierwsze, służy map digitToInt . showdo konwersji potencjalnie złego identyfikatora na listę cyfr.
  • Następnie purgedopasowuje wzór zła i zastępuje go dobrym odpowiednikiem.
  • Wreszcie foldl' ((+).(*10)) 0zmniejsza listę cyfr do jednej Integer.

Zobaczmy, czy to działa!

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

Wygląda dobrze. I dla zabawy wersja golfowa.

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

1

Jawa

Czy to nie wystarczy?

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

Blisko, ale tak powinno być String.valueOf(currentId + 1).
nyuszika7h

No tak, zapomniałem o tym +1! : D
Valentin Grégoire

Ten warunek jest bezużyteczny; oryginalne rozwiązanie nieznacznie zmodyfikowane według mojej sugestii też będzie działać:return Integer.parseInt(String.valueOf(currentId + 1).replace("666", "667"));
nyuszika7h

1
Nieprawda ... 66600 zostanie zwrócony jako 66701, czyli o 1 za wysoko.
Valentin Grégoire

1

R

Zastąpienie 666 działaniem 667.

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

Wyniki

> 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 różne odpowiedzi 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)

Konwertuje liczbę na ciąg znaków, a następnie iteruje każdy znak, dopóki nie znajdzie, 666a następnie zmienia ostatni 6na a 7i wyprowadza 0dla wszystkich kolejnych znaków.

2. JavaScript (wersja robocza ECMAScript 6)

Funkcja rekurencyjna bez manipulacji ciągiem:

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

Lub bardziej szczegółowo:

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

Testy:

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

3. JavaScript

Używanie wyrażeń regularnych:

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

Lub (to samo, ale przy użyciu ECMAScript 6)

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

W pierwszej wersji, jeśli wpiszesz 6 septillionów, 666 sextillionów, otrzymasz wartość zwrotną 6.667tak technicznie, że nadal tam jest. Nie sądzę, że można temu zaradzić.
Spedwards

1e20jest o największym rzędzie wielkości, który JavaScript (przynajmniej w FireFox) wydrukuje jako liczbę całkowitą bez uciekania się do notacji naukowej.
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_

daje

2
667
667000000
667000000
66700

edycja: 2. rozwiązanie

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_

plony

2
667
667000000
667000000
66700
1236670

1
co nie wydaje się poprawnymi odpowiedziami. 665 powinno dać 667, 66600 powinno dać
66700

1
Twoje wyniki zawierają wiele podciągów „666”.
Glenn Randers-Pehrson

To jest żenujące. Naprawiłem 2 (!) Błędy ogrodzenia, które popełniłem, ponieważ zapomniałem, że awkindeksuje łańcuchy na podstawie 1.
mschilli

@Cruncher Jak wyraźnie zaznaczono w pytaniu, f(665) returns 667ponieważ prosi o „następną liczbę całkowitą, która nie zawiera 666”
ace_HongKongIndependence 30.04.2014

Dodałem drugi sposób: a) więcej awkish ib) minimalizuje użycie funkcji string.
mschilli

0

Pyton:

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

Lub:

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

Nie rozumiem, jak to działa. Czy to nie zmieniłoby się 666666w 667667zamiast 667000?
Martin Ender

@ m.buettner Dobra uwaga, myślę, że już mam rozwiązanie.
29ıʇǝɥʇuʎs

0

Jawa

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

Za pomocą funkcji rekurencyjnej znajdź skrajnie lewy 666 i oblicz, ile należy zmienić, gdy ponownie pojawi się stos wywołań.


Nie sądzę, aby ten kod był poprawny. Jaki daje wynik dla danych wejściowych 666666666?
algorytmshark

Masz rację, nie zdawałem sobie sprawy, że dane wejściowe mogą już zawierać liczby zła. Więc f (666666666) -> 667667667?
Roger Lindsjö

f(666666666) -> 667000000
djhurio

@ djhurio Wydaje się, że nie mogę dziś wygenerować testów dla przypadków skrajnych. Wierzę, że już to naprawiłem, ale kod nie jest już tak krótki.
Roger Lindsjö

1
@ RogerLindsjö To popularity-contestnie jest code-golf.
nyuszika7h

0

Partia

Prosta iterowana manipulacja ciągiem.

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

Zaczyna się od pierwszych trzech znaków liczby (jako łańcucha) i przechodzi do końca, aż znajdzie 666, następnie zamienia 666 na 667 i zapętla długość łańcucha dodając zera.

Wszystkie przypadki testowe dają prawidłowe wyniki.


0

perl, 45 bajtów

Pojedynczy regex z flagą / e wykonuje całą pracę tutaj:

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

0

SQL

Mówiąc ściślej, 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

Pyton

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

Wyniki 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

DO#

Czy robię to dobrze

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

W akcji:

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

wynik:

2 
667 
667000000 
667000000 
66700 
456670 

0

C ++

Wiem, że to nie jest kod-golf, ale (a) niektórzy sugerowali, że jest to dobre wyzwanie w golfa, i (b) to jest moje pierwsze wyzwanie / odpowiedź na golfa, pomyślałem, że będzie fajnie, a jeśli to zrobię tutaj nie pokazuję się w prawdziwym wyzwaniu golfowym za bycie okropnym golfistą. X)

Zasadniczo zastąpione „666” przez „667” działa, jeśli zrobisz to dla pierwszego wystąpienia liczby, a następnie wypiszesz końcowe zera.

Gra w golfa ( 175 155 znaków):

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

Nie golfowany:

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

Myślę, że nie potrzebujesz x+=c=='6'?1:0, możesz uciec x+=c=='6'. Jednak nie próbowałem tego.
nyuszika7h

Pominąłeś też std::wcześniej stringstream. Bez tego się nie kompiluje.
nyuszika7h

Dodano std ::, dzięki za @ nyuszika7h. Popełniłem błąd, używając IDE, które wygenerowało się automatycznie „using namespace std;” aby to przetestować. -_- Spróbuję x+=c=='6'zmniejszyć, a także spojrzeć na to z cyframi int, a nie na znaki sstream ...
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

0

perl, 36 tylko sub, bez bajtów

Krótsza wersja niż moje ostatnie rozwiązanie, wykorzystująca połączenie operacji arytmetycznych i wyrażeń regularnych.

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

print + (<> + 1) = ~ s / 666 (. *) / 667 $ 1 / r- $ 1 (zapisałeś bajt) (jeszcze dwa, jeśli używasz powiedz) - chociaż żądanie dotyczyło funkcji, więc usuń print + i użyj sub {...}
Altreus

0

do

#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 - bez sprawdzania granic i zdecydowanie za dużo białych znaków, ale to nie golf. Również zabawne trochę formatowania w „while (d -> 0)”.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.