Tránh các số nguyên ác! [đóng cửa]


53

Bạn đang phát triển một số mã để tạo số ID. Chính sách yêu cầu không có số ID bao gồm dãy số 666 .

Tạo một hàm (hoặc tương đương với ngôn ngữ của bạn), lấy tham số nguyên dương và trả về số nguyên tiếp theo không bao gồm 666 khi số nguyên đó được biểu thị bằng số thập phân. (60606 là tốt, 66600 thì không.)

Mã của bạn không được sử dụng vòng lặp thêm một vòng cho đến khi tìm thấy kết quả phù hợp với quy tắc.

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.

CẬP NHẬT:
Thay thế 666 bằng 667 sẽ không hoạt động nếu có nhiều hơn 666 trong đầu vào.


1
Thế còn 456667 thì sao? Điều đó có nên trả lại 456670 không, hay chúng ta chỉ lo lắng về một chiếc 666 hàng đầu?
Kyle Kanos

11
Tôi nghĩ rằng điều này sẽ tốt hơn khi chơi golf mã hơn là thi đấu phổ biến vì có những giải pháp đơn giản như vậy.
Nate Eldredge

10
@ nyuszika7h nhưng kết quả nên như vậy 66700.
Martin Ender

3
như một thách thức thực sự, cũng cần phải có "666" bất cứ nơi nào trong mã
DLeh

2
Tùy thuộc vào việc triển khai regex của bạn, bạn có thể sử dụng '6 {3}' để phát hiện 666.
celtschk

Câu trả lời:


53

Python, không có thao tác chuỗi

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

Hoạt động bằng cách tìm các quyền hạn 10, ptrong đó 666 xuất hiện và thêm p - n % pvào nđó thay thế 666xxxxxbằng 66700000.


6
Tôi thích điều này ở chỗ nếu đây thực sự là một yêu cầu thực sự của khách hàng, thì việc thực hiện này là không hack, hợp lý và hiệu quả.
RomanSt

Điều này có hoạt động với các số có chứa nhiều phiên bản 666 không?
supercat

Đúng. 666 ngoài cùng bên trái là cái duy nhất thực sự quan trọng và thuật toán này sửa cái cuối cùng.
cardboard_box

19
@romkyns Đăng một yêu cầu thực tế của khách hàng đối với codegolf để lừa người khác thực hiện công việc của họ cho họ? Thật là ác! ( ẩn )
billpg

3
Đối với tất cả những người sử dụng python 3: Mã này không hoạt động trên python 3+, để chạy mã này trên python 3, bạn phải đổi m /= 10sang m //= 10. Nếu bạn không thì m sẽ trở thành một float và điều kiện m % 1000 == 666sẽ liên tục là sai và "666" khác trong n được giữ nguyên.
Sirac

50

JavaScript (được cập nhật để hoạt động với tất cả các trường hợp thử nghiệm)

Sự thật ít được biết đến là thực tế có bốn 6s, nhưng một trong những người khác đã phản bội và biến thành dạng mã để xóa chúng khỏi các chữ số thế giới của các con số. Đây là sáu kẻ phản bội:

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

Đây là một lời giải thích. Đầu tiên, làm đẹp mã và loại bỏ những thứ vô dụng như ''+'string'((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)
);

Chuyển đổi các ký hiệu lạ (như ~indexOf['replace']) thành các ký hiệu phổ biến hơn:

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

Và bây giờ hiểu đơn giản là thuật toán đi như thế này:

  • Nếu đã có 666 trong đầu vào,

    • thay thế nó bằng 667.
    • thay thế mỗi chữ số sau đó bằng 0.
  • khác

    • thêm một vào số
    • LƯU Ý: hiện tại chúng tôi được đảm bảo không có 666, 666 ở cuối chuỗi hoặc 666 ở một nơi khác đã có các số 0 đi đến cuối (nghĩ "mang theo" khi thực hiện bổ sung "thủ công").
    • nếu có 666, hãy thay thế bằng 667.

