7-сегментні відмінності


26

Я думаю, що більшість людей тут знають, що таке 7-сегментний дисплей для цифр:

 _         _   _         _    _    _    _    _ 
| |    |   _|  _|  |_|  |_   |_     |  |_|  |_|
|_|    |  |_   _|    |   _|  |_|    |  |_|   _|

Ми можемо визначити різницю в 7 сегментах (7SD) між двома цифрами, щоб це кількість сегментів, які потрібно переключити, щоб переключитися з однієї на іншу. Наприклад, 7SD між 1і 2дорівнює 5 (три горизонтальні сегменти та два нижні вертикальних сегменти потрібно змістити), а 7SD між 6 і 8 - 1 .

Крім того, ми можемо визначити 7SD між двома числами як суму 7SD між їх відповідними цифрами. Якщо одне число довше іншого, ми припускаємо, що вони вирівняні вправо, і додамо кількість сегментів, необхідних для відображення додаткових найбільш значущих цифр більшої кількості. Як приклад, розглянемо 7SD між 12345та 549:

  x:  1 2 3 4 5
  y:      5 4 9
7SD:  2+5+2+0+1 = 10

Ваше завдання - обчислити 7SD між n і n + 1 , заданими n .

Для зручності ось повна таблиця 7SD між окремими цифрами. Рядок _представляє порожнє місце.

   _ 0 1 2 3 4 5 6 7 8 9

_  0 6 2 5 5 4 5 6 3 7 6
0  6 0 4 3 3 4 3 2 3 1 2
1  2 4 0 5 3 2 5 6 1 5 4
2  5 3 5 0 2 5 4 3 4 2 3
3  5 3 3 2 0 3 2 3 2 2 1
4  4 4 2 5 3 0 3 4 3 3 2
5  5 3 5 4 2 3 0 1 4 2 1
6  6 2 6 3 3 4 1 0 5 1 2
7  3 3 1 4 2 3 4 5 0 4 3
8  7 1 5 2 2 3 2 1 4 0 1
9  6 2 4 3 1 2 1 2 3 1 0

Вхідні дані

  • Введення - це одне додатне ціле число n.
  • Ви можете написати програму або функцію, взявши вхід через STDIN (або найближчу альтернативу), аргумент командного рядка або аргумент функції.
  • Ви можете припустити, що вхід є щонайменше на одне менше, ніж найбільше число, яке може бути представлене стандартним цілим типом вашої мови, якщо цей тип підтримує принаймні значення до 127.

Вихідні дані

  • Ви повинні надрукувати єдине ціле число, 7SD між nі n+1.
  • Ви можете виводити через STDOUT (або найближчу альтернативу), значення повернення функції або аргумент функції (out).

Оцінка балів

Застосовуються стандартні правила , найкоротший код (у байтах) виграє.

Випробування

З якоїсь незрозумілої причини ця послідовність ще не є в OEIS, хоча існує тісно пов'язана послідовність A123587 . Ось перші 100 номерів (починаючи з n = 1, 2, 3, ...):

5, 2, 3, 3, 1, 5, 4, 1, 4, 4, 5, 2, 3, 3, 1, 5, 4, 1, 7, 4, 5, 2, 3, 3, 1, 
5, 4, 1, 4, 4, 5, 2, 3, 3, 1, 5, 4, 1, 5, 4, 5, 2, 3, 3, 1, 5, 4, 1, 5, 4, 
5, 2, 3, 3, 1, 5, 4, 1, 3, 4, 5, 2, 3, 3, 1, 5, 4, 1, 7, 4, 5, 2, 3, 3, 1, 
5, 4, 1, 6, 4, 5, 2, 3, 3, 1, 5, 4, 1, 3, 4, 5, 2, 3, 3, 1, 5, 4, 1, 6, 4

Перший вхід, для якого 7SD більший, ніж 9, 1999має давати 11. Ось кілька інших великих прикладів:

n          7SD
1999        11
12345        1
999999      14
5699999     15
8765210248   1

Відповіді:


8

Желе , 25 22 21 20 байт

‘DṁDḟ"DFị9979482ḃ5¤S

Спробуйте в Інтернеті! або перевірити всі тестові випадки .

Фон

Спочатку збільшуємо вхід n і відкидаємо всі цифри n + 1 , які не змінилися.

Наприклад, якщо n дорівнює 5699999 , отримуємо наступне.

n     : 5700000
n + 1 : 5699999
Result:  700000

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

digit:   1 2 3 4 5 6 7 8 9 0
toggles: 4 5 2 3 3 1 5 4 1 2

Вихід - це просто сума окремих перемикань.

Це працює для більшості значень n , але слід бути особливо обережним, якщо n + 1 має більше цифр, ніж n . У цьому випадку всі цифри повинні бути 9- ми, і ми вирішуємо цю проблему, відрізаючи пробіл 0 від n + 1 .

Наприклад, якщо n дорівнює 999999 , отримуємо наступне.

n     :  999999
n + 1 : 1000000
Result: 100000

