Comptage efficace


35

Quand j'étais enfant et que je voulais compter les billets d'un dollar dans mes économies, j'ai compté à voix haute:

un deux trois quatre cinq six sept huit neuf dix;
onze, douze, treize, quatorze, quinze, seize, dix-sept, dix-huit, dix-neuf, vingt;
vingt et un, vingt-deux, vingt-trois, vingt-quatre, vingt-cinq ...

Finalement, j'en ai eu marre de prononcer chacun de ces nombres à plusieurs syllabes. Étant d'esprit mathématique, j'ai créé une méthode de comptage beaucoup plus efficace:

un deux trois quatre cinq six sept huit neuf dix;
un, deux, trois, quatre, cinq, six, sept, huit, neuf, vingt;
un, deux, trois, quatre, cinq, six, sept, huit, neuf, trente ...

Comme vous pouvez le constater, je ne prononcerais que le ou les chiffres qui ont changé par rapport au numéro précédent. Cela présente l’avantage supplémentaire qu’il est considérablement plus répétitif que les noms anglais des nombres, et qu’il nécessite donc moins de réflexion pour le calcul.

Défi

Ecrivez un programme / fonction qui prend un entier positif et affiche / retourne comment je le compterais: c’est-à-dire le chiffre non nul le plus à droite et tous les zéros à la fin.

Exemples

   1    1
   2    2
  10   10
  11    1
  29    9
  30   30
  99    9
 100  100
 119    9
 120   20
 200  200
 409    9
1020   20

Une liste complète des cas de test ne devrait pas être nécessaire. C'est A274206 sur OEIS.

Règles

  • Votre entrée doit théoriquement fonctionner pour tous les entiers positifs, en ignorant les problèmes de précision et de mémoire.
  • L'entrée et la sortie doivent être en décimal.
  • Vous pouvez choisir de prendre en entrée et / ou en sortie un nombre, une chaîne ou un tableau de chiffres.
  • L'entrée est garantie d'être un entier positif. Votre entrée peut faire n'importe quoi pour une entrée invalide.

C'est le , donc le code le plus court en octets gagne.


Ainsi, "en décimal" inclut-il une liste de chiffres décimaux, comme [1,0,2,0]-> [2,0]pour le dernier cas de test? (Je ne suis pas clair sur la phrase "tableau à élément unique").
Jonathan Allan

1
@JonathanAllan Par "tableau à élément unique", je voulais dire un tableau contenant un seul nombre ou une seule chaîne qui représente l'entier. Je ne pensais pas que permettre des tableaux de chiffres fût une bonne idée, mais maintenant cela ressemble à une restriction arbitraire puisque les chaînes sont autorisées (et les chaînes sont très similaires aux tableaux dans de nombreuses langues). Je vais donc autoriser un tableau de chiffres sauf s'il existe une bonne raison de ne pas le faire.
ETHproductions

5
Dang it, vous avez volé mon secret: P
LegionMammal978

1
Je pense que presque tout le monde a compté comme ça comme un gosse. ;) Au moins je l'ai fait aussi. :)
Kevin Cruijssen le

7
@KevinCruijssen "comme un enfant"?
Martin Ender

Réponses:


19

Python 2 , 28 octets

f=lambda n:n%10or 10*f(n/10)

Essayez-le en ligne!

Une formule récursive fonctionne très proprement. Si le dernier chiffre est différent de zéro, indiquez-le. Sinon, supprimez le zéro final, calculez le résultat et multipliez-le par 10.


11

Gelée , 6 3 octets

-3 octets en ayant les E / S sous forme de liste décimale de chiffres .

ṫTṪ

Suite de test sur Essayez-le en ligne!

Comment?

ṫTṪ - Main link: listOfDigits  e.g.  [1,    0,    2,    0]  or [1,      1,    9  ]
 T  - truthy indexes                 [1,          3      ]     [1,      2,    3  ]
ṫ   - tail (vectorises)              [[1,0,2,0],  [2,0]  ]     [[1,1,9],[1,9],[9]]
  Ṫ - tail pop                                    [2,0]                       [9]

Si nous ne pouvons pas prendre de listes décimales, un 6 octets est:

DµṫTṪḌ

Que vous pouvez voir ici .

Cela fait la même chose, mais convertit un entier en une liste décimale au préalable et reconvertit en un entier par la suite.


Tandis que je parcourais les premières réponses, je me suis dit: "Je parie qu'il existe une solution de gelée à 3 octets ..."
DLosc

9

C, 30 29 27 octets

Fier de cela alors que j'abuse de deux exploits de C pour jouer au golf (décrit à la fin du post); Ceci est spécifiquement pour C (GCC)


