Conteggio efficiente


35

Quando ero un bambino e volevo contare le banconote da un dollaro nei miei risparmi di una vita, contavo ad alta voce:

uno due tre quattro cinque sei sette otto nove dieci;
undici, dodici, tredici, quattordici, quindici, sedici, diciassette, diciotto, diciannove, venti;
ventuno, ventidue, ventitre, ventiquattro, venticinque ...

Alla fine mi sono stancato di pronunciare ciascuno di questi numeri a più sillabe. Pensando matematicamente, ho creato un metodo di conteggio molto più efficiente:

uno due tre quattro cinque sei sette otto nove dieci;
uno, due, tre, quattro, cinque, sei, sette, otto, nove, venti;
uno, due, tre, quattro, cinque, sei, sette, otto, nove, trenta ...

Come puoi vedere, vorrei solo pronunciare le cifre che sono cambiate rispetto al numero precedente. Ciò ha l'ulteriore vantaggio di essere considerevolmente più ripetitivo rispetto ai nomi inglesi per i numeri, e quindi richiede meno capacità di calcolo per il calcolo.

Sfida

Scrivi un programma / funzione che accetta un numero intero positivo e restituisce / restituisce il modo in cui lo conterei: cioè la cifra diversa da zero più a destra e tutti gli zero finali.

Esempi

   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

Un elenco completo di casi di test non dovrebbe essere necessario. Questo è A274206 su OEIS.

Regole

  • La tua voce deve teoricamente funzionare per tutti i numeri interi positivi, ignorando i problemi di precisione e memoria.
  • L'input e l'output devono essere decimali.
  • Puoi scegliere di prendere input e / o output come un numero, una stringa o una matrice di cifre.
  • L'input è garantito per essere un numero intero positivo. La tua voce può fare qualsiasi cosa per input non valido.

Questo è , quindi vince il codice più breve in byte.


Quindi "in decimale" include un elenco di cifre decimali, come [1,0,2,0]-> [2,0]per l'ultimo caso di test? (Non sono chiaro sulla frase "array a elemento singolo").
Jonathan Allan,

1
@JonathanAllan Per "array a elemento singolo" intendevo un array che contiene un singolo numero o stringa che rappresenta l'intero. Non pensavo che consentire matrici di cifre fosse una buona idea, ma ora sembra una limitazione arbitraria poiché le stringhe sono consentite (e le stringhe sono molto simili alle matrici in molte lingue). Quindi permetterò una serie di cifre a meno che non ci sia una buona ragione per non farlo.
ETHproductions

5
Maledizione, hai rubato il mio segreto: P
LegionMammal978,

1
Penso che quasi tutti abbiano contato così da bambini. ;) Almeno anche io. :)
Kevin Cruijssen il

7
@KevinCruijssen "da bambino"?
Martin Ender,

Risposte:


19

Python 2 , 28 byte

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

Provalo online!

Una formula ricorsiva funziona in modo molto pulito. Se l'ultima cifra è diversa da zero, emetterla. Altrimenti, rimuovere lo zero finale, calcolare l'output per quello e moltiplicarlo per 10.


11

Gelatina , 6 3 byte

-3 byte avendo I / O come un elenco decimale di cifre .

ṫTṪ

Test suite su Provalo online!

Come?

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

Se non riusciamo a prendere le liste decimali un 6 byte è:

DµṫTṪḌ

Che puoi vedere qui .

Questo fa la stessa cosa, ma converte in anticipo un numero intero in un elenco decimale e successivamente lo converte in un numero intero.


Mentre stavo scorrendo le prime risposte, mi sono detto: "Scommetto che esiste una soluzione Jelly a 3 byte ..."
DLosc,

9

C, 30 29 27 byte

Orgoglioso di questo mentre abuso di due exploit C per giocare a golf (descritto alla fine del post); Questo è specifico per C (GCC)


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

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

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

Provalo online (versione 27 byte)


Primo tentativo (30 byte): abusa del fatto che in GCC se non viene dichiarato alcun valore in ternario, verrà restituito il valore condizionale. Ecco perché il mio operatore ternario è vuoto per il valore di ritorno della verità.

Secondo tentativo (29 byte): abusa del bug di memoria in GCC dove, per quanto ho capito, se una funzione non ha valore di ritorno, quando più di due variabili sono state significativamente utilizzate nella funzione, l'ultimo valore impostato della prima variabile argomento sarà restituito.
   (Modifica: ma questo "valore impostato" deve essere impostato in alcuni modi, ad esempio l'impostazione di una variabile con =o +=funziona ma l'impostazione con %=non funziona; strano)

