Zbierz swoje duby razem


24

Na 4chan popularna gra to get. Każdy post na stronie otrzymuje sekwencyjny identyfikator posta. Ponieważ nie możesz ich wpływać ani określać, ludzie próbują odgadnąć (przynajmniej część) własnego numeru postu, zwykle pierwszych kilku cyfr. Inna wersja gry nosi nazwę dubs, a jej celem jest uzyskanie powtarzających się cyfr na końcu numeru (tj. 1234555).

Twoim zadaniem, jeśli chcesz to zaakceptować, jest napisanie programu, który przyjmuje jako dane wejściowy identyfikator postu (standardowa liczba całkowita, możesz założyć poniżej 2 ^ 32) i zwraca liczbę powtarzających się cyfr na końcu.

Zasady

  • Standardowe luki są niedozwolone .
  • Program może być funkcją, pełnym programem, poleceniem REPL, cokolwiek działa, pod warunkiem, że do uruchomienia nie są potrzebne żadne niepoliczone kody / argumenty.
  • Dane wejściowe mogą pochodzić z STDIN, argumentów funkcji, argumentu wiersza poleceń, pliku, co tylko Ci odpowiada.

Przypadki testowe

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
Czy wolno nam brać dane wejściowe jako ciąg znaków?
Dead Possum

6
@DeadPossum Zakładam, że jest to dozwolone, ponieważ i tak dostajesz ciąg znaków, jeśli czytasz dane wejściowe ze STDIN, argument wiersza poleceń lub pliku (wszystkie są dopuszczalnymi metodami wprowadzania).
Martin Ender

1
Czy możemy założyć, że wartość wejściowa będzie większa niż 0?
Martin Ender

1
@MartinEnder Tak
sagiksp

2
Głosowanie na grę dubs! Check'em!
ZombieChowder

Odpowiedzi:


19

Mathematica, 29 bajtów

Co powiesz na rozwiązanie arytmetyczne?

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

Bardzo się cieszę, że to przewyższa proste podejście Mathematica.

Wyjaśnienie

Sam kod oblicza 9 * n + n% 10, a następnie znajduje największą potęgę 10, która dzieli dane wejściowe, lub innymi słowy, zlicza zera końcowe. Musimy pokazać, jeśli n kończy się na k powtarzających się cyfr, że 9 * n + n% 10 ma k końcowych zer.

Cyfry powtórzeń najłatwiej jest wyrazić matematycznie, dzieląc liczbę taką jak 99999 (czyli 10 5 -1 ) przez 9, a następnie mnożąc przez powtórzoną cyfrę. Możemy więc napisać n = m * 10 k + d * (10 k -1) / 9 , gdzie m ≢ d (mod 10) , aby upewnić się, że n nie kończy się więcej niż k powtarzanymi cyframi. Zauważ, że d = n% 10 .

Podłączmy to do naszej formuły 9 * n + n% 10 . Otrzymujemy 9 * m * 10 k + d * (10 k -1) + d . D na końcu jest anulowane, przez to że pozostaje: 9 m * 10 * k + D * 10 k = (9 * M + d) * 10 k . Ale 9 ≡ -1 (mod 10) , więc 9 * m + d ≡ d - m (mod 10) . Ale stwierdziliśmy, że m ≢ d (mod 10), a zatem d - m ≢ 0 (mod 10) .

Innymi słowy, pokazaliśmy, że 9 * m + d nie jest podzielne przez 10, a zatem największa moc 10, która dzieli 9 * n + n% 10 = (9 * m + d) * 10 k to k , liczba końcowych powtarzających się cyfr.

Jako bonus, to rozwiązanie drukuje poprawny wynik , dla danych wejściowych 0.


1
W takich chwilach chciałbym, żeby ta strona wspierała MathJax; pogrubione formuły nie są tak ładne jak formuły. Fajnie, że poświęciłeś trochę czasu na napisanie indeksu górnego wykładnika.
wizzwizz4,

1
@ wizzwizz4 Kiedyś korzystałem z formatowania kodu, ale odkryłem, że pogrubienie (które jest zwykle używane przez Dennisa) jest nieco bardziej czytelne. Ale zgodził się, nie jest tak miły jak MathJax.
Martin Ender

13

Siatkówka , 9 bajtów