3) b=10;f(a){a=a%b?:b*f(a/b);} // 27 octets

2) b;f(a){b=a=a%10?:10*f(a/10);} // 29 octets

1) f(i){return i%10?:10*f(i/10);}// 30 octets

Essayez-le en ligne (version 27 octets)


Première tentative (30 octets): abuse du fait que, dans GCC, si aucune valeur n'est déclarée en ternaire, la valeur conditionnelle sera renvoyée. D'où la raison pour laquelle mon opérateur ternaire est vide pour la valeur de retour de vérité.

Deuxième tentative (29 octets): Abuse un bogue de mémoire dans GCC où, pour autant que je sache, si une fonction n'a pas de valeur de retour, lorsque plus de deux variables ont été utilisées de manière significative dans la fonction, la dernière valeur définie du premier argument sera retourné.
   (Édition: mais cette "valeur définie" doit être définie de certaines manières, par exemple définir une variable avec =ou +=fonctionne, mais la définir avec %=ne fonctionne pas; bizarre)

Troisième tentative (27 octets): Étant donné que je dois utiliser de manière significative la deuxième variable (b) pour abuser correctement du bogue de mémoire mentionné ci-dessus, je peux aussi bien l’utiliser comme variable réelle pour "10" à des fins de substitution.
   (Remarque: je devrais pouvoir permuter a=a%bavec a%=bpour enregistrer un autre octet, mais malheureusement, l'exploit de mémoire ci-dessus cesse de "fonctionner", je ne peux donc pas)


Vous voudrez peut-être ajouter "GCC" au titre de votre réponse car il est spécifique à GCC (cela ne fonctionne pas avec clang). En outre, le "bogue de mémoire" est probablement simplement un comportement indéfini qui se produit en raison de la disposition spécifique du cadre de pile utilisée par GCC. Cela ne fonctionne probablement pas sur d'autres plateformes, même avec GCC.
simon

@gurka DONE, merci
Albert Renshaw

7

Retina , 7 à 6 octets

!`.0*$

Essayez-le en ligne (tous les cas de test)

Les correspondances de sortie d'un chiffre suivi de zéros à la fin de la chaîne d'entrée. Bien que non requis, cela se passe aussi pour 0.


Euh, j'avais pensé [1-9](ou [^0]) serait nécessaire à la place de \d. Je suppose que la gourmandise de *assure le bon résultat à chaque fois.
ETHproductions

@ETHproductions Cela n'a rien à voir avec la gourmandise *mais avec le fait que les allumettes sont recherchées de gauche à droite. \d0*?$fonctionnerait aussi.
Martin Ender

utiliser la regex .0*$devrait marcher
12Me21

S'il y a un moyen (assez court) de ne produire que le dernier match, vous pouvez utiliser.0*
12Me21

@ 12Me21 La seule façon de faire est de ne faire correspondre que la dernière occurrence ou d'utiliser un remplacement ou quelque chose du genre. Ce ne sera pas plus court.
mbomb007

7

Cubix , 18 32 octets

Je pense que je devrai y revenir un peu plus tard et voir si je peux le compresser un peu. Mais pour le moment le voici.
Il se trouve que je pensais à cela totalement dans le mauvais sens. Maintenant, le processus applique de manière incrémentielle un mod (1,10,100,1000, ...) à l'entier en entrée et affiche le premier qui n'est pas zéro. Un peu plus ennuyeux, mais plus court.

!N%*I1^\.u;u@O\;;r

Essayez-le ici

    ! N
    % *
I 1 ^ \ . u ; u
@ O \ ; ; r . .
    . .
    . .

Toujours sympa de voir une réponse Cubix :)
Oliver

@obarakon Vous avez bientôt une version améliorée à installer. Vraiment fait celui-ci dans le mauvais sens
MickyT

5

JavaScript, 21 octets

f=n=>n%10||10*f(n/10)

Cas de test


5

Javascript 19 18 octets

Merci à ETHproductions pour le golf d'un octet et à Patrick Roberts pour le golf de deux octets

x=>x.match`.0*$`

Retourne un tableau de chaînes qui correspond à l'expression régulière à la fin de la chaîne d'entrée avec n'importe quel caractère suivi du plus grand nombre de zéros possible.

Essayez-le en ligne


5
Je ne pense pas que vous ayez besoin du g, car il n'y a jamais qu'un seul match à trouver.
ETHproductions

Économisez 2 octets en utilisantx=>x.match`.0*$`
Patrick Roberts


3

Grime , 5 octets

d\0*e

Essayez-le en ligne!

Explication

       Find the longest substring of the input matching this pattern:
d      a digit, then
 \0*   zero or more 0s, then
    e  edge of input (which is handled as an Nx1 rectangle of characters).

3

Brachylog , 2 octets

a₁

Essayez-le en ligne!

Le suffixe intégré a₁, pour les entiers, est implémenté comme suit :

brachylog_adfix('integer':1, 'integer':0, 'integer':0).
brachylog_adfix('integer':1, 'integer':I, 'integer':P) :-
    H #\= 0,
    H2 #\= 0,
    abs(P) #=< abs(I),
    integer_value('integer':Sign:[H|T], I),
    integer_value('integer':Sign:[H2|T2], P),
    brachylog_adfix('integer':1, [H|T], [H2|T2]).

Brachylog aime pouvoir traiter les nombres entiers comme des listes de chiffres et utilise pour cela le prédicat de l'utilitaire personnalisé integer_value/2. La chose intéressante à propos integer_value/2ici est que, comme il doit être capable de traduire correctement une liste de chiffres avec des zéros non significatifs, il est également possible de traduire un entier en une liste de chiffres avec des zéros non significatifs, donc les prédicats qui ne le souhaitent pas. arrive (la plupart d’entre eux, en particulier ceux qui ne sont pas ressemblants a) interdisent aux têtes de leurs listes de chiffres d’être égaux à 0. Ainsi, tout en a₁générant les suffixes les plus courts en premier pour les listes et les chaînes, il saute tout suffixe d’un entier avec un 0 en tête, Outre l’élimination des doublons, cela signifie également que le premier suffixe généré est le dernier chiffre différent de zéro, avec tous les zéros à la fin.


2

Flaque de cerveau , 74 octets

{({}<>)<>}(()){{}<>(({}<>)[((((()()()){}){}){}){}]<(())>){((<{}{}>))}{}}{}

Essayez-le en ligne!

Imprime uniquement les derniers non-0 et tous les derniers 0.

Explication:

{({}<>)<>}                    # Move everything to the other stack (reverse the input)
(())                          # Push a 1 to get started
{                             # do...
  {}<>                        #   pop the result of the equals check (or initial 1)
  (                           #   push...
    ({}<>)                    #     the top value from the other stack (also put this on the stack)
    [((((()()()){}){}){}){}]  #     minus the ASCII value of 0
    <(())>                    #     on top of a 1
  )                           #   close the push   
  {                           #   if not zero (ie. if not equal)
    ((<{}{}>))                #     replace the 1 from 3 lines back with a 0
  }{}                         #   end if and pop the extra 0
}                             # while the copied value != "0"
{}                            # pop the result of the equals check


2

TI-Basic, 18 octets

If fPart(.1Ans
Return
Ans.1
prgmA
10Ans

2

R, 33 octets

Implémenté comme une fonction non nommée

function(x)rle(x%%10^(0:99))$v[2]

Ceci s'applique à un mod de 10 ^ 0 à 10 ^ 99. rleest utilisé pour réduire les résultats afin que le deuxième élément soit toujours le résultat souhaité.
Essayez-le en ligne!


2

Zsh , 18 16 octets

<<<${(M)1%[^0]*}

Essayez-le en ligne! Essayez-le en ligne!

Bash , 25 octets

r=${1%[^0]*}
echo ${1#$r}

Essayez-le en ligne!


Les shells ont besoin d'appeler des programmes externes pour utiliser regex, nous devons donc nous débrouiller avec globbing.

L' ${1%[^0]*}extension correspond au suffixe le plus court commençant par un caractère différent de zéro et le supprime.

  • Dans Zsh, l'ajout de l' (M)indicateur permet de conserver le suffixe correspondant au lieu de le supprimer.
  • Dans Bash, l' ${1% }extension supprime comme préfixe tout ce qui reste.

1

GNU sed , 17 14 + 1 (drapeau r) = 15 octets

Edit: 2 octets de moins grâce à Riley

s:.*([^0]):\1:

Cela fonctionne en supprimant tout jusqu'au chiffre non nul le plus à droite, qui est ensuite imprimé avec tous les zéros de fin existants. Le script peut gérer plusieurs tests en une fois, chacun sur une ligne distincte.

Essayez-le en ligne! (tous les exemples de tests)


1

Mathematica, 26 octets

Fonction pure qui prend une liste de chiffres et génère une liste de chiffres:

#/.{___,x_,y:0...}:>{x,y}&

Explication

#                           First argument
 /.                           Replace
   {                              start of list followed by
    ___,                          zero or more elements followed by
        x_,                       an element (referred to later as x) followed by
           y:0...                 a sequence of zero or more 0s (referred to later as y) followed by
                 }                end of list
                  :>            with
                    {x,y}         {x,y}
                         &   End of function.

Cela fonctionne car il trouve la correspondance la plus à gauche pour x, qui doit être l'élément non nul le plus à droite de la liste car il est suivi d'une séquence de zéro de plus 0s, puis de la fin de la liste.


1

Java 8, 47 octets

c'est une expression lambda assignable à un IntUnaryOperator:

x->{int m=1;for(;x%m<1;m*=10);return x%m*m/10;}

explication: multiplier m par 10 jusqu'à ce que x%mN'est pas égal à 0. return x%m*m/10Nécessite la division, car m est un ordre de grandeur supérieur au résultat souhaité.


1

Perl 6 , 10 octets

{+m/.0*$/}

Solution de regex triviale. Entrer et sortir un nombre.


1

MATL , 10 7 octets

3 octets sauvegardés grâce à @B. Mehta!

tfX>Jh)

L'entrée et la sortie sont un tableau de chiffres.

Essayez-le en ligne!

Ou vérifier tous les cas de test .

Explication

t     % Input string implicitly. Duplicate
f     % Push indices of non-zero digits
X>    % Keep maximum, say k
Jh    % Attach 1j to give [k, 1j]. This is interpreted as an index "k:end"
)     % Index into original string. Display implcitly

Etant donné que nous sommes autorisés à prendre l’entrée et la sortie sous forme de vecteur d’entiers, vous pouvez supprimer 48-entièrement l’économie de 3 octets: essayez-le en ligne!
B. Mehta

1

C #, 30 28 octets

Basé sur cette réponse JavaScript , je suppose donc que tous les crédits lui vont un peu.

Golfé

i=a=>a%10<1?10*i(a/10):a%10;
  • -2 octets en supprimant ()environ agrâce à Emigna

1
Je pense que vous devez nommer explicitement la fonction ipour que cela fonctionne lorsque vous utilisez la récursivité.
Emigna

@ Emigna tu as raison! J'ai totalement raté ça :(
Metoniem

Mis à jour le mais je ne suis pas sûr à 100% s'il est correct de cette façon
Metoniem le

1
Je ne connais pas le consensus à ce sujet en C #. Cette syntaxe est valide, mais ne fonctionnera que si le délégué a déjà été déclaré (sinon, iil sera non déclaré pour l'appel récursif).
Emigna

1
La parenthèse autour an'est pas nécessaire dans les deux cas.
Emigna

1

J, 27 octets

10&|`(10*(p%&10))@.(0=10&|)

Il est basé sur la formule de xnor, donc créditez-le.


1

Kotlin, 49 octets

lambda, assignable à (List<Int>) -> List<Int>

{a->a.slice(a.indexOfLast{it in 1..9}..a.size-1)}
  • nom de paramètre implicite itdansindexOfLast
  • .. pour construire des gammes

1

Perl 5, 12 octets

11, plus 1 pour -nEau lieu de-e

say/(.0*$)/

1

05AB1E , 9 octets

RD0Ê1k>£R

Essayez-le en ligne! ou en tant que suite de tests

Explication

R          # reverse input
 D         # duplicate
  0Ê       # check each for inequality with 0
    1k     # get the index of the first 1
      >    # increment
       £   # take that many digits from the input
        R  # reverse



@MagicOctopusUrn: Il ne s'agit que de vérifier le dernier chiffre. Ce devrait être le dernier chiffre différent de zéro et tout après.
Emigna


1

Stax , 5 octets

æΩ$3╚

Exécuter et déboguer

Procédure:

  1. Calculez la "multiplicité" par 10. (C'est le nombre de fois que 10 divise également l'entrée)
  2. Ajouter 1.
  3. Conservez autant de caractères à droite de (l'entrée sous forme de chaîne).

1

05AB1E , 4 octets

ĀÅ¡θ

I / O sous forme de liste de chiffres.

Essayez-le en ligne ou vérifiez tous les cas de test (la suite de tests contient une jointure pour une meilleure lisibilité).

Explication:

Ā     # Python-style truthify each digit in the (implicit) input-list (0 if 0; 1 if [1-9])
      #  i.e. [9,0,4,0,3,0,0] → [1,0,1,0,1,0,0]
 Å¡   # Split the (implicit) input-list on truthy values (1s)
      #  i.e. [9,0,4,0,3,0,0] and [1,0,1,0,1,0,0] → [[],[9,0],[4,0],[3,0,0]]
   θ  # And only leave the last inner list
      #  i.e. [[],[9,0],[4,0],[3,0,0]] → [3,0,0]
      # (after which it is output implicitly as result)


0

Haskell 57 octets

f(x:s)a|x=='0'=f s$'0':a|1>0=x:a
t x=f(reverse.show$x)[]

Input    -> Output
t 120    -> "20"
t 30200  -> "200"
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.