Phiên bản cũ (không hoạt động 666666666) :

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

Để hiểu điều này, trước tiên hãy làm đẹp nó:

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

Bây giờ, hãy loại bỏ những thứ vô dụng như '' + string'str' + 'ing', loại bỏ sbiến không cần thiết và thay đổi sự kỳ lạ như -~![]thành 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,'')chỉ đơn giản là "length":

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

"undefined"[0]"u", và "u".length1:

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

Bây giờ chúng ta đã hoàn thành! Nó nên khá dễ hiểu bây giờ.


13
Tôi thích câu trả lời của bạn nhưng không thành công666666666
Michael M.

3
@Michael Đã thêm phiên bản mới! Hoạt động cho 666666666, và phông chữ của 6fancier;)
Doorknob

1
Huh - sử dụng ~1cho != -1là khá mát mẻ.
wchargein

@WChargin Quá tệ khi không hoạt động trong LiveScript. Tôi biết đây không phải là mã golf nhưng tôi có một phiên bản golf trong bài viết của mình để giải trí.
nyuszika7h

Nó không hoạt động trong LiveScript :). ~a.indexOf('b')tạo ra JS chính xác, hãy thử nó trên lifecript.net!
Ven

20

Táo

Trang web này không có đủ câu trả lời Applescript. Hãy xua đuổi ma quỷ!

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)

Nhật ký đầu ra:

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

Tôi muốn nhận được một số trích dẫn mạnh mẽ hơn từ The Exorcist về điều này, nhưng điều đó sẽ khiến bài đăng này được quyết định NSFW. Bạn có thể đọc trang IMDB thay thế.


Làm thế nào để bạn chạy cái này mà không có OS X?
nyuszika7h

Tôi nghĩ Applescript phụ thuộc khá nhiều vào OSX stackoverflow.com/questions/7642299/, - Tôi không biết về bất kỳ cổng nào cho các nền tảng khác. OS 9 đã có phiên bản Applescript, mặc dù không có gì đảm bảo rằng tập lệnh này sẽ chạy ở đó.
Chấn thương kỹ thuật số

2
Nó sẽ làm cho bài viết Không phải cho công việc an toàn? Khỉ thật, công việc của tôi không nguy hiểm
Cruncher

1
@Cruncher oops ;-)
Chấn thương kỹ thuật số

1
+1 cho sự lựa chọn tên biến (và vì tập lệnh apple rất tuyệt).
Floris

15

Perl

Bạn nói rằng chúng ta không được tăng trong một vòng lặp. Tôi hoàn toàn không sử dụng bất kỳ toán tử toán học nào! Đây là một cách tiếp cận thay thế regex thuần túy (không đảm bảo nó an toàn cho sự tỉnh táo của bạn).

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

Ba thay thế đầu tiên tăng số lượng một. Tôi đã tự mình giải quyết vấn đề đó một lần, nhưng nó bao gồm một sự thay thế phải được lặp đi lặp lại cho đến khi không có sự thay thế nào được thực hiện nữa, vì vậy tôi đã sử dụng phương pháp của Andrew Cheong thay thế.

Sự thay thế thứ tư biến tất cả các chữ số sau a 666thành số không. Sự thay thế cuối cùng biến phần còn lại 666thành a 667.

Như một phần thưởng, điều này sẽ hoạt động với nhiều số nguyên trong đầu vào miễn là chúng được phân tách bằng các ký tự không có chữ số.


8

LiveScript

Đây là uốn cong các quy tắc. Bạn thấy đấy, bạn nói tôi không được sử dụng một vòng lặp thêm một vòng cho đến khi nó tìm thấy một kết quả chính xác. Vì vậy, tôi trừ đi một trừ thay!

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

Một phiên bản chơi gôn trong 53 48 45 byte cho vui:

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

