ПОЛУЧИТЕ свои дабы вместе

24

На 4chan популярной игрой является get. Каждое сообщение на сайте получает последовательный идентификатор сообщения. Поскольку вы не можете влиять на них или определять их, люди пытаются угадать (хотя бы часть) свой собственный номер сообщения, обычно первые несколько цифр. Другая версия игры называется dubs, и ее целью является получение повторяющихся цифр в конце номера (т.е. 1234555).

Ваша задача, если вы хотите принять это, - написать программу, которая принимает идентификатор записи в качестве ввода (стандартное целое число, которое вы можете считать ниже 2 ^ 32) и возвращает количество повторяющихся цифр в конце.

правила

  • Стандартные лазейки запрещены .
  • Программа может быть функцией, полной программой, командой REPL, чем угодно, действительно, до тех пор, пока для ее запуска не требуется внешний несчетный код / ​​аргументы.
  • Входные данные могут поступать из STDIN, аргументов функции, аргумента командной строки, файла, что угодно.

Тестовые случаи

Input: 14892093
Output: 1

Input: 12344444
Output: 5

Input: 112311
Output: 2

Input: 888888
Output: 6

Input: 135866667 //Post number I got on /pol/ few days ago, rip
Output: 1
sagiksp
источник
1
Разрешено ли нам принимать ввод как строку?
Мертвый Опоссум
6
@DeadPossum Я бы предположил, что это разрешено, так как в любом случае вы получаете строку, если вы читаете ввод из STDIN, аргумента командной строки или файла (все это допустимые методы ввода).
Мартин Эндер
1
Можем ли мы предположить, что вход будет больше 0?
Мартин Эндер,
1
@MartinEnder Да
sagiksp
2
Upvote для игры дабс! Check'em!
ZombieChowder

Ответы:

19

Mathematica, 29 байт

Как насчет арифметического решения?

