邪悪な整数を避けてください![閉まっている]


53

ID番号を生成するためのコードを開発しています。ポリシーでは、ID番号に数字列666が含まれていないことが必要です。

正の整数パラメーターを取り、その整数が10進数で表現されたときに666を含まない次の整数を返す関数(または言語の同等物)を作成します。(60606は大丈夫ですが、66600は大丈夫です。)

コードでは、ルールに適合する結果が見つかるまで、ループを追加するループを使用しないでください。

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.

更新:
入力に複数の666がある場合、666を667に置き換えても機能しません。


1
456667のようなものはどうですか?456670を返す必要がありますか、それとも先頭の666だけが心配ですか?
カイルカノス

11
このような簡単な解決策があるので、これは人気コンテストよりもコードゴルフとして優れていると思います。
ネイト・エルドリッジ14

10
@ nyuszika7hしかし結果はになるはずです66700
マーティンエンダー14

3
本当の挑戦として、また、コード内の「666」どこにも持っていないようにする必要性があったはず
DLeh

2
あなたの正規表現の実装によっては、666を検出するために、「6 {3}」使用することができます
celtschk

回答:


53

Python、文字列操作なし

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

p666が現れる10のべき乗を見つけ、それをp - n % pn置き換え666xxxxxて追加することで機能し66700000ます。


6
これだったらということで、このようなI 実際に本当の顧客の要件、この実装は、非ハック賢明かつ効率的です。
RomanSt

これは、666の複数のインスタンスを含む数値で機能しますか?
supercat

はい。一番左の666が実際に重要な唯一のものであり、このアルゴリズムはそれを最後に修正します。
cardboard_box 14

19
@romkyns実際の顧客の要件をcodegolfに投稿して、他の人をだまして仕事をさせますか?それは悪です!(非表示
billpg

3
python 3を使用するすべての人にとって、このコードはpython 3以降では機能しません。python3でこのコードを実行するには、に変更m /= 10する必要がありますm //= 10。そうしないと、mは浮動小数点数になり、条件m % 1000 == 666は常にfalseになり、nの他の「666」は変更されません。
Sirac

50

JavaScript(すべてのテストケースで動作するように更新)

あまり知られていない真実は、実際には4がありますが6、そのうちの1つは他のものを裏切り、コード形式に変形して、数字の世界桁からそれらを根絶することです。その裏切り者は次のとおりです。

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

ここに説明があります。まず、コードを美化など役に立たないものを削除''+'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)
);

奇妙な表記(~indexOfやなど['replace'])をより一般的な表記に変換します。

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

そして、アルゴリズムが次のようになることを理解してください。

  • 入力にすでに666がある場合、

    • 667に置き換えます。
    • その後のすべての数字を0に置き換えます。
  • そうでなければ、

    • 番号に1を追加します。
    • 注:666がないか、文字列の末尾に666があるか、または末尾にゼロが既にある666があることが保証されています(「手動」加算を行うときは「持ち運び」を考えてください)。
    • 666がある場合は、667に置き換えます。

古いバージョン(では機能しません666666666

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

これを理解するために、まずそれを美しくしましょう:

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

では、'' + stringやなどの役に立たないものを'str' + 'ing'削除し、不必要なs変数を削除し、次のよう-~![]に奇妙さを変更し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,'')単純に"length"

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

そして"undefined"[0]ある"u"、と"u".lengthあります1

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

これで完了です!今ではかなり簡単に理解できるはずです。


13
私はあなたの答えが好きですが、失敗しました666666666
マイケルM.

3
@Michaelが新しいバージョンを追加しました!のため666666666に動作し、フォント6はより洗練されています;)
ドアノブ

1
はぁ-使用する~1ためには、!= -1かなりクールです。
wchargin 14

@WChargin残念ながら、LiveScriptでは機能しません。私はこれがゴルフのコードではないことを知っていますが、楽しみのために私の投稿にはゴルフバージョンがあります。
nyuszika7h

LiveScriptで動作します:)。~a.indexOf('b')正しいJSを生成します。livescript.netで試してください!
ヴェン

20

Applescript

このサイトには十分なApplescript回答がありません。いくつかの悪魔を追い払おう!

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)

ログ出力:

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

エクソシストからのより強力な引用のいくつかをこれに入れたいと思っていましたが、それにより、これは明らかにNSFWに投稿されました。代わりにIMDBページを読むことができます。


OS Xなしでこれをどのように実行しますか?
nyuszika7h 14

私はAppleScriptをはOSXの依存はかなりあると思いstackoverflow.com/questions/7642299/... -私は他のプラットフォームへの任意のポートを認識していませんよ。OS 9に Applescriptのバージョンがありましたが、このスクリプトがそこで実行されるという保証はありません。
デジタル外傷

2
Not For Safe Work?を投稿したでしょう。くそー、私の仕事は危険ではない
ランチャー14

1
@Cruncherおっと;-)
デジタル外傷14