Cảm ơn người dùng1737909 đã giúp chơi golf hơn nữa.

Xét nghiệm

Yêu cầu Node.js với LiveScriptmô-đun npm hoặc thư viện khẳng định tương thích.

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
Nó sẽ thất bại khủng khiếp khi bạn đến 665999, vì ngăn xếp của bạn sẽ nổ tung.
TimWolla

9
Rất thông minh. Bạn nên viết RFC để phát hiện ra sơ hở như thế.
billpg

1
@TimWolla Thật thú vị. Làm thế nào bạn tìm được?
nyuszika7h

1
@ nyuszika7h: Nếu bạn nghĩ về nó, 666000 đến 666999 sẽ thất bại ... bạn sẽ được đệ quy ít nhất 1000 lần.
Andrew Coonce

1
Tôi không có một lý do cụ thể, tôi đoán.
nyuszika7h

6

Hồng ngọc

Đây là (tôi nghĩ) câu trả lời đầu tiên hoạt động cho 666666666. (Ngoại trừ câu trả lời -1 gian lận .;))

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

Bây giờ tôi đang rất vội; giải thích sẽ được bổ sung sau.

Cập nhật : phiên bản hiệu quả hơn nhiều (tôi tin rằng thời gian chạy gần như không đổi):

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

Trên thực tế, câu trả lời của tôi hoạt động tốt cho
666666666.

Thời gian chạy liên tục là không thể. Ngay cả việc kiểm tra xem "666" có tồn tại hay không là một vấn đề tuyến tính. Đây là một vấn đề hoàn toàn khó khăn hơn thế.
Cruncher

4

PowerShell

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

4

J

Cuối cùng, một cách sử dụng tốt cho E.!

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

Về bản chất, chúng tôi tìm vị trí đầu tiên trong đó đối số có đầy đủ 666và chúng tôi thay thế chuỗi con đó và mọi thứ sau đó 66700000...cho đến khi kết thúc.