IntegerExponent[9#+#~Mod~10]&

Мне очень приятно видеть, что это превосходит прямой подход Mathematica.

объяснение

Сам код вычисляет 9 * n + n% 10, а затем находит наибольшую степень 10, которая делит вход, или, другими словами, подсчитывает завершающие нули. Нам нужно показать, что если n заканчивается k повторяющимися цифрами, то 9 * n + n% 10 имеет k конечных нулей.

Повторные цифры легче всего выразить математически путем деления числа, такого как 99999 (что составляет 10 5 -1 ) на 9, и затем умножения на повторяющуюся цифру. Таким образом, мы можем написать n = m * 10 k + d * (10 k -1) / 9 , где m d (mod 10) , чтобы гарантировать, что n не заканчивается более чем k повторяющимися цифрами. Обратите внимание, что d = n% 10 .

Давайте включим это в нашу формулу 9 * n + n% 10 . Мы получаем 9 * m * 10 k + d * (10 k -1) + d . Значение d в конце отменяется, поэтому у нас осталось: 9 * m * 10 k + d * 10 k = (9 * m + d) * 10 k . Но 9 ≡ -1 (мод 10) , поэтому 9 * m + d ≡ d - m (мод 10) . Но мы утверждали, что m ≢ d (мод 10) и, следовательно, d - m ≢ 0 (мод 10) .

Другими словами, мы показали, что 9 * m + d не делится на 10 и, следовательно, наибольшая степень 10, которая делит 9 * n + n% 10 = (9 * m + d) * 10 k, равна k , количество конечных повторяющихся цифр.

В качестве бонуса это решение печатает правильный результат для ввода 0.

Мартин Эндер
источник
1
В такие времена я бы хотел, чтобы этот сайт поддерживал MathJax; смелые формулы не так хороши, как набранные. Приятно, что вы нашли время, чтобы написать верхний индекс показателей.
wizzwizz4
1
@ wizzwizz4 Раньше я использовал форматирование кода, но я обнаружил, что жирный шрифт (который обычно используется Деннисом) немного более читабелен, чем этот. Но согласился, это не так хорошо, как MathJax.
Мартин Эндер
13

Сетчатка , 9 байт

&`(.)\1*$

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

Подсчитывает количество совпадающих совпадений, (.)\1*$регулярное выражение которых совпадает с суффиксом идентичных символов.

Мартин Эндер
источник
2
Должно быть, это мем: ты и твое регулярное выражение
Кристофер
Мне нужно изучить все эти модификаторы - я бы просто пошел на (.)(?=\1*$).
Нил
1
@DownChristopher он буквально создал язык на основе регулярных выражений, это выходит за рамки мемов материала c:
Rod
1
@Neil Если это какое-то утешение, моя первая попытка была (?=(.)\1*$)(так же, как и ваша).
Мартин Эндер
1
Да, это так, спасибо!
Нил
9

Брахилог , 4 байта

ẹḅtl

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

объяснение

ẹ       Elements: split to a list of digits
 ḅ      Blocks: group consecutive equal digits into lists
  t     Tail: take the last list
   l    Length: Output is the length of that last list

Если бы мы работали непосредственно с целыми числами (и я не уверен, почему я не реализовал это так, как оно делает), это было бы только 3 байта, поскольку не было бы необходимости.

Fatalize
источник
9

Python 2 , 47 41 байт

lambda s:len(`s`)-len(`s`.rstrip(`s%10`))

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

36 байт - для более гибкого ввода

lambda s:len(s)-len(s.rstrip(s[-1]))

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

прут
источник
Вау. Я должен изучать встроенные функции более внимательно. +1
Мертвый Опоссум
2
@DeadPossum dir(object)наш друг с:
Род
Кстати, нам не разрешено принимать строки в качестве входных данных. «Если ваш метод ввода автоматически возвращает строки, то конечно, но вы не можете предполагать, что ввод будет предоставлен как строки». : C
Мертвый Опоссум
1
@DeadPossum Я думаю, что автор передумал об этом. Комментарий, кажется, был удален.
Брайан МакКатчон
8

Javascript (ES6), 55 52 32 30 байт

a=>a.match`(.)\\1*$`[0].length
  • Сохраненные 19 байт благодаря @MartinEnder путем замены регулярных выражений
  • Сохранено 2 байта благодаря @ user81655 с использованием тегов литералов шаблонов

Использование регулярного выражения для соответствия последней группе последней цифры

Примечание: первый раз. Не стесняйтесь делать замечания.

f=a=>a.match`(.)\\1*$`[0].length


console.log(f("14892093"));//1
console.log(f("12344444"));//5
console.log(f("112311"));//2
console.log(f("888888"));//6
console.log(f("135866667 "));//1
Weedoze
источник
Добро пожаловать в PPCG! Вы можете сохранить много байтов, используя /(.)\1*$/
Мартин Эндер,
Кроме того, безымянные функции вполне подходят (например, если вам не нужно имя для рекурсивных вызовов), поэтому вы можете сохранить два байта в f=.
Мартин Эндер
Отличная работа! Это, безусловно, проходит обзор, но это может быть в гольф
Кристофер
@MartinEnder Спасибо! Я все еще должен научиться
играть
@DownChristopher Спасибо! Я постараюсь сделать лучше в следующий раз
Weedoze
7

PHP, 47 45 40 байт

while($argn[-++$i]==$argn[-1]);echo$i-1;

Бежать с echo <n> | php -nR '<code>

Кажется, цикл все еще меньше, чем мой первый ответ. просто посчитайте символы, которые равны последним. Это использует отрицательные смещения строк в PHP 7.1 .

-5 байт по Титу. Благодарность !


Старый ответ:

<?=strlen($a=$argv[1])-strlen(chop($a,$a[-1]));

удаляет справа каждый символ, соответствующий крайнему правому символу, и вычисляет разницу в длине.

Christoph
источник
-Rи $argnможет сэкономить 5 байтов.
Титус
6

Perl 5 , 22 байта

21 байт кода + -pфлаг.

/(.)\1*$/;$_=length$&

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

/(.)\1*$/получает последние идентичные числа, а затем $_=length$&назначает его длину $_, которая неявно печатается благодаря -pфлажку.

папа
источник
6

C (gcc) , 32 29 байт

f(x){x=x%100%11?1:-~f(x/10);}

Это порт моего ответа Python .

Это работает с gcc, но отсутствие returnоператора - неопределенное поведение.

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

Деннис
источник
Я запутался, почему вы не передаете указатель и не меняете значение в этом месте, или просто возвращаете значение. Похоже, что это просто изменяет локальную копию, что делает функцию непригодной для использования, но это работает на TIO. Вы также добавляете 1 к n в нижнем колонтитуле, а не sizeof (int), разве это не сдвинет его на 1 байт вперед, а не на всю ширину int? Ясно, что есть некоторые уловки, которые я мог бы изучить здесь, и я мог бы использовать первый из них в своем собственном ответе.
Биджан,
2
Все, что returnделает оператор - сохраняет возвращаемое значение в EAX. При использовании gcc присвоение его переменной происходит так же. Что касается арифметики указателя, то когда вы добавляете 1 к указателю int, он перемещается к следующему int, а не к следующему байту.
Деннис
Существуют ли случаи (при использовании целочисленных значений), когда было бы лучше вернуться, кажется, что в худшем случае вы создадите новый тип int и назначите его.
Биджан,
Компиляторы @Bijan C всегда выравнивают прямой доступ к памяти по размеру атома рассматриваемого примитива - хотя я не помню,
cat
5

C # , 63 62 байта


Golfed

i=>{int a=i.Length-1,b=a;while(a-->0&&i[a]==i[b]);return b-a;}

Ungolfed

i => {
    int a = i.Length - 1,
        b = a;

    while( a-- > 0 && i[ a ] == i[ b ] );

    return b - a;
}

Ungolfed читаемый

i => {
    int a = i.Length - 1, // Store the length of the input
        b = a ;           // Get the position of the last char

    // Cycle through the string from the right to the left
    //   while the current char is equal to the last char
    while( a-- > 0 && i[ a ] == i[ b ] );

    // Return the difference between the last position
    //   and the last occurrence of the same char
    return b - a;
}

Полный код

using System;

namespace Namespace {
   class Program {
      static void Main( String[] args ) {
         Func<String, Int32> f = i => {
            int a = i.Length - 1, b = a;
            while( a-- > 0 && i[ a ] == i[ b ] );
            return b - a;
         };

         List<String>
            testCases = new List<String>() {
               "14892093",
               "12344444",
               "112311",
               "888888",
               "135866667"
            };

         foreach( String testCase in testCases ) {
            Console.WriteLine( $" Input: {testCase}\nOutput: {f( testCase )}\n" );
         }

         Console.ReadLine();
      }
   }
}

релизы

  • v1.1 - - 1 byte - Благодаря комментарию Кевина .
  • v1.0 -  63 bytes- Исходное решение.

Заметки

Нечего добавить

auhmaan
источник
+1 Вы можете сыграть в гольф на 1 байт. Как это:i=>{int a=i.Length-1,b=a;while(a-->0&&i[a]==i[b]);return b-a;}
Кевин Круйссен
4

MATL , 6 5 байт

1 байт сохранен благодаря @Luis

&Y'O)

Попробуйте это на MATL Online

объяснение

        % Implicitly grab input as a string
&Y'     % Perform run-length encoding on the string but keep only the second output
        % Which is the number of successive times an element appeared
O)      % Grab the last element from this array
        % Implicitly display
Suever
источник
Я забыл, что &сделал это для Y':-D Почему бы не принять ввод как строку, заключенную в кавычки и избавиться от j?
Луис Мендо
@ LuisMendo Я не был уверен, смогу ли я сделать это, так как в
задании
Я предположил это из комментария Мартина и из правил по умолчанию, которые позволяют это. Но я не совсем уверен
Луис Мендо
@ LuisMendo А, ладно, не видел его комментарий. Буду обновлять!
Suever
4

Cubix, 24 19 байт

)uO)ABq-!wpUp)W.@;;

Заметка

  • Фактически подсчитывает, сколько одинаковых символов находится в конце ввода, так что это работает и для действительно больших целых чисел, и для действительно длинных строк (при условии, что количество одинаковых символов в конце меньше максимальной точности JavaScript ( около 15 цифр в базе-10).
  • Ввод идет в поле ввода, вывод выводится в поле вывода

Попробуй здесь

объяснение

Во-первых, давайте расширим куб

    ) u
    O )
A B q - ! w p U
p ) W . @ ; ; .
    . .
    . .

Этапы выполнения могут быть разделены на три этапа:

  1. Разбор ввода
  2. Сравнить персонажей
  3. Распечатать результат

Этап 1: Ввод

Первые два символа, которые выполняются, Aи B. Aчитает все вводимые данные и помещает их в виде кодов символов в стек. Обратите внимание, что это делается в обратном порядке, первый символ заканчивается сверху стека, последний символ почти внизу. В самом низу находится -1( EOF), который будет использоваться в качестве счетчика для количества последовательных символов в конце строки. Так как нам нужно, чтобы верхняя часть стека содержала последние два символа, мы обращаемся к стеку перед входом в цикл. Обратите внимание , что верхняя часть стека теперь выглядит следующим образом : ..., C[n-1], C[n], -1.

Место IP на кубе находится там, где оно Eесть, и оно указывает вправо. Все инструкции, которые еще не были выполнены, были заменены на no-ops (полные остановки).

    . .
    . .
A B E . . . . .
. . . . . . . .
    . .
    . .

Этап 2: Сравнение персонажей

Стек - это ..., C[a-1], C[a], counterгде counterсчетчик увеличивается, когда два проверяемых символа равны ( C[a]и C[a-1]). IP сначала входит в этот цикл у Sперсонажа, двигаясь вправо. EХарактер положение , в котором IP будет в конечном итоге (указывая право) , когда C[a]и C[a-1]не имеют то же значение, что означает , что вычитание C[a]из C[a-1]не уступающие 0, в этом случае инструкции , следующей за !будет пропущен (который является w).

    . .
    . .
. S q - ! w E .
p ) W . . ; ; .
    . .
    . .

Вот инструкции, которые выполняются во время полного цикла:

q-!;;p) # Explanation
q       # Push counter to the bottom of the stack
        #     Stack (counter, ..., C[a-1], C[a])
 -      # Subtract C[a] from C[a-1], which is 0 if both are equal
        #     Stack (counter, ..., C[a-1], C[a], C[a-1]-C[a])
  !     # Leave the loop if C[a-1]-C[a] does not equal 0
   ;;   # Remove result of subtraction and C[a] from stack
        #     Stack (counter, ..., C[a-1])
     p  # Move the bottom of the stack to the top
        #     Stack (..., C[a-1], counter)
      ) # Increment the counter
        #     Stack (..., C[a-1], counter + 1)

И тогда это зацикливается.

Этап 3: печать результатов

Так как мы вышли из цикла раньше, стек выглядит следующим образом : counter, ..., C[a-1]-C[a]. Счетчик легко напечатать, но мы должны увеличить счетчик один раз, потому что мы не делали этого на последней итерации цикла, и еще раз, потому что мы начали считать -1вместо 0. Путь на кубе выглядит следующим образом, начиная с Sнаправления вправо. Два no-ops, которые выполняются IP, заменяются стрелками, которые указывают в направлении IP.

    ) u
    O )
. B . . . S p U
. ) . . @ . . .
    > >
    . .

Инструкции выполняются в следующем порядке. Обратите внимание, что B)инструкции в конце изменяют стек, но не влияют на программу, так как мы собираемся завершить его, и мы больше не используем стек.

p))OB)@ # Explanation
p       # Pull the counter to the top
        #     Stack: (..., counter)
 ))     # Add two
        #     Stack: (..., counter + 2)
   O    # Output as number
    B)  # Reverse the stack and increment the top
      @ # End the program

Alea iacta est.

Люк
источник
3

Пакет, 91 байт

@set s=-%1
@set n=1
:l
@if %s:~-2,1%==%s:~-1% set s=%s:~,-1%&set/an+=1&goto l
@echo %n%

В -предотвращает испытание от стекания начала строки.

Нил
источник
3

JavaScript (ES6), 34 байта

f=(n,p)=>n%10-p?0:1+f(n/10|0,n%10)

Не короче, чем решение регулярных выражений.

Рекурсивная функция, которая оценивает цифры справа налево, останавливаясь при обнаружении другой цифры. Результатом является количество итераций. pнаходится undefinedна первой итерации, что означает n%10-pвозврат NaN(ложь). После этого pравна предыдущей цифре с n%10. Когда текущая цифра ( n%10) и предыдущая ( p) различаются, цикл заканчивается.

user81655
источник
3

Рёда , 12 байт

{count|tail}

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

Это анонимная функция, которая ожидает, что каждый символ входной строки помещается в поток (я думаю, что это верно в духе недавнего мета-вопроса ).

Он использует две встроенные функции: countи tail:

  1. count считывает значения из потока и передает количество последовательных элементов в поток.
  2. tail возвращает последнее значение в потоке.
fergusq
источник
3

T-SQL, 238 214 байт

declare @ varchar(max) = '' declare @i int=0, @e int=0, @n int=right(@,1), @m int while (@i<=len(@)) begin set @m=(substring(@,len(@)-@i,1)) if (@n=@m) set @e=@e+1 else if (@i=0) set @e=1 set @i=@i+1 end select @e

Или:

declare @ varchar(max) = '12345678999999'
declare 
    @i int = 0,
    @e int = 0,
    @n int = right(@,1),
    @m int

while (@i <= len(@))
begin
    set @m = (substring(@,len(@)-@i,1))
    if (@n = @m) set @e = @e + 1
    else
    if (@i) = 0 set @e = 1
    set @i = @i + 1
end
select @e
Nelz
источник
2

Java 7, 78 байт

int c(int n){return(""+n).length()-(""+n).replaceAll("(.)\\1*$","").length();}

Попробуй это здесь.

Я пробовал некоторые вещи, используя рекурсию или цикл, но оба оказались выше 100 байт ..

Кевин Круйссен
источник
2

Powershell, 41 байт

for($n="$args";$n[-1]-eq$n[-++$a]){};$a-1

прямой цикл в обратном направлении, пока символ не совпадает с последним символом в строке, возвращает индекс этого символа -1.

-3 благодаря @AdmBorkBork - вместо цикла время используется цикл for.

colsw
источник
2

Mathematica, 33 30 байт

Спасибо Грегу Мартину за сохранение 3 байта.

Tr[1^Last@Split@Characters@#]&

Принимает ввод в виде строки.

Получает десятичные цифры (в виде символов), разбивает их на серии одинаковых элементов, получает последний цикл и вычисляет длину с помощью стандартного трюка получения суммы вектора 1^list.

Мартин Эндер
источник
Charactersвместо IntegerDigits?
Грег Мартин
@GregMartin Ах да, наверное. Спасибо.
Мартин Эндер,
Вы до сих пор не разбили этого другого проницательного игрока в гольф Mathematica за этот вопрос;)
Грег Мартин,
@GregMartin Какой позор. :)
Мартин Эндер
2

JavaScript (ES6), 39 38 37 27 байт

f=n=>n%100%11?1:1+f(n/10|0)

Возможно, не короче, чем решение на основе регулярных выражений, но я не удержался от написания решения, полностью основанного на арифметике. Техника состоит в том, чтобы повторно брать n % 100 % 11и делить на 10, пока результат не станет ненулевым, а затем посчитать итерации. Это работает, потому что, если последние две цифры одинаковы, n % 100 % 11будет 0.

ETHproductions
источник
Ах, ты закончил как раз передо мной, ха-ха! Я не уверен, стоит ли публиковать другой ответ, так как они, скорее всего, сойдутся после игры в гольф, но вот мое решение, использующее 34 байта:f=(n,p)=>n%10-p?0:1+f(n/10|0,n%10)
user81655
@ user81655 Отлично, не стесняйтесь. Я не думаю, что мои сойдутся к этому без полной перестройки, и, конечно, теперь, когда я видел твои, этого не произойдет ;-)
ETHproductions
2

Haskell , 33 байта

f(h:t)=sum[1|all(==h)t]+f t
f _=0

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

Принимает строку ввода. Неоднократно обрезает первый символ и добавляет 1, если все символы в суффиксе равны первому.

XNOR
источник
2

R 35 байт

rle(rev(charToRaw(scan(,''))))$l[1]

Краткое объяснение

                  scan(,'')         # get input as a string
        charToRaw(         )        # convert to a vector of raws (splits the string)
    rev(                    )       # reverse the vector
rle(                         )$l[1] # the first length from run length encoding
MickyT
источник
2

Befunge-98 , 19 байт

01g3j@.$~:01p-!j$1+

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

Это можно было бы сделать короче, если бы мне удалось использовать только стек.

Как это работает:

01g3j@.$~:01p-!j$1+
01g                 ; Get the stored value (default: 32)                 ;
   3j               ; Skip to the ~                                      ;
        ~           ; Get the next character of input                    ;
         :01p       ; Overwrite the stored value with the new char       ;
             -!     ; Compare the old value and the new                  ;
               j$   ; Skip the $ when equal, else pop the counter        ;
                 1+ ; Increment the counter                              ;

; When the input runs out, ~ reflects the IP and we run: ;
   @.$
     $              ; Pop the extraneous value (the stored value) ;
   @.               ; Print the number and exit                   ;
Джастин
источник
2

Python 3 - 50 44 байта

Полная программа (в Python 3 input()возвращает строку, независимо от ввода):

g=input();print(len(g)-len(g.rstrip(g[-1]))) 
Мистер Xcoder
источник