Junte seus dubs


24

No 4chan, um jogo popular é o get. Cada postagem no site recebe um ID de postagem sequencial. Como você não pode influenciá-los ou determiná-los, as pessoas tentam adivinhar (pelo menos uma parte) seu próprio número de postagem, geralmente os primeiros dígitos. Outra versão do jogo é chamada dubs, e seu objetivo é obter dígitos repetidos no final do número (por exemplo, 1234555).

Sua tarefa, se você deseja aceitá-la, é escrever um programa que use uma identificação de postagem como entrada (número inteiro padrão, você pode assumir abaixo de 2 ^ 32) e retornar quantos dígitos repetidos existem no final.

Regras

  • As brechas padrão não são permitidas .
  • O programa pode ser uma função, programa completo, comando REPL, o que realmente funciona, desde que nenhum código / argumento externo não contado seja necessário para executá-lo.
  • A entrada pode vir de STDIN, argumentos de função, argumento de linha de comando, arquivo, o que for mais conveniente para você.

Casos de teste

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

11
É permitido receber entrada como string?
Gambá morto

6
@DeadPossum Eu diria que isso é permitido, desde que você obtenha uma string de qualquer maneira, se você ler a entrada de STDIN, argumento da linha de comando ou arquivo (que são todos os métodos de entrada admissíveis).
Martin Ender

11
Podemos assumir que a entrada será maior que 0?
Martin Ender

11
@MartinEnder Yes
sagiksp

2
Voto positivo para o jogo de dubs! Check'em!
ZombieChowder em 28/03

Respostas:


19

Mathematica, 29 bytes

Que tal uma solução aritmética?

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

Estou muito satisfeito ao ver que isso supera a abordagem direta do Mathematica.

Explicação

O próprio código calcula 9 * n + n% 10 e, em seguida, encontra a maior potência de 10 que divide a entrada, ou seja, conta os zeros à direita. Precisamos mostrar se n termina em k dígitos repetidos, que 9 * n + n% 10 tem k zeros à direita.

Os dígitos repetitivos são expressos matematicamente mais facilmente dividindo um número como 99999 (que é 10 5 -1 ) por 9 e multiplicando pelo dígito repetido. Portanto, podemos escrever n = m * 10 k + d * (10 k -1) / 9 , onde m ≢ d (mod 10) , para garantir que n não termine em mais de k dígitos repetidos. Observe que d = n% 10 .

Vamos inserir isso em nossa fórmula 9 * n + n% 10 . Temos 9 * m * 10 k + d * (10 k -1) + d . O d no final é cancelado, então ficamos com: 9 * m * 10 k + d * 10 k = (9 * m + d) * 10 k . Mas 9 ≡ -1 (mod 10) , então 9 * m + d ≡ d - m (mod 10) . Mas afirmamos que m ≢ d (mod 10) e, portanto, d - m ≢ 0 (mod 10) .

Em outras palavras, mostramos que 9 * m + d não é divisível por 10 e, portanto, a maior potência de 10 que divide 9 * n + n% 10 = (9 * m + d) * 10 k é k , o número de dígitos repetidos à direita.

Como um bônus, esta solução imprime o resultado correto,, para entrada 0.


11
Em momentos como este, desejo que este site seja compatível com o MathJax; as fórmulas em negrito não são tão boas quanto as tipográficas. É bom que você tenha dedicado um tempo para escrever os expoentes sobrescritos.
wizzwizz4

11
@ wizzwizz4 Eu costumava usar formatação de código, mas descobri que o negrito (que geralmente é usado por Dennis) é um pouco mais legível do que isso. Mas concordou, não é tão bom quanto o MathJax.
Martin Ender

13

Retina , 9 bytes

