Metti insieme i tuoi dubbi


24

Su 4chan, un gioco popolare è get. Ogni post sul sito ottiene un ID post sequenziale. Dal momento che non puoi influenzarli o determinarli, le persone cercano di indovinare (almeno una parte del) numero di posta, di solito le prime cifre. Un'altra versione del gioco si chiama dubs, e il suo obiettivo è quello di ottenere cifre ripetute alla fine del numero (cioè 1234555).

Il tuo compito, se desideri accettarlo, è scrivere un programma che accetta un ID post come input (numero intero standard, puoi assumere sotto 2 ^ 32) e restituisce quante cifre ripetitive ci sono alla fine.

Regole

  • Le scappatoie standard non sono ammesse .
  • Il programma può essere una funzione, un programma completo, un comando REPL, qualunque cosa funzioni, in realtà, purché non siano necessari codice / argomenti esterni non conteggiati per eseguirlo.
  • L'input può provenire da STDIN, argomenti della funzione, argomento della riga di comando, file, qualunque cosa tu voglia.

Casi test

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
È consentito accettare input come stringa?
Dead Possum,

6
@DeadPossum Suppongo che sia consentito, dato che ottieni comunque una stringa se leggi l'input da STDIN, argomento della riga di comando o file (che sono tutti metodi di input ammessi).
Martin Ender,

1
Possiamo supporre che l'ingresso sarà maggiore di 0?
Martin Ender,

1
@MartinEnder Sì
sagiksp,

2
Upvote per il gioco dubs! Check'em!
ZombieChowder

Risposte:


19

Mathematica, 29 byte

Che ne dici di una soluzione aritmetica?

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

Sono molto contento di vedere che questo batte l'approccio diretto di Mathematica.

Spiegazione

Il codice stesso calcola 9 * n + n% 10 e quindi trova la potenza maggiore di 10 che divide l'input o, in altre parole, conta gli zeri finali. Dobbiamo mostrare se n finisce in k cifre ripetute, che 9 * n + n% 10 ha k zeri finali.

Le cifre di ripetizione sono più facilmente espresse matematicamente dividendo un numero come 99999 (che è 10 5 -1 ) per 9 e quindi moltiplicando per la cifra ripetuta. Quindi possiamo scrivere n = m * 10 k + d * (10 k -1) / 9 , dove m ≢ d (mod 10) , per garantire che n non finisca in più di k cifre ripetute. Si noti che d = n% 10 .

Inseriamolo nella nostra formula 9 * n + n% 10 . Otteniamo 9 * m * 10 k + d * (10 k -1) + d . La d alla fine viene annullata, quindi restiamo con: 9 * m * 10 k + d * 10 k = (9 * m + d) * 10 k . Ma 9 ≡ -1 (mod 10) , quindi 9 * m + d ≡ d - m (mod 10) . Ma abbiamo affermato che m ≢ d (mod 10) e quindi d - m ≢ 0 (mod 10) .

In altre parole, abbiamo dimostrato che 9 * m + d non è divisibile per 10 e, pertanto, la più grande potenza di 10 che divide 9 * n + n% 10 = (9 * m + d) * 10 k è k , il numero di cifre ripetute finali.

Come bonus, questa soluzione stampa il risultato corretto , per l'input 0.


1
In momenti come questo vorrei che questo sito supportasse MathJax; le formule in grassetto non sono belle come quelle composte. È bello che tu abbia preso il tempo di scrivere l'apice dell'esponente.
wizzwizz4,

1
@ wizzwizz4 Prima usavo la formattazione del codice, ma ho scoperto che grassetto (che di solito viene usato da Dennis) è un po 'più leggibile di così. Ma d'accordo, non è bello come MathJax.
Martin Ender,

13

Retina , 9 byte

