Зробіть свої дублі разом


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

1
Чи дозволяється нам приймати введення як рядок?
Мертвий Поссум

6
@DeadPossum Я б припустив, що це дозволено, оскільки ви все одно отримаєте рядок, якщо прочитаєте вхід з STDIN, аргументу командного рядка або файлу (які всі допустимі способи введення).
Мартін Ендер

1
Чи можна припустити, що вхід буде більшим за 0?
Мартін Ендер

1
@MartinEnder Так
sagiksp

2
Підвищення для гри в дублі! Check'em!
ZombieChowder

Відповіді:


19

Математика, 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 . Д в кінці буде скасована, тому ми залишилися з: 9 * м * 10 K + D * 10 K = (9 * т + D) * 10 K . Але 9 ≡ -1 (mod 10) , тому 9 * m + d ≡ d - m (mod 10) . Але ми стверджували, що m ≢ d (mod 10) і, отже, d - m ≢ 0 (mod 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 він буквально зробив регулярні вирази на основі мови, це виходить за рамками меми матеріал з:
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 байти, оскільки це було б не потрібно.


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:
Род

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

Ласкаво просимо до PPCG! Ви можете зберегти багато байтів, скориставшись зворотною допомогою замість того, щоб вручну заповнити повторний символ:/(.)\1*$/
Мартін Ендер

Крім того, неназвані функції є повністю чудовими (якщо, наприклад, вам не потрібна назва для рекурсивних дзвінків), ви можете зберегти два байти на f=.
Мартін Ендер

Хороша робота! Це точно проходить огляд, але це може бути гольф
Крістофер

@MartinEnder Дякую! Мені ще належить навчитися грати в гольф
Weedoze

@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]));

видаляє праворуч кожен символ, що відповідає самому правому символу, і обчислює різницю в довжині.


-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 pointer, він переміщується до наступного int, а не до наступного байта.
Денніс

Чи є випадки (коли використовується ints), коли було б краще повернутися, здається, що в гіршому випадку ви зробите новий int і призначите це.
Біджан

Компілятори @Bijan C завжди вирівнюють прямий доступ до пам'яті до розміру атома примітиву, про який йде мова - я не пам'ятаю, чи є він у стандарті, хоча
кіт


5

C # , 63 62 байти


Гольф

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

Безумовно

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

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

    return b - a;
}

Незрозумілий читабельний

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- Початкове рішення.

Примітки

Нічого додати


+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

Я забув, що &це робив так Y':-D Чому б не взяти введення як рядок, укладений у лапки і не позбутися j?
Луїс Мендо

@LuisMendo Я не був впевнений, чи зможу це зробити, оскільки виклик прямо сказав, що вхід є "цілим числом"
Suever

Я припустив це з коментаря Мартіна та з правил за замовчуванням, які це дозволяють. Але я не дуже впевнений
Луїс Мендо

@LuisMendo Ага, добре, не побачив його коментар. Буде оновлено!
Сьювер

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, вказуючи праворуч. Два нерегульовані опції, які виконуються 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) відрізняються, цикл закінчується.


3

Рода , 12 байт

{count|tail}

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

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

Він використовує дві вбудовані: countі tail:

  1. count зчитує значення з потоку і підштовхує кількість послідовних елементів до потоку.
  2. tail повертає останнє значення в потоці.

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


2

Powershell, 41 байт

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

прямий цикл назад, поки знак не відповідає останньому знаку в рядку, поверніть індекс цього знака -1.

-3 завдяки @AdmBorkBork - використовуючи цикл замість деякого часу.


2

Mathematica, 33 30 байт

Дякуємо Грегу Мартіну за збереження 3 байтів.

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

Вводиться як рядок.

Отримує десяткові цифри (у вигляді символів), розбиває їх на прогони однакових елементів, отримує останній запуск і обчислює довжину за допомогою стандартного трюку взяття суми вектора 1^list.


Charactersзамість IntegerDigits?
Грег Мартін

@GregMartin Ага так, я думаю. Спасибі.
Мартін Ендер


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


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

@ user81655 Це чудово, сміливо публікуйте це. Я не думаю, що моє не сходиться до цього без повного перетворення, і, звичайно, тепер, коли я бачив ваше, що не відбудеться ;-)
ETHproductions


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

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

Пітон 3 - 50 44 байти

Повна програма (в Python 3 input()повертає рядок, незалежно від введення):

g=input();print(len(g)-len(g.rstrip(g[-1]))) 
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.