Избегайте злых чисел! [закрыто]


53

Вы разрабатываете некоторый код для генерации идентификационных номеров. Политика требует, чтобы никакие идентификационные номера не включали последовательность цифр 666 .

Создайте функцию (или эквивалент вашего языка), которая принимает положительный целочисленный параметр и возвращает следующее целое число, которое не включает 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 на 667 не будет работать, если на входе более одного 666.


1
А как насчет 456667? Должно ли это вернуть 456670, или нас беспокоит только ведущий 666?
Кайл Канос,

11
Я думаю, что это было бы лучше в качестве кода-гольфа, чем конкурса популярности, поскольку существуют такие простые решения.
Нейт Элдридж

10
@ nyuszika7h но результат должен быть 66700.
Мартин Эндер

3
как настоящий вызов, должно было также быть требование не иметь «666» где-либо в коде
DLeh

2
В зависимости от вашей реализации регулярных выражений, вы можете использовать '6 {3}' для обнаружения 666.
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

Работает путем нахождения степеней 10, pгде появляется 666, и добавления p - n % pк nкоторым заменяется 666xxxxxна 66700000.


6
Мне нравится это в том , что если бы это было на самом деле реальное требование к клиенту, эта реализация не является Hacky, разумной и эффективной.
RomanSt

Будет ли это работать с числами, которые содержат несколько экземпляров 666?
суперкат

Да. Самый левый 666 - единственный, который действительно имеет значение, и этот алгоритм фиксирует этот последний.
картонная

19
@romkyns Опубликовать фактическое требование клиента к Codegolf, чтобы заставить других людей делать свою работу за них? Это зло! ( прячется )
billpg

3
Для всех, кто использует Python 3: этот код не работает на Python 3+, чтобы запустить этот код на Python 3, вы должны перейти m /= 10на m //= 10. Если вы этого не сделаете, то m станет плавающей точкой, и условие m % 1000 == 666будет постоянно ложным, а остальные «666» в n остаются без изменений.
Сирак

50

JavaScript (обновлен для работы со всеми тестами)

Малоизвестная истина заключается в том, что на самом деле существует четыре 6s, но один из них предал других и превратился в кодовую форму, чтобы искоренить их из мировых цифр чисел. Вот эта предательская шестерка:

    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.
  • иначе,

    • добавить один к числу.
    • ПРИМЕЧАНИЕ: теперь у нас гарантированно не будет ни 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
Майкл М.

3
@Michael Добавлена ​​новая версия! Работает на 666666666, и шрифт 6
изумительнее

1
Да, использовать ~1для != -1это очень круто.
wchargin

@WChargin Жаль, что не работает в LiveScript. Я знаю, что это не кодовый гольф, но в моем сообщении есть версия для гольфа.
nyuszika7h

Это работает в LiveScript :). ~a.indexOf('b')генерирует правильный JS, попробуйте это на livecript.net!
Ven

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

Я думаю, что Applescript в значительной степени зависит от OSX stackoverflow.com/questions/7642299/… - я не знаю никаких портов для других платформ. OS 9 действительно имела версию Applescript, хотя нет никаких гарантий, что этот скрипт будет работать там.
Цифровая травма

2
Это сделал бы пост Не для безопасной работы? Черт возьми, моя работа не опасна
Cruncher

1
@Cruncher упс ;-)
Цифровая травма

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

Первые три замены увеличивают число на единицу. Однажды я сам решил эту проблему, но она включала замену, которую нужно было повторять до тех пор, пока не было выполнено никаких замен, поэтому вместо этого я использовал подход Эндрю Чонга .

Четвертая подстановка превращает все цифры после a 666в нули. Окончательная замена превращает оставшиеся 666в 667.

В качестве бонуса это будет работать с несколькими целыми числами на входе, если они разделены нецифровыми символами.


8

LiveScript

Это сгибание правил. Видите ли, вы сказали, что я не должен использовать цикл, который добавляет один, пока не найдет правильный результат. Поэтому я вычитаю минус один вместо этого!

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.js с LiveScriptмодулем npm или совместимой библиотекой assert.

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, он ужасно провалится, так как ваш стек взорвется.
TimWolla

9
Очень умно. Вы должны писать RFC, чтобы обнаружить подобные лазейки.
billpg

1
@TimWolla Это интересно. Как ты это нашел?
nyuszika7h

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», является линейной проблемой. Это более сложная проблема, чем эта.
Cruncher


4

J

Наконец, хорошее использование для E.!

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

По сути, мы находим первую позицию, в которой аргумент имеет полную 666, и заменяем эту подстроку и все после на 66700000...до конца.