&`(.)\1*$

Experimente online!

Conta o número de correspondências sobrepostas, (.)\1*$que é uma regex que corresponde a um sufixo de caracteres idênticos.


2
Este deve ser um meme: você e seu regex
Christopher

Eu preciso aprender todos esses modificadores - eu teria acabado de procurar (.)(?=\1*$).
285 Neil

11
@DownChristopher ele literalmente fez uma linguagem baseada em regex, isso vai além meme c materiais:
Rod

11
@ Neil Se houver algum consolo, minha primeira tentativa foi (?=(.)\1*$)(basicamente a mesma que a sua).
Martin Ender

11
Sim, obrigado!
285 Neil

9

Braquilog , 4 bytes

ẹḅtl

Experimente online!

Explicação

ẹ       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

Se trabalhasse diretamente em números inteiros (e não sei por que não o implementei), isso seria apenas 3 bytes, pois não seria necessário.


9

Python 2 , 47 41 bytes

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

Experimente online!

36 bytes - Para uma entrada mais flexível

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

Experimente online!


Uau. Eu tenho que aprender a construir com mais atenção +1
Gambá morto

2
@DeadPossum dir(object)é nosso amigo c:
Rod

BTW, não estamos autorizados a receber string como entrada. "Se o seu método de entrada retornar automaticamente as strings, com certeza, mas você não pode assumir que a entrada será fornecida como strings." : C
Dead Possum

11
@DeadPossum Acho que o autor mudou de idéia sobre isso. O comentário parece ter sido excluído.
Brian McCutchon

8

Javascript (ES6), 55 52 32 30 bytes

a=>a.match`(.)\\1*$`[0].length
  • Guardado 19 bytes graças a @MartinEnder, substituindo o regex
  • Economizou 2 bytes graças a @ user81655 usando literais de modelos marcados

Usando uma regex para corresponder ao último grupo do último dígito

Nota: Primeira publicação. Não hesite em fazer comentários.

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

Bem-vindo ao PPCG! Você pode salvar muitos bytes usando uma referência reversa em vez de preencher manualmente o caractere repetido:/(.)\1*$/
Martin Ender

Além disso, funções não nomeadas são completamente boas (a menos que você precise do nome para chamadas recursivas, por exemplo), para que você possa salvar dois bytes no f=.
Martin Ender

Bom trabalho! Isso com certeza passa a revisão, mas isso poderia ser golfed
Christopher

@MartinEnder Thanks! Eu ainda tenho que aprender a golf
Weedoze

@DownChristopher Thanks! Vou tentar fazer melhor na próxima vez
Weedoze 28/03


7

PHP, 47 45 40 bytes

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

Correr com echo <n> | php -nR '<code>

parece que um loop ainda é menor que minha primeira resposta. basta contar os caracteres iguais ao último. Isso usa deslocamentos negativos de string do PHP 7.1 .

-5 bytes por Titus. Obrigado !


Resposta antiga:

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

remove da direita todos os caracteres correspondentes ao caracter mais à direita e calcula a diferença no comprimento.


-Re $argnpoderia economizar 5 bytes.
Titus




6

Perl 5 , 22 bytes

21 bytes de código + -psinalizador.

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

Experimente online!

/(.)\1*$/obtém os últimos números idênticos e $_=length$&atribui seu comprimento a $_, que é implicitamente impresso graças ao -psinalizador.


6

C (gcc) , 32 29 bytes

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

Esta é uma porta da minha resposta Python .

Isso funciona com o gcc, mas a falta de uma returndeclaração é um comportamento indefinido.

Experimente online!


Estou confuso, como é que você não passa um ponteiro e altera o valor no local ou apenas retorna o valor. Parece que apenas altera a cópia local, o que tornaria a função inutilizável, mas isso funciona no TIO. Você também adiciona 1 a n no rodapé, em vez de sizeof (int), isso não o moveria 1 byte para a frente, em vez da largura total de um int? Claramente, existem alguns truques que eu poderia aprender aqui e provavelmente poderia usar o primeiro em minha própria resposta.
Bijan

2
Tudo o returnque a instrução faz é armazenar o valor de retorno no EAX. Com o gcc, atribuí-lo a uma variável faz a mesma coisa. Quanto à aritmética do ponteiro, quando você adiciona 1 a um ponteiro int, ele passa para o próximo int, não para o próximo byte.
Dennis

Existem casos (ao usar ints) em que seria melhor retornar, parece que no pior caso você faria um novo int e atribuiu isso.
Bijan

Compiladores C @Bijan sempre acesso directo à memória alinhar com o tamanho de um átomo do primitivo em questão - não me lembro se é no padrão, embora
cat


5

C # , 63 62 bytes


Golfe

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 legible

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

Código completo

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

Lançamentos

  • v1.1 - - 1 byte - Graças ao comentário de Kevin .
  • v1.0 -  63 bytes- Solução inicial.

Notas

Nada para adicionar




4

MATL , 6 5 bytes

1 byte salvo graças a @Luis

&Y'O)

Experimente no MATL Online

Explicação

        % 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

Eu tinha esquecido que &fiz isso para Y':-D Por que não pegar a entrada como uma string entre aspas e livrar-me j?
Luis Mendo

@LuisMendo Eu não tinha certeza se eu poderia fazer isso desde o desafio disse explicitamente que a entrada foi um "inteiro"
Suever

Eu assumi isso pelo comentário de Martin e pelas regras padrão, que permitem isso. Mas eu não tenho certeza
Luis Mendo

@LuisMendo Ah ok não viu o comentário dele. Atualizará!
Suever 28/03

4

Cubix, 24 19 bytes

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

Nota

  • Na verdade, conta quantos dos mesmos caracteres existem no final da entrada, portanto, isso também funciona para números inteiros muito grandes e cadeias muito longas (desde que a quantidade de caracteres no final seja menor que a precisão máxima do JavaScript ( cerca de 15 dígitos na base 10).
  • A entrada entra no campo de entrada, a saída é impressa no campo de saída

Experimente aqui

Explicação

Primeiro, vamos expandir o cubo

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

As etapas da execução podem ser divididas em três fases:

  1. Analisar entrada
  2. Compare caracteres
  3. Imprimir resultado

Fase 1: Entrada

Os dois primeiros caracteres que são executados são Ae B. Alê todas as entradas e as envia como códigos de caracteres para a pilha. Observe que isso é feito ao contrário, o primeiro caractere termina no topo da pilha, o último caractere quase na parte inferior. Na parte inferior, é colocado -1( EOF), que será usado como um contador para a quantidade de caracteres consecutivos no final da string. Como precisamos que o topo da pilha contenha os dois últimos caracteres, invertemos a pilha antes de inserir o loop. Observe que a parte superior da pilha agora se parece com:..., C[n-1], C[n], -1 .

O lugar do IP no cubo é onde Eestá e está apontando para a direita. Todas as instruções que ainda não foram executadas foram substituídas por no-ops (pontos finais).

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

Fase 2: Comparação de caracteres

A pilha é ..., C[a-1], C[a], counteronde counterestá o contador para incrementar quando os dois caracteres para verificar ( C[a]e C[a-1]) são iguais. O IP primeiro entra nesse loop no Spersonagem, movendo-se para a direita. O Ecaractere é a posição em que o IP terminará (apontando para a direita) quando C[a]e C[a-1]não terá o mesmo valor, o que significa que subtrair C[a]de C[a-1]não produz 0, nesse caso a instrução a seguir !será ignorada (que é a w).

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

Aqui estão as instruções que são executadas durante um loop completo:

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)

E então ele volta.

Fase 3: resultado da impressão

Desde que deixou o circuito cedo, os olhares pilha assim: counter, ..., C[a-1]-C[a]. É fácil imprimir o contador, mas precisamos incrementá-lo uma vez porque não o fizemos na última iteração do loop e mais uma vez porque começamos a contar em -1vez de 0. O caminho no cubo se parece com isso, começando em S, apontando para a direita. As duas operações não executadas pelo IP são substituídas por setas que apontam na direção do IP.

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

As instruções são executadas na seguinte ordem. Observe que as B)instruções no final alteram a pilha, mas não afetam o programa, pois estamos prestes a finalizá-la e não usamos mais a pilha.

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

Lote, 91 bytes

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

Os -impede que o teste seja executado fora do início da string.


3

JavaScript (ES6), 34 bytes

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

Não é mais curto que a solução regex.

Função recursiva que avalia os dígitos da direita para a esquerda, parando quando um dígito diferente é encontrado. O resultado é o número de iterações. pestá undefinedna primeira iteração, o que significa n%10-pretornos NaN(falsy). Depois disso, pigual ao dígito anterior com n%10. Quando o dígito atual ( n%10) e o anterior ( p) são diferentes, o loop termina.


3

Röda , 12 bytes

{count|tail}

Experimente online!

Esta é uma função anônima que espera que cada caractere da string de entrada seja enviado ao fluxo (acho que isso é válido no espírito de uma meta questão recente ).

Ele usa dois builtins: counte tail:

  1. count lê valores do fluxo e envia o número de elementos consecutivos ao fluxo.
  2. tail retorna o último valor no fluxo.

3

T-SQL, 238 214 bytes

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

Ou:

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 bytes

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

Experimente aqui.

Eu tentei algumas coisas usando recursão ou loop, mas ambas terminaram acima de 100 bytes.


2

Powershell, 41 bytes

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

loop direto para trás até que um caractere não corresponda ao último caractere da string, retorne o índice desse caractere -1.

-3 graças a @AdmBorkBork - usando um loop for em vez de um tempo.


2

Mathematica, 33 30 bytes

Obrigado a Greg Martin por salvar 3 bytes.

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

Recebe a entrada como uma sequência.

Obtém os dígitos decimais (na forma de caracteres), os divide em execuções de elementos idênticos, obtém a última execução e calcula o comprimento com o truque padrão de obter a soma do vetor 1^list.


Charactersem vez de IntegerDigits?
Greg Martin

@GregMartin Ah sim, eu acho. Obrigado.
Martin Ender

Você ainda não bater aquele outro astuto Mathematica golfista para esta pergunta;)
Greg Martin

@GregMartin Que vergonha. :)
Martin Ender


2

JavaScript (ES6), 39 38 37 27 bytes

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

Talvez não seja menor que a solução baseada em regex, mas não resisti em escrever uma solução totalmente baseada em aritmética. A técnica é pegar n % 100 % 11e dividir repetidamente por 10 até que o resultado seja diferente de zero e conte as iterações. Isso funciona porque se os dois últimos dígitos forem iguais, n % 100 % 11será 0.


Ah, você terminou antes de mim haha! Não tenho certeza se postarei outra resposta, pois elas provavelmente convergirão após o golfe, mas aqui está a minha solução usando 34 bytes:f=(n,p)=>n%10-p?0:1+f(n/10|0,n%10)
user81655 28/17/17

@ user81655 Isso é ótimo, fique à vontade para publicá-lo. Eu não acho que o meu irá convergir para baixo para que, sem uma reforma completa, e, claro, agora que eu vi seu que não vai acontecer ;-)
ETHproductions

2

Haskell , 33 bytes

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

Experimente online!

Pega a entrada da string. Corta repetidamente o primeiro caractere e adiciona 1 se todos os caracteres no sufixo forem iguais ao primeiro.


2

R, 35 bytes

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

Breve explicação

                  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 bytes

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

Experimente online!

Isso poderia ser mais curto se eu conseguisse usar apenas a pilha.

Como funciona:

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 bytes

Programa completo (no Python 3, input()retorna uma string, independentemente da entrada):

g=input();print(len(g)-len(g.rstrip(g[-1]))) 
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.