Семисегментная прокрутка

15

Песочница Пост

вступление

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

введите описание изображения здесь

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

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

Если вместо текста нам нужно показывать только цифры, постер может быть гораздо менее изощренным с использованием так называемых семисегментных маркеров, таких как:

введите описание изображения здесь

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

введите описание изображения здесь

Вопрос, который мы задаем себе, состоит в том, сколько изменений освещения (сколько включений и выключений) необходимо сделать, чтобы пройти через один из этих плакатов определенное число?

Например, чтобы показать 123 в 3-значном знаке, который начинается со всех выключенных светодиодов, мы будем иметь:

введите описание изображения здесь

Это делает в общей сложности 42 смены огней.


Вызов

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

правила

  • Предположим, что входные данные состоят из неотрицательного числа (N> = 0) и длины положительного знака (M> 0)
  • Предположим, длина знака> = длина номера (M> = цифры (N))

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

123, 3        => 42
45, 5         => 60
111, 3        => 12
98765, 10     => 220
0, 3          => 36
Луис Фелипе Де Иисус Муньос
источник
1
Какова цель вопроса? В действительности, такая деталь, как MAX7219, будет контролировать 8 цифр, и для их отображения вы просто отправите 8 цифр в MAX7219 с помощью команд SPI. 8-й разряд десятичной запятой из 1 или 2 цифр будет использоваться для индикатора - / +. Например, 4 можно объединить в цепочку, чтобы создать экран размером 8 x 32 точек для прокрутки текста, как этот, который я сделал: youtube.com/watch?v=hwYqgyMc5S4
CrossRoads
3
@CrossRoads На самом деле это не предназначено для реального аппаратного ответа или чего-то подобного.
Сложно
1
Предлагаемый тестовый пример:0,3 => 36
Час Браун
1
Можем ли мы взять первое целое число как строку или список цифр?
Οurous
1
@ Οurous нет, вы должны принять оба входных данных как целое число
Луис Фелипе Де Иисус Муньос

Ответы:

7

Python 2 , 129 126 119 104 байта

def f(n,k,p=0):z=p<1or n>0;q=-~ord('}/lx2Z^o~z'[n%10])*z;return(z and f(n/10,k,q))+k*bin(p^q).count('1')

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

Спасибо за большие 15 байтов из овсов .

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

Час Браун
источник
4
Что на самом деле, черт возьми, это колдовство. Вы Лорд Питона. Я так счастлив получить мой код размером менее 200 байт, тогда вы обнаруживаете'7367355777e0d93bf0fb'
Дон Тысяча
@Rushabh Мехта: Хе хе. Ну, я стою только на плечах гигантов. Ознакомьтесь с этими советами, написанными настоящими рыцарями-джедаями. Струнная стратегия, которую я узнал здесь .
Час Браун
2
104 байта или 102 байта с непечатаемой ( \x7f) между pи {.
овс
@ovs: Хорошая настройка!
Час Браун
3

Желе , 23 байта

Dị“¤]þ+>~Œ¶?w‘Ø0j^ƝBFS×

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

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

Как?

В течение всего шоу каждый 7-сегментный дисплей (в какой-то момент) переходит от пустого к первому разряду, затем ко второму и т. Д. И, наконец, из последнего к пустому снова. Каждый из переходов стоит поразрядное XOR включенных сегментов от цифры до цифры (где пусто «цифра» с 0 сегментами). Я украл on-сегменты как целые числа из предыдущей версии ответа ETHproductions , но любая перестановка из 7 сегментов тоже подойдет .

Dị“¤]þ+>~Œ¶?w‘Ø0j^ƝBFS× - Link: integer to display, V; integer sign length, L  e.g. 123, 3
D                       - cast V to decimal digits                                  [1,2,3]
  “¤]þ+>~Œ¶?w‘          - code-page indices list = [3,93,31,43,62,126,19,127,63,119]
 ị                      - index into (1-based & modular) (vectorises)             [3,93,31]
              Ø0        - literal = [0,0]                                             [0,0]
                j       - join                                                [0,3,93,31,0]
                  Ɲ     - pairwise application of:
                 ^      -   bitwise XOR                                        [3,94,66,31]
                   B    - convert to binary digits (vectorises)               [[1,1],[1,0,1,1,1,1,0],[1,0,0,0,0,1,0],[1,1,1,1,1]]
                    F   - flatten                                             [1,1,1,0,1,1,1,1,0,1,0,0,0,0,1,0,1,1,1,1,1]
                     S  - sum                                                            14
                      × - multiply by L                                                  42
