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


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
Я б рекомендував найкоротший код як критерій виграшу та тег код-гольф (я навіть не помічав, що його не було!). Крім того, вам, мабуть, слід поставити тестовий випадок, який охоплює 50 або 500; також, можливо, одна, яка охоплює -50, і та, яка охоплює 0, була б хорошою ідеєю.
Джонатан Аллан

1
@JonathanAllan: Я оновлю приклади.
Арасувель

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

14
Ви кажете: "Номер старту завжди буде меншим, ніж кінцеве число". але один із ваших прикладів (-50, -59) прямо суперечить цьому
theonlygusti

Відповіді:


21

JavaScript (ES6), 36 33 байт

Здійснює введення з синтаксисом currying (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 Це має більше сенсу. Оновлено.
Арнольд

NB: Я не міг знайти жодної поради про синтаксис currying ES6, тому я написав його .
Арнольд

5
@TheLethalCoder b<aє для того, щоб зупинити рекурсію після підрахунку всіх чисел від bдо a, тому її видалення просто спричинить нескінченну рекурсію.
ETHproductions

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

17

Желе , 8 7 байт

-1 байт завдяки Деннісу (використовуйте той факт, що індексація в число трактує це число як десятковий список)

rAw€5¬S

СпробуйтеItOnline!

Як?

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

2 , 6 5 байт

Збережено байт завдяки Аднану

Ÿ5¢_O

Спробуйте в Інтернеті!

Пояснення

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

Примітка. Це працює через помилку в тому, ¢щоб функція застосовувалась до кожного елемента замість підрахунку відповідних елементів у списку.


Ви можете видалити, `як він поводиться однаково на масивах: p.
Аднан

@Adnan: Дякую! Я збирався це перевірити, але забув;)
Емінька

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оператора, який знаходиться !на С-подібних мовах, але він займає 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.å_O6 байт.
Аднан

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

Хаскелл , 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?
1717

@aross: Це так. Але PHP 7.1 старіший на 5 годин ( опубліковано 1 грудня )
Тит

1
Звичайно, я просто запитав, тому що я звик вказувати версію, якщо вона 7 або вище. Це також своєрідна
умова

1
Конвенція для PHP - наскільки я бачив - полягає у використанні останньої версії, якщо не вказано інше.
Тит

Я не думаю, що у багатьох людей є остання незначна версія. Найменш поширений на даний момент знаменник, мабуть, буде 5,5. Особисто я використовую FC 25 (вважається досить передній край), який наразі поширює PHP 7.0. Якщо ви працюєте в Windows, вам, ймовірно, потрібно оновити вручну.
1717

4

Математика, 46 44 42 байт

Дякуємо алефальфі та 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визначає, чи не містить список цифр числа 5s, і 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

Ви маєте рацію, я скопіював / вставив неправильну версію.
ГБ

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;}

Безголовки:

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 Дякую! також видалено пробіл між в і `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

Швидкий 52 байти

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

Оскільки ваш виклик - це виклик кодогольфа, вам слід включити свій рахунок. Крім того, у кодегольфі (принаймні тут), це вимога, що всі програми муз можуть бути фактично протиборчими (наприклад, назва вашої функції може бути лише одним символом; ваша фактична функція, ймовірно, може бути зведена до одного рядка). Я не знаю Свіфта, можливо, доведеться мене виправити.
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 Використовує той же алгоритм, але інший спосіб реалізації з циклом час і не є лямбда-функцією.


Це програма, а не функція, і вона використовується, а не для. Чим не відрізняється? Гаразд, він все ще шукає рядок "5" всередині посиленого вводу, погоджений. Чи є кращий спосіб?
ElPedro

Саме так воно і є, тому воно є захисним. Вибачте, можливо, я мав би зробити свій коментар іншим.
ElPedro

Той самий алгоритм, інший спосіб реалізації. Немає проблем з вашими коментарями. Це краще сказано?
ElPedro

Так, так :) Я видалю ці коментарі, щоб розділ коментарів виглядав чисто.
Yytsi

1

Java 7, 77 байт

Це вдосконалення відповіді Кевінса , але оскільки я ще не маю репутації коментувати, цю нову відповідь доведеться робити.

Отже, що я зробив:

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

for-loop ( 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, на жаль, ні, оскільки на Яві булевий справді є просто булевим. Тож потрійна операція - єдиний шлях.
Тобіас Мейстер

Гм, це сумно. Про що (""+a).contains("5")||r++?
Крістоф

1
@Christoph теж не буде працювати, тому що ви не можете мати булевий вираз самостійно. Я намагався змусити його працювати в інших місцях (наприклад, декларація for-loop), але не з великим успіхом. Хороша ідея Тхо;)
Тобіас Майстер

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));

Golfed 7 байт завдяки ETHproductions .


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

Дуже дякую! Мені довелося видалити свої гольфи. Я так пишався ними. :(
Християн Додов

Я думаю, ви можете використовувати currying, тобто `s => e =>`
TheLethalCoder

У верхній відповіді використовується синтаксис currying. Я не редагуватиму шахту, оскільки вона стане майже такою самою. Дякую, що вказали на це, хоча!
Християн Додов

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=>
currying,

Також цей список виводить не кількість
TheLethalCoder

1
@KevinCruijssen З вашими правками це, по суті, моя відповідь ...
TheLethalCoder

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.