Эффективный подсчет


35

Когда я был ребенком и хотел считать долларовые банкноты в своих сбережениях, я считал вслух:

один два три четыре пять шесть семь восемь девять десять;
одиннадцать, двенадцать, тринадцать, четырнадцать, пятнадцать, шестнадцать, семнадцать, восемнадцать, девятнадцать, двадцать;
двадцать один, двадцать два, двадцать три, двадцать четыре, двадцать пять ...

В конце концов мне надоело произносить каждое из этих многосложных чисел. Будучи математически мыслящим, я создал гораздо более эффективный метод подсчета:

один два три четыре пять шесть семь восемь девять десять;
один, два, три, четыре, пять, шесть, семь, восемь, девять, двадцать;
один, два, три, четыре, пять, шесть, семь, восемь, девять, тридцать ...

Как видите, я бы произносил только те цифры, которые изменились по сравнению с предыдущим номером. Это имеет дополнительное преимущество, заключающееся в том, что оно значительно более повторяется, чем английские названия чисел, и, следовательно, требует меньше умственных способностей для вычислений.

Вызов

Напишите программу / функцию, которая принимает положительное целое число и выводит / возвращает, как я бы посчитал, то есть самую правую ненулевую цифру и все конечные нули.

Примеры

   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

Полный список тест-кейсов не обязателен. Это A274206 на OEIS.

правила

  • Ваша запись должна теоретически работать для всех натуральных чисел, игнорируя точность и проблемы с памятью.
  • Вход и выход должны быть в десятичном формате.
  • Вы можете выбрать ввод и / или вывод в виде числа, строки или массива цифр.
  • Ввод гарантированно будет положительным целым числом. Ваша запись может сделать что угодно для неверного ввода.

Это , поэтому выигрывает самый короткий код в байтах.


Так включает ли "в десятичной" список десятичных цифр, как [1,0,2,0]-> [2,0]для последнего теста? (Мне неясно фраза "массив из одного элемента").
Джонатан Аллан

1
@JonathanAllan Под «массивом из одного элемента» я подразумевал массив, который содержит одно число или строку, представляющую целое число. Я не думал, что разрешать массивы цифр было хорошей идеей, но сейчас это выглядит как произвольное ограничение, так как строки разрешены (а строки очень похожи на массивы во многих языках). Так что я позволю массив цифр, если нет веской причины не делать этого.
ETHproductions

5
Черт
возьми

1
Я думаю, что почти все считали это ребенком. ;) По крайней мере, я так и сделал. :)
Кевин Круйссен

7
@KevinCruijssen "как ребенок"?
Мартин Эндер

Ответы:


19

Python 2 , 28 байт

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

Попробуйте онлайн!

Рекурсивная формула работает очень чисто. Если последняя цифра ненулевая, выведите ее. В противном случае удалите конечный ноль, вычислите выход для этого и умножьте его на 10.


11

Желе , 6 3 байта

-3 байта при наличии ввода / вывода в виде десятичного списка цифр .

ṫTṪ

Набор тестов на Попробуй онлайн!

Как?

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

Если мы не можем взять десятичные списки, 6 байт:

DµṫTṪḌ

Который вы можете увидеть здесь .

Это делает то же самое, но предварительно преобразует целое число в десятичный список и впоследствии преобразует обратно в целое число.


Просматривая первые несколько ответов, я сказал себе: «Могу поспорить, что есть 3-байтовое решение Jelly…»
DLosc

9

C, 30 29 27 байтов

Горжусь этим, когда я использую два C-эксплойта, чтобы сыграть в гольф (описано в конце поста); Это специально для C (GCC)


3) b=10;f(a){a=a%b?:b*f(a/b);}// 27 байт

2) b;f(a){b=a=a%10?:10*f(a/10);}// 29 байт

1) f(i){return i%10?:10*f(i/10);}// 30 байт

Попробуйте онлайн (27-байтовая версия)


Первая попытка (30 байт): злоупотребляет тем фактом, что в GCC, если никакое значение не объявлено в троичной форме, будет возвращено условное значение. Следовательно, почему мой троичный оператор пуст для истинного возвращаемого значения.