Объяснил подробно:

  • ":@>: - Увеличить на единицу и преобразовать в строку.
  • '666'&E. - Создайте вектор логических значений, истинный в каждом месте, где в строке начинается «666».
  • i.1: - Найти индекс первого истинного в векторе, иначе вернуть длину вектора.
  • #@[-]- Длина строки (которая также является длиной вектора) минус результат i..
  • '667'{.!.'0'~ - Возьмите подстроку «667» с длиной этого результата, добавив справа «0», если необходимо.
  • {.~- Возьмите подстроку с длиной исходного результата из i..
  • , - Добавить два вместе.

В использовании:

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

Ungolfed:

public static int f(int b)
{
    b++;
    var z = new Regex("666[\\d]*");
    var q = z.Replace(b+"", "667", 1);
    return Int32.Parse(q.PadRight((b+"").Length, '0')); 
}

Скрипка: http://dotnetfiddle.net/XB83bf


1
Квадратные скобки в вашем регулярном выражении не нужны, и есть также много синтаксически ненужных пробелов.
рекурсивный

Ох, и Int32может быть заменен на int.
рекурсивный

@recursive Вы правы, спасибо!
Попытка

Обратите внимание, что это конкурс популярности, а не код-гольф . Сказав, что если вы чувствуете, что выбривание персонажей сделает ваш ответ более популярным, сделайте это!
Цифровая травма

2
Сначала я увидел dotnetfiddle.net =) УДИВИТЕЛЬНЫЙ!
Coops

2

питон

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

Как и в случае с картонной коробкой, это делит число на группы из трех цифр путем деления на степени десяти. Он использует индекс первого вхождения 666, чтобы округлить число соответствующим образом.


2

Хаскель (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для преобразования возможно злой идентификатор в список цифр.
  • Затем purgeсопоставляет шаблон зла и заменяет его хорошим эквивалентом.
  • Наконец, foldl' ((+).(*10)) 0сокращает список цифр до одного 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

Ява

Разве этого недостаточно, чтобы сделать это?

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

1
Не верно ... 66600 будет возвращено как 66701, что на 1 слишком высоко.
Валентин Грегуар

1

р

Замена 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 Draft)

Рекурсивная функция без манипуляции со строками:

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 septillion, 666 sextillion, вы получите возвращаемое значение, 6.667так что технически он все еще там. Не думаю, что это может помочь, хотя.
Спедвардс

1e20примерно на порядок выше, что JavaScript (по крайней мере, в 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" подстрок.
Гленн Рандерс-Персон

Это смущает. Я исправил 2 (!) Ошибки забора поста, которые я сделал, потому что я забыл, что awkиндексирует строки на основе 1.
mschilli

@Cruncher Как четко указано в вопросе, так f(665) returns 667как он запрашивает «следующее целое число, которое не включает 666»
ace_HongKongIndependence

Я добавил 2-й способ, который а) больше awkish и б) минимизирует использование строковых функций.
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'))

Я не понимаю, как это работает. Не будет ли этот поворот 666666в 667667а 667000?
Мартин Эндер

@ m.buettner Хороший вопрос, я думаю, что у меня уже есть решение.
Aprıʇǝɥʇuʎs

0

Ява

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?
алгоритмистика

Вы правы, не поняли, что на входе уже могут быть цифры Зла. Итак, f (666666666) -> 667667667?
Роджер Линдсё

f(666666666) -> 667000000
Джурио

@djhurio Кажется, я не могу генерировать тесты для крайних случаев сегодня. Поверьте, я исправил это сейчас, но код уже не такой короткий.
Роджер Линдсё

1
@ RogerLindsjö Это, а popularity-contestне code-golf.
nyuszika7h

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%

Он начинается с первых трех символов числа (в виде строки) и продолжается до конца, пока не найдет 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

питон

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

УВА

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

Я знаю, что это не код-гольф, но (а) некоторые люди предположили, что это хороший вызов для гольфа, и (б) это мой первый ответ на вызов в гольф, я подумал, что это будет весело, и если я это сделаю это здесь, я не появляюсь в реальной проблеме гольфа для того, чтобы быть ужасным игроком в гольф. ИКС)

По сути, замена '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;}

Ungolfed:

#include<sstream>
int f(int x){
    std::stringstream s,o;
    s<<++x;    // Increment to next int.
    x=0;       // Reusing this to count 6s
    for(char c=s.get();!s.eof();c=s.get()){    // For each digit
        if (c=='6'){
           ++x;    // Count sixes...
        }
        if(x==3) {  // Devil's number!
            c='7'; // Output 7 here.
            ++x;   // Increment once more.
        } else if (x > 3) {
            c='0';    // Already replaced 666 with 667, so write out 0s
        }
        o<<c;   // Append digit
    }
    o>>x; // Get int
    return x;
}

Я думаю, что вам не нужно x+=c=='6'?1:0, вы можете сойти с рук x+=c=='6'. Хотя не пробовал.
nyuszika7h

Кроме того, вы пропустили std::ранее stringstream. Это не компилируется без этого.
nyuszika7h

Добавил std ::, спасибо за это @ nyuszika7h. Я сделал ошибку, используя IDE, которая автоматически сгенерировала 'using namespace std;' чтобы проверить это. -_- Я попробую x+=c=='6'сокращение, а также посмотрю на это с помощью цифр int, а не sstream-символов ...
mike32


0

perl, 36 просто саб, без байтов

Более короткая версия, чем мое последнее решение, с использованием сочетания операций арифметики и регулярных выражений.

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

print + (<> + 1) = ~ s / 666 (. *) / 667 $ 1 / r- $ 1 (сэкономил вам байт) (еще два, если вы скажете) - хотя запрос был для функции, поэтому удалите print + и используйте sub {...}
Altreus

0

С

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

Хорошо - без проверки границ и слишком много пробелов, но это не гольф. Также забавно немного форматировать в "while (d -> 0)".

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.