Уникайте злих цілих чисел! [зачинено]


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?
supercat

Так. Найменше лівий 666 - це єдиний, який насправді має значення, і цей алгоритм фіксує останній.
cardboard_box

19
@romkyns Опублікувати справжню реальну вимогу клієнта до кодегольфа, щоб обдурити інших людей робити свою роботу за них? Це зло! ( приховує )
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вигадливіший;)
Doorknob

1
Так, користуватися ~1для != -1досить здорово.
wchargin

@WChargin Шкода, що не працює в LiveScript. Я знаю, що це не код гольфу, але у мене в пості є версія для гольфу.
nyuszika7h

Це працює в LiveScript :). ~a.indexOf('b')генерує правильний JS, спробуйте на livecript.net!
Вен

20

Яблукопис

На цьому сайті недостатньо відповідей на Apple. Нехай виганяють деяких демонів!

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

Я хотів би ввійти в цю частину більш потужних цитат The Exorcist , але це зробило б цю публікацію рішучо NSFW. Ви можете замість цього прочитати сторінку IMDB.


Як це запустити, не маючи ОС X?
nyuszika7h

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

2
Це зробило б посаду Не для безпечної роботи? Блін, моя робота не є небезпечною
Cruncher

1
@Cruncher oops ;-)
Digital Trauma

1
+1 для вибору змінних імен (і тому, що сценарій яблук крутий).
Флоріс

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на a 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

Завдяки користувачу1737909 за те, що допомагає гольфу в подальшому.

Тести

Потрібен Node.js з LiveScriptмодулем npm або сумісною бібліотекою аспертів.

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.

Постійний час виконання неможливий. Навіть перевірка наявності "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'));}

Безголівки:

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
Квадратні дужки у вашому регулярному виразі непотрібні, а також є багато синтаксично непотрібних пробілів.
рекурсивна

О, і Int32можна замінити на int.
рекурсивна

@recursive Ви праві, дякую!
Пробуємо

Зауважте, це популярність-конкурс, а не гольф-код . Сказавши, що якщо ви відчуваєте, що збривати персонажів, зробить вашу відповідь більш популярною, тоді йдіть за цим!
Цифрова травма

2
Вперше я бачив dotnetfiddle.net =) ДУЖЕ!
Чашки

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

Подібно до рішення cardboard_box, це розділяє число на групи з трьох цифр шляхом поділу на потужності на десять. Він використовує індекс першого появи 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для перетворення імовірного ідентифікатора в список цифр.
  • Далі, 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

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

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

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до а, 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 септиліонів, 666 секстиліон, ви отримаєте зворотну вартість, 6.667так що технічно це все ще є. Не думаю, що це може допомогти.
Spedwards

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

Я додав другий спосіб, а) більше awkish і b) мінімізує використання рядкових функцій.
mschilli

0

Пітон:

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 Добре, я думаю, що у мене вже є рішення.
ɐɔıʇǝɥʇ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?
алгоритм

Ви праві, не усвідомлювали, що вхідні дані вже можуть містити злі числа. Так f (666666666) -> 667667667?
Роджер Ліндсьйо,

f(666666666) -> 667000000
djhurio

@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

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

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

Я знаю, що це не код-гольф, але (а) деякі люди припустили, що це хороший виклик у гольф, і (б) це моя перша проблема / відповідь на гольф, я подумав, що це буде весело, і якщо я це зробити це тут я не показуюсь справжньою проблемою для гольфу за те, що я був страшним гольфістом. X)

В основному, заміни "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

Крім того, ви пропустили std::раніше stringstream. Без цього він не компілюється.
nyuszika7h

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


0

perl, 36 тільки sub, без байтів

Більш коротка версія, ніж моє останнє рішення, з використанням суміші арифметичних та регулярних виразів.

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

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

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.