Hindari bilangan bulat jahat! [Tutup]


53

Anda sedang mengembangkan beberapa kode untuk menghasilkan nomor ID. Kebijakan mensyaratkan bahwa tidak ada nomor ID yang menyertakan urutan digit 666 .

Buat fungsi (atau bahasa Anda yang setara) yang mengambil parameter bilangan bulat positif dan mengembalikan bilangan bulat berikutnya yang tidak termasuk 666 ketika bilangan bulat itu dinyatakan dalam desimal. (60606 baik-baik saja, 66600 tidak.)

Kode Anda tidak boleh menggunakan loop yang menambahkan satu sampai menemukan hasil yang sesuai dengan aturan.

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:
Mengganti 666 dengan 667 tidak akan berfungsi jika ada lebih dari satu 666 di input.


1
Bagaimana dengan sesuatu seperti 456667? Haruskah itu mengembalikan 456670, atau kita hanya khawatir tentang 666 terkemuka?
Kyle Kanos

11
Saya pikir ini akan lebih baik sebagai kode-golf daripada kontes-popularitas karena ada solusi langsung seperti itu.
Nate Eldredge

10
@ nyuszika7h tetapi hasilnya harus 66700.
Martin Ender

3
sebagai tantangan nyata, seharusnya juga ada persyaratan untuk tidak memiliki "666" di mana pun dalam kode
DLeh

2
Bergantung pada implementasi regex Anda, Anda dapat menggunakan '6 {3}' untuk mendeteksi 666.
celtschk

Jawaban:


53

Python, tidak ada manipulasi string

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

Pekerjaan dengan mencari kekuatan dari 10, p, di mana 666 muncul, dan menambahkan p - n % puntuk nyang menggantikan 666xxxxxdengan 66700000.


6
Saya suka ini karena jika ini sebenarnya adalah kebutuhan pelanggan nyata , implementasi ini tidak dapat diretas, masuk akal, dan efisien.
RomanSt

Apakah ini akan berfungsi dengan angka yang mengandung banyak instance 666?
supercat

Iya. 666 paling kiri adalah satu-satunya yang benar-benar penting, dan algoritma ini memperbaiki yang terakhir.
cardboard_box

19
@romkyns Pasang persyaratan pelanggan nyata yang sebenarnya untuk codegolf untuk menipu orang lain agar melakukan pekerjaan mereka untuk mereka? Itu jahat! ( menyembunyikan )
billpg

3
Untuk setiap orang yang menggunakan python 3: Kode ini tidak bekerja pada python 3 +, untuk menjalankan kode ini pada python 3 Anda harus perubahan m /= 10ke m //= 10. Jika Anda tidak maka m akan menjadi pelampung dan kondisi m % 1000 == 666terus menerus akan palsu dan lainnya "666" di n yang tersisa tidak berubah.
Sirac

50

JavaScript (diperbarui untuk bekerja dengan semua kasus uji)

Kebenaran yang sedikit diketahui adalah bahwa sebenarnya ada empat 6, tetapi salah satu dari yang dikhianati yang lain dan polymorphed ke dalam bentuk kode untuk membasmi mereka dari digit angka dunia . Inilah enam pengkhianat itu:

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

Berikut ini penjelasannya. Pertama, percantik kode dan hapus hal-hal yang tidak berguna seperti ''+'string'dan ((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)
);

Ubah notasi aneh (seperti ~indexOfdan ['replace']) menjadi yang lebih umum:

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

Dan sekarang cukup pahami bahwa algoritmenya seperti ini:

  • Jika sudah ada input 666,

    • ganti dengan 667.
    • ganti setiap digit setelah itu dengan 0.
  • lain,

    • tambahkan satu ke nomor.
    • CATATAN: kami sekarang dijamin tidak memiliki nomor 666, 666 di akhir string, atau 666 di tempat lain yang sudah memiliki nol hingga akhir (pikirkan "carry" saat melakukan penambahan "manual").
    • jika ada 666, ganti dengan 667.

Versi lama (tidak berfungsi untuk 666666666) :

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

Untuk memahami ini, mari kita mempercantiknya:

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

Sekarang mari kita hapus hal-hal yang tidak berguna seperti '' + stringdan 'str' + 'ing', hapus svariabel yang tidak perlu , dan ubah keanehan seperti -~![]menjadi 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,'')hanya "length":

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

Dan "undefined"[0]adalah "u", dan "u".lengthadalah 1:

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

Sekarang kita sudah selesai! Seharusnya cukup mudah dimengerti sekarang.


