Не дай мне пять!


38

Вопрос:

Вам дадут начальные и конечные целые числа последовательности, и вы должны вернуть количество целых чисел в ней, которые не содержат цифры 5. Начальные и конечные числа должны быть включены!

Примеры:

1,9 → 1,2,3,4,6,7,8,9 → Результат 8

4,17 → 4,6,7,8,9,10,11,12,13,14,16,17 → Результат 12

50,60 → 60 → Результат 1

-59, -50 → → Результат 0

Результат может содержать пять.

Начальный номер всегда будет меньше конечного. Оба числа могут быть также отрицательными!

Мне очень интересно ваше решение и то, как вы его решаете. Возможно, кто-то из вас найдет простое решение по чистой математике.

Редактировать Это задача игры в гольф, поэтому выигрывает самый короткий код.


3
@betseq: Это близко; но этот имеет переменный диапазон (и не требует по модулю).
Титус

4
Я бы порекомендовал кратчайший код в качестве критерия выигрыша и тег code-golf (я даже не заметил, что это не так!). Кроме того, вам, вероятно, следует поставить контрольный пример, который охватывает 50 или 500; также может быть тот, который охватывает -50, и тот, который охватывает 0, было бы хорошей идеей.
Джонатан Аллан

1
@JonathanAllan: я буду обновлять примеры.
Арасувель

4
Тестовый пример: 50, 59 -> 0.
Згарб

14
Вы говорите: «Начальный номер всегда будет меньше конечного номера». но один из ваших примеров (-50, -59) прямо противоречит этому
theonlygusti

Ответы:


21

JavaScript (ES6), 36 33 байта

Принимает ввод с синтаксисом карри (a)(b).

a=>F=b=>b<a?0:!/5/.test(b)+F(b-1)

Отформатировано и прокомментировано

a =>                 // outer function: takes 'a' as argument, returns F
  F = b =>           // inner function F: takes 'b' as argument, returns the final result
    b < a ?          // if b is less than a
      0              //   return 0
    :                // else
      !/5/.test(b) + //   add 1 if the decimal representation of b does not contain any '5'
      F(b - 1)       //   and do a recursive call to F with b - 1

Контрольные примеры


(Я обычно предпочитаю testболее , execкогда вам нужно только логическое значение.)
Neil

@Neil Это действительно имеет больше смысла. Обновлено.
Arnauld

NB: Я не смог найти ни одного совета о синтаксисе карри ES6, поэтому я написал один .
Arnauld

5
@TheLethalCoder b<aпредназначен для остановки рекурсии после подсчета всех чисел от bдо a, поэтому ее удаление вызовет бесконечную рекурсию.
ETHproductions

1
@HristiyanDodov Безымянная внешняя функция принимает в aкачестве аргумента и возвращает Fфункцию, которая в свою очередь принимает в bкачестве аргумента и - как вы заметили - вызывается рекурсивно для итерации от bдо a, увеличивая счетчик для всех целых чисел, которые не содержат 5в своей десятичной дроби представление.
Arnauld

17

Желе , 8 7 байт

-1 байт благодаря Деннису (используйте тот факт, что индексирование по числу обрабатывает это число как десятичный список)

rAw€5¬S

TryItOnline!

Как?

rAw€5¬S - Main link: from, to    e.g. -51, -44
r       - range(from, to)        e.g. [-51,-50,-49,-48,-47,-46,-45,-44]
 A      - absolute value         e.g. [51,50,49,48,47,46,45,44]
  w€    - first index of... for €ach (0 if not present)
    5   - five                   e.g. [1,1,0,0,0,0,2,0]
     ¬  - logical not            e.g. [0,0,1,1,1,1,0,1]
      S - sum                    e.g. 5

* Абсолютное значение атома Aнеобходимо, так как отрицательное число, приведенное к десятичному списку, имеет отрицательные записи, ни одна из которых никогда не будет 5(данный пример будет считать все восемь, а не два).


rAw€5¬Sсохраняет байт.
Деннис

@ Денис спасибо! Является ли мое описание «трактует это число как десятичный список» точно?
Джонатан Аллан

2
Довольно много. wпреобразует целочисленный аргумент в десятичные цифры
Деннис