Вторая попытка (29 байт): злоупотребляет ошибкой памяти в GCC, где, насколько я понимаю, если у функции нет возвращаемого значения, когда в функции было сознательно использовано более двух переменных, последнее заданное значение первой аргументной переменной будет возвращен.
   (Изменить: но это «заданное значение» должно быть установлено определенным образом, например, установка переменной с помощью =или +=работает, но установка с помощью %=не работает; странно)

Третья попытка (27 байт): поскольку я все равно должен осмысленно использовать вторую переменную (b) для правильного использования ошибки памяти, упомянутой выше, я также могу использовать ее в качестве фактической переменной для замены «10».
   (Примечание: я должен быть в состоянии свопа a=a%bс , a%=bчтобы сохранить другие байты , но , к сожалению , это приводит к тому , ошибке памяти эксплуатирует выше остановки «работает», так что я не могу)


Возможно, вы захотите добавить «GCC» в заголовок вашего ответа, поскольку он специфичен для GCC (он не работает на clang). Кроме того, «ошибка памяти», вероятно, является просто неопределенным поведением, которое срабатывает из-за определенной компоновки кадров стека, которую использует GCC. Вероятно, он не работает на других платформах, даже с GCC.
симон

@gurka Готово, спасибо
Альберт Реншоу

7

Сетчатка , 7 6 байт

