Effizientes Zählen


35

Als ich ein Kind war und die Dollarnoten zu meinen Ersparnissen zählen wollte, zählte ich laut:

eins zwei drei vier fünf sechs sieben acht neun zehn;
elf, zwölf, dreizehn, vierzehn, fünfzehn, sechzehn, siebzehn, achtzehn, neunzehn, zwanzig;
einundzwanzig, zweiundzwanzig, dreiundzwanzig, vierundzwanzig, fünfundzwanzig ...

Schließlich hatte ich es satt, jede dieser mehrsilbigen Zahlen auszusprechen. Aus mathematischen Gründen habe ich eine wesentlich effizientere Methode zum Zählen entwickelt:

eins zwei drei vier fünf sechs sieben acht neun zehn;
eins, zwei, drei, vier, fünf, sechs, sieben, acht, neun, zwanzig;
eins, zwei, drei, vier, fünf, sechs, sieben, acht, neun, dreißig ...

Wie Sie sehen, würde ich nur die Ziffern aussprechen, die sich von der vorherigen Nummer geändert haben. Dies hat den zusätzlichen Vorteil, dass es sich bei Zahlen wesentlich häufiger als die englischen Namen wiederholt und daher weniger Brainpower für die Berechnung benötigt.

Herausforderung

Schreiben Sie ein Programm / eine Funktion, die eine positive Ganzzahl aufnimmt und ausgibt / zurückgibt, wie ich es zählen würde: das ist die am weitesten rechts stehende Ziffer ungleich Null und alle nachfolgenden Nullen.

Beispiele

   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

Eine vollständige Liste der Testfälle sollte nicht erforderlich sein. Dies ist A274206 auf OEIS.

Regeln

  • Ihre Eingabe muss theoretisch für alle positiven Ganzzahlen funktionieren, wobei Genauigkeits- und Speicherprobleme ignoriert werden.
  • Ein- und Ausgabe müssen dezimal sein.
  • Sie können festlegen, ob die Eingabe und / oder Ausgabe als Zahl, Zeichenfolge oder Ziffernfolge erfolgen soll.
  • Die Eingabe ist garantiert eine positive Ganzzahl. Ihre Eingabe kann alles für ungültige Eingaben tun.

Das ist , also gewinnt der kürzeste Code in Bytes.


Enthält "in Dezimal" also eine Liste von Dezimalstellen, wie [1,0,2,0]-> [2,0]für den letzten Testfall? (Ich bin nicht sicher, was den Ausdruck "Einzelelement-Array" angeht).
Jonathan Allan

1
@JonathanAllan Mit "Einzelelement-Array" meine ich ein Array, das eine einzelne Zahl oder Zeichenfolge enthält, die die Ganzzahl darstellt. Ich hielt es nicht für eine gute Idee, Arrays von Ziffern zuzulassen, aber jetzt scheint es eine willkürliche Einschränkung zu sein, da Zeichenfolgen zulässig sind (und Zeichenfolgen Arrays in vielen Sprachen sehr ähnlich sind). Ich erlaube also eine Reihe von Ziffern, es sei denn, es gibt einen guten Grund, dies nicht zu tun.
ETHproductions


1
Ich denke, fast jeder hat als Kind so gezählt. ;) Zumindest habe ich das auch getan. :)
Kevin Cruijssen

7
@ KevinCruijssen "als Kind"?
Martin Ender

Antworten:


19

Python 2 , 28 Bytes

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

Probieren Sie es online!

Eine rekursive Formel funktioniert sehr sauber. Wenn die letzte Ziffer ungleich Null ist, geben Sie sie aus. Entfernen Sie andernfalls die letzte Null, berechnen Sie die Ausgabe dafür und multiplizieren Sie sie mit 10.


11

Gelee , 6 3 Bytes

-3 Bytes durch Eingabe / Ausgabe als dezimale Ziffernliste .

ṫTṪ