Джонатан Аллан
источник
Не могли бы вы сохранить байт, взяв число в качестве массива цифр? tio.run/##ATsAxP9qZWxsef//…
Лохматый
Да, но «Учитывая неотрицательное число» и «вход состоит из неотрицательного числа» показалось мне строгим.
Джонатан Аллан
3

JavaScript (Node.js) , 104 94 93 93 байта

Сохранено 1 байт благодаря @Shaggy

B=n=>n&&n%2+B(n>>1)
F=(d,w,q)=>w*B(q^(q=d&&"w`>|i]_p}".charCodeAt(d%10)))+(d&&F(d/10|0,w,q))

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

ETHproductions
источник
Я думаю, что это работает для -1 байта.
лохматый
@ Шэгги Хороший трюк, спасибо!
ETHproductions
OP пояснил , что оба входа должны определенно быть целыми числами (а не списки цифр или строки)
Οurous
@ Οurous Спасибо, исправлено на +0 байт.
ETHproductions
1
Кроме того, я думаю, 0,3следует дать 36; Вы даете 0. (У меня была такая же проблема - исправление этого стоило мне около 10 байт грррр ... :)).
Час Браун
2

Japt, 31 30 байт

Адаптировано из решения Jonathan's Jelly. Принимает ввод в обратном порядке с номером, отображаемым в виде массива цифр.

*Vm!c"w]+>~?" pT ä^T x_¤¬x

Попытайся

мохнатый
источник
OP пояснил , что оба входа должны определенно быть целыми числами (а не списки цифр или строки)
Οurous
2

Чистый , 280 байт

import StdEnv,Data.List
~ =toInt
?s=sum[(~s>>p)rem 2\\p<-[0..6]]
$n l#j=repeatn l 0
#n=j++[~c-47\\c<-:toString n]++j
#k=[getItems(map((!!)[0,119,3,62,31,75,93,125,19,127,95])n)[i-l..i-1]\\i<-[0..length n]]
=sum(zipWith@(tl k)k)
@[u][]= ?u
@[u:x][v:y]= ?((bitxor)u v)+ @x y
@[][]=0

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

Там должен быть более короткий путь ..

Οurous
источник
1

Древесный уголь , 40 байт

≔⁺×⁷0⭆S§⪪”)∧??%←⁶%*An”⁷IιθI×NΣEθ¬⁼ι§θ⁺⁷κ

Попробуйте онлайн! Ссылка на подробную версию кода. Работает путем преобразования входных данных в значения двоичного сегмента, а затем подсчитывает количество изменений между каждым символом. Объяснение:

      S                     Convert first input to string
     ⭆                      Map over digits and join
         ”)∧??%←⁶%*An”      Compressed segment value string
        ⪪             ⁷     Split into groups of seven characters
                        ι   Current digit
                       I    Convert to integer
       §                    Index into groups
    0                       Literal `0`
  ×⁷                        Repeat seven times
 ⁺                          Concatentate
≔                        θ  Assign to variable `q`

     θ          Variable `q`
    E           Map over characters
             κ  Current index
           ⁺⁷   Add seven
          θ     Variable `q`
         §      Cyclically index
        ι       Current character
       ⁼        Compare
      ¬         Logical not
   Σ            Sum results
  N             Second input
 ×              Multiply
I               Cast to string
                Implicitly print
Нил
источник
1

JavaScript (Node.js) , 88 байт

Принимает вход как (integer)(width).

n=>w=>[...n+'',g=n=>n&&1+g(n&n-1)].map(c=>s+=g(x^(x=Buffer('w$]m.k{%o')[c])),x=s=0)|s*w

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

Как?

{d1,d2,...,dN}NвесN

Nзнак равно(T'd1+Σязнак равно2NTdя-1,dя+T'N)×вес

TИкс,YИксYT'ИксИкс

комментарии

n => w =>                       // n = integer; w = width of display
  [ ...n + '',                  // coerce n to a string and split it
    g = n =>                    // g = helper function counting the number of 1's
      n && 1 + g(n & n - 1)     // by defining it here, we also force an extra iteration
  ]                             // with an undefined digit (interpreted as the blank digit)
  .map(c =>                     // for each entry c in this array:
    s += g(                     //   add to s the result of a call to g():
      x ^ (x =                  //     XOR the previous value of x
        Buffer('w$]m.k{%?o')[c] //     with the new one, picked from a 10-entry lookup
      )                         //     gives undefined (coerced to 0) for the last entry
    ),                          //   end of call to g()
    x = s = 0                   //   start with x = 0 and s = 0
  ) | s * w                     // end of map(); return s * w
Arnauld
источник