OBTENEZ vos dubs ensemble

24

Sur 4chan, un jeu populaire est obtenu. Chaque publication sur le site reçoit un identifiant de publication séquentiel. Comme vous ne pouvez pas les influencer ou les déterminer, les gens essaient de deviner (au moins une partie de) leur propre numéro de poste, généralement les premiers chiffres. Une autre version du jeu s'appelle les doublons, et son objectif est d'obtenir des chiffres répétitifs à la fin du numéro (par exemple 1234555).

Votre tâche, si vous souhaitez l'accepter, est d'écrire un programme qui prend un post id en entrée (entier standard, vous pouvez supposer en dessous de 2 ^ 32), et retourne combien de chiffres se répètent à la fin.

Règles

  • Les failles standard ne sont pas autorisées .
  • Le programme peut être une fonction, un programme complet, une commande REPL, tout ce qui fonctionne vraiment, tant qu'aucun code / argument non compté externe n'est nécessaire pour l'exécuter.
  • L'entrée peut provenir de STDIN, des arguments de fonction, de l'argument de ligne de commande, du fichier, selon ce qui vous convient.

Cas de 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
sagiksp
la source
1
Sommes-nous autorisés à prendre l'entrée comme chaîne?
Dead Possum
6
@DeadPossum Je suppose que c'est autorisé, car vous obtenez quand même une chaîne si vous lisez l'entrée de STDIN, l'argument de ligne de commande ou le fichier (qui sont tous des méthodes d'entrée admissibles).
Martin Ender
1
Pouvons-nous supposer que l'entrée sera supérieure à 0?
Martin Ender
1
@MartinEnder Yes
sagiksp
2
Upvote pour le jeu de dubs! Check'em!
ZombieChowder

Réponses:

19

Mathematica, 29 octets

Que diriez-vous d'une solution arithmétique?

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

Je suis très heureux de voir que cela dépasse l'approche directe de Mathematica.

Explication

Le code lui-même calcule 9 * n + n% 10 et trouve ensuite la plus grande puissance de 10 qui divise l'entrée, ou en d'autres termes, compte les zéros de fin. Nous devons montrer si n se termine par k chiffres répétés, que 9 * n + n% 10 a k zéros de fin.

Les chiffres de répétition s'expriment le plus facilement mathématiquement en divisant un nombre comme 99999 (qui est 10 5 -1 ) par 9 , puis en multipliant par le chiffre répété. Nous pouvons donc écrire n = m * 10 k + d * (10 k -1) / 9 , où m ≢ d (mod 10) , pour nous assurer que n ne se termine pas par plus de k chiffres répétés. Notez que d = n% 10 .

Insérons cela dans notre formule 9 * n + n% 10 . On obtient 9 * m * 10 k + d * (10 k -1) + d . Le d à la fin est annulé, nous nous retrouvons donc avec: 9 * m * 10 k + d * 10 k = (9 * m + d) * 10 k . Mais 9 ≡ -1 (mod 10) , donc 9 * m + d ≡ d - m (mod 10) . Mais nous avons affirmé que m ≢ d (mod 10) et donc d - m ≢ 0 (mod 10) .

En d'autres termes, nous avons montré que 9 * m + d n'est pas divisible par 10 et donc, la plus grande puissance de 10 qui divise 9 * n + n% 10 = (9 * m + d) * 10 k est k , le nombre de chiffres répétés à la fin.

En prime, cette solution imprime le résultat correct,, pour la saisie 0.

Martin Ender
la source
1
C'est dans des moments comme celui-ci que je souhaite que ce site supporte MathJax; les formules en gras ne sont pas aussi agréables que les formules. C'est bien que vous ayez pris le temps d'écrire l'exposant des exposants.
wizzwizz4
1
@ wizzwizz4 J'avais l'habitude d'utiliser la mise en forme du code, mais j'ai trouvé que le gras (qui est généralement utilisé par Dennis) est un peu plus lisible que cela. Mais d'accord, ce n'est pas aussi agréable que MathJax.
Martin Ender
13

Rétine , 9 octets