Terzo tentativo (27 byte): poiché devo comunque utilizzare in modo significativo la seconda variabile (b) per abusare correttamente del bug di memoria di cui sopra, posso anche usarlo come variabile effettiva per "10" per la sostituzione.
   (Nota: dovrei essere in grado di scambiare a=a%bcon a%=bper salvare un altro byte ma sfortunatamente questo fa sì che l'exploit dei bug di memoria sopra smetta di "funzionare", quindi non posso)


Potresti voler aggiungere "GCC" al titolo della tua risposta poiché è specifico di GCC (non funziona su clang). Inoltre, il "bug di memoria" è probabilmente solo un comportamento indefinito che sembra funzionare a causa del layout dello stack frame specifico che GCC utilizza. Probabilmente non funziona su altre piattaforme, nemmeno con GCC.
simon,

@gurka Fatto, grazie
Albert Renshaw,

7

Retina , 7 6 byte

!`.0*$

Provalo online (tutti i casi di test)

Corrispondenze di output di una cifra seguite da eventuali zeri alla fine della stringa di input. Anche se non richiesto, anche questo funziona 0.


Huh, avevo pensato [1-9](o [^0]) sarebbe stato necessario invece di \d. Immagino che l'avidità di *garantisce sempre l'output corretto.
ETHproductions

@ETHproductions Questo non ha nulla a che fare con l'avidità di *ma con il fatto che le partite vengono cercate da sinistra a destra. \d0*?$funzionerebbe anche.
Martin Ender,

usando il regex .0*$dovrebbe funzionare
12Me21

Se c'è un modo (abbastanza breve) per produrre solo l'ultima partita, potresti usare.0*
12Me21

@ 12Me21 L'unico modo per farlo è abbinare solo l'ultima occorrenza o usare un sostituto o qualcosa del genere. Non sarà più breve.
mbomb007,

7

Cubix , 18 32 byte

Penso che dovrò spendere qualche tempo su questo in seguito e vedere se riesco a comprimerlo un po '. Ma per il momento eccolo qui.
Si scopre che stavo pensando a questo totalmente nel modo sbagliato. Ora il processo applica in modo incrementale una mod (1,10,100,1000, ...) all'intero di input e stampa il primo che non è zero. Un po 'più noioso, ma più breve.

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

Provalo qui

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

Sempre bello vedere una risposta Cubix :)
Oliver,

@obarakon Ne ho subito uno migliorato da mettere in piedi presto. L'ho fatto davvero nel modo sbagliato
MickyT il

5

JavaScript, 21 byte

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

Casi test


5

Javascript 19 18 byte

Grazie a ETHproductions per giocare a golf a un byte e Patrick Roberts per giocare a golf a due byte

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

Restituisce una matrice di stringhe che corrispondono alla regex di essere alla fine della stringa di input con qualsiasi carattere seguito dal maggior numero possibile di zero.

Provalo online


5
Non credo che ti serva g, visto che c'è sempre una sola corrispondenza da trovare.
ETHproductions

Salvare 2 byte utilizzandox=>x.match`.0*$`
Patrick Roberts il


3

Grime , 5 byte

d\0*e

Provalo online!

Spiegazione

       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 byte

a₁

Provalo online!

Il suffisso incorporato a₁, per numeri interi, è implementato come:

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]).

A Brachylog piace essere in grado di trattare numeri interi come elenchi di cifre, e per questo utilizza il predicato dell'utilità personalizzata integer_value/2. La cosa interessante integer_value/2qui è che, poiché deve essere in grado di tradurre correttamente un elenco di cifre con zeri iniziali, finisce anche per essere in grado di tradurre un numero intero in un elenco di cifre con zeri iniziali, quindi i predicati che non vogliono che succede (la maggior parte di loro, specialmente quelli non simili come a) vietano alle teste delle loro liste di cifre di essere 0. Quindi, mentre a₁genera prima i suffissi più brevi per liste e stringhe, salta su qualsiasi suffisso di un numero intero con uno 0 iniziale, che in Oltre a rimuovere i duplicati, significa anche che il primo suffisso generato è la cifra non zero più a destra con tutti gli zero finali.


2

Brain-Flak , 74 byte

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

Provalo online!

Stampa solo l'ultimo non-0 e tutti gli 0 finali.

Spiegazione:

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

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

2

R, 33 byte

Implementato come una funzione senza nome

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

Questo applica una mod da 10 ^ 0 a 10 ^ 99. rleviene utilizzato per ridurre i risultati in modo che il secondo elemento sia sempre il risultato desiderato.
Provalo online!


2

Zsh , 18 16 byte

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

Provalo online! Provalo online!

Bash , 25 byte

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

Provalo online!


Le shell devono chiamare programmi esterni per usare regex, quindi dobbiamo accontentarci del globbing.

L' ${1%[^0]*}espansione corrisponde al suffisso più breve che inizia con un carattere diverso da zero e lo rimuove.

  • In Zsh, l'aggiunta del (M)flag fa sì che il suffisso corrispondente venga mantenuto anziché rimosso.
  • In Bash, l' ${1% }espansione rimuove come prefisso tutto ciò che rimane.

1

GNU sed , 17 14 + 1 (flag r) = 15 byte

Modifica: 2 byte in meno grazie a Riley

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

Funziona eliminando tutto fino alla cifra non zero più a destra, che viene quindi stampata insieme a eventuali zeri finali esistenti. Lo script può gestire più test in un'unica esecuzione, ciascuno su una riga separata.

Provalo online! (tutti gli esempi di test)


1

Mathematica, 26 byte

Funzione pura che prende un elenco di cifre e visualizza un elenco di cifre:

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

Spiegazione

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

Funziona poiché trova la corrispondenza più a sinistra per x, che deve essere l'elemento non zero più a destra dell'elenco poiché è seguito da una sequenza di zero di più se 0quindi dalla fine dell'elenco.


1

Java 8, 47 byte

questa è un'espressione lambda assegnabile a IntUnaryOperator:

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

spiegazione: moltiplicare m per 10 fino a quando x%mnon è 0. return x%m*m/10richiede la divisione perché m è un ordine di grandezza maggiore del risultato desiderato.


1

Perl 6 , 10 byte

{+m/.0*$/}

Soluzione regex triviale. Input e output di un numero.


1

MATL , 10 7 byte

3 byte salvati grazie a @B. Mehta!

tfX>Jh)

L'input e l'output sono una matrice di cifre.

Provalo online!

Oppure verifica tutti i casi di test .

Spiegazione

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

Dal momento che ci è permesso prendere input e output come un vettore di numeri interi, puoi rimuoverlo 48-completamente, salvando 3 byte: provalo online!
B. Mehta,

1

C #, 30 28 byte

Sulla base di questa risposta JavaScript , quindi suppongo che tutti i crediti andranno a lui.

golfed

i=a=>a%10<1?10*i(a/10):a%10;
  • -2 byte rimuovendo ()circa agrazie Emigna

1
Penso che sia necessario nominare in modo esplicito la funzione iaffinché questo funzioni mentre si utilizza la ricorsione.
Emigna,

@Emigna hai ragione! Mi mancava del tutto :(
Metoniem il

Aggiornato ma non sono sicuro al 100% se è corretto in questo modo
Metoniem

1
Non conosco il consenso su questo in C #. Tale sintassi è valida, ma funzionerà solo se il delegato è già stato dichiarato (altrimenti inon sarà dichiarato per la chiamata ricorsiva).
Emigna,

1
La parentesi anon è richiesta in entrambi i modi.
Emigna,

1

J, 27 byte

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

È basato sulla formula di xnor, quindi crediti a lui.


1

Kotlin, 49 byte

lambda, assegnabile a (List<Int>) -> List<Int>

{a->a.slice(a.indexOfLast{it in 1..9}..a.size-1)}
  • nome del parametro implicito itinindexOfLast
  • .. per le gamme di edifici

1

Perl 5, 12 byte

11, più 1 per -nEanziché-e

say/(.0*$)/



1

Stax , 5 byte

æΩ$3╚

Esegui ed esegui il debug

Procedura:

  1. Calcola "molteplicità" per 10. (Questo è il numero di volte in cui 10 divide uniformemente l'input)
  2. Aggiungi 1
  3. Mantieni molti caratteri a destra di (l'input come stringa).

1

05AB1E , 4 byte

ĀÅ¡θ

I / O come elenco di cifre.

Provalo online o verifica tutti i casi di test (la suite di test contiene un join per una migliore leggibilità).

Spiegazione:

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

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