Считать без 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
Я чувствую, что у нас был вызов как это ...
Конор О'Брайен

5
Это всегда 7было пропущено, когда я играл, но вы вместо этого сказали бы что-нибудь другое, вместо того, чтобы перейти к следующему номеру в строке.
mbomb007

12
@ mbomb007: Когда я играл, ты не был бы удален из круга. Вместо этого вы бы выпили. Но это не было в начальной школе. Во всяком случае, получить более 80 было почти невозможно, особенно после первого часа.
Томаш


4
@ mbomb007: Это будет зависеть от доказательства того, что вы пьете.
Томаш

Ответы:


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
@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 за сообщение, что я был глуп, используя 2 переменные, и спасибо Митчу Шварцу.

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, что ты ожидал? Ясность?
Эрик Outgolfer

1
@EriktheGolfer что? Это само определение «самодокументируемого кода».

@ dan1111 Кажется, ты знаешь Perl. Я понятия не имею, как работает Perl, из-за его знаменитой странности.
Эрик Outgolfer

@ dan1111 Спасибо! Вполне доволен тем, как коротко получилось!
Дом Гастингс

1
@DomHastings Ну, в PPCG мы принимаем Perl как верхний уровень странности, а Jelly / Actually / O5AB1E - как верхний уровень путаницы. Похоже, что вы никогда не видели этот вызов :)
Эрик Outgolfer

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? Просто обычный цикл for короче: 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 превосходит это (edit: больше нет :-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и удалить пространство.
Эрик Outgolfer

@EriktheGolfer Спасибо! Я изменю это на Python 2, поскольку это намного короче.
0WJYxW9FMN

42s: 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 вам просто нужно определить переменную и установить для нее значение null, 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при использовании его тоже.
user59178

@ user59178 Я предположил, что функция должна вернуть $ i
Xanderhall

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

Сохранить байт с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 байт

вдохновлен Xanderhall , но последняя идея, наконец, оправдывает свой ответ.

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 (Dyalog Unicode) , 33 28 27 19 байтов SBCS

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

Попробуйте онлайн!

-6 спасибо Адаму. -8 благодаря нгн.

Старое объяснение:

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 благодаря нгн.

Старое объяснение:

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

сетчатый, 30 байтов

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

Попробуйте онлайн!

объяснение

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

in v

Это преобразует input в nUmber, затем идет вниз ( 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. И если вы делаете это умно, вы можете вставить операцию в условие while: W|!%=hQ3/Q \ 3; Q`.
Якуб

Извините:W|!%=hQ3/`Q\3;Q
Якуб

@Jakube Переменная не просто увеличивается, а спасибо.
Эрик Outgolfer

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 в качестве входных данных, так что все должно быть в порядке.

Ungolfed

(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.