Efektywne liczenie


35

Kiedy byłem dzieckiem i chciałem liczyć dolary w moich oszczędnościach na życie, liczyłem głośno:

jeden dwa trzy cztery pięć sześć siedem osiem dziewięć dziesięć;
jedenaście, dwanaście, trzynaście, czternaście, piętnaście, szesnaście, siedemnaście, osiemnaście, dziewiętnaście, dwadzieścia;
dwadzieścia jeden, dwadzieścia dwa, dwadzieścia trzy, dwadzieścia cztery, dwadzieścia pięć ...

W końcu zmęczyło mnie wymawianie każdej z tych wielosylabowych liczb. Z matematycznego punktu widzenia stworzyłem znacznie bardziej wydajną metodę liczenia:

jeden dwa trzy cztery pięć sześć siedem osiem dziewięć dziesięć;
jeden, dwa, trzy, cztery, pięć, sześć, siedem, osiem, dziewięć, dwadzieścia;
jeden, dwa, trzy, cztery, pięć, sześć, siedem, osiem, dziewięć, trzydzieści ...

Jak widać, wymawiałbym tylko cyfry, które zmieniły się od poprzedniego numeru. Ma to tę dodatkową zaletę, że jest znacznie bardziej powtarzalne niż angielskie nazwy liczb, a zatem wymaga mniejszej mocy mózgowej do obliczeń.

Wyzwanie

Napisz program / funkcję, która przyjmuje dodatnią liczbę całkowitą i zwraca / zwraca tak, jak bym to policzyła: to znaczy najbardziej niezerową cyfrę po prawej stronie i wszystkie zera końcowe.

Przykłady

   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

Pełna lista przypadków testowych nie powinna być konieczna. To jest A274206 w OEIS.

Zasady

  • Wpis musi teoretycznie działać dla wszystkich liczb całkowitych dodatnich, ignorując problemy z precyzją i pamięcią.
  • Dane wejściowe i wyjściowe muszą być dziesiętne.
  • Możesz zdecydować się na wejście i / lub wyjście jako liczbę, ciąg znaków lub tablicę cyfr.
  • Dane wejściowe mają być dodatnią liczbą całkowitą. Twój wpis może zrobić wszystko dla nieprawidłowych danych wejściowych.

To jest , więc wygrywa najkrótszy kod w bajtach.


Czy więc „w systemie dziesiętnym” zawiera listę cyfr dziesiętnych, takich jak [1,0,2,0]-> [2,0]dla ostatniego przypadku testowego? (Nie jestem pewien, co do frazy „tablica jednopunktowa”).
Jonathan Allan

1
@JonathanAllan Przez „tablicę pojedynczego elementu” rozumiałem tablicę, która zawiera pojedynczą liczbę lub ciąg znaków reprezentujący liczbę całkowitą. Nie sądziłem, że zezwolenie na tablice cyfr jest dobrym pomysłem, ale teraz wydaje się, że jest to arbitralne ograniczenie, ponieważ łańcuchy są dozwolone (a łańcuchy są bardzo podobne do tablic w wielu językach). Pozwolę więc na szereg cyfr, chyba że istnieje dobry powód, aby tego nie robić.
ETHprodukcje

5
Cholera, ukradłeś mój sekret: P
LegionMammal978

1
Myślę, że prawie wszyscy tak uważali za dzieci. ;) Przynajmniej ja też. :)
Kevin Cruijssen

7
@KevinCruijssen „jak dziecko”?
Martin Ender

Odpowiedzi:


19

Python 2 , 28 bajtów

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

Wypróbuj online!

Recursywna formuła działa bardzo czysto. Jeśli ostatnia cyfra jest niezerowa, wyślij ją. W przeciwnym razie usuń końcowe zero, oblicz dla tego wynik i pomnóż go przez 10.


11

Galaretka , 6 3 bajtów

-3 bajty, mając I / O jako dziesiętną listę cyfr .

ṫTṪ