&`(.)\1*$

Provalo online!

Conta il numero di corrispondenze sovrapposte di (.)\1*$cui è una regex che corrisponde a un suffisso di caratteri identici.


2
Questo deve essere un meme: tu e la tua regex
Christopher,

Devo imparare tutti questi modificatori - mi sarei appena aspettato (.)(?=\1*$).
Neil,

1
@DownChristopher ha letteralmente creato un linguaggio basato sulla regex, che va oltre il materiale meme c:
Rod

1
@Neil Se è una consolazione, il mio primo tentativo è stato (?=(.)\1*$)(quindi sostanzialmente uguale al tuo).
Martin Ender,

1
Sì lo è, grazie!
Neil,

9

Brachylog , 4 byte

ẹḅtl

Provalo online!

Spiegazione

ẹ       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 funzionasse direttamente su numeri interi (e non sono sicuro del motivo per cui non l'ho implementato in questo modo), questo sarebbe solo 3 byte in quanto non sarebbe necessario.


9

Python 2 , 47 41 byte

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

Provalo online!

36 byte - Per un input più flessibile

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

Provalo online!


Wow. Devo imparare i builtin più attentamente. +1
Dead Possum

2
@DeadPossum dir(object)è il nostro amico c:
Rod

A proposito non ci è permesso prendere la stringa come input. "Se il tuo metodo di input restituisce automaticamente le stringhe, sicuramente, ma non puoi supporre che l'input verrà fornito come stringhe." : C
Dead Possum,

1
@DeadPossum Penso che l'autore abbia cambiato idea in merito. Il commento sembra essere stato eliminato.
Brian McCutchon,

8

Javascript (ES6), 55 52 32 30 byte

a=>a.match`(.)\\1*$`[0].length
  • Salvato 19 byte grazie a @MartinEnder sostituendo il regex
  • Salvato 2 byte grazie a @ user81655 usando letterali template con tag

Usando una regex per abbinare l'ultimo gruppo dell'ultima cifra

Nota: prima pubblicazione. Non esitate a fare commenti.

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

Benvenuti in PPCG! Puoi salvare molti byte usando un backreference invece di compilare manualmente il carattere ripetuto:/(.)\1*$/
Martin Ender

Inoltre, le funzioni senza nome sono completamente valide (a meno che non sia necessario il nome per le chiamate ricorsive, ad esempio), quindi è possibile salvare due byte sul f=.
Martin Ender,

Buon lavoro! Questo sicuramente passa la recensione ma questo potrebbe essere golfato
Christopher

@MartinEnder Grazie! Devo ancora imparare a giocare a golf
Weedoze,

@DownChristopher Grazie! Proverò a fare meglio la prossima volta
Weedoze,

7

C, 62 56 48 47 byte

Salvataggio di un byte grazie a @Steadybox!

j,k;f(n){for(k=j=n%10;j==n%10;n/=10,k++);k-=j;}

Provalo online!


7

PHP, 47 45 40 byte

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

Corri con echo <n> | php -nR '<code>

sembra che un ciclo sia ancora più piccolo della mia prima risposta. conta semplicemente i caratteri uguali all'ultimo. Questo utilizza offset di stringa negativi di PHP 7.1 .

-5 byte di Tito. Grazie !


Vecchia risposta:

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

rimuove da destra ogni carattere corrispondente al carattere più a destra e calcola la differenza nella lunghezza.


-Re $argnpotrebbe salvare 5 byte.
Tito




6

Perl 5 , 22 byte

21 byte di codice + -pflag.

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

Provalo online!

/(.)\1*$/ottiene gli ultimi numeri identici e quindi $_=length$&assegna la sua lunghezza a $_, che è implicitamente stampata grazie alla -pbandiera.


6

C (gcc) , 32 29 byte

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

Questa è una porta della mia risposta Python .

Questo funziona con gcc, ma la mancanza di una returndichiarazione è un comportamento indefinito.

Provalo online!


Sono confuso, come mai non si passa nemmeno un puntatore e si cambia il valore nella posizione, o semplicemente si restituisce il valore. Sembra che cambi semplicemente la copia locale, il che renderebbe inutilizzabile la funzione, ma funziona su TIO. Aggiungete anche 1 a n nel piè di pagina, piuttosto che sizeof (int), non lo sposterà di 1 byte in avanti, anziché l'intera larghezza di un int? Chiaramente ci sono alcuni trucchi che potrei imparare qui, e probabilmente potrei usare il primo nella mia risposta.
Bijan,

2
Tutto returnciò che fa l' istruzione è la memorizzazione del valore restituito in EAX. Con gcc, assegnarlo a una variabile sembra fare la stessa cosa. Per quanto riguarda l'aritmetica del puntatore, quando si aggiunge 1 a un puntatore int, si passa al successivo int, non al byte successivo.
Dennis,

Ci sono casi (quando si usano ints) quando sarebbe meglio tornare, sembra che nel peggiore dei casi si creerebbe un nuovo int e lo si assegni.
Bijan,

I compilatori di @Bijan C allineano sempre l'accesso diretto alla memoria alle dimensioni di un atomo della primitiva in questione - non ricordo se è nello standard, però
cat

5

Python 2, 51 byte

Prende intero come input. Provalo online

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

48 byte per stringa come input. Provalo online

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

5

C # , 63 62 byte


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

Leggibile non golfato

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

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

Uscite

  • v1.1 - - 1 byte - Grazie al commento di Kevin .
  • v1.0 -  63 bytes- Soluzione iniziale.

Gli appunti

Niente da aggiungere


+1 Puoi giocare a golf di 1 byte, però. In questo modo:i=>{int a=i.Length-1,b=a;while(a-->0&&i[a]==i[b]);return b-a;}
Kevin Cruijssen,


4

MATL , 6 5 byte

1 byte salvato grazie a @Luis

&Y'O)

Provalo su MATL Online

Spiegazione

        % 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

Avevo dimenticato che lo &faceva per Y':-D Perché non prendere l'input come una stringa racchiusa tra virgolette e sbarazzarsi di j?
Luis Mendo,

@LuisMendo Non ero sicuro di poterlo fare poiché la sfida diceva esplicitamente che l'input era un "numero intero"
Suever,

L'ho assunto dal commento di Martin e dalle regole predefinite, che lo consentono. Ma non ne sono proprio sicuro
Luis Mendo,

@LuisMendo Ah ok non ho visto il suo commento. Si aggiorna!
Suever,

4

Cubix, 24 19 byte

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

Nota

  • Conta effettivamente quanti caratteri uguali si trovano alla fine dell'input, quindi funziona per numeri molto grandi e stringhe molto lunghe (purché la quantità degli stessi caratteri alla fine sia inferiore alla massima precisione di JavaScript ( circa 15 cifre in base-10).
  • L'input va nel campo di input, l'output viene stampato nel campo di output

Provalo qui

Spiegazione

Innanzitutto, espandiamo il cubo

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

I passaggi nell'esecuzione possono essere suddivisi in tre fasi:

  1. Input di analisi
  2. Confronta i personaggi
  3. Stampa il risultato

Fase 1: input

I primi due caratteri che vengono eseguiti sono Ae B. Alegge tutti gli input e li inserisce come codici carattere nello stack. Nota che questo è fatto al contrario, il primo personaggio finisce in cima alla pila, l'ultimo personaggio quasi in fondo. In fondo, viene posizionato -1( EOF), che verrà utilizzato come contatore per la quantità di caratteri consecutivi alla fine della stringa. Poiché abbiamo bisogno che la parte superiore dello stack contenga gli ultimi due caratteri, invertiamo lo stack prima di entrare nel loop. Si noti che la parte superiore dello stack ora appare come segue: ..., C[n-1], C[n], -1.

La posizione dell'IP sul cubo è dove si Etrova e sta puntando a destra. Tutte le istruzioni che non sono state ancora eseguite, sono state sostituite da no-op (stop completi).

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

Fase 2: confronto dei personaggi

Lo stack è ..., C[a-1], C[a], counter, dove si countertrova il contatore da incrementare quando i due caratteri da controllare ( C[a]e C[a-1]) sono uguali. L'IP entra per primo in questo loop sul Spersonaggio, spostandosi a destra. Il Ecarattere è la posizione in cui il PI finirà (punta destra) quando C[a]e C[a-1]non hanno lo stesso valore, il che significa che sottraendo C[a]dal C[a-1]non ancora fruttifera 0, nel qual caso l'istruzione che segue l' !verranno saltati (che è una w).

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

Ecco le istruzioni che vengono eseguite durante un ciclo 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 poi gira intorno.

Fase 3: stampare il risultato

Dal momento che abbiamo lasciato il ciclo precoce, gli sguardi di stack in questo modo: counter, ..., C[a-1]-C[a]. È facile stampare il contatore, ma dobbiamo incrementare il contatore una volta perché non l'abbiamo fatto nell'ultima iterazione del ciclo e ancora una volta perché abbiamo iniziato a contare -1invece di 0. Il percorso sul cubo si presenta così, a partire da S, puntando a destra. Le due no-op eseguite dall'IP vengono sostituite da frecce che puntano nella direzione dell'IP.

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

Le istruzioni vengono eseguite nel seguente ordine. Nota che le B)istruzioni alla fine cambiano lo stack, ma non influenzano il programma, poiché stiamo per terminarlo e non utilizziamo più lo stack.

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

Il dado è tratto.


3

Lotto, 91 byte

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

Le -impedisce la prova di scappare dall'inizio della stringa.


3

JavaScript (ES6), 34 byte

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

Non più breve della soluzione regex.

Funzione ricorsiva che valuta le cifre da destra a sinistra, interrompendosi quando viene rilevata una cifra diversa. Il risultato è il numero di iterazioni. pè undefinedsulla prima iterazione, che significa n%10-pritorni NaN(falsa). Dopo di che,p uguale alla cifra precedente con n%10. Quando la cifra corrente ( n%10) e la precedente ( p) sono diverse, il ciclo termina.


3

Röda , 12 byte

{count|tail}

Provalo online!

Questa è una funzione anonima che prevede che ogni carattere della stringa di input venga inviato allo stream (penso che questo sia valido nello spirito di una recente meta domanda ).

Utilizza due builtin: counte tail:

  1. count legge i valori dallo stream e invia il numero di elementi consecutivi allo stream.
  2. tail restituisce l'ultimo valore nel flusso.

3

T-SQL, 238 214 byte

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

O:

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 byte

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

Provalo qui.

Ho provato alcune cose usando la ricorsione o un ciclo, ma entrambi sono finiti sopra i 100 byte ..


2

Powershell, 41 byte

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

ciclo semplice all'indietro fino a quando un carattere non corrisponde all'ultimo carattere nella stringa, restituisce l'indice di quel carattere -1.

-3 grazie a @AdmBorkBork - usando un ciclo for anziché un po '.


2

Mathematica, 33 30 byte

Grazie a Greg Martin per aver salvato 3 byte.

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

Accetta l'input come stringa.

Ottiene le cifre decimali (sotto forma di caratteri), le divide in sequenze di elementi identici, ottiene l'ultima corsa e calcola la lunghezza con il trucco standard di prendere la somma del vettore 1^list.


Charactersinvece di IntegerDigits?
Greg Martin,

@GregMartin Ah sì, immagino. Grazie.
Martin Ender,

Non devi ancora battere quell'altro scaltro golfista Mathematica per questa domanda;)
Greg Martin,

@GregMartin Che peccato. :)
Martin Ender,


2

JavaScript (ES6), 39 38 37 27 byte

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

Forse non più breve della soluzione basata su regex, ma non ho potuto resistere alla scrittura di una soluzione interamente basata sull'aritmetica. La tecnica è prendere n % 100 % 11e dividere ripetutamente per 10 fino a quando il risultato è diverso da zero, quindi contare le iterazioni. Questo funziona perché se le ultime due cifre sono uguali, n % 100 % 11lo sarà 0.


Ah, hai finito poco prima di me ahah! Non sono sicuro se pubblicare un'altra risposta, poiché molto probabilmente convergeranno dopo il golf, ma ecco la mia soluzione usando 34 byte:f=(n,p)=>n%10-p?0:1+f(n/10|0,n%10)
user81655

@ user81655 Fantastico, sentiti libero di pubblicarlo. Non credo che il mio converrà in quello senza un completo rifacimento, e ovviamente ora che ho visto il tuo che non accadrà ;-)
ETHproductions

2

Haskell , 33 byte

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

Provalo online!

Accetta l'input di stringa. Taglia ripetutamente il primo carattere e aggiunge 1 se tutti i caratteri nel suffisso sono uguali al primo.


2

R, 35 byte

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

Breve spiegazione

                  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 byte

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

Provalo online!

Ciò potrebbe essere ridotto se riuscissi a utilizzare solo lo stack.

Come funziona:

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 byte

Programma completo (in Python 3, input()restituisce una stringa, indipendentemente dall'input):

g=input();print(len(g)-len(g.rstrip(g[-1]))) 
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.