Giải thích chi tiết:

  • ":@>: - Tăng thêm một và chuyển đổi thành chuỗi.
  • '666'&E. - Tạo một vectơ booleans, đúng ở mỗi nơi '666' bắt đầu trong chuỗi.
  • i.1: - Tìm chỉ số của true đầu tiên trong vectơ, khác trả về độ dài của vectơ.
  • #@[-]- Độ dài của chuỗi (cũng là độ dài của vectơ) trừ đi kết quả của i..
  • '667'{.!.'0'~ - Lấy một chuỗi con '667' với độ dài của kết quả đó, đệm bên phải với '0' nếu cần.
  • {.~- Lấy một chuỗi con với độ dài của kết quả ban đầu từ i..
  • , - Nối hai người lại với nhau.

Đang sử dụng:

   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

Và vì đây không phải là một môn đánh gôn, nên điều này không cần phải chơi golf với những tối ưu hóa điên rồ. Mọi người đều thắng!


3

C #

148 137 ký tự

Đã có thể cạo sạch một vài ký tự nhờ @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'));}

Ung dung:

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

Câu đố: http://dotnetfiddle.net/XB83bf


1
Dấu ngoặc vuông trong regex của bạn là không cần thiết, và cũng có rất nhiều khoảng trắng không cần thiết về mặt cú pháp.
đệ quy

Oh, và Int32có thể được thay thế bằng int.
đệ quy

@recursive Bạn đã đúng, cảm ơn!
Dùng thử

Lưu ý đây là một cuộc thi phổ biến và không phải là môn đánh gôn . Đã nói rằng nếu bạn cảm thấy cạo nhân vật sẽ làm cho câu trả lời của bạn trở nên phổ biến hơn, thì hãy đi cho nó!
Chấn thương kỹ thuật số

2
Đầu tiên tôi đã thấy dotnetfiddle.net =) TUYỆT VỜI!
Coops

2

Con trăn

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

Mã nội tuyến thay đổi nội dung bên trong $_, một ý thức hệ khá chuẩn trong perl. Có thể được sử dụng kết hợp với -pcờ như thế này:

$ perl -p % <<< 66666
66700

2

J

Không có chuỗi, vòng lặp hoặc điều kiện:

   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

Tương tự như giải pháp của tông_box, cách này chia số thành các nhóm có ba chữ số bằng cách chia cho lũy thừa mười. Nó sử dụng chỉ số của lần xuất hiện đầu tiên là 666 để làm tròn số lên một cách thích hợp.


2

Haskell (70 ký tự)

Đây là một thực hiện đơn giản trong 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 []         = []
  • Đầu tiên, nó sử dụng map digitToInt . showđể chuyển đổi một ID xấu có thể thành một danh sách các chữ số.
  • Tiếp theo, purgephù hợp với mô hình ác và thay thế nó bằng tương đương tốt của nó.
  • Cuối cùng, foldl' ((+).(*10)) 0giảm danh sách các chữ số thành một Integer.

Hãy xem nó hoạt động!

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

Có vẻ tốt. Và chỉ để cho vui một phiên bản golf.

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

1

Java

Nó không đủ để làm điều này?

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

Đóng, nhưng đó nên được String.valueOf(currentId + 1).
nyuszika7h

Oh đúng, tôi quên rằng +1 điều! : D
Valentin Grégoire

Điều kiện đó là vô ích; giải pháp ban đầu được sửa đổi một chút theo đề nghị của tôi cũng sẽ hoạt động:return Integer.parseInt(String.valueOf(currentId + 1).replace("666", "667"));
nyuszika7h

1
Không đúng ... 66600 sẽ được trả về là 66701, tức là 1 quá cao.
Valentin Grégoire

1

R

Thay thế 666 bằng 667 công trình.

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

Các kết quả

> 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 câu trả lời JavaScript khác nhau:

1. JavaScript (Bản thảo 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)

Chuyển đổi số thành một chuỗi sau đó lặp lại qua từng ký tự cho đến khi tìm thấy 666sau đó nó thay đổi kéo dài 6thành a 7và đầu ra0 cho tất cả các ký tự sau.

2. JavaScript (Bản thảo ECMAScript 6)

Hàm đệ quy không có thao tác chuỗi:

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

Hoặc dài dòng hơn:

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

Các xét nghiệm:

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

3. JavaScript

Sử dụng biểu thức chính quy:

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

Hoặc (tương tự nhưng sử dụng ECMAScript 6)

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

Với phiên bản đầu tiên của bạn, nếu bạn nhập 6 septillion, 666 sextillion, bạn sẽ nhận được giá trị trả về 6.667vì vậy về mặt kỹ thuật vẫn còn đó. Đừng nghĩ rằng nó có thể được giúp đỡ mặc dù.
Spedwards

1e20là về thứ tự cường độ lớn nhất mà JavaScript (ít nhất là trong FireFox) sẽ in dưới dạng một số nguyên mà không cần dùng đến ký hiệu khoa học.
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_

cho

2
667
667000000
667000000
66700

chỉnh sửa: giải pháp thứ 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_

sản lượng

2
667
667000000
667000000
66700
1236670

1
mà dường như không phải là câu trả lời đúng. 665 nên cho 667, 66600 nên cho 66700, v.v.
ace_HongKongInependence

1
Kết quả của bạn chứa rất nhiều chuỗi con "666".
Glenn Randers-Pehrson

Điều đó thật xấu hổ. Tôi đã sửa 2 lỗi hàng rào (!) Tôi mắc phải vì tôi quên rằng awklập chỉ mục chuỗi dựa trên 1.
mschilli

@Cruncher Như đã nêu rõ ràng trong câu hỏi, f(665) returns 667vì nó đang hỏi "số nguyên tiếp theo không bao gồm 666"
ace_HongKongInependence

Tôi đã thêm một cách thứ 2 là a) nhiều awkish và b) giảm thiểu việc sử dụng các hàm chuỗi.
mschilli