!`.0*$

Попробуйте онлайн (все тестовые случаи)

Выходные совпадения цифры, за которой следуют любые нули в конце входной строки. Хотя это и не обязательно, это также работает для 0.


Да, я подумал [1-9](или [^0]) будет необходимо вместо \d. Я предполагаю, что жадность *гарантирует правильный вывод каждый раз.
ETHproductions

@ETHproductions Это не имеет ничего общего с жадностью, *но с тем фактом, что совпадения ищутся слева направо. \d0*?$также будет работать.
Мартин Эндер

использование регулярных выражений .0*$должно работать
12Me21

Если есть (достаточно короткий) способ вывода только последнего совпадения, вы можете использовать.0*
12Me21

@ 12Me21 Единственный способ сделать это - сопоставить только последнее вхождение или использовать замену или что-то в этом роде. Это не будет короче.
mbomb007

7

Cubix , 18 32 байта

Я думаю, мне придется потратить некоторое время на это позже и посмотреть, смогу ли я немного сжать его. Но на данный момент вот оно.
Оказывается, я думал об этом совершенно неправильно. Теперь процесс постепенно применяет мод (1,10,100,1000, ...) к входному целому числу и печатает первое, которое не равно нулю. Немного скучнее, но короче.

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

Попробуй здесь

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

Всегда приятно видеть ответ Cubix :)
Оливер

@obarakon Получил улучшенный, чтобы поставить в ближайшее время. Действительно сделал это неправильно
MickyT


5

Javascript 19 18 байт

Благодаря ETHproductions для игры в гольф на один байт и Патрика Робертса для игры в гольф на два байта

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

Возвращает массив строк, которые соответствуют регулярному выражению нахождения в конце входной строки с любым символом, за которым следует наибольшее возможное число нулей.

Попробуйте онлайн


5
Я не думаю, что вам нужно g, потому что есть только один матч, чтобы найти.
ETHproductions

Сохранить 2 байта с помощьюx=>x.match`.0*$`
Патрик Робертс



3

Брахилог , 2 байта

a₁

Попробуйте онлайн!

Встроенный суффикс a₁для целых чисел реализован следующим образом:

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 любит иметь возможность рассматривать целые числа как списки цифр, и для этого он использует предикат пользовательской утилиты integer_value/2. Здесь интересно то integer_value/2, что, поскольку он должен уметь правильно переводить список цифр с ведущими нулями, он также может преобразовывать целое число в список цифр с лидирующими нулями, поэтому предикаты, которые этого не хотят случается (большинство из них, особенно недетализированные, например a), запрещают заголовкам их списков цифр быть 0. Поэтому, хотя a₁генерирует суффиксы, самые короткие для списков и строк, он пропускает любой суффикс целого числа с ведущим 0, который в дополнение к удалению дубликатов также означает, что первый сгенерированный суффикс является самой правой ненулевой цифрой со всеми завершающими нулями.


2

Brain-Flak , 74 байта

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

Попробуйте онлайн!

Печатает только последние не 0 и все завершающие 0.

Объяснение:

{({}<>)<>}                    # 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 байта

Реализовано как безымянная функция

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

Это применяет мод от 10 ^ 0 до 10 ^ 99. rleиспользуется для уменьшения результатов, так что второй элемент всегда является желаемым результатом.
Попробуйте онлайн!


2

Зш , 18 16 байт

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

Попробуйте онлайн! Попробуйте онлайн!

Баш , 25 байт

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

Попробуйте онлайн!


Оболочки должны вызывать внешние программы для использования регулярных выражений, поэтому мы должны обходиться без глобализации.

${1%[^0]*}Расширение соответствует кратчайшему суффиксу , начинающемуся с ненулевым символом, и удаляет его.

  • В Zsh добавление (M)флага приводит к тому, что соответствующий суффикс сохраняется, а не удаляется.
  • В Bash ${1% }расширение удаляет в качестве префикса все, что осталось.

1

ГНУ Сед , 17 14 + 1 (флаг r) = 15 байт

Изменить: 2 байта меньше благодаря Райли

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

Он работает, удаляя все до самой правой ненулевой цифры, которая затем печатается вместе с любыми существующими конечными нулями. Сценарий может обрабатывать несколько тестов за один прогон, каждый на отдельной строке.

Попробуйте онлайн! (все тестовые примеры)


1

Mathematica, 26 байтов

Чистая функция, которая берет список цифр и выводит список цифр:

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

объяснение

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

Это работает, поскольку он находит крайнее левое совпадение для x, которое должно быть самым правым ненулевым элементом списка, поскольку за ним следует последовательность из нуля больше 0s, а затем конец списка.


1

Java 8, 47 байт

это лямбда-выражение, присваиваемое IntUnaryOperator:

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

Объяснение: умножьте m на 10, пока x%mне будет 0. return x%m*m/10Требуется деление, потому что m на порядок больше, чем желаемый результат.


1

Perl 6 , 10 байт

{+m/.0*$/}

Тривиальное регулярное выражение. Входы и выходы числа.


1

MATL , 10 7 байт

3 байта сохранены благодаря @B. Мехта!

tfX>Jh)

Ввод и вывод - это массив цифр.

Попробуйте онлайн!

Или проверьте все тестовые случаи .

объяснение

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

Поскольку нам разрешено принимать входные и выходные данные как вектор целых чисел, вы можете 48-полностью удалить 3 байта: попробуйте онлайн!
Б. Мехта

1

C #, 30 28 байт

На основе этом ответе JavaScript , я предполагаю, что все кредиты вроде бы идут к нему.

Golfed

i=a=>a%10<1?10*i(a/10):a%10;
  • -2 байта, удаляя ()вокруг aблагодаря Emigna

1
Я думаю, что вам нужно явно назвать функцию, iчтобы она работала, когда вы используете рекурсию.
Emigna

@ Emigna, ты прав! Я полностью пропустил это :(
Metoniem

Обновил, но я не уверен на 100%, правильно ли это так
Metoniem

1
Я не знаю консенсуса по этому вопросу в C #. Этот синтаксис действителен, но будет работать только в том случае, если делегат уже был объявлен (в противном случае iон не будет объявлен для рекурсивного вызова).
Emigna

1
Скобка вокруг aне требуется в любом случае, хотя.
Emigna

1

J, 27 байт

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

Это основано на формуле xnor, так что кредиты ему.


1

Котлин, 49 байт

лямбда, присваивается (List<Int>) -> List<Int>

{a->a.slice(a.indexOfLast{it in 1..9}..a.size-1)}
  • неявное имя параметра itвindexOfLast
  • .. для построения полигонов


1

05AB1E , 9 байтов

RD0Ê1k>£R

Попробуйте онлайн! или как тестовый набор

объяснение

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: это только проверка последней цифры. Это должна быть последняя ненулевая цифра и все после.
Эминья



1

05AB1E , 4 байта

ĀÅ¡θ

Ввод / вывод в виде списка цифр.

Попробуйте онлайн или проверьте все тесты (набор тестов содержит объединение для лучшей читаемости).

Объяснение:

Ā     # 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 байт

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"
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.