Порахуйте без 3


45

Фон

Коли я навчався в початковій школі, ми грали в гру з математики, яка йде так.

Усі діти сидять у великому колі та по черзі рахують, починаючи з 1 .

Однак під час підрахунку необхідно пропустити такі цифри:

  • Числа, кратні 3 .
  • Числа, у яких десятичне подання є 3 .

Перші 15 номерів, про які діти повинні сказати, є

1 2 4 5 7 8 10 11 14 16 17 19 20 22 25

Кожен раз, коли хтось помиляється з номером - каже число, яке не в послідовності, або пропускає число, яке є, - його видаляють із кола. Це триває, поки не залишиться лише одна дитина.

Завдання

Вам погано в цій грі, тому ви вирішили обдурити. Напишіть програму або функцію, яка, задавши номер послідовності, обчислює наступне число послідовності.

Вам не доведеться обробляти числа, які не можуть бути представлені, використовуючи рідний числовий тип вашої мови, за умови, що ваша програма працює правильно до введення 251 і якщо ваш алгоритм працює для довільно великих входів.

Для введення та виводу можна використовувати будь-яку зручну базу.

Оскільки ви повинні приховати свій код, він повинен бути якомога коротшим. Насправді це , тому виграє найкоротший код у байтах.

Тестові справи

  1 ->   2
  2 ->   4
 11 ->  14
 22 ->  25
 29 ->  40
251 -> 254

5
Я відчуваю, що у нас був такий виклик ...
Conor O'Brien

5
Це завжди 7було пропущено, коли я грав його, але ви скажете щось інше, замість того, щоб перейти до наступного номера підряд.
mbomb007

12
@ mbomb007: Коли я грав у нього, тебе не видалили б із кола. Натомість ви б пили. Але цього було не в початковій школі. У будь-якому випадку, досягти 80 років було майже неможливо, особливо після першої години.
tomasz


4
@ mbomb007: Це залежатиме від доказів того, що ви п'єте.
tomasz

Відповіді:


21

Брахілог , 10 байт

<.='e3:I'*

Спробуйте в Інтернеті!

Пояснення

(?)<.                Output > Input
    .=               Assign a value to the Output
    . 'e3            3 cannot be an element of the Output (i.e. one of its digits)
        3:I'*(.)     There is no I such that 3*I = Output

3
Такі відповіді такі прекрасні в Брахілогу :)
Емінья

3
@Emigna Це майже не відчуває себе достатньо гольовим іноді, тому що в основному описує виклик безпосередньо. Так і є багато відповідей на тій мові :)
Fatalize

14

JavaScript (ES6), 30 байт

f=n=>++n%3*!/3/.test(n)?n:f(n)

І індекс 2, і індекс 3 повертають число 4 з цією функцією
nl-x

1
@ nl-x Так, оскільки 4 - наступне число у послідовності після 2 і 3. Це не індексується; це просто наступне число в послідовності.
ETHproductions

Я думаю, я починаю це розуміти ... Моє погано
nl-x

8

J, 24 байти

