Intro
The information panels are everywhere. When the technology became cheaper, the paper posters were transformed into luminous signs that show words that appear on one side and come out on the other, like the one on the figure:
When one of these signs starts up, it usually starts empty and the text leaves from the right side to the left, moving until it disappears.
Its functionality is to go on and off the small light bulbs (LEDs) to give the sensation of movement.
If instead of text we only need to show numbers, the poster can be much less sophisticated using the so-called seven-segment markers like the following:
In this case each number is represented by the combination on / off of only 7 light segments that allow to represent all the numbers:
The question we ask ourselves is how many changes of lights (how many on and off) should be made to pass through one of these posters a certain number?
For example, to show the 123 in a 3-digit sign that starts with all the LEDs off we will have:
This makes a total of 42 changes of lights.
Challenge
Given a non-negative number and a positive sign length calculate the number of lights changes.
Rules
- Assume input consist in a non-negative number (N>= 0) and a positive sign length (M> 0)
- Assume Sign length>= Number length (M>= digits(N))
Test cases
123, 3 => 42
45, 5 => 60
111, 3 => 12
98765, 10 => 220
0, 3 => 36
7 Answers 7
Python 2, (削除) 129 (削除ここまで) (削除) 126 (削除ここまで) (削除) 119 (削除ここまで) 104 bytes
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')
Thx for a big 15 bytes from ovs.
As specified, takes a non-negative number and a positive sign length, and returns total changes.
-
5\$\begingroup\$ What the actual fuck is this sorcery. You are a Python Lord. I get so happy getting my code under 200 bytes then you show up with
'7367355777e0d93bf0fb'
\$\endgroup\$Rushabh Mehta– Rushabh Mehta2018年08月23日 00:40:06 +00:00Commented Aug 23, 2018 at 0:40 -
\$\begingroup\$ @Rushabh Mehta: Heh heh. Well, I'm only standing on the shoulders of giants. Check out these tips posted by the true Jedi Knights. The string strategy I learned from here. \$\endgroup\$Chas Brown– Chas Brown2018年08月23日 03:35:59 +00:00Commented Aug 23, 2018 at 3:35
-
3
Jelly, 23 bytes
Dị"¤]þ+&g×ばつ
A dyadic link accepting the integer to display on the left and the sign length on the right which yields the number of changes (also works if the number of digits in the integer to display is greater than the sign length).
How?
During the entire show each 7-segment display (at some point) transitions from empty to the first digit, then to the second and so on, and finally from the last to empty again. The transitions each cost the bitwise XOR of the on-segments of the from-digit and to-digit (where empty is a "digit" with 0 on-segments). I stole the on-segments as integers from a previous revision of ETHproductions' answer, but any permutation of the 7 segments would do just as well.
Dị"¤]þ+&g×ばつ - 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
-
\$\begingroup\$ Could you save a byte by taking the number as a digit array? tio.run/##ATsAxP9qZWxsef//… \$\endgroup\$Shaggy– Shaggy2018年08月22日 20:26:35 +00:00Commented Aug 22, 2018 at 20:26
-
\$\begingroup\$ Yes, but "Given a non-negative number" and "input consist in a non-negative number" seemed strict to me. \$\endgroup\$Jonathan Allan– Jonathan Allan2018年08月22日 21:17:15 +00:00Commented Aug 22, 2018 at 21:17
JavaScript (Node.js), (削除) 104 (削除ここまで) (削除) 94 (削除ここまで) (削除) 93 (削除ここまで) 93 bytes
Saved 1 byte thanks to @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))
-
-
\$\begingroup\$ @Shaggy Nice trick, thanks! \$\endgroup\$ETHproductions– ETHproductions2018年08月22日 22:33:45 +00:00Commented Aug 22, 2018 at 22:33
-
\$\begingroup\$ OP has clarified that both inputs must specifically be integers (and not lists of digits or strings) \$\endgroup\$Οurous– Οurous2018年08月23日 00:47:55 +00:00Commented Aug 23, 2018 at 0:47
-
\$\begingroup\$ @Οurous Thanks, fixed at +0 bytes. \$\endgroup\$ETHproductions– ETHproductions2018年08月23日 01:08:38 +00:00Commented Aug 23, 2018 at 1:08
-
1\$\begingroup\$ Also, I think
0,3
should give36
; you give0
. (I had the same problem - fixing this cost me about 10 bytes grrrr... :) ). \$\endgroup\$Chas Brown– Chas Brown2018年08月23日 06:03:37 +00:00Commented Aug 23, 2018 at 6:03
Japt, (削除) 31 (削除ここまで) 30 bytes
Adapted from Jonathan's Jelly solution. Takes input in reverse order with the number to be displayed as a digit array.
*Vm!c"w]+>~?" pT ä^T x_¤¬x
-
\$\begingroup\$ OP has clarified that both inputs must specifically be integers (and not lists of digits or strings) \$\endgroup\$Οurous– Οurous2018年08月23日 00:48:17 +00:00Commented Aug 23, 2018 at 0:48
Clean, 280 bytes
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
There has to be a shorter way..
Charcoal, 40 bytes
×ばつ70⭆S§⪪")∧??%←6%*An×ばつNΣEθ¬=ι§θ+7κ
Try it online! Link is to verbose version of code. Works by converting the input into the binary segment values, then counting the number of changes between each character. Explanation:
S Convert first input to string
⭆ Map over digits and join
")∧??%←6%*An" Compressed segment value string
⪪ 7 Split into groups of seven characters
ι Current digit
I Convert to integer
§ Index into groups
0 Literal `0`
×ばつ7 Repeat seven times
+ Concatentate
≔ θ Assign to variable `q`
θ Variable `q`
E Map over characters
κ Current index
+7 Add seven
θ Variable `q`
§ Cyclically index
ι Current character
= Compare
¬ Logical not
Σ Sum results
N Second input
×ばつ Multiply
I Cast to string
Implicitly print
JavaScript (Node.js), 88 bytes
Takes input as (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
How?
Given a list \$\{d_1,d_2,\dots,d_n\}\$ of \$n\$ digits and a display width \$w\,ドル the total number \$N\$ of light changes is given by:
$$N=({T'}_{d_1}+\sum_{i=2}^n{T_{d_{i-1},d_i}}+{T'}_n)\times w$$
Where \$T_{x,y}\$ is the number of light changes for a transition from digit \$x\$ to digit \$y\$ and \${T'}_{x}\$ is the number of light changes for a transition from the blank digit to digit \$x\$ (or the other way around).
Commented
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
0,3 => 36
\$\endgroup\$