1
変数名の選択に対して+1(およびAppleスクリプトがクールなため)。
フローリス

15

Perl

ループでインクリメントしてはいけないと言っていました。数学演算子をまったく使用していません!これは純粋な正規表現の置換アプローチです(正気のために安全であるという保証はありません)。

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

最初の3つの置換は、番号を1ずつ増やします。私は一度その問題を自分で解決しましたが、置換が含まれるまでループする必要があったため、代わりにAndrew Cheongのアプローチを使用しました。

4番目の置換は、a 666に続くすべての数字をゼロに変換します。最終置換ターンは残り666667

おまけとして、これは、数字以外の文字で区切られている限り、入力内の複数の整数で機能します。


8

LiveScript

これはルールを曲げています。おわかりのように、正しい結果が見つかるまで、ループを追加するループを使用しないでください。そのため、代わりにマイナス1引きます!

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

楽しみのために53 48 45バイトのゴルフバージョン:

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

さらにゴルフを助けてくれたuser1737909に感謝します。

テスト

Node.jsLiveScriptnpmモジュールまたは互換性のあるアサートライブラリが必要です。

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
スタックが爆発するため、665999に達すると恐ろしく失敗します。
ティムウォラ14

9
非常に賢い。そのような抜け穴を見つけるためにRFCを書くべきです。
billpg

1
@TimWollaそれは面白いです。どうやって見つけたの?
nyuszika7h 14

1
@ nyuszika7h:考えてみると、666000〜666999はすべて失敗します...少なくとも1000回再帰します。
アンドリュークーンス

1
特別な理由はないと思う。
nyuszika7h

6

ルビー

これは(私が思うに)666666666で機能する最初の答えです(-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

今急いでいます。説明は後で追加されます。

更新:はるかに効率的なバージョン(ほぼ一定のランタイム)

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

実際、私の答えは666666666でうまく機能します。
isaacg

一定の実行時間は不可能です。「666」が存在するかどうかを確認することも線形の問題です。これは、それよりも厳密に難しい問題です。
ランチャー14


4

J

最後に、E.

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

本質的に、引数にfullがある最初の位置を見つけ、666その部分文字列とそれ以降をすべてで置き換えます66700000...最後までます。

詳細な説明:

  • ":@>: -1ずつインクリメントし、文字列に変換します。
  • '666'&E. -ブール値のベクトルを作成します。「666」が文字列で始まる各場所でtrueです。
  • i.1: -ベクトル内の最初のtrueのインデックスを見つけます。そうでない場合は、ベクトルの長さを返します。
  • #@[-] -文字列の長さ(ベクトルの長さでもあります)から結果を引いたもの i.
  • '667'{.!.'0'~ -結果の長さで「667」の部分文字列を取得し、必要に応じて「0」を右側に埋め込みます。
  • {.~ -元の結果の長さの部分文字列を取得します i.ます。
  • , -2つを一緒に追加します。

使用中で:

   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

そして、これはコードゴルフではないため、クレイジーな最適化でゴルフを地獄に落とす必要はありません。みんなが勝つ!


3

C#

148 137文字

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

ゴルフをしていない:

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

フィドル:http : //dotnetfiddle.net/XB83bf


1
正規表現の角括弧は不要です。また、構文的に不要なスペースもたくさんあります。
再帰14

ああ、そしてInt32に置き換えることができますint
再帰的14

@再帰あなたは正しい、ありがとう!
試行

これは人気コンテストであり、code-golfではありません。あなたがキャラクターを剃るのを感じるならあなたの答えがより人気になると言って、それのために行きなさい!
デジタル外傷

2
まず、dotnetfiddle.net =)を見てきました!
コープ14

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

内部のコンテンツを変更するインラインコード$_、perlのかなり標準的なイデオロギー。次の-pようなフラグと組み合わせて使用​​できます。

$ perl -p % <<< 66666
66700

2

J

文字列、ループ、条件なし:

   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

cardboard_boxのソリューションと同様に、これは、10の累乗で割ることにより、数字を3桁のグループに分けます。666の最初の出現のインデックスを使用して、数値を適切に切り上げます。


2

Haskell(70文字)

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 []         = []
  • まず、map digitToInt . show悪の可能性があるIDを数字のリストに変換するために使用します。
  • 次に、purge邪悪なパターンに一致し、それを同等の適切なパターンに置き換えます。
  • 最後に、foldl' ((+).(*10)) 0数字のリストを1 に減らしIntegerます。

動作するかどうか見てみましょう!

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

いいね。そして、楽しみのためにゴルフバージョンです。

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

1

Java

これを行うのに十分ではありませんか?

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

閉じますが、それはでなければなりませんString.valueOf(currentId + 1)
nyuszika7h

ああ、私はその+1を忘れてしまいました!:D
バレンティングレゴワール

その条件は役に立ちません。私の提案に従ってわずかに変更された元のソリューションも機能します:return Integer.parseInt(String.valueOf(currentId + 1).replace("666", "667"));
nyuszika7h 14

1
真実ではありません... 66600は66701として返されますが、これは1が高すぎます。
バレンティングレゴワール14

1

R

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

結果

> 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つの異なる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)

数値を文字列に変換し、見つかった各文字を繰り返し666、最後の文字6をaに変更し、後続のすべての文字7を出力0します。

2. JavaScript(ECMAScript 6ドラフト)

文字列操作のない再帰関数:

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

またはより詳細に:

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

テスト:

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

3. JavaScript

正規表現の使用:

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

または(同じですがECMAScript 6を使用)

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

最初のバージョンでは、6兆9千6千6兆を入力すると6.667、技術的にはまだそこにある戻り値が得られます。しかし、それが助けになるとは思わないでください。
-Spedwards

1e20JavaScript(少なくともFireFoxでは)が科学表記法に頼らずに整数として印刷される最大桁数です。
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_

与える

2
667
667000000
667000000
66700

編集: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_

利回り

2
667
667000000
667000000
66700
1236670

1
これは正解ではないようです。665は667、66600は66700などを与える必要があります
ace_HongKongIndependence

1
結果には、多くの「666」サブストリングが含まれています。
グレンランダース-パーソン

それは恥ずかしいです。awkインデックス文字列が1 から始まることを忘れていたため、作成した2(!)フェンスポストエラーを修正しました。
mschilli 14

@Cruncher質問で明示的に述べf(665) returns 667られているように、「666を含まない次の整数」を求めているため
ace_HongKongIndependence 14

2番目の方法を追加しましたawk。a )より使いやすく、b)文字列関数の使用を最小限にします。
mschilli