Pakiet testowy w Wypróbuj online!

W jaki sposób?

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

Jeśli nie możemy pobrać list dziesiętnych, 6 bajtów to:

DµṫTṪḌ

Które możesz zobaczyć tutaj .

Robi to samo, ale wcześniej konwertuje liczbę całkowitą na listę dziesiętną, a następnie konwertuje z powrotem na liczbę całkowitą.


Gdy przewijałem kilka pierwszych odpowiedzi, powiedziałem sobie: „Założę się, że istnieje 3-bajtowe rozwiązanie galaretki ...”
DLosc

9

C, 30 29 27 bajtów

Dumny z tego, ponieważ wykorzystuję dwa exploity C do gry w golfa (opisane na końcu postu); Dotyczy to w szczególności C (GCC)


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

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

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

Wypróbuj online (wersja 27-bajtowa)


Pierwsza próba (30 bajtów): narusza fakt, że w GCC, jeśli żadna wartość nie zostanie zadeklarowana w potrójnym, wartość warunkowa zostanie zwrócona. Dlatego mój trójskładnikowy operator jest pusty dla wartości zwracanej przez prawdę.

Druga próba (29 bajtów): nadużywa błędu pamięci w GCC, gdzie, o ile rozumiem, jeśli funkcja nie ma wartości zwracanej, gdy w funkcji zostały znacząco wykorzystane więcej niż dwie zmienne, ostatnia ustawiona wartość pierwszej zmiennej argumentu będzie zwrócony.
   (Edycja: ale ta „wartość zadana” musi być ustawiona w określony sposób, na przykład ustawienie zmiennej za pomocą =lub +=działa, ale ustawienie za pomocą %=nie działa; dziwne)

Trzecia próba (27 bajtów): Ponieważ muszę sensownie wykorzystać drugą zmienną (b), aby właściwie nadużyć wspomnianego wyżej błędu pamięci, równie dobrze mogę użyć jej jako rzeczywistej zmiennej dla „10” do podstawienia.
   (Uwaga: Byłbym w stanie zamiany a=a%bz a%=bzaoszczędzić kolejny bajt ale niestety to powoduje błąd pamięci wykorzystać wyżej stop „działa”, więc nie mogę)


Możesz dodać „GCC” do tytułu swojej odpowiedzi, ponieważ jest on specyficzny dla GCC (nie działa na clang). Ponadto „błąd pamięci” to prawdopodobnie po prostu niezdefiniowane zachowanie, które zdarza się działać z powodu określonego układu ramek stosu, z którego korzysta GCC. Prawdopodobnie nie działa na innych platformach, nawet z GCC.
simon

@Gurka Gotowe, dziękuję
Albert Renshaw

7

Siatkówka , 7 6 bajtów