Це працює, тому що провідний 1 оцінює 4 перемикання (відстань між 0 і 1 ), а фактична кількість перемикань дорівнює 2 (відстань між 0 і 1 ), а придушення однієї відсталої точки 0 видаляє 2 суми перемикання з суми.

Як це працює

‘DṁDḟ"DFị9979482ḃ5¤S  Main link. Argument: n

‘                     Compute n+1.
 D                    Convert n+1 from integer to base 10.
   D                  Convert n from integer to base 10.
  ṁ                   Mold the left result as the right result.
                      This chops of a 0 if n+1 has more digits than n.
    ḟ"D               Vectorized filter-false with the base 10 digits of n.
                      This removes the digits from n+1 that are identical to
                      the corresponding digits of n.
       F              Flatten the resulting list of lists.
         9979482ḃ5¤   Convert 9979482 to bijective base 5.
                      This yields [4, 5, 2, 3, 3, 1, 5, 4, 1, 2].
        ị             Retrieve the digits at the right that correspond to the
                      indices at the left.
                   S  Compute the sum of the results.

10

JavaScript (ES6), 46 40 байт

f=n=>n?+"452331541"[n%10]||f(n/10|0)+2:2

Альтернативна рецептура, також 46 40 байт:

f=n=>n?26523308>>n%10*3&7||f(n/10|0)+2:2

Редагувати: Збережено 6 байт завдяки @xsot.


Якщо логічний або оператор в ES6 поводиться як один у python, ви можете додатково скоротити другий код. Зверніться до мого подання для прикладу.
xsot

@xsot Насправді я можу скоротити обидва! Я не думаю, що це допомагає мені змінити нульовий спеціальний регістр, оскільки це лише 4 байти.
Ніл

Нічого собі, я здивований, що перший працює. Я очікував помилки.
xsot

@xsot javascript не просто вимикається. Це просто робить все, що здавалося найбільш правильним підходом за ці десять днів, коли народився Javascript. . Пізніші версії дозволяють вам скористатися дещо суворішою поведінкою, але навіщо хтось тут робити це? Короткочасова поведінка логічних операторів є досить поширеною, хоча лише PHP робить неправильну справу, завжди повертаючи булеву систему.
Джон Дворак

@JanDvorak Насправді мене здивувало те, що ви можете отримати доступ до індексу рядка, більшого за довжину рядка.
xsot

10

Python, 50 48 байт

f=lambda n:26523308-0**n*2>>n%10*3&7or f(n/10)+2

Пояснення

Ця функція діє на найменш nзначущій цифрі числа , підсумовуючи 7SD цифр при збільшенні на одиницю до першої нецифрової цифри 9.

26523308- це бітова маска, що кодує відображення цифр 0-8. Коли n=0, що виникає лише тоді, коли nскладається лише 9s, відповідь буде знята двома. Це компенсується виразом 0**n*2. Що стосується цифри 9, то бітова маска оцінюється до нуля, що спровокує рекурсивний виклик при додаванні 2до 7SD.


Чи можемо ми пояснити, як це відбувається перетворення? Я маю на увазі +1 за кмітливість, але в розумному я загубився.
CAD97

8

05AB1E , 31 30 28 27 26 байт

Код:

9Ü©T%•2X›ùì•sè¹g®g-·¹Ú9Q·O

Пояснення ( застаріле ):

9Ü                              # Trim off trailing 9's
  ©                             # Copy this into the register
   T%                           # Get the last non-9 digit
     žh                         # Short for 0123456789
       •2X›ù앧                 # Compressed version of 4523315412
               ‡                # Transliterate

Ми змінюємо наступне на останню цифру, що не має 9 значень:

0 -> 4
1 -> 5
2 -> 2
3 -> 3
4 -> 3
5 -> 1
6 -> 5
7 -> 4
8 -> 1
9 -> 2

Для особливих випадків:

                ¹g              # Get the length of the input
                  ®g            # Get the length of the input with all trailing 9 gone
                    -           # Substract, giving the number of 9's at the end of 
                                  the input
                     2*         # Multiply by two
                       O        # Sum everything up
                        ¹Ú      # Uniquify the input
                          9Qi   # If this is equal to 9 (only 9's in the input)
                             Ì  #   Increment by 2 (_ -> 1)

Використовує кодування CP-1252 . Спробуйте в Інтернеті! .

28 байт альтернатива: D[¤©•2X›ùì•sès®9Ê#¨]\rÚ9Q4*O.



3

MATL , 61 39 36 байт

tQvV15\'3dAsMh818RG5'6Y27WZaw)Z}Z~Bz

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

Пояснення

tQv            % Implicit input. Duplicate, add 1, concatenate vertically
V              % Convert to 2D char array: each number in a row, possibly left-padded 
               % with a space
15\            % Modulo 15. With modular indexing this corresponds to the order
               % '9', ' ', '0', '1', ..., '8'