0

Python:

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

または:

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

私はそれがどのように機能するかわかりません。そのターンではないでしょう666666667667代わりには667000
マーティンエンダー14

@ m.buettner良い点、私はすでに解決策を持っていると思います。
ɐɔıʇǝɥʇ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
    }
}

再帰関数を使用して左端の666を見つけ、コールスタックを再度ポップするときに数値を調整する量を計算します。


このコードは正しいとは思わない。入力666666666に対してどのような結果が得られますか?
algorithmshark 14

あなたは正しい、入力が既に悪の数を含むことができることに気づかなかった。それで、f(666666666)-> 667667667?
ロジャー・リンショー14

f(666666666) -> 667000000
djhurio

@djhurio今日、エッジケースのテストを生成できないようです。私は今それを修正したと信じていますが、コードはもう短くありません。
ロジャーリンショー

1
@RogerLindsjöこれはでありpopularity-contest、ではありませんcode-golf
nyuszika7h 14

0

バッチ

単純な反復文字列操作。

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

数字の最初の3文字(文字列として)から始まり、666が見つかるまで最後まで進み、666を667に置き換え、ゼロを追加して文字列の長さまでループします。

テストケースはすべて正しい結果を生成します。


0

perl、45バイト

/ eフラグを含む単一の正規表現は、ここですべての作業を行います。

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

0

SQL

正確には、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

ジュリア

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の結果

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#

私はそれを正しくやっていますか

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

動作中:

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

結果:

2 
667 
667000000 
667000000 
66700 
456670 

0

C ++

私はこれがコードゴルフではないことを知っていますが、(a)何人かの人々はそれが良いゴルフチャレンジであることを示唆しており、(b)これは私の最初のチャレンジ/ゴルフの答えであり、私はそれが楽しいと思ったこれは、ひどいゴルファーであるための実際のゴルフチャレンジには現れません。バツ)

基本的に、数字の最初のインスタンスに対して「666」を「667」に置き換えてから、末尾の0を書き出します。

ゴルフ(175 155文字):

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

ゴルフをしていない:

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

私はあなたが必要としないと思うx+=c=='6'?1:0あなたが逃げることができ、x+=c=='6'。しかし、試したことはありません。
nyuszika7h 14年

また、std::前は省略しましたstringstream。それなしではコンパイルできません。
nyuszika7h 14年

std ::を追加しました。@ nyuszika7hに感謝します。「名前空間stdを使用」を自動生成するIDEを使用するというミスを犯しました。。で、それをテストするために-_-私がしようとするx+=c=='6'削減だけでなく、int型の数字ではなくsstream提供の文字でこれをやって見て...
mike32

0

ルビー

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はサブのみ、バイトなし

算術演算と正規表現演算を組み合わせて使用​​する、私の最後のソリューションよりも短いバージョン。

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

print +(<> + 1)=〜s / 666(。*)/ 667 $ 1 / r- $ 1(1バイト節約)(sayを使用する場合はさらに2つ)-要求は関数に対するものであるため、print +を削除して使用するsub {...}
アルトレウス14

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-境界チェックがなく、余白が多すぎますが、ゴルフではありません。また、「while(d-> 0)」の楽しいフォーマットです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.