Testsuite bei Online testen !

Wie?

ṫ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]

Wenn wir keine Dezimallisten erstellen könnten, wäre ein 6-Byte-Wert:

DµṫTṪḌ

Was Sie hier sehen können .

Dies macht dasselbe, konvertiert aber vorher eine Ganzzahl in eine Dezimalliste und anschließend zurück in eine Ganzzahl.


Als ich an den ersten Antworten
vorbeirollte

9

C 30 29 27 Bytes

Darauf bin ich stolz, da ich zwei C-Exploits missbrauche, um dies zu verbessern (beschrieben am Ende des Beitrags). Dies ist speziell für C (GCC)


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

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

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

Probieren Sie es online aus (27-Byte-Version)


Erster Versuch (30 Byte): Nutzt die Tatsache, dass in GCC der bedingte Wert zurückgegeben wird, wenn in ternary kein Wert deklariert wird. Daher ist mein ternärer Operator für den Wahrheitswert leer.

Zweiter Versuch (29 Bytes): Missbraucht einen Speicherfehler in GCC, wenn meines Wissens nach eine Funktion keinen Rückgabewert hat, wenn mehr als zwei Variablen in der Funktion sinnvoll verwendet wurden, den zuletzt eingestellten Wert der ersten Argumentvariablen Wird zurückgegeben.
   (Edit: aber dieser "Set-Wert" muss auf bestimmte Arten gesetzt werden, zum Beispiel das Setzen einer Variablen mit =oder +=funktioniert, aber das Setzen mit %=funktioniert nicht; komisch)

Dritter Versuch (27 Byte): Da ich die zweite Variable (b) auf jeden Fall sinnvoll nutzen muss, um den oben genannten Speicherfehler ordnungsgemäß zu missbrauchen, kann ich sie auch als tatsächliche Variable für "10" zum Ersetzen verwenden.
   (Hinweis: Ich sollte in der Lage sein, a=a%bmit zu tauschen a%=b, um ein weiteres Byte zu speichern. Leider führt dies dazu, dass der oben genannte Speicherfehler nicht mehr funktioniert, sodass ich nicht mehr kann.)


Möglicherweise möchten Sie dem Titel Ihrer Antwort "GCC" hinzufügen, da es GCC-spezifisch ist (es funktioniert nicht bei Klängen). Außerdem ist der "Speicherfehler" wahrscheinlich nur ein undefiniertes Verhalten, das aufgrund des von GCC verwendeten speziellen Stack-Frame-Layouts auftritt. Auf anderen Plattformen funktioniert es wahrscheinlich nicht, auch nicht mit GCC.
Simon

@ Gurka Fertig, danke
Albert Renshaw

7

Retina , 7 6 Bytes