'3dAsMh818RG5' % This string encodes active segments for each of the 11 chars
6Y2            % Source alphabet printable ASCII chars (predefined literal)
7W             % Target alphabet: [0 1 ... 127]
Za             % Base conversion: decode string into vector of 11 numbers, where each
               % number from 0 to 127 encodes the 7-segment representation of a digit,
               % in the order '9', ' ', '0', '1', ..., '8'
w              % Swap top two elements in stack
)              % Use as index. Gives 2-row array, where each column is a digit 
Z}             % Split into the two rows
Z~             % Bitwise XOR, elementwise
B              % Convert to binary. Each number gives a row
z              % Number of nonzero elements. Implicitly display

3

Джулія, 44 байти

!x=x<1?2:(t=x%10÷1)<9?3045058÷6^t%6:2+!.1x

Спробуйте тут.

Денніс врятував байт!


1
З цікавості, чому б просто не використати цифри?
Conor O'Brien

Я не можу повірити, що є Джулія ТІО. Welp, час, щоб потім вивчити Джулію ...
Mama Fun Roll

3

Пітон, 71 66 байт

48 байт по xsot . Ще більше магічної математики!

f=lambda n:(2+f(n/10)if n%10==9else 26523308>>n%10*3&7)if n else 2

Побачити це на ideone

Тому що попередня відповідь Python не працює і далеко не оптимальна. Простий порт попередньої версії ES6 . Тепер, використовуючи біт подвійний (з альтернативної формули ES6), щоб вирізати акторський склад!

Можна змусити працювати з Python 3, явно використовуючи floordiv для +1 байта.


ви можете вивезти місце після9
Мальтісен

@Maltysen, мабуть, ти маєш рацію. Я думав , що це помилка , тому що eє допустимим лист після NUM, наприклад, 9e9.
CAD97

Це довше, ніж моя відповідь на Java ! Як ми можемо це виправити? Зауважте, що повернення порівняння n%10==9до n%10<9значення не економить, оскільки пробіл у цьому порядку не потребує.
CAD97

І я повернувся, побачивши, що xsot зробив набагато коротшу версію Python. Молодці!
CAD97

2

Джольф, 32 байти

Ώ?H?<γ%Ht9P."452331541"γ+2Ώc/Ht2

Спробуйте тут!

Пояснення

Це переклад відповіді Ніла.

Ώ?H?<γ%Ht9P."452331541"γ+2Ώc/Ht2
Ώ                                 define a function Ώ of H
 ?H                            2  (when H is zero, return is 2)
      %Ht                         H mod 10
     γ                            γ = ^
   ?<    9                        is it less than 9?
                                  if so:
           ."452331541"γ           get the γth element of that string
          P                        as a number
                                  else
                        +2         add two to
                          Ώ        Ώ over
                           c/Ht    int(H / 10)


0

J, 53 байти

2:`((2+10$:@<.@%~[)`(6|3045058<.@%6^])@.(9>])10&|)@.*

Спочатку заснований на рішенні @ Ніла . Потім покращується, зберігаючи байт, використовуючи ту ж формулу в розчині @ Lynn .

54-байтна версія на основі рядка є

2:`((2+10$:@<.@%~[)`('452331541'".@{~])@.(9>])10&|)@.*

Використання

   f =: 2:`((2+10$:@<.@%~[)`(6|3045058<.@%6^])@.(9>])10&|)@.*
   f 1999
11
   f 1999 12345 999999 5699999 8765210248
11 1 14 15 1

0

Сітківка , 34 байти

M!`.9*$
^9
0
T`d`4523315412
.
$*
.

Спробуйте в Інтернеті!(Перший рядок просто дозволяє обробляти декілька тестових випадків одночасно.)

Пояснення

Як і більшість відповідей, виявлених до цього часу, нам не потрібно використовувати повну таблицю, оскільки 9при збільшенні є лише найменш значущі нецифрові зміни. Ось так і працює ця відповідь.

M!`.9*$

Це відповідає ( M) регулярному вираженню, .9*$тобто першій цифрі, яка відокремлена лише 9s від кінця. !Каже Retina замінити вхід з цим матчем, відкидаючи все , що не впливає на 7SD.

^9
0

Якщо вхід зараз починається з 9цього засобу, то сам вхід складався лише з 9s, тому 7-сегментний дисплей повинен додати a, 1який коштує 2. Найпростіший спосіб вирішити це - замінити провідне 9в даному випадку на a 0, оскільки вартість збільшення 9(до 0) є, 2а вартість збільшення 0(до 1) становить 4, тому це збільшує загальну вартість на 2необхідну кількість.

T`d`4523315412

Тепер у нас є етап транслітерації, який замінює кожну цифру її вартістю для її збільшення (оскільки dрозширюється до 0123456789). Зауважте, що це перша піддіагональ таблиці 7SD.

.
$*

Це замінює кожну цифру nз nкопіями 1, тобто він перетворює кожну цифру унарний, і так як немає сепараторів негайно додає їх разом.

.

Нарешті, ми підраховуємо кількість знаків (тобто кількість збігів .) у результаті, що перетворює одинарну суму назад у десяткову.

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