3(]0&({$:)~e.&":+.0=|)>:

Підхід прямого руху вперед, який просто пересувається вперед від вводу n, поки не знайде наступне число, що діє за правилами.

Форми п'яти смайликів, $:, :), 0=, =|, і >:.

Використання

   f =: 3(]0&({$:)~e.&":+.0=|)>:
   (,.f"0) 1 2 11 22 29 251
  1   2
  2   4
 11  14
 22  25
 29  40
251 254

Пояснення

3(]0&({$:)~e.&":+.0=|)>:  Input: integer n
                      >:  Increment n
3                         The constant 3
 (                   )    Operate dyadically with 3 (LHS) and n+1 (RHS)
                    |       Take (n+1) mod 3
                  0=        Test if equal to 0
             &":            Format both 3 and n+1 as a string
           e.               Test if it contains '3' in str(n+1)
                +.          Logical OR the results from those two tests
  ]                         Right identity, gets n+1
   0&(   )~                 If the result from logical OR is true
       $:                     Call recursively on n+1
      {                       Return that as the result
                            Else act as identity function and return n+1

Що ж, J - це, мабуть, найбільш схильна до усміхнення мова програмування.
Адам

8

Python 2, 73 66 43 байт

Завдяки xnor за те, що він сказав мені, що я був нерозумним за допомогою двох змінних, а також завдяки Мітчу Шварцу.

x=~input()
while'3'[:x%3]in`x`:x-=1
print-x

1
Оновлення з двома змінними виглядає дуже надто складно. Я думаю, що вам просто потрібно x=input()+1 while'3'[:x%3]in`x`:x+=1 print x.
xnor

@xnor, о так, нерозумно мені, я не знаю, чому я це зробив
Даніель

Поліпшення на один байт, починаючи з x=~input(), віднімання замість додавання та друку -x.
Мітч Шварц

1
@Artyer Це лише 1 з 3 помилок, введених у цій редакції.
Мітч Шварц

1
@Dopapp Поточна редакція (Без пробілу) становить 43 байти? mothereff.in/…
Artyer


7

Perl, 19 байт

18 байт код + 1 для -p.

++$_%3&&!/3/||redo

Використання

perl -pe '++$_%3&&!/3/||redo' <<< 8
10

perl -pe '++$_%3&&!/3/||redo' <<< 11
14

1
@ dan1111 Це Perl, що ти очікував? Чіткість?
Erik the Outgolfer

1
@EriktheGolfer що? Це саме визначення «коду самодокументування».

@ dan1111 Здається, ви знаєте Perl. Я не маю уявлення про те, як працює Перл, через його знамениті дивацтва.
Ерік Аутгольфер

@ dan1111 Дякую! Цілком задоволений тим, як коротко це вийшло!
Дом Гастінгс

1
@DomHastings Добре, що в PPCG ми вважаємо Perl як верхній рівень дивацтва, а Jelly / Справді / O5AB1E як верхній рівень безладу. Здається, ви ще жодного разу не бачили цього виклику :)
Ерік Вигнавець

6

Java 8, 57 56 55 50 байт

Дякуємо @Numberknot за 1 байт Дякуємо @Kevin Cruijssen за 5 байт

i->{for(;++i%3<1|(i+"").contains("3"););return i;}

Це Function<Integer, Integer>

Пояснення

Наївна реалізація, яка просто зростає, поки не досягне прийнятного числа.

Тестовий клас

public class CodeGolf {

    public static void main(String[] args) {
        Function<Integer, Integer> countingGame = i->{for(;++i%3<1|(i+"").contains("3"););return i;};
        int val = 1;
        for (int i = 0; i < 10; i++) {
            System.out.print(val + " ");
            val = countingGame.apply(val);
        }
    }

}

Результат тестового класу:

1 2 4 5 7 8 10 11 14 16

2
Ви можете використовувати |замість||
Numberknot

1
@Numberknot Я не мав уявлення, що побітові оператори функціонують як логічні в деяких контекстах! Дякую!
Сократичний Фенікс

1
Чому do-while? Просто звичайний цикл коротший: i->{for(;++i%3<1|(i+"").contains("3"););return i;}( 50 байт )
Кевін Кройсейсен

@KevinCruijssen Ну ... Я думав , порівняння whileі do-while, і вони обидва дали мені той же рахунок, але мені сподобалося, як do-whileвиглядала ... Я не думав , використовуючи forпетлю ... Дякую!
Сократичний Фенікс

5

Japt, 18 байт

°U%3*!Us f'3 ?U:ßU

Перевірте це в Інтернеті

У мене нарешті є шанс скористатися ß:-)

Як це працює

                    // Implicit: U = input integer
°U%3                // Increment U, and take its modulo by 3.
     !Us f'3        // Take all matches of /3/ in the number, then take logical NOT.
                    // This returns true if the number does not contain a 3.
    *               // Multiply. Returns 0 if U%3 === 0  or the number contains a 3.
             ?U     // If this is truthy (non-zero), return U.
               :ßU  // Otherwise, return the result of running the program again on U.
                    // Implicit: output last expression

5

PowerShell v2 +, 46 байт

for($a=$args[0]+1;$a-match3-or!($a%3)){$a++}$a

Здійснює введення $args[0], додає 1, зберігає $a, запускає forцикл. Умовно триває цикл, коли або $a-match3(збіг з регулярними виразами) -or $a%3дорівнює нулю ( !з яких є 1). Цикл просто збільшується $a++. В кінці циклу ми просто розміщуємо $aна конвеєрі, а вихід через неявне Write-Outputвідбувається при завершенні програми.

Приклади

PS C:\Tools\Scripts\golfing> 1,2,11,22,29,33,102,251,254|%{"$_ --> "+(.\count-without-three.ps1 $_)}
1 --> 2
2 --> 4
11 --> 14
22 --> 25
29 --> 40
33 --> 40
102 --> 104
251 --> 254
254 --> 256

4

R, 46 байт

n=scan()+1;while(!n%%3|grepl(3,n))n=n+1;cat(n)

Я думаю, що повернення значення (а не друк у stdout) дозволено, тому ви можете зберегти 5 байтів, маючи просто nзамість cat(n).
rturnbull

4

Python 2, 49 44 42 байт

f=lambda x:'3'[:~x%3]in`~x`and f(x+1)or-~x

Інший запис Python перевищує це (редагувати: не більше :-D), але я розмістив його, тому що мені більше подобається його рекурсивний підхід. Завдяки Мітчу Шварцу та Еріку Гольфісту за те, що вони допомогли мені зробити це коротшим.


1
Ви можете зробити це в Python 2: f=lambda x:f(x+1)if x%3>1or'3'in`x+1`else-~x. Якщо ви хочете зберегти Python 3, ви можете грати в гольф останній x+1в -~xі видалити простір.
Erik the Outgolfer

@EriktheGolfer Дякую! Я зміню його на Python 2, оскільки він коротший.
0WJYxW9FMN

42- f=lambda x:'3'[:~x%3]in`~x`and f(x+1)or-~xі : таf=lambda x:f(x+1)if'3'[:~x%3]in`~x`else-~x
Мітч Шварц

3

Луа, 58 байт

i=...+1while(i%3==0or(i..""):find"3")do i=i+1 end print(i)


3

C #, 56 , 51 байт.

Це напрочуд коротко для відповіді C #!

x=>{while(++x%3<1|(x+"").Contains("3"));return x;};

Ви можете зменшити його до 43, якщо ви зробите його рекурсивним t=x=>(++x)%3<1|(x+"").Contains("3")?t(x):x; в Visual Studio, вам просто потрібно визначити змінну і встановити її на нуль, Func<int, int> t = null;а потім визначити рекурсивну функцію в наступному рядку.
Grax32

Проблема полягає в тому, що якщо я зроблю це рекурсивно, мені доведеться рахувати визначення функції та типу.
Морган Трапп

Чи десь я можу піти, щоб переглянути ці вказівки? Я вважаю, що тут гольф C # заплутаний.
Grax32

@Grax В основному вам потрібно включити будь-який код, необхідний для запуску коду, за винятком присвоєння імені в разі нерекурсивної функції. На жаль, не знаю, де ви знайдете конкретний набір настанов.
Морган Трапп

@MorganThrapp, будь ласка, ознайомтеся зі своєю відповіді c # з рекурсією на 49 байт :)
Лі




2

Рубін, 47 байт

i=gets.to_i;i while(i+=1)%3==0||"#{i}"=~/3/;p i

Я справді відчуваю, що це можна пограти в гольф далі.


ви можете використовувати iзамість"#{i}"
Mhmd

2

MATL , 14 байт

`Qtt3\wV51-hA~

Спробуйте в Інтернеті!

Пояснення

`       % Do...while
  Q     %   Add 1. Takes input implicitly in the first iteration
  tt    %   Duplicate twice
  3\    %   Modulo 3
  wV    %   Swap, string representation
  51-   %   Subtract 51, which is ASCII for '3'
  h     %   Concatenate
  A~    %   True if any result was 0. That indicates that the number
        %   was a multiple of 3 or had some '3' digit; and thus a 
        %   new iteration is needed

2

Лабіринт , 117 102 байти

?       """""""""""_
):_3    (         0/{!@
;  %;:}_';:_3-_10 1
"  1            %;_
""""_""""""""{;;'

Спробуйте в Інтернеті!

Лабіринт - це двовимірна мова програмування на основі стеку, а на стиках напрямок визначається верхом стека (позитив іде вправо, негатив - вліво, нуль йде прямо). У цих програмах є дві основні петлі. Перший мод вводить ціле число на 3 і з кроком, якщо 0. Другий повторно перевіряє, чи є остання цифра 3 (віднімаючи 3 і модедуючи на 10), а потім ділимо на 10, щоб отримати нову останню цифру.


2

PHP, 60 55 54 46 байт

Дякуємо @ user59178 за бриття кількох байтів, @AlexHowansky за байт, @Titus ще кілька байтів

for(;strstr($i=++$argv[1],51)|$i%3<1;);echo$i;

Викликається з командного рядка з -r. Наївний метод, який цикли, поки число кратне 3, або має 3 у своїх цифрах.


1
Ви можете зберегти 7 байт, просто скориставшись програмою, що приймає введення з командного рядка, а не функцією: for($i=$argv[1];!(++$i%3)|strpos(" $i",'3'););echo$i;це можливо зробити краще, призначивши і $iпід час його використання.
користувач59178

@ user59178 Я припустив, що функція повинна була повернути $ i
Xanderhall

питання більшості часу є досить гнучкими щодо того, як робиться введення та виведення даних, якщо потрібна річ надана та отримана. Крім того, дивлячись на відповіді іншими мовами, більшість вирішує надрукувати на stdout.
користувач59178

Збережіть байт зstrpos(_.$i,'3')
Алекс Хованський

Збережіть один байт за допомогою %3<1 , один з 51замість '3', ще два з strstr($i)замість strpos(_.$i)і ще два, замінивши |операндів у другій версії: <?for(;strstr($i=++$argv[1],51)|$i%3<1;);echo$i;-> 48 байт
Тіт

2

PHP, 47 41 байт

натхненний Ксандерхоллом , але остання ідея нарешті виправдовує власну відповідь.

while(strstr($n+=$n=&$argn%3,51));echo$n;

або

while(strpbrk($n+=$n=&$argn%3,3));echo$n;

Це скористається тим, що вхід також з послідовності: Для $n%3==1, новий модуль є 2. Бо $n%3==2новий модуль є 4-3=1. $n%3==0ніколи не буває.

Запустіть як трубу -Rабо спробуйте їх в Інтернеті .


2

APL (Діалог Юнікод) , 33 28 27 19 байт SBCS

1∘+⍣{('3'∊⍕⍺)<×3|⍺}

Спробуйте в Інтернеті!

-6 завдяки Адаму. -8 завдяки ngn.

Старе пояснення:

1-⍨g⍣((×3|⊢)>'3'∊⍕)∘(g←+∘1)
                       +∘1   curry + with 1, gives the increment function
                             increments the left argument so we do not return the number itself
                    (g   )  assign to "g"
                            compose g with the repeat
                            does parsing the argument to a string...
             '3'            ...contain '3'?
        3|⊢                  residue of a division by 3
         )                 direction (0 if 0, 1 if greater, ¯1 is lower)
     (      >     )          and not (we want the left side to be 1, the right side 0)
   g                        repeat "g" (increment) until this function is true ^
1-⍨                          afterwards, decrement: inversed -

APL (Dyalog Extended) , 23 17 байт SBCS

1∘+⍣(3(×⍤|>∊⍥⍕)⊣)

Спробуйте в Інтернеті!

Завдяки Адаму. -6 завдяки ngn.

Старе пояснення:

0+⍣(3(×⍤|>∊⍥⍕)⊢)⍢(1+⊢)⊢
0                        the left argument (⍺)
 +⍣(3(×⍤|>∊⍥⍕)⊢)         the left function (⍺⍺)
                 (1+⊢)   the right function (⍵⍵)
                             (increments its argument)
                        the right argument (⍵)
                             (just returns the input)
                        under:
                             calls (⍵⍵ ⍵) first, which increments the input
                             also (⍵⍵ ⍺) which gives 1
                             then calls (⍺incremented ⍺⍺ incremented)
                             afterwards, does the opposite of ⍵⍵, and decrements the result
                         fixpoint: repeats the left operation until the right side is truthy
 +                       calls + with incremented and the input (so, 1+input)
   (3(×⍤|>∊⍥⍕)⊢)         right operation
    3                    on its left, "3"
                        on its right, the current iteration
      ×⍤|                divisibility check: × atop |
        |                    starts with 3|⊢ (residue of ⊢/3)
      ×                      then returns the direction (0 if 0, 1 if greater, ¯1 is lower)
          ∊⍥⍕            contains 3:
                           stringifies both its arguments (3 and ⊢)
          ∊⍥                checks for membership
         >               divisibility "and not" contains 3

2

Perl 6 , 27 25 24 байти

{max $_+1...{!/3/&$_%3}}

Спробуйте в Інтернеті!

Знаходить перше число, більший за вхідний, у якого немає трійки, і залишок, коли його модулюють 3. Я сподівався зробити щось фантазійне з умовою, наприклад, !/3/&*%3але це не працює з! .:(

Пояснення:

{                      }   # Anonymous code block
     $_+1                  # From the input+1
         ...               # Get the series
            {         }    # That ends when
             !/3/            # The number does not contain a 3
                 &           # and
                  $_%3       # The number is not divisible by 3
 max                       # And get the last element of the series

1

C, 81 байт

f(int n){int m;l:if(++n%3){for(m=n;m>0;m/=10)if(m%10==3)goto l;return n;}goto l;}

1

ретикулярна, 30 байт

in v
?v$>1+d3,qds:3@cQm*
;\$o

Спробуйте в Інтернеті!

Пояснення

1: ініціалізація

in v

Це перетворює input в umber n, а потім знижується (v )

2: петля

?v$>1+d3,qds:3@cQm*
   >                 go right!              [n]
    1+               add 1                  [n+1]
      d3,            duplicate and mod 3    [n+1, (n+1)%3]
         qd          reverse and duplicate  [(n+1)%3, n+1, n+1]
           s         cast to string         [(n+1)%3, n+1, `n+1`]
            :3@c     count numbers of "3"   [(n+1)%3, n+1, `n+1`.count(3)]
                Qm*  negate and rotate      [n+1, continue?]
?v                   terminate if continue
  $                  drop continue

3: фінал

;\$o
 \$o  drop and output
;     terminate

1

Пакет, 93 байти

@set/pn=
:l
@set/an+=1,r=n%%3
@if %r%==0 goto l
@if not "%n:3=%"=="%n%" goto l
@echo %n%

Здійснює введення даних STDIN.


1

CJam, 19 байт

ri{)__3%!\`'3e=e|}g

ОНЛАЙН

Пояснення:

ri{)__3%!\`'3e=e|}g
r                   Get token
 i                  Convert to integer
  {              }  Block
   )                 Increment
    _                Duplicate
     _               Duplicate
      3              Push 3
       %             Modulo
        !            NOT gate
         \           Swap
          `          String representation
           '3        Push '3'
             e=      Count occurrences
               e|    OR gate
                  g While popped ToS is true

Якщо б було запропоновано менш детальне пояснення, я зробив би це:

ri{)__3%!\`'3e=e|}g
ri                  Get integer
  {              }  Block
   )                 Increment
    __               Triplicate
      3%!            Test non-divisibility with 3
         \           Swap
          `'3e=      Count occurrences of '3' in string repr
               e|    OR gate
                  g While popped ToS is true

1

Pyth, 19 байт

JhQW|!%J3/`J\3=hJ;J

Тестовий набір

Я впевнений, що можу пограти в це ... це те саме, що моя відповідь CJam.

Пояснення:

JhQW|!%J3/`J\3=hJ;J
  Q                 Evaluated input
 h                  Increment
J                   Assign J to value
       J            Variable J
        3           Value 3
      %             Modulo
     !              Logical NOT
           J        Variable J
          `         String representation
            \3      Value "3"
         /          Count occurrences
    |               Logical OR
               h    Increment
                J   Variable J
              =     Apply function then assign
                 ;  End statement block
                  J Variable J

Я розмістив спосіб, що коротше. Тим не менш, ось рада для вашого підходу: не використовуйте змінну J. Можна збільшувати Q. І якщо ви робите це розумно, ви можете W|!%=hQ3/ввести операцію в режим " Q \ 3; Q".
Jakube

Вибачте:W|!%=hQ3/`Q\3;Q
Jakube

@Jakube Змінна не просто збільшується, а дякує.
Ерік Аутгольфер

1

Clojure, 73 байти

(fn c[n](let[m(inc n)](if(or(=(rem m 3)0)(some #(=\3 %)(str m)))(c m)m)))

Рекурсивно циклічно, тоді nяк ділиться на 3, або містить 3 у своєму рядковому поданні. Хоча я використовую неоптимізовану рекурсію, він міг обробити 2999999 як вхід, тому це повинно бути нормально.

Безумовно

(defn count-without-3 [n]
  (let [m (inc n)]
    (if (or (= (rem m 3) 0)
            (some #(= \3 %) (str m)))
      (count-without-3 m)
      m)))
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.