&`(.)\1*$

Wypróbuj online!

Liczy liczbę nakładających się dopasowań, (.)\1*$których wyrażenie regularne pasuje do sufiksu identycznych znaków.


2
To musi być mem: ty i twój regex
Christopher

Muszę nauczyć się wszystkich tych modyfikatorów - po prostu bym po to poszedł (.)(?=\1*$).
Neil

1
@DownChristopher dosłownie stworzył język oparty na wyrażeniach regularnych, wykracza to poza materiał memów c:
Rod

1
@Neil Jeśli to jakaś pociecha, moja pierwsza próba była (?=(.)\1*$)(w zasadzie taka sama jak twoja).
Martin Ender

1
Zgadza się, dziękuję!
Neil

9

Brachylog , 4 bajty

ẹḅtl

Wypróbuj online!

Wyjaśnienie

ẹ       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

Gdyby działał bezpośrednio na liczbach całkowitych (i nie jestem pewien, dlaczego nie zaimplementowałem go w taki sposób, aby to zrobił), byłyby to tylko 3 bajty, ponieważ nie byłyby potrzebne.


9

Python 2 , 47 41 bajtów

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

Wypróbuj online!

36 bajtów - dla bardziej elastycznego wprowadzania

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

Wypróbuj online!


Łał. Muszę nauczyć się wbudowań z większą uwagą. +1
Dead Possum

2
@DeadPossum dir(object)jest naszym przyjacielem c:
Rod

BTW, nie wolno nam przyjmować ciągu jako danych wejściowych. „Jeśli twoja metoda wprowadzania automatycznie zwraca ciągi, to na pewno, ale nie możesz zakładać, że dane wejściowe zostaną dostarczone jako ciągi.” : C
Dead Possum

1
@DeadPossum Myślę, że autor zmienił zdanie na ten temat. Wygląda na to, że komentarz został usunięty.
Brian McCutchon

8

JavaScript (ES6), 55 52 32 30 bajtów

a=>a.match`(.)\\1*$`[0].length
  • Zaoszczędź 19 bajtów dzięki @MartinEnder, zastępując wyrażenie regularne
  • Zaoszczędzono 2 bajty dzięki @ user81655 przy użyciu oznaczonych literałów szablonów

Użycie wyrażenia regularnego w celu dopasowania ostatniej grupy ostatniej cyfry

Uwaga: Pierwsze opublikowanie. Nie wahaj się czynić uwag.

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

Witamy w PPCG! Możesz zaoszczędzić wiele bajtów, korzystając z odsyłacza wstecznego zamiast ręcznie wpisywać powtórzony znak:/(.)\1*$/
Martin Ender

Ponadto funkcje bez nazw są w porządku (chyba, że ​​potrzebujesz nazwy dla wywołań rekurencyjnych), dzięki czemu możesz zapisać dwa bajty na f=.
Martin Ender

Dobra robota! To z pewnością pozytywna ocena, ale można to pograć w golfa
Christopher

@MartinEnder Thanks! Nadal muszę się nauczyć gry w golfa
Weedoze

@DownChristopher Thanks! Następnym razem postaram się zrobić lepiej
Weedoze


7

PHP, 47 45 40 bajtów

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

Biegnij z echo <n> | php -nR '<code>

wydaje się, że pętla jest wciąż mniejsza niż moja pierwsza odpowiedź. po prostu policz znaki, które są równe ostatnim. Używa to przesunięć ciągu ujemnego o wartości PHP 7.1 .

-5 bajtów Tytusa. Dzięki !


Stara odpowiedź:

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

usuwa z prawej każdy znak pasujący do znaku z prawej strony i oblicza różnicę długości.


-Ri $argnmoże zaoszczędzić 5 bajtów.
Tytus




6

Perl 5 , 22 bajtów

21 bajtów kodu + -pflaga.

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

Wypróbuj online!

/(.)\1*$/pobiera ostatnie identyczne liczby, a następnie $_=length$&przypisuje swoją długość do $_, która jest domyślnie drukowana dzięki -pfladze.


6

C (gcc) , 32 29 bajtów

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

To jest port mojej odpowiedzi w Pythonie .

Działa to z gcc, ale brak returninstrukcji jest niezdefiniowanym zachowaniem.

Wypróbuj online!


Jestem zdezorientowany, dlaczego nie przekazujesz wskaźnika i nie zmieniasz wartości w lokalizacji, lub po prostu zwracasz wartość. Wygląda na to, że po prostu zmienia lokalną kopię, co uniemożliwiłoby korzystanie z tej funkcji, ale działa to na TIO. Dodajesz również 1 do n w stopce, a nie sizeof (int), czy nie przesuwałoby to 1 bajta do przodu, zamiast pełnej szerokości int? Oczywiście jest kilka sztuczek, których mogę się tutaj nauczyć i prawdopodobnie mógłbym użyć pierwszej z moich własnych odpowiedzi.
Bijan

2
Wszystko, co returnrobi, to przechowywanie wartości zwracanej w EAX. W przypadku gcc przypisanie jej do zmiennej dzieje się tak samo. Jeśli chodzi o arytmetykę wskaźnika, po dodaniu 1 do wskaźnika int przenosi się do następnego int, a nie do następnego bajtu.
Dennis

Czy są przypadki (przy użyciu int), kiedy lepiej byłoby wrócić, wydaje się, że w najgorszym przypadku zrobiłbyś nową int i przypisałeś to.
Bijan

Kompilatory @Bijan C zawsze wyrównują bezpośredni dostęp do pamięci do wielkości atomu tego prymitywnego elementu - nie pamiętam jednak, czy jest w standardzie
cat

5

Python 2, 51 bajtów

Pobiera na wejściu liczbę całkowitą. Wypróbuj online

lambda S:[x==`S`[-1]for x in`S`[::-1]+'~'].index(0)

48 bajtów dla ciągu jako danych wejściowych. Wypróbuj online

lambda S:[x==S[-1]for x in S[::-1]+'~'].index(0)

5

C # , 63 62 bajtów


Grał w golfa

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

Bez golfa

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

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

    return b - a;
}

Nieczytelny czytelny

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;
}

Pełny kod

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();
      }
   }
}

Prasowe

  • v1.1 - - 1 byte - Dzięki komentarzowi Kevina .
  • v1.0 -  63 bytes- Wstępne rozwiązanie.

Notatki

Nic do dodania


+1 Możesz jednak zagrać w golfa o 1 bajt. Jak to:i=>{int a=i.Length-1,b=a;while(a-->0&&i[a]==i[b]);return b-a;}
Kevin Cruijssen


4

MATL , 6 5 bajtów

1 bajt zapisany dzięki @Luis

&Y'O)

Wypróbuj w MATL Online

Wyjaśnienie

        % 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

Zapomniałem, że to &zrobiło to Y':-D Dlaczego nie wziąć wkładu jako ciągu ujętego w cytaty i się go pozbyć j?
Luis Mendo

@LuisMendo Nie byłem pewien, czy mógłbym to zrobić, ponieważ wyzwanie wyraźnie mówiło, że dane wejściowe to „liczba całkowita”
Suever

Założyłem to na podstawie komentarza Martina i domyślnych reguł, które na to pozwalają. Ale nie jestem do końca pewien
Luis Mendo

@LuisMendo Ah ok nie widział swojego komentarza. Zaktualizuję!
Suever

4

Cubix, 24 19 bajtów

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

Uwaga

  • Faktycznie liczy, ile takich samych znaków znajduje się na końcu danych wejściowych, więc działa to również w przypadku naprawdę dużych liczb całkowitych i naprawdę długich ciągów znaków (o ile liczba takich samych znaków na końcu jest mniejsza niż maksymalna precyzja JavaScript ( około 15 cyfr w bazie-10).
  • Dane wejściowe trafiają do pola wejściowego, dane wyjściowe są drukowane do pola wyjściowego

Wypróbuj tutaj

Wyjaśnienie

Najpierw rozwińmy kostkę

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

Kroki wykonania można podzielić na trzy fazy:

  1. Analizuj dane wejściowe
  2. Porównaj postacie
  3. Wydrukuj wynik

Faza 1: Wejście

Pierwsze dwa znaki, które są wykonywane, to Ai B. Aodczytuje wszystkie dane wejściowe i wypycha je jako kody znaków na stos. Zauważ, że odbywa się to w odwrotnej kolejności, pierwsza postać kończy się na stosie, a ostatnia prawie na dole. Na samym dole znajduje się -1( EOF), który będzie używany jako licznik ilości kolejnych znaków na końcu ciągu. Ponieważ potrzebujemy, aby góra stosu zawierała dwa ostatnie znaki, odwracamy stos przed wejściem do pętli. Zauważ, że górna część stosu wygląda teraz:..., C[n-1], C[n], -1 .

Miejsce IP na kostce jest tam, gdzie Ejest i wskazuje w prawo. Wszystkie instrukcje, które nie zostały jeszcze wykonane, zostały zastąpione przez brak operacji (kropki).

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

Faza 2: Porównanie postaci

Stos to ..., C[a-1], C[a], counter, gdzie counterjest licznik przyrostu, gdy dwa znaki do sprawdzenia ( C[a]i C[a-1]) są równe. IP najpierw wchodzi w tę pętlę przy Sznaku, przesuwając się w prawo. EPostać jest stanowisko, gdzie IP skończy się (wskazując prawo), gdy C[a]i C[a-1]nie mają tę samą wartość, co oznacza, że odjęcie C[a]od C[a-1]nie daje 0, w którym to przypadku instrukcji po !zostanie pominięty (co jest w).

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

Oto instrukcje, które są wykonywane podczas pełnej pętli:

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)

A potem się zapętla.

Faza 3: wydrukuj wynik

Ponieważ opuścił pętlę wcześnie, wygląd stos słuszne: counter, ..., C[a-1]-C[a]. Łatwo jest wydrukować licznik, ale musimy zwiększyć licznik raz, ponieważ nie zrobiliśmy tego w ostatniej iteracji pętli, i jeszcze raz, ponieważ -1zamiast tego zaczęliśmy liczyć 0. Ścieżka na kostce wygląda tak, zaczynając od S, wskazując w prawo. Dwie operacje „no-op” wykonywane przez adres IP są zastępowane strzałkami wskazującymi w kierunku adresu IP.

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

Instrukcje są wykonywane w następującej kolejności. Zauważ, że B)instrukcje na końcu zmieniają stos, ale nie wpływają na program, ponieważ mamy zamiar go zakończyć i nie używamy już stosu.

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

Partia, 91 bajtów

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

W -zapobiega testy z zjechania początek łańcucha.


3

JavaScript (ES6), 34 bajty

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

Nie krótszy niż rozwiązanie wyrażenia regularnego.

Funkcja rekurencyjna, która ocenia cyfry od prawej do lewej, zatrzymując się po napotkaniu innej cyfry. Wynikiem jest liczba iteracji. pjest undefinedna pierwszej iteracji, co oznacza n%10-pzwroty NaN(fałsz). Następnie prówna się poprzedniej cyfrze z n%10. Gdy bieżąca cyfra ( n%10) i poprzednia ( p) są różne, pętla kończy się.


3

Röda , 12 bajtów

{count|tail}

Wypróbuj online!

Jest to anonimowa funkcja, która oczekuje, że każdy znak ciągu wejściowego zostanie wypchnięty do strumienia (myślę, że jest to poprawne w duchu ostatniego pytania meta ).

Wykorzystuje dwa wbudowane: counti tail:

  1. count odczytuje wartości ze strumienia i przekazuje liczbę kolejnych elementów do strumienia.
  2. tail zwraca ostatnią wartość w strumieniu.

3

T-SQL, 238 214 bajtów

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

Lub:

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

Java 7, 78 bajtów

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

Wypróbuj tutaj.

Próbowałem pewnych rzeczy za pomocą rekurencji lub pętli, ale oba zakończyły się powyżej 100 bajtów ..


2

PowerShell, 41 bajtów

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

prosta pętla do tyłu, dopóki znak nie pasuje do ostatniego znaku w ciągu, zwróć indeks tego znaku -1.

-3 dzięki @AdmBorkBork - zamiast używać pętli for.


2

Mathematica, 33 30 bajtów

Podziękowania dla Grega Martina za uratowanie 3 bajtów.

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

Pobiera dane wejściowe jako ciąg.

Pobiera cyfry dziesiętne (w postaci znaków), dzieli je na przebiegi identycznych elementów, pobiera ostatni przebieg i oblicza długość standardową sztuczką polegającą na pobraniu sumy wektora 1^list.


Characterszamiast IntegerDigits?
Greg Martin

@GregMartin Ah tak, tak myślę. Dzięki.
Martin Ender

Nadal nie pokonujesz tego drugiego sprytnego golfisty Mathematica za to pytanie;)
Greg Martin

@GregMartin Co za wstyd. :)
Martin Ender


2

JavaScript (ES6), 39 38 37 27 bajtów

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

Może nie mniej niż rozwiązanie oparte na wyrażeniach regularnych, ale nie mogłem się oprzeć napisaniu rozwiązania opartego całkowicie na arytmetyce. Techniką jest wielokrotne przyjmowanie n % 100 % 11i dzielenie przez 10, aż wynik będzie niezerowy, a następnie zliczanie iteracji. Działa to, ponieważ jeśli dwie ostatnie cyfry są takie same, n % 100 % 11to będzie 0.


Ach, skończyłeś tuż przede mną haha! Nie jestem pewien, czy opublikować inną odpowiedź, ponieważ najprawdopodobniej f=(n,p)=>n%10-p?0:1+f(n/10|0,n%10)
zbiegną się po grze w

@ user81655 To świetnie, nie krępuj się opublikować. Nie sądzę, żeby moje zbiegło się do tego bez kompletnego remontu, i oczywiście teraz, kiedy widziałem twoje, to się nie wydarzy ;-)
ETHprodukcje

2

Haskell , 33 bajty

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

Wypróbuj online!

Pobiera ciąg znaków. Wielokrotnie odcina pierwszy znak i dodaje 1, jeśli wszystkie znaki w sufiksie są równe pierwszemu.


2

R, 35 bajtów

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

Krótkie wyjaśnienie

                  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 bajtów

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

Wypróbuj online!

Można by to skrócić, gdybym tylko użył stosu.

Jak to działa:

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 bajty

Pełny program (w Pythonie 3 input()zwraca ciąg, bez względu na dane wejściowe):

g=input();print(len(g)-len(g.rstrip(g[-1]))) 
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.