13

2sable , 6 5 байт

Сохранил байт благодаря Аднану

Ÿ5¢_O

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

объяснение

 Ÿ      # inclusive range
  5¢    # count 5's in each element of the range
    _   # negate
     O  # sum

Примечание. Это работает из-за ошибки в ¢применении функции к каждому элементу вместо подсчета соответствующих элементов в списке.


Вы можете удалить `как он ведет себя так же на массивах: p.
Аднан

@Adnan: Спасибо! Я собирался проверить это, но забыл;)
Emigna

9

Python2, 59 55 52 51 47 43 42 байта

f=lambda a,b:a<=b and-(`5`in`a`)-~f(a+1,b)

Рекурсивное решение. Спасибо @xnor за мотивацию для поиска решения с использованием логических операторов! Кроме того, спасибо @JonathanAllan и @xnor за то, что они направили меня и обрезали байт с 43 до 42!

Другие попытки на 43 байта

f=lambda a,b:a<=b and-~-(`5`in`a`)+f(a+1,b)
f=lambda a,b:a<=b and 1-(`5`in`a`)+f(a+1,b)

Будет if!`x`.count('5')работать?
Титус

2
@Titus Python имеет notоператор, который находится !на C-подобных языках, но занимает 3 байта :(
Yytsi

1
Подумайте об использовании логического короткого замыкания с andи or.
xnor

1
Да, красиво сделано! Теперь подумайте о сокращении этого not.
xnor

1
Ты действительно близко! Продолжайте пробовать вещи.
xnor


6

05AB1E , 8 7 6 байт

Сохранил байт благодаря Аднану

Ÿ5.å_O

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

объяснение

Ÿ         # inclusive range
 5.å      # map 5 in y for each y in the list
    _     # logical negation 
     O    # sum

05AB1E также имеет векторизацию å, то есть вы можете сделать Ÿ5.å_Oдля 6 байтов.
Аднан

negate смысл -n или n==0?1:0?
ETHproductions

@ETHproductions: Извините, это было неясно. Я имел в виду логическое отрицание, поэтомуn==0?1:0
Эминья

6

Pyth, 9 8 байт

Сохраненный байт благодаря FryAmTheEggman!

lf-\5T}E

Объяснение:

        Q # Input
      }E  # Form an inclusive range starting from another input
          #   order is reversed, but doesn't matter
 f-\5T    # Filter by absence of '5'
l         # Count the number of elements left

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


5

Perl 6 , 23 байта

{+grep {!/5/},$^a..$^b}

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

Как это работает

{                     }  # A lambda.
              $^a..$^b   # Range between the two lambda arguments.
  grep {!/5/},           # Get those whose string representation doesn't match the regex /5/.
 +                       # Return the size of this list.

5

Haskell , 39 байт

s!e=sum[1|x<-[s..e],notElem '5'$show x]

Попробуйте онлайн! Использование:

Prelude> 4 ! 17
12

Объяснение:

             [s..e]                     -- yields the range from s to e inclusive
          x<-[s..e]                     -- for each x in this range
          x<-[s..e],notElem '5'$show x  -- if the char '5' is not in the string representation of x
       [1|x<-[s..e],notElem '5'$show x] -- then add a 1 to the resulting list      
s!e=sum[1|x<-[s..e],notElem '5'$show x] -- take the sum of the list

4

R, 33 байта

f=function(x,y)sum(!grepl(5,x:y))

Использование:

> f=function(x,y)sum(!grepl(5,x:y))
> f(40,60)
[1] 10
> f(1,9)
[1] 8
> f(4,17)
[1] 12



4

PHP 7.1, 57 55 байт

for([,$a,$b]=$argv;$a<=$b;)$n+=!strstr($a++,53);echo$n;

Бежать с php -r '<code>' <a> <b>


Разве это не синтаксис PHP7.1?
aross

@aross: так и есть. Но PHP 7.1 старше 5 часов ( опубликовано 1 декабря )
Титус

1
конечно, я просто спросил, потому что я привык указывать версию, если она 7 или выше. Это также своего рода конвенции для Python
aross

1
Насколько я видел, соглашение для PHP - использовать самую последнюю версию, если не указано иное.
Титус

Я не думаю, что многие люди имеют последнюю минорную версию. Наименьший общий знаменатель на данный момент, вероятно, будет 5,5. Лично я использую FC 25 (считается довольно современным), который в настоящее время распространяет PHP 7.0. Если вы работаете в Windows, вам, вероятно, нужно обновить вручную.
aross

4

Mathematica, 46 44 42 байта

Спасибо alephalpha и DavidC за сохранение 2 байта каждый!

Tr@Boole[FreeQ@5/@IntegerDigits@Range@##]&

Безымянная функция, принимающая два целочисленных аргумента и возвращающая целое число. IntegerDigits@Range@##преобразует все числа между входами в списки цифр; FreeQ@5проверяет эти списки, чтобы решить, какие из них не содержат 5. Затем Booleпреобразует логические значения в нули и единицы и Trсуммирует результаты.

Другие решения (44 и 47 байтов):

Count[Range@##,x_/;IntegerDigits@x~FreeQ~5]&

IntegerDigits@x~FreeQ~5определяет, свободен ли список цифр числа от 5 с, и Count[Range@##,x_/;...]&подсчитывает, сколько чисел между входами проходит этот тест.

Tr[Sign[1##&@@IntegerDigits@#-5]^2&/@Range@##]&

1##&@@IntegerDigits@#-5берет список цифр числа, вычитает 5 из всех и умножает ответы вместе; Sign[...]^2затем преобразует все ненулевые числа в 1.


1
Count[Range@##,x_/;IntegerDigits@x~FreeQ~5]&
DavidC

1
Tr@Boole[FreeQ@5/@IntegerDigits@Range@##]&
алефальфа

3

Рубин, 36 35 байт

->a,b{(a..b).count{|x|!x.to_s[?5]}}

Thx IMP1 за -1 байт


1
Разве это не возвращает список без чисел, содержащих 5, а не размер этого списка?
IMP1

Вы правы, я скопировал / вставил не ту версию.
GB

1
Вы также можете использовать ?5( '5'символ) вместо /5/ в поиске, чтобы сохранить байт.
IMP1

3

Java 7, 80 78 байт

int c(int a,int b){int r=0;for(;a<=b;)r+=(""+a++).contains("5")?0:1;return r;}

Ungolfed:

int c(int a, int b){
  int r = 0;
  for (; a <= b; ) {
    r += ("" + a++).contains("5")
          ? 0
          : 1;
  }
  return r;
}

Тестовый код:

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

class M{
  static int c(int a,int b){int r=0;for(;a<=b;)r+=(""+a++).contains("5")?0:1;return r;}

  public static void main(String[] a){
    System.out.println(c(1, 9));
    System.out.println(c(4, 17));
  }
}

Выход:

8
12

3

PowerShell, 42 41 байт

param($a,$b)$a..$b|%{$z+=!($_-match5)};$z

Вызывается из командной строки как. \ No5s.ps1 1 20


1
Вы можете оставить место, чтобы сохранить байт. При строго числовых шаблонах регулярных выражений вам не нужен разделитель (например, -replace3или -split1или -notmatch5).
AdmBorkBork

Ах, хорошо, спасибо @AdmBorkBork
mcmurdo

2

Python 2, 61 56 байт

lambda a,b:len([n for n in range(a,b+1) if not"5"in`n`])

-5 байт благодаря tukkaaX


Не расстраивайтесь! Веселье и вызов себе - вот что важно. Вы можете удалить два пробела в not "5" in:) Кроме того, если вы используете Python2, вы можете заключать в xкавычки `` вместо выполнения str(x).
Yytsi

@TuukkaX Спасибо! также убрал пробел между in и `x`
sagiksp

Вы можете удалить []. Вам также не нужно пространство раньше if.
Деннис

@Dennis Я уже пробовал это, но он жалуется, что «объект типа« генератор »не имеет len ()».
Yytsi

@TuukkaX Верно. lambda a,b:sum(not"5"in`n`for n in range(a,b+1))работает хоть. tio.run/nexus/…
Деннис

2

Swift 52 байта

($0...$1).filter { !String($0).contains("5") }.count

Так как ваш вызов - это вызов Codegolf, вы должны указать свой счет. Кроме того, в Codegolf (по крайней мере, здесь), это требование, чтобы все программы должны были фактически конкурировать (например, имя вашей функции может быть просто одним символом, ваша действительная функция, вероятно, может быть уменьшена до одной строки). Я не знаю, Свифт, возможно, тебе придется поправить меня.
clismique

2

Пакетный, 95 байтов

@set/an=0,i=%1
:g
@if "%i%"=="%i:5=%" set/an+=1
@set/ai+=1
@if %i% leq %2 goto g
@echo %n%

Зацикливание вручную сохраняет некоторые байты, потому что в любом случае мне нужен счетчик цикла в переменной.


2

PHP, 56 байт

for($i=$argv[1];$i<=$argv[2];)trim(5,$i++)&&$x++;echo$x;

Запустите так:

php -r 'for($i=$argv[1];$i<=$argv[2];)trim(5,$i++)&&$x++;echo$x;' 1 9 2>/dev/null;echo
> 8

Версия для PHP 7.1 будет 53 байта (кредиты для Тита):

for([,$i,$e]=$argv;$i<=$e;)trim(5,$i++)&&$x++;echo$x;

объяснение

for(
  $i=$argv[1];          # Set iterator to first input.
  $i<=$argv[2];         # Loop until second input is reached.
)
  trim(5,$i++) && $x++; # Trim string "5" with the characters in the
                        # current number; results in empty string when
                        # `5` is present in the number. If that is not
                        # the case, increment `$x`

echo$x;                 # Output `$x`

Ах, черт возьми, я trimснова забыл о втором параметре.
Титус

2

CJam "легкое чистое математическое решение", 60

{{Ab5+_,\_5#)<\9e]);_4f>.m9b}%}:F;q~_:z$\:*0>{((+F:-}{F:+)}?

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

Он принимает числа в любом порядке, в массиве.

Объяснение:

Одной из основных проблем является вычисление f (n) = числа не 5 чисел от 1 до n (включительно) для любого положительного n. И ответ таков: возьмите десятичные цифры n, замените все цифры после первых 5 (если есть) на 9, затем замените все цифры 5..9 на 4..8 (уменьшение) и преобразуйте из базы 9. Например, 1752 → 1759 → 1648 → 1 * 9 ^ 3 + 6 * 9 ^ 2 + 4 * 9 + 8 = 1259. По сути, каждая позиция цифры имеет 9 допустимых значений, и 5xxxx эквивалентен 49999, потому что между ними больше нет действительных чисел.

Как только мы решили это, у нас есть несколько случаев: если входные числа (скажем, a и b, a <b) (строго) положительны, то результатом будет f (b) -f (a-1). Если они отрицательные, то мы можем взять абсолютные значения, изменить их порядок и использовать тот же расчет. И если a <= 0 <= b, то результатом будет f (-a) + f (b) +1.

Программа сначала реализует функцию F, как описано выше (но применяется к каждому числу в массиве), затем читает входные данные, преобразует числа в абсолютное значение и переупорядочивает их, и использует одно из 2 приведенных выше вычислений, основываясь на том, * b> 0 изначально.


Не "чистый", но хороший метод. здесь, получить +1 :)
Мэтью Ро

@ MatthewRoh спасибо, но что ты имеешь в виду под чистым? Это решение, которое выполняет прямые математические расчеты для входных чисел, без перебора диапазона. Что еще ты ожидал?
aditsu

2

Python 2 , 54 байта

i,j=input();k=0
while i<=j:k+=not"5"in`i`;i+=1
print k

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

Не самый короткий ответ Python Использует тот же алгоритм, но другой способ реализации с циклом while и не является лямбда-функцией.


Это программа, а не функция, и она использует вместо вместо. Чем не отличается? Хорошо, он все еще ищет строку "5" внутри увеличенного ввода, согласен. Есть ли способ лучше?
ElPedro

Это именно то, что есть, и именно поэтому это почтение. Извините, возможно, следовало сделать мой комментарий другим.
ElPedro

Тот же алгоритм, другой способ реализации. Нет проблем с вашими комментариями. Это лучше сформулировано?
ElPedro

Да, я удалю эти комментарии, чтобы раздел комментариев выглядел чистым.
Yytsi

1

Java 7, 77 байт

Это улучшение Kevins Answer , но, поскольку у меня пока нет репутации комментировать, этот новый ответ придется делать.

Итак, что я сделал:

  • Заменить indexOfоператоры contains(-1 байт)
  • Переместить увеличивающуюся часть цикла for в условный оператор (-2 байта)

цикл for ( 77 байт ):

int c(int a,int b){int r=1;for(;a++<b;)r+=(""+a).contains("5")?0:1;return r;}

рекурсивный ( 79 байт ):

int d(int r,int a,int b){r+=(""+a).contains("5")?0:1;return a!=b?d(r,a+1,b):r;}

Выход:

8
12

8
12

Проверьте это здесь !


Добро пожаловать в PPCG! Хорошие результаты в уже довольно симпатичном ответе. Я не так много знаю о Java, но не должен (""+a).contains("5")?0:1быть заменен !(""+a).contains("5")?
Кристоф

1
К сожалению, @Christoph нет, поскольку в Java логическое значение действительно просто логическое. Таким образом, троичная операция - единственный путь.
Тобиас Майстер

Хм, это грустно. Как насчет (""+a).contains("5")||r++?
Кристоф

1
@Christoph, который тоже не сработает, потому что вы не можете иметь логическое выражение само по себе. Я пытался заставить его работать в других местах (например, объявление цикла for), но без особого успеха. Отличная идея;)
Тобиас Майстер

1

C #, 67 байт

a=>b=>{int c=0;for(;a<=b;)c+=(a+++"").Contains("5")?0:1;return c;};

Я надеялся использовать, for(int c=0;...)но потом не удалось скомпилировать, потому что возвращение выходит за рамкиc
TheLethalCoder

1

JavaScript (ES6), 58 56 49 байт

let f =

(s,e)=>{for(c=0;s<=e;)c+=!/5/.test(s++);return c}

console.log(f(1, 9));
console.log(f(4, 17));
console.log(f(-9, -1));

Гольф 7 байтов благодаря ETHproductions .


1
Вы можете использовать, c+=!/5/.test(s++)чтобы сохранить несколько байтов :-)
ETHproductions

Большое спасибо! Я должен был удалить свои гольфы, хотя. Я так гордился ими. :(
Христиан Додов

Я думаю, что вы можете использовать карри, т.е. `s => e =>`
TheLethalCoder

Верхний ответ использует выделку синтаксиса. Я не буду редактировать мой, потому что он станет почти таким же. Спасибо за указание на это, хотя!
Христиан Додов

1

MATL , 10 байт

&:!V53-!As

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

объяснение

        % Implicitly grab two input arguments
&:      % Create an array from [input1....input2]
!V      % Convert to a string where each number is it's own row
53-     % Subtract ASCII '5' from each character.
!A      % Detect which rows have no false values (no 5's). Returns a logical array
s       % Sum the logical array to get the # numbers without 5's
        % Implicitly display the result

1

C #, 77 байт

(n,m)=>{var g=0;for(var i=n;i<m+1;i++)g+=(i+"").Contains("5")?0:1;return g;};

Анонимный лямбда-звонок.

Использует n(первое число) и m(последнее число) в качестве входных данных, а затем проверяет с помощью включения строки ( "".Contains("")).


Я не тот, кто понижает голос, но по модулю 5 не является правильным решением для задачи, поставленной ОП. Он должен исключать все, что содержит цифру 5в своем номере, поэтому 10(что ваш ответ не будет учитываться) следует учитывать.
Кевин Круйссен

@KevinCruijssen Исправлено.
devRicher

Это не компилируется, так как gдолжно быть инициализировано, когда указано, как оно названо, varтак что вам нужно, var g="";и вы можете использовать каррирование, т.е.n=>m=>
TheLethalCoder

Также это выводит список, а не счет
TheLethalCoder

1
@KevinCruijssen С вашими правками это по сути мой ответ ...
TheLethalCoder

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