!`.0*$

Wypróbuj online (wszystkie przypadki testowe)

Wyjściowe dopasowania cyfry, po której następuje dowolne zera na końcu łańcucha wejściowego. Chociaż nie jest to wymagane, zdarza się również, że działa 0.


Uznałem [1-9](lub [^0]), że będzie to konieczne \d. Wydaje mi się, że chciwość *zapewnia za każdym razem prawidłową wydajność.
ETHprodukcje

@ETHproductions Nie ma to nic wspólnego z chciwością, *ale z faktem, że mecze są wyszukiwane od lewej do prawej. \d0*?$też by działał.
Martin Ender

użycie wyrażenia regularnego .0*$powinno działać
12Me21

Jeśli istnieje (wystarczająco krótki) sposób na wyświetlenie tylko ostatniego dopasowania, możesz użyć.0*
12Me21

@ 12Me21 Jedynym sposobem na to jest dopasowanie tylko ostatniego wystąpienia lub użycie zamiennika lub czegoś innego. Nie będzie krótszy.
mbomb007

7

Cubix , 18 32 bajtów

Myślę, że będę musiał poświęcić trochę czasu na później i sprawdzić, czy mogę to trochę skompresować. Ale w tej chwili jest.
Okazuje się, że myślałem o tym całkowicie niewłaściwie. Teraz proces przyrostowo stosuje mod (1,10,100,1000, ...) do wejściowej liczby całkowitej i wypisuje pierwszy, który nie jest zerowy. Trochę nudniej, ale krócej.

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

Wypróbuj tutaj

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

Zawsze miło jest zobaczyć odpowiedź Cubix :)
Oliver

@obarakon Dostałem ulepszony, aby wkrótce go zainstalować. Naprawdę zrobiłem to w niewłaściwy sposób
MickyT

5

JavaScript, 21 bajtów

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

Przypadki testowe


5

Javascript 19 18 bajtów

Dzięki produktom ETH za grę w golfa o jeden bajt i Patricka Robertsa za grę w golfa w dwa bajty

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

Zwraca tablicę ciągów pasujących do wyrażenia regularnego znajdującego się na końcu ciągu wejściowego z dowolnym znakiem, po którym następuje jak największa liczba zer.

Wypróbuj online


5
Nie sądzę, żebyś potrzebował g, ponieważ zawsze można znaleźć tylko jedno dopasowanie.
ETHprodukcje

Zaoszczędź 2 bajty, używającx=>x.match`.0*$`
Patrick Roberts,


3

Brud , 5 bajtów

d\0*e

Wypróbuj online!

Wyjaśnienie

       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 bajty

a₁

Wypróbuj online!

Wbudowany sufiks a₁dla liczb całkowitych jest implementowany jako:

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 lubi traktować liczby całkowite jak listy cyfr i do tego używa predykatu narzędzia niestandardowego integer_value/2. Ciekawa rzecz winteger_value/2 tutaj jest to, że ponieważ musi być w stanie poprawnie przetłumaczyć listę cyfr z zerami wiodącymi, w rezultacie może także przetłumaczyć liczbę całkowitą na listę cyfr z wiodącymi zerami, więc predykaty, które tego nie chcą zdarzają się (większość z nich, szczególnie te niedetetyczne a) zabraniają głowicom ich cyfr wartości równej 0. Tak więc, podczas gdy a₁generuje sufiksy najkrótsze jako pierwsze dla list i ciągów znaków, pomija dowolny przyrostek liczby całkowitej z wiodącym 0, który w oprócz usuwania duplikatów oznacza również, że pierwszy wygenerowany sufiks jest najdalszą z prawej cyfrą niezerową ze wszystkimi końcowymi zerami.


2

Brain-Flak , 74 bajty

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

Wypróbuj online!

Drukuje tylko ostatnie niezerowe i wszystkie końcowe zera.

Wyjaśnienie:

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

R, 33 bajty

Zaimplementowano jako funkcję bez nazwy

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

Dotyczy to modów od 10 ^ 0 do 10 ^ 99. rlesłuży do zmniejszenia wyników, dzięki czemu drugi element jest zawsze pożądanym rezultatem.
Wypróbuj online!


2

Zsh , 18 16 bajtów

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

Wypróbuj online! Wypróbuj online!

Bash , 25 bajtów

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

Wypróbuj online!


Powłoki muszą wywoływać programy zewnętrzne w celu użycia wyrażenia regularnego, więc musimy zadowolić się globowaniem.

${1%[^0]*}Ekspansja odpowiada najkrótszej przyrostek rozpoczynające się od znaku niezerową i usuwa go.

  • W Zsh dodanie (M)flagi powoduje, że dopasowany sufiks jest przechowywany zamiast usuwany.
  • W Bash ${1% }rozszerzenie usuwa jako prefiks wszystko, co pozostało.

1

GNU sed , 17 14 + 1 (flaga r) = 15 bajtów

Edycja: 2 bajty mniej dzięki Riley

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

Działa poprzez usuwanie wszystkiego, aż do najbardziej niezerowej cyfry po prawej stronie, która jest następnie drukowana wraz z wszelkimi istniejącymi zerami końcowymi. Skrypt może obsłużyć wiele testów w jednym przebiegu, każdy w osobnym wierszu.

Wypróbuj online! (wszystkie przykłady testów)


1

Mathematica, 26 bajtów

Czysta funkcja, która pobiera listę cyfr i wyświetla listę cyfr:

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

Wyjaśnienie

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

Działa to, ponieważ znajduje dopasowanie najbardziej po lewej stronie x, które musi być najbardziej niezerowym elementem listy po prawej stronie, ponieważ następuje po nim sekwencja zero więcej 0s, a następnie koniec listy.


1

Java 8, 47 bajtów

jest to wyrażenie lambda przypisane do IntUnaryOperator:

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

wyjaśnienie: pomnóż m przez 10, aż x%mnie będzie 0. return x%m*m/10wymaga podziału, ponieważ m jest o rząd wielkości większy niż pożądany wynik.


1

Perl 6 , 10 bajtów

{+m/.0*$/}

Trywialne rozwiązanie wyrażenia regularnego. Wejściowe i wyjściowe liczby.


1

MATL , 10 7 bajtów

3 bajty zapisane dzięki @B. Mehta!

tfX>Jh)

Dane wejściowe i wyjściowe są tablicą cyfr.

Wypróbuj online!

Lub sprawdź wszystkie przypadki testowe .

Wyjaśnienie

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

Ponieważ możemy przyjmować dane wejściowe i wyjściowe jako wektor liczb całkowitych, możesz 48-całkowicie usunąć , oszczędzając 3 bajty: Wypróbuj online!
B. Mehta

1

C #, 30 28 bajtów

W oparciu o tę odpowiedź JavaScript , więc przypuszczam, że wszystkie kredyty należą mu.

Grał w golfa

i=a=>a%10<1?10*i(a/10):a%10;
  • -2 bajty poprzez usunięcie ()wokół adzięki Emignie

1
Myślę, że musisz jawnie nazwać funkcję, iaby działała, gdy używasz rekurencji.
Emigna

@Emigna masz rację! Całkowicie za tym tęskniłem :(
Metoniem

Zaktualizowałem go, ale nie jestem w 100% pewien, czy jest to poprawne w ten sposób
Metoniem

1
Nie znam konsensusu w tej sprawie w języku C #. Ta składnia jest poprawna, ale zadziała tylko wtedy, gdy delegat został już zadeklarowany (w przeciwnym raziei zostanie dla wywołania rekurencyjnego).
Emigna

1
Nawias wokół anie jest jednak wymagany.
Emigna

1

J, 27 bajtów

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

Opiera się na formule Xnora, więc mu to przypisuje.


1

Kotlin, 49 bajtów

lambda, przypisywalny do (List<Int>) -> List<Int>

{a->a.slice(a.indexOfLast{it in 1..9}..a.size-1)}
  • niejawna nazwa parametru itwindexOfLast
  • .. do budowania zakresów


1

05AB1E , 9 bajtów

RD0Ê1k>£R

Wypróbuj online! lub jako pakiet testowy

Wyjaśnienie

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: To tylko sprawdzanie ostatniej cyfry. Powinna to być ostatnia niezerowa cyfra i wszystko po.
Emigna,


1

Stax , 5 bajtów

æΩ$3╚

Uruchom i debuguj

Procedura:

  1. Oblicz „krotność” przez 10. (tyle razy 10 równomiernie dzieli dane wejściowe)
  2. Dodaj 1.
  3. Zachowaj tyle znaków z prawej strony (dane wejściowe jako ciąg znaków).

1

05AB1E , 4 bajty

ĀÅ¡θ

I / O jako lista cyfr.

Wypróbuj online lub sprawdź wszystkie przypadki testowe (pakiet testowy zawiera złączenie dla lepszej czytelności).

Wyjaśnienie:

Ā     # 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 bajtów

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"
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.