13
Saya suka jawaban Anda tetapi gagal untuk666666666
Michael M.

3
@Michael Menambahkan versi baru! Berfungsi untuk 666666666, dan font dari 6pelamun;)
Gagang pintu

1
Huh - menggunakan ~1untuk != -1itu sangat keren.
wchargin

@WChargin Sayang sekali itu tidak berfungsi di LiveScript. Saya tahu ini bukan kode golf tetapi saya memiliki versi golf di pos saya untuk bersenang-senang.
nyuszika7h

Itu bekerja di LiveScript :). ~a.indexOf('b')buat JS yang benar, coba di livescript.net!
Ven

20

Applescript

Situs ini tidak memiliki cukup jawaban Applescript. Mari kita singkirkan beberapa setan!

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)

Output log:

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

Saya ingin mendapatkan beberapa kutipan yang lebih kuat dari The Exorcist ke dalam ini, tapi itu akan membuat ini diposting jelas NSFW. Anda dapat membaca halaman IMDB sebagai gantinya.


Bagaimana Anda menjalankan ini tanpa memiliki OS X?
nyuszika7h

Saya pikir Applescript sangat tergantung pada OSX stackoverflow.com/questions/7642299/... - Saya tidak mengetahui adanya port ke platform lain. OS 9 memang memiliki versi Applescript, meskipun tidak ada jaminan bahwa skrip ini akan berjalan di sana.
Digital Trauma

2
Itu akan membuat posting Bukan Untuk Pekerjaan Aman? Sialan, pekerjaanku tidak berbahaya
Cruncher

1
@Cruncher oops ;-)
Digital Trauma

1
+1 untuk pilihan nama variabel (dan karena skrip apel keren).
Floris

15

Perl

Anda bilang kita tidak harus menambah dalam satu lingkaran. Saya tidak menggunakan operator matematika sama sekali! Ini adalah pendekatan substitusi murni (tidak ada jaminan aman untuk kewarasan Anda).

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

Tiga pergantian pemain pertama menambah satu per satu. Saya memang pernah memecahkan masalah itu sendiri, tetapi itu termasuk substitusi yang harus dilingkarkan sampai tidak ada lagi penggantian yang dibuat, jadi saya menggunakan pendekatan Andrew Cheong sebagai gantinya.

Substitusi keempat mengubah semua digit setelah a 666menjadi nol. Substitusi terakhir mengubah sisanya 666menjadi a 667.

Sebagai bonus, ini akan bekerja dengan beberapa bilangan bulat dalam input selama mereka dipisahkan oleh karakter non-digit.


8

LiveScript

Ini menekuk aturan. Anda lihat, Anda bilang saya tidak boleh menggunakan loop yang menambahkan satu sampai ia menemukan hasil yang benar. Jadi saya mengurangi minus satu sebagai gantinya!

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

Versi golf dalam 53 48 45 byte untuk bersenang-senang:

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

Terima kasih kepada pengguna1737909 untuk membantu golf lebih jauh.

Tes

Membutuhkan Node.js dengan LiveScriptmodul npm atau pustaka yang kompatibel.

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
Ini akan gagal total ketika Anda mencapai 665999, karena tumpukan Anda akan meledak.
TimWolla

9
Sangat pintar. Anda harus menulis RFC untuk menemukan celah seperti itu.
billpg

1
@TimWolla Itu menarik. Bagaimana Anda menemukan itu?
nyuszika7h

1
@ nyuszika7h: Jika Anda memikirkannya, 666000 hingga 666999 semuanya akan gagal ... Anda akan mengulang setidaknya 1000 kali.
Andrew Coonce

1
Saya tidak punya alasan khusus, saya kira.
nyuszika7h

6

Rubi

Ini adalah (saya pikir) jawaban pertama yang berfungsi untuk 666666666. (Kecuali cheaty yang mengurangi -1 jawaban.;))

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

Saya sedang terburu-buru sekarang; Penjelasan akan ditambahkan nanti.

Pembaruan : versi yang jauh lebih efisien (saya kira runtime hampir konstan):

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

Sebenarnya, jawaban saya berfungsi dengan baik untuk 666666666.
isaacg

Runtime yang konstan tidak mungkin. Bahkan memeriksa apakah "666" ada adalah masalah linier. Ini adalah masalah yang sangat sulit dari itu.
Cruncher

4

PowerShell

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

4

J

Akhirnya, gunakan untuk E.!

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

Intinya, kami menemukan posisi pertama di mana argumen memiliki penuh 666, dan kami mengganti substring itu dan semuanya setelah dengan 66700000...sampai akhir.