!`.0*$

Online testen (alle Testfälle)

Geben Sie Übereinstimmungen einer Ziffer gefolgt von Nullen am Ende der Eingabezeichenfolge aus. Dies ist zwar nicht erforderlich, funktioniert aber auch für 0.


Huh, ich hatte gedacht [1-9](oder [^0]) wäre nötig statt \d. Ich denke, die Gier von *sorgt jedes Mal für die richtige Ausgabe.
ETHproductions

@ETHproductions Das hat nichts mit der Gier von zu tun, *sondern damit, dass Übereinstimmungen von links nach rechts gesucht werden. \d0*?$würde auch funktionieren.
Martin Ender

mit der Regex .0*$sollte funktionieren
12Me21

Wenn es eine (ausreichend kurze) Möglichkeit gibt, nur das letzte Match auszugeben, können Sie.0*
12Me21

@ 12Me21 Die einzige Möglichkeit, dies zu tun, besteht darin, nur das letzte Vorkommen abzugleichen oder einen Ersatz oder etwas zu verwenden. Es wird nicht kürzer sein.
mbomb007

7

Cubix , 18 32 Bytes

Ich denke, ich muss später etwas Zeit dafür aufwenden und sehen, ob ich es ein bisschen komprimieren kann. Aber für den Moment ist es hier.
Es stellte sich heraus, dass ich völlig falsch darüber nachdachte. Jetzt wendet der Prozess inkrementell einen Mod (1,10,100,1000, ...) auf die eingegebene Ganzzahl an und gibt die erste aus, die nicht Null ist. Etwas langweiliger, aber kürzer.

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

Probieren Sie es hier aus

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

Immer schön, eine Cubix-Antwort zu sehen :)
Oliver

@obarakon Habe ein verbessertes, das bald fertig werden soll. Wirklich falsch gemacht
MickyT

5

JavaScript, 21 Bytes

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

Testfälle


5

Javascript 19 18 Bytes

Dank an ETHproductions für das Golfen ab einem Byte und Patrick Roberts für das Golfen ab zwei Byte

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

Gibt ein Array von Zeichenfolgen zurück, die dem regulären Ausdruck am Ende der Eingabezeichenfolge mit einem beliebigen Zeichen gefolgt von der größtmöglichen Anzahl von Nullen entsprechen.

Probieren Sie es online


5
Ich glaube nicht, dass Sie das brauchen g, da es immer nur einen Treffer gibt.
ETHproductions

Sparen Sie 2 Bytes mitx=>x.match`.0*$`
Patrick Roberts


3

Schmutz , 5 Bytes

d\0*e

Probieren Sie es online!

Erläuterung

       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 Bytes

a₁

Probieren Sie es online!

Das a₁für Ganzzahlen eingebaute Suffix wird wie folgt implementiert:

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 ist gern in der Lage, Ganzzahlen als Ziffernlisten zu behandeln, und verwendet dafür das benutzerdefinierte Dienstprogramm-Prädikat integer_value/2. Das Interessante daran integer_value/2ist, dass es in der Lage sein muss, eine Ziffernliste mit führenden Nullen korrekt zu übersetzen, und dass es am Ende auch in der Lage ist, eine Ganzzahl in eine Ziffernliste mit führenden Nullen zu übersetzen, also Prädikate, die das nicht wollen Zufall (die meisten von ihnen, insbesondere die nicht-endlichen wie a) verbieten, dass die Köpfe ihrer Ziffernlisten 0 sind. Während also a₁die kürzesten Suffixe für Listen und Strings erstellt werden, überspringt es jedes Suffix einer Ganzzahl mit einer führenden 0, die in Neben dem Entfernen von Duplikaten bedeutet dies auch, dass das erste generierte Suffix die ganz rechts stehende Ziffer ungleich Null mit allen nachfolgenden Nullen ist.


2

Brain-Flak , 74 Bytes

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

Probieren Sie es online!

Druckt nur die letzten Nullen und alle nachfolgenden Nullen.

Erläuterung:

{({}<>)<>}                    # 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 Bytes

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

2

R, 33 Bytes

Als unbenannte Funktion implementiert

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

Dies gilt für einen Mod von 10 ^ 0 bis 10 ^ 99. rlewird verwendet, um die Ergebnisse so zu reduzieren, dass das zweite Element immer das gewünschte Ergebnis ist.
Probieren Sie es online!


2

Zsh , 18 16 Bytes

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

Probieren Sie es online! Probieren Sie es online!

Bash , 25 Bytes

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

Probieren Sie es online!


Shells müssen externe Programme aufrufen, um Regex verwenden zu können, also müssen wir uns mit Globbing begnügen.

Die ${1%[^0]*}Erweiterung stimmt mit dem kürzesten Suffix überein, das mit einem Zeichen ungleich Null beginnt, und entfernt es.

  • In Zsh wird beim Hinzufügen des (M)Flags das übereinstimmende Suffix beibehalten und nicht entfernt.
  • In Bash wird die ${1% }verbleibende Erweiterung als Präfix entfernt.

1

GNU sed , 17 14 + 1 (r Flag) = 15 Bytes

Edit: 2 Bytes weniger dank Riley

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

Es löscht alles bis zur am weitesten rechts stehenden Ziffer ungleich Null, die dann zusammen mit eventuell vorhandenen nachgestellten Nullen gedruckt wird. Das Skript kann mehrere Tests in einem Durchgang ausführen, die sich jeweils in einer separaten Zeile befinden.

Probieren Sie es online! (alle Testbeispiele)


1

Mathematica, 26 Bytes

Reine Funktion, die eine Ziffernliste aufnimmt und eine Ziffernliste ausgibt:

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

Erläuterung

#                           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.

Dies funktioniert, da es die am weitesten links liegende Übereinstimmung für findet x, die das am weitesten rechts liegende Nicht-Null-Element der Liste sein muss, da auf sie eine Folge von Nullen von mehr 0s und dann das Ende der Liste folgt .


1

Java 8, 47 Bytes

Dies ist ein Lambda-Ausdruck, der zugewiesen werden kann IntUnaryOperator:

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

Erklärung: Multiplizieren Sie m mit 10, bis x%mnicht 0 return x%m*m/10ist. Dies erfordert die Division, da m eine Größenordnung größer ist als das gewünschte Ergebnis.


1

Perl 6 , 10 Bytes

{+m/.0*$/}

Triviale Regex-Lösung. Eingabe und Ausgabe einer Nummer.


1

MATL , 10 7 Bytes

3 Bytes gespart dank @B. Mehta!

tfX>Jh)

Ein- und Ausgabe sind ein Array von Ziffern.

Probieren Sie es online!

Oder überprüfen Sie alle Testfälle .

Erläuterung

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

Da wir die Ein- und Ausgabe als Vektor von ganzen Zahlen verwenden dürfen, können Sie die 48-gesamten 3 Bytes sparen: Probieren Sie es online aus!
B. Mehta

1

C #, 30 28 Bytes

Basierend auf dieser JavaScript-Antwort , gehen wohl alle Credits an ihn.

Golf gespielt

i=a=>a%10<1?10*i(a/10):a%10;
  • -2 Bytes durch Entfernen ()um adank Emigna

1
Ich denke, Sie müssen die Funktion explizit benennen, idamit dies funktioniert, wenn Sie die Rekursion verwenden.
Emigna

@Emigna du hast recht! Ich habe das total verpasst :(
Metoniem

Aktualisiert es, aber ich bin nicht 100% sicher, ob es so richtig ist
Metoniem

1
Ich kenne den Konsens in C # nicht. Diese Syntax ist gültig, funktioniert jedoch nur, wenn der Delegat bereits deklariert wurde (andernfalls iwird sie für den rekursiven Aufruf nicht deklariert).
Emigna

1
Die Klammer aist in beiden Fällen nicht erforderlich.
Emigna

1

J, 27 Bytes

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

Es basiert auf der Formel von xnor.


1

Kotlin, 49 Bytes

Lambda, zuweisbar auf (List<Int>) -> List<Int>

{a->a.slice(a.indexOfLast{it in 1..9}..a.size-1)}
  • impliziter Parametername itinindexOfLast
  • .. zum Bauen von Bereichen

1

Perl 5, 12 Bytes

11 plus 1 für -nEstatt-e

say/(.0*$)/

1

05AB1E , 9 Bytes

RD0Ê1k>£R

Probieren Sie es online! oder als Testsuite

Erläuterung

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: Das überprüft nur die letzte Ziffer. Es sollte die letzte Ziffer ungleich Null sein und alles danach.
Emigna



1

05AB1E , 4 Bytes

ĀÅ¡θ

I / O als Ziffernliste.

Probieren Sie es online aus oder überprüfen Sie alle Testfälle (die Testsuite enthält einen Join zur besseren Lesbarkeit).

Erläuterung:

Ā     # 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 Bytes

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"
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.