0

Con trăn:

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

Hoặc là:

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

Tôi không thấy nó hoạt động như thế nào. Điều đó sẽ không biến 666666thành 667667thay vì 667000?
Martin Ender

@ m.buettner Điểm tốt, tôi nghĩ rằng tôi đã có một giải pháp.
Iuʎ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
    }
}

Sử dụng hàm đệ quy để tìm 666 ngoài cùng bên trái và tính toán mức độ điều chỉnh số khi bật lại ngăn xếp cuộc gọi.


Tôi không nghĩ mã này là chính xác. Nó mang lại kết quả gì cho đầu vào 666666666?
thuật toán

Bạn đã đúng, không nhận ra rằng đầu vào đã có thể chứa số Evil. Vậy f (666666666) -> 667667667?
Roger Lindsjö

f(666666666) -> 667000000
djhurio

@djhurio Có vẻ như tôi không thể tạo các bài kiểm tra cho các trường hợp cạnh ngày hôm nay. Hãy tin rằng tôi đã sửa nó ngay bây giờ, nhưng mã không còn quá ngắn nữa.
Roger Lindsjö

1
@ RogerLindsjö Đây là một popularity-contest, không phải a code-golf.
nyuszika7h

0

Mẻ

Thao tác chuỗi lặp đơn giản.

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

Nó bắt đầu ở ba ký tự đầu tiên của số (dưới dạng một chuỗi) và đi đến cuối cho đến khi tìm thấy 666, sau đó thay thế 666 bằng 667 và lặp lại theo chiều dài của chuỗi thêm số không.

Các trường hợp thử nghiệm đều cho kết quả chính xác.


0

perl, 45 byte

Một regex duy nhất với cờ / e thực hiện tất cả công việc ở đây:

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

0

SQL

Nói chính xác, 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

Con trăn

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

Kết quả 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 #

Tôi làm đúng không

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

Trong hành động:

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

kết quả:

2 
667 
667000000 
667000000 
66700 
456670 

0

C ++

Tôi biết đây không phải là môn đánh gôn, nhưng (a) một số người cho rằng đây là một thử thách golf tốt và (b) đây là thử thách / câu trả lời golf đầu tiên của tôi, tôi nghĩ nó sẽ rất vui, và nếu tôi làm vậy Điều này ở đây tôi không được thể hiện trong một thử thách golf thực sự vì là một tay golf khủng khiếp. X)

Về cơ bản, thay thế '666' bằng '667' hoạt động nếu bạn thực hiện nó cho ví dụ đầu tiên trong số và sau đó viết ra các dấu 0.

Chơi gôn ( 175 155 ký tự):

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

Ung dung:

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

Tôi nghĩ rằng bạn không cần x+=c=='6'?1:0, bạn có thể thoát khỏi x+=c=='6'. Mặc dù vậy, đã không thử nó.
nyuszika7h

Ngoài ra, bạn đã bỏ đi std::trước stringstream. Nó không biên dịch mà không có điều đó.
nyuszika7h

Đã thêm std ::, cảm ơn vì điều đó @ nyuszika7h. Tôi đã phạm sai lầm khi sử dụng IDE tự động phát sinh 'bằng cách sử dụng không gian tên std;' để kiểm tra nó. -_- Tôi sẽ thử x+=c=='6'giảm, cũng như xem xét việc này với các chữ số int thay vì ký tự dòng ...
mike32

0

Hồng ngọc

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 chỉ là phụ, không có byte

Một phiên bản ngắn hơn giải pháp cuối cùng của tôi, sử dụng kết hợp các ops số học và regex.

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

in phụ {...}
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 - không có giới hạn kiểm tra và quá nhiều khoảng trắng nhưng đó không phải là golf. Cũng là một chút thú vị của định dạng trong "while (d -> 0)".

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.