Dijelaskan secara rinci:

  • ":@>: - Kenaikan satu demi satu dan dikonversi menjadi string.
  • '666'&E. - Buatlah vektor boolean, berlaku di setiap tempat yang '666' dimulai dalam string.
  • i.1: - Temukan indeks true pertama dalam vektor, jika tidak kembalikan panjang vektor.
  • #@[-]- Panjang string (yang juga merupakan panjang vektor) minus hasil dari i..
  • '667'{.!.'0'~ - Ambil substring '667' dengan panjang hasil itu, padding di sebelah kanan dengan '0' jika perlu.
  • {.~- Ambil substring dengan panjang hasil asli dari i..
  • , - Tambahkan keduanya bersamaan.

Digunakan:

   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

Dan karena ini bukan kode golf, ini tidak harus golf ke neraka dengan optimisasi gila. Semua orang menang!


3

C #

148 137 karakter

Mampu mencukur beberapa karakter berkat @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'));}

Tidak Disatukan:

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
Kurung kotak di regex Anda tidak perlu, dan ada juga banyak ruang yang tidak perlu secara sintaksis.
rekursif

Oh, dan Int32bisa diganti dengan int.
rekursif

@recursive Anda benar, terima kasih!
Mencoba

Perhatikan ini adalah kontes popularitas dan bukan golf kode . Setelah mengatakan bahwa jika Anda merasa kehilangan karakter akan membuat jawaban Anda lebih populer, maka lakukanlah!
Digital Trauma

2
Pertama saya melihat dotnetfiddle.net =) LUAR BIASA!
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)

2

Perl

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

Kode sebaris yang mengubah konten di dalamnya $_, ideologi yang cukup standar di perl. Dapat digunakan bersamaan dengan -pflag seperti ini:

$ perl -p % <<< 66666
66700

2

J

Tanpa string, loop, atau kondisional:

   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

Demikian pula dengan solusi cardboard_box, ini memisahkan angka menjadi kelompok tiga digit dengan membaginya dengan kekuatan sepuluh. Ini menggunakan indeks kejadian pertama 666 untuk mengumpulkan angka dengan tepat.


2

Haskell (70 karakter)

Berikut ini adalah implementasi sederhana di 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 []         = []
  • Pertama, ini digunakan map digitToInt . showuntuk mengkonversi ID jahat yang mungkin menjadi daftar angka.
  • Selanjutnya, purgecocokkan dengan pola jahat dan gantikan dengan padanannya yang baik.
  • Akhirnya, foldl' ((+).(*10)) 0kurangi daftar digit menjadi satu Integer.

Mari kita lihat apakah itu berhasil!

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

Kelihatan bagus. Dan hanya untuk bersenang-senang versi golf.

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

1

Jawa

Bukankah itu cukup untuk melakukan ini?

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

Tutup, tapi seharusnya begitu String.valueOf(currentId + 1).
nyuszika7h

Oh benar, saya lupa benda +1 itu! : D
Valentin Grégoire

Persyaratan itu tidak berguna; solusi asli sedikit dimodifikasi sesuai saran saya akan bekerja juga:return Integer.parseInt(String.valueOf(currentId + 1).replace("666", "667"));
nyuszika7h

1
Tidak benar ... 66600 akan dikembalikan sebagai 66701, yang berarti 1 terlalu tinggi.
Valentin Grégoire

1

R

Mengganti 666 dengan 667 karya.

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

Hasil

> 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 jawaban JavaScript yang berbeda:

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)

Bertobat jumlah ke string kemudian iterates atas masing-masing karakter sampai menemukan 666maka perubahan yang terakhir 6ke 7dan output 0untuk semua karakter berikut.

2. JavaScript (Draft ECMAScript 6)

Fungsi rekursif tanpa manipulasi string:

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

Atau lebih tepatnya:

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

Tes:

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

3. JavaScript

Menggunakan ekspresi reguler:

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

Atau (sama tetapi menggunakan ECMAScript 6)

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

Dengan versi pertama Anda, jika Anda memasukkan 6 septillion, 666 sextillion Anda mendapatkan nilai pengembalian 6.667jadi secara teknis itu masih ada. Tapi jangan berpikir itu bisa membantu.
Spedwards

1e20adalah tentang urutan besarnya terbesar yang akan dicetak JavaScript (setidaknya di FireFox) sebagai bilangan bulat tanpa menggunakan notasi ilmiah.
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_

memberi

2
667
667000000
667000000
66700

sunting: solusi ke-2

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_

hasil panen

2
667
667000000
667000000
66700
1236670