&`(.)\1*$

Essayez-le en ligne!

Compte le nombre de correspondances (.)\1*$qui se chevauchent, dont une expression régulière qui correspond à un suffixe de caractères identiques.

Martin Ender
la source
2
Ce doit être un mème: vous et votre regex
Christopher
J'ai besoin d'apprendre tous ces modificateurs - je serais juste parti (.)(?=\1*$).
Neil
1
@DownChristopher il a littéralement fait un langage basé sur les regex, cela va au-delà du matériau meme c:
Rod
1
@Neil Si c'est une consolation, ma première tentative a été (?=(.)\1*$)(donc fondamentalement la même que la vôtre).
Martin Ender
1
Oui c'est ça merci!
Neil
9

Brachylog , 4 octets

ẹḅtl

Essayez-le en ligne!

Explication

ẹ       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

Si je travaillais directement sur des entiers (et je ne sais pas pourquoi je ne l'ai pas implémenté pour qu'il le fasse), ce ne serait que de 3 octets car cela ne serait pas nécessaire.

Fatalize
la source
9

Python 2 , 47 41 octets

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

Essayez-le en ligne!

36 octets - Pour une entrée plus flexible

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

Essayez-le en ligne!

Barre
la source
Sensationnel. Je dois apprendre les buildins plus attentivement. +1
Dead Possum
2
@DeadPossum dir(object)est notre ami c:
Rod
BTW nous ne sommes pas autorisés à prendre la chaîne en entrée. "Si votre méthode d'entrée retourne automatiquement des chaînes, alors bien sûr, mais vous ne pouvez pas supposer que l'entrée sera fournie sous forme de chaînes." : C
Dead Possum
1
@DeadPossum Je pense que l'auteur a changé d'avis à ce sujet. Le commentaire semble avoir été supprimé.
Brian McCutchon
8

Javascript (ES6), 55 52 32 30 octets

a=>a.match`(.)\\1*$`[0].length
  • Enregistré 19 octets grâce à @MartinEnder en remplaçant l'expression régulière
  • 2 octets enregistrés grâce à @ user81655 en utilisant des modèles de littéraux de modèles

Utilisation d'une expression régulière pour faire correspondre le dernier groupe du dernier chiffre

Remarque: première publication. N'hésitez pas à faire des remarques.

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
la source
Bienvenue chez PPCG! Vous pouvez économiser beaucoup d'octets en utilisant une référence arrière au lieu de remplir manuellement le caractère répété:/(.)\1*$/
Martin Ender
De plus, les fonctions sans nom sont tout à fait correctes (sauf si vous avez besoin du nom pour les appels récursifs par exemple), vous pouvez donc économiser deux octets sur le f=.
Martin Ender
Bon travail! Cela passe à coup sûr l'examen, mais cela pourrait être joué
Christopher
@MartinEnder Merci! Je dois encore apprendre à
jouer
@DownChristopher Merci! J'essaierai de faire mieux la prochaine fois
Weedoze
7

C, 62 56 48 47 octets

Un octet enregistré grâce à @Steadybox!

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

Essayez-le en ligne!

betseg
la source
7

PHP, 47 45 40 octets

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

Courir avec echo <n> | php -nR '<code>

semble une boucle est encore plus petite que ma première réponse. comptez simplement les caractères égaux au dernier. Cela utilise des décalages de chaîne négatifs de PHP 7.1 .

-5 octets par Titus. Merci !


Ancienne réponse:

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

supprime de droite chaque caractère correspondant au caractère le plus à droite et calcule la différence de longueur.

Christoph
la source
-Ret $argnpourrait économiser 5 octets.
Titus
6

Gelée , 5 octets

DŒgṪL

Essayez-le en ligne!

Explication

D      # convert from integer to decimal   
 Œg    # group runs of equal elements
   Ṫ   # tail
    L  # length
Emigna
la source
6

Perl 5 , 22 octets

21 octets de code + -pindicateur.

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

Essayez-le en ligne!

/(.)\1*$/obtient les derniers nombres identiques, puis $_=length$&attribue sa longueur à $_, qui est implicitement imprimée grâce à -pflag.

Dada
la source
6

C (gcc) , 32 29 octets

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

Ceci est un port de ma réponse Python .

Ce travail avec gcc, mais le manque d'un return instruction est un comportement indéfini.

Essayez-le en ligne!

Dennis
la source
Je suis confus, comment se fait-il que vous ne passiez ni un pointeur, ni ne changiez la valeur à l'emplacement, ou que vous retourniez simplement la valeur. Il semble que cela modifie simplement la copie locale, ce qui rendrait la fonction inutilisable, mais cela fonctionne sur TIO. Vous ajoutez également 1 à n dans le pied de page, plutôt que sizeof (int), cela ne le déplacerait-il pas de 1 octet vers l'avant, plutôt que la pleine largeur d'un int? Il y a clairement quelques astuces que je pourrais apprendre ici, et je pourrais probablement utiliser le premier dans ma propre réponse.
Bijan
2
Tous les return instruction ne fait que stocker la valeur de retour dans EAX. Avec gcc, l'affecter à une variable fait la même chose. Quant à l'arithmétique du pointeur, lorsque vous ajoutez 1 à un pointeur int, il passe au prochain int, pas au prochain octet.
Dennis
Y a-t-il des cas (lorsque vous utilisez des ints) où il serait préférable de revenir, il semble que dans le pire des cas, vous fassiez un nouvel entier et l'assigniez.
Bijan
Les compilateurs @Bijan C alignent toujours l'accès direct à la mémoire à la taille d'un atome de la primitive en question - je ne me souviens pas si c'est dans la norme, cependant
cat
5

Python 2, 51 octets

Prend un entier comme entrée. Essayez-le en ligne

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

48 octets pour la chaîne en entrée. Essayez-le en ligne

lambda S:[x==S[-1]for x in S[::-1]+'~'].index(0)
Possum mort
la source
5

C # , 63 62 octets


Golfé

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

Non golfé

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

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

    return b - a;
}

Non lisible non lisible

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

Code complet

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

Communiqués

  • v1.1 -- 1 byte  - Merci au commentaire de Kevin .
  • v1.0 - 63 bytes - Solution initiale.

Remarques

Rien à ajouter

auhmaan
la source
+1 Vous pouvez cependant jouer au golf sur 1 octet. Comme ça:i=>{int a=i.Length-1,b=a;while(a-->0&&i[a]==i[b]);return b-a;}
Kevin Cruijssen
4

MATL , 6 5 octets

1 octet enregistré grâce à @Luis

&Y'O)

Essayez-le sur MATL Online

Explication

        % 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
la source
J'avais oublié que cela &faisait ça pour Y':-D Pourquoi ne pas prendre l'entrée comme une chaîne entre guillemets et s'en débarrasser j?
Luis Mendo
@LuisMendo Je ne savais pas si je pouvais le faire puisque le défi disait explicitement que l'entrée était un "entier"
Suever
Je l'ai supposé d'après le commentaire de Martin et les règles par défaut qui le permettent. Mais je ne suis pas vraiment sûr
Luis Mendo
@LuisMendo Ah ok n'a pas vu son commentaire. Mettra à jour!
Suever
4

Cubix, 24 19 octets

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

Remarque

  • Compte en fait combien de mêmes caractères se trouvent à la fin de l'entrée, donc cela fonctionne aussi pour les très grands entiers et les très longues chaînes (tant que la quantité de mêmes caractères à la fin est inférieure à la précision maximale de JavaScript ( environ 15 chiffres en base 10).
  • L'entrée va dans le champ d'entrée, la sortie est imprimée dans le champ de sortie

Essayez-le ici

Explication

Tout d'abord, développons le cube

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

Les étapes de l'exécution peuvent être divisées en trois phases:

  1. Entrée d'analyse
  2. Comparer les personnages
  3. Résultat d'impression

Phase 1: entrée

Les deux premiers caractères exécutés sont Aet B. Alit toutes les entrées et les envoie sous forme de codes de caractères à la pile. Notez que cela se fait à l'envers, le premier caractère se retrouve en haut de la pile, le dernier caractère presque en bas. Tout en bas, -1( EOF) est placé, qui sera utilisé comme compteur pour le nombre de caractères consécutifs à la fin de la chaîne. Puisque nous avons besoin que le haut de la pile contienne les deux derniers caractères, nous inversons la pile, avant d'entrer dans la boucle. Notez que la partie supérieure de la pile ressemble maintenant à:..., C[n-1], C[n], -1 .

La place de l'IP sur le cube est l'endroit où se Etrouve, et il pointe vers la droite. Toutes les instructions qui n'ont pas encore été exécutées ont été remplacées par des no-ops (arrêts complets).

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

Phase 2: Comparaison des personnages

La pile est ..., C[a-1], C[a], counter, où counterest le compteur à incrémenter lorsque les deux caractères à vérifier ( C[a]et C[a-1]) sont égaux. L'IP entre d'abord dans cette boucle au niveau du Spersonnage, se déplaçant vers la droite. Le Ecaractère est la position où l'IP finira (pointant vers la droite) quand C[a]et n'aura C[a-1]pas la même valeur, ce qui signifie que la soustraction C[a]de C[a-1]ne donnera pas 0, auquel cas l'instruction suivant le !sera sautée (qui est a w).

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

Voici les instructions qui sont exécutées pendant une boucle complète:

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)

Et puis il tourne en boucle.

Phase 3: impression du résultat

Depuis que nous avons quitté la boucle au début, la pile ressemble à ceci: counter, ..., C[a-1]-C[a]. Il est facile d'imprimer le compteur, mais nous devons l'incrémenter une fois parce que nous ne l'avons pas fait lors de la dernière itération de la boucle, et encore une fois parce que nous avons commencé à compter à la -1place de 0. Le chemin sur le cube ressemble à ceci, en commençant par S, pointant vers la droite. Les deux no-op qui sont exécutés par l'IP sont remplacés par des flèches qui pointent dans la direction de l'IP.

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

Les instructions sont exécutées dans l'ordre suivant. Notez que les B)instructions à la fin changent la pile, mais n'affectent pas le programme, car nous sommes sur le point de le terminer, et nous n'utilisons plus la pile.

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

Le sort en est jeté.

Luc
la source
3

Lot, 91 octets

@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 -empêche le test de s'exécuter au début de la chaîne.

Neil
la source
3

JavaScript (ES6), 34 octets

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

Pas plus court que la solution regex.

Fonction récursive qui évalue les chiffres de droite à gauche, s'arrêtant lorsqu'un autre chiffre est rencontré. Le résultat est le nombre d'itérations. pest undefinedsur la première itération, ce qui signifie des n%10-pretours NaN(fausse). Après cela, pest égal au chiffre précédent avec n%10. Lorsque le chiffre actuel ( n%10) et le précédent ( p) sont différents, la boucle se termine.

user81655
la source
3

Röda , 12 octets

{count|tail}

Essayez-le en ligne!

Il s'agit d'une fonction anonyme qui s'attend à ce que chaque caractère de la chaîne d'entrée soit poussé vers le flux (je pense que cela est valide dans l'esprit d' une méta-question récente ).

Il utilise deux fonctions intégrées: countet tail:

  1. count lit les valeurs du flux et pousse le nombre d'éléments consécutifs dans le flux.
  2. tail renvoie la dernière valeur du flux.
fergusq
la source
3

T-SQL, 238 214 octets

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
Nelz
la source
2

Java 7, 78 octets

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

Essayez-le ici.

J'ai essayé certaines choses en utilisant la récursivité ou une boucle, mais les deux ont fini au-dessus de 100 octets ..

Kevin Cruijssen
la source
2

Powershell, 41 octets

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

boucle directe vers l'arrière jusqu'à ce qu'un caractère ne corresponde pas au dernier caractère de la chaîne, retourne l'index de ce caractère -1.

-3 grâce à @AdmBorkBork - en utilisant une boucle for au lieu d'un certain temps.

colsw
la source
2

Mathematica, 33 30 octets

Merci à Greg Martin d'avoir économisé 3 octets.

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

Prend l'entrée sous forme de chaîne.

Obtient les chiffres décimaux (sous forme de caractères), les divise en séries d'éléments identiques, obtient la dernière série et calcule la longueur avec l'astuce standard de prendre la somme du vecteur 1^list.

Martin Ender
la source
Charactersau lieu de IntegerDigits?
Greg Martin
@GregMartin Ah ouais, je suppose. Merci.
Martin Ender
Vous ne battez toujours pas cet autre golfeur astucieux de Mathematica pour cette question;)
Greg Martin
@GregMartin Quelle honte. :)
Martin Ender
2

JavaScript (ES6), 39 38 37 27 octets

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

Peut-être pas plus court que la solution basée sur l'expression rationnelle, mais je n'ai pas pu résister à l'écriture d'une solution entièrement basée sur l'arithmétique. La technique consiste à prendre n % 100 % 11et à diviser par 10 à plusieurs reprises jusqu'à ce que le résultat ne soit pas nul, puis à compter les itérations. Cela fonctionne parce que si les deux derniers chiffres sont identiques, le n % 100 % 11sera 0.

ETHproductions
la source
Ah, tu as fini juste avant moi haha! Je ne sais pas s'il faut poster une autre réponse, car elles convergeront très probablement après le golf, mais voici ma solution en utilisant 34 octets:f=(n,p)=>n%10-p?0:1+f(n/10|0,n%10)
user81655
@ user81655 C'est super, n'hésitez pas à le poster. Je ne pense pas que le mien convergera vers cela sans une refonte complète, et bien sûr maintenant que j'ai vu le vôtre, cela ne se produira pas ;-)
ETHproductions
2

Haskell , 33 octets

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

Essayez-le en ligne!

Prend l'entrée de chaîne. Coupe à plusieurs reprises le premier caractère et ajoute 1 si tous les caractères du suffixe sont égaux au premier.

xnor
la source
2

R, 35 octets

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

Brève explication

                  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
la source
2

Befunge-98 , 19 octets

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

Essayez-le en ligne!

Cela pourrait être raccourci si je réussissais à n'utiliser que la pile.

Comment ça marche:

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                   ;
Justin
la source
2

Python 3 - 50 44 octets

Programme complet (en Python 3, input()retourne une chaîne, peu importe l'entrée):

g=input();print(len(g)-len(g.rstrip(g[-1]))) 
M. Xcoder
la source