1
yang sepertinya bukan jawaban yang benar. 665 harus memberikan 667, 66600 harus memberikan 66700 dll
ace_HongKongIndependence

1
Hasil Anda mengandung banyak "666" substring.
Glenn Randers-Pehrson

Itu memalukan. Saya memperbaiki 2 (-) pagar-post-kesalahan yang saya buat karena saya lupa bahwa awkindeks berbasis string 1.
mschilli

@Cruncher Seperti yang secara eksplisit dinyatakan dalam pertanyaan, f(665) returns 667karena meminta "bilangan bulat berikutnya yang tidak termasuk 666"
ace_HongKongIndependence

Saya menambahkan cara ke-2 yaitu a) lebih banyak awkish dan b) meminimalkan penggunaan fungsi string.
mschilli

0

Python:

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

Atau:

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

Saya tidak melihat cara kerjanya. Bukankah itu berubah 666666menjadi 667667bukan 667000?
Martin Ender

@ m.buettner Poin bagus, saya pikir saya sudah punya solusi.
ɐɔıʇǝɥʇu

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

Menggunakan fungsi rekursif untuk menemukan 666 paling kiri dan menghitung berapa banyak untuk menyesuaikan nomor ketika muncul lagi tumpukan panggilan.


Saya rasa kode ini tidak benar. Apa hasil yang diberikannya untuk input 666666666?
algorithmshark

Anda benar, tidak menyadari bahwa input sudah dapat berisi angka-angka jahat. Jadi f (666666666) -> 667667667?
Roger Lindsjö

f(666666666) -> 667000000
djhurio

@ Djurio Sepertinya saya tidak dapat menghasilkan tes untuk kasus tepi hari ini. Percayalah saya sudah memperbaikinya sekarang, tetapi kodenya tidak begitu pendek lagi.
Roger Lindsjö

1
@ RogerLindsjö Ini adalah popularity-contest, bukan a code-golf.
nyuszika7h

0

Batch

Manipulasi string berulang sederhana.

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

Ini dimulai pada tiga karakter pertama dari nomor (sebagai string), dan bekerja sampai akhir sampai menemukan 666, kemudian menggantikan 666 dengan 667, dan loop ke panjang string menambahkan nol.

Semua test case menghasilkan hasil yang benar.


0

perl, 45 byte

Regex tunggal dengan flag / e melakukan semua pekerjaan di sini:

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

0

SQL

Lebih tepatnya, 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

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)

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

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

Apakah saya melakukannya dengan benar

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

Dalam aksi:

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

hasil:

2 
667 
667000000 
667000000 
66700 
456670 

0

C ++

Saya tahu ini bukan kode-golf, tetapi (a) beberapa orang menyarankan itu adalah tantangan golf yang bagus, dan (b) ini adalah tantangan / golf jawaban pertama saya, saya pikir ini akan menyenangkan, dan jika saya melakukannya ini di sini saya tidak muncul dalam tantangan golf yang sebenarnya untuk menjadi pegolf yang mengerikan. X)

Pada dasarnya, mengganti '666' dengan '667' berfungsi jika Anda melakukannya untuk contoh pertama dalam angka dan kemudian menuliskan 0 trailing.

Golfed ( 175 155 chars):

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

Tidak Disatukan:

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

Saya pikir Anda tidak perlu x+=c=='6'?1:0, Anda bisa lolos x+=c=='6'. Tapi belum pernah mencobanya.
nyuszika7h

Juga, Anda mengabaikan std::sebelumnya stringstream. Itu tidak dapat dikompilasi tanpa itu.
nyuszika7h

Menambahkan std ::, terima kasih untuk itu @ nyuszika7h. Saya membuat kesalahan dengan menggunakan IDE yang di-autogenerasi 'menggunakan namespace std;' . uji di -_- Saya akan mencoba x+=c=='6'pengurangan, serta melihat melakukan ini dengan angka int bukan chars sstream ...
mike32

0

Rubi

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 hanya sub, tidak ada byte

Versi yang lebih pendek dari solusi terakhir saya, menggunakan campuran ops aritmatika dan regex.

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

print + (<> + 1) = ~ s / 666 (. *) / 667 $ 1 / r- $ 1 (menyelamatkan Anda satu byte) (dua lagi jika Anda menggunakan katakan) - meskipun permintaan adalah untuk fungsi jadi hapus print + dan gunakan 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 - tidak ada batas memeriksa dan spasi terlalu banyak tapi itu bukan golf. Juga sedikit menyenangkan memformat di "